diff options
| author | NotAPenguin <michiel.vandeginste@gmail.com> | 2024-09-02 23:17:17 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-09-02 23:17:17 +0200 |
| commit | 1b820de08a05070909a267e17f033fcf58ac8710 (patch) | |
| tree | 02831a025986a06b20f87e5bcc69d1e0c639a342 /src/main/java/tectech/mechanics/tesla | |
| parent | afd3fd92b6a6ab9ab0d0dc3214e6bc8ff7a86c9b (diff) | |
| download | GT5-Unofficial-1b820de08a05070909a267e17f033fcf58ac8710.tar.gz GT5-Unofficial-1b820de08a05070909a267e17f033fcf58ac8710.tar.bz2 GT5-Unofficial-1b820de08a05070909a267e17f033fcf58ac8710.zip | |
The Great Renaming (#3014)
* move kekztech to a single root dir
* move detrav to a single root dir
* move gtnh-lanthanides to a single root dir
* move tectech and delete some gross reflection in gt++
* remove more reflection inside gt5u
* delete more reflection in gt++
* fix imports
* move bartworks and bwcrossmod
* fix proxies
* move galactigreg and ggfab
* move gtneioreplugin
* try to fix gt++ bee loader
* apply the rename rules to BW
* apply rename rules to bwcrossmod
* apply rename rules to detrav scanner mod
* apply rename rules to galacticgreg
* apply rename rules to ggfab
* apply rename rules to goodgenerator
* apply rename rules to gtnh-lanthanides
* apply rename rules to gt++
* apply rename rules to kekztech
* apply rename rules to kubatech
* apply rename rules to tectech
* apply rename rules to gt
apply the rename rules to gt
* fix tt import
* fix mui hopefully
* fix coremod except intergalactic
* rename assline recipe class
* fix a class name i stumbled on
* rename StructureUtility to GTStructureUtility to prevent conflict with structurelib
* temporary rename of GTTooltipDataCache to old name
* fix gt client/server proxy names
Diffstat (limited to 'src/main/java/tectech/mechanics/tesla')
3 files changed, 289 insertions, 0 deletions
diff --git a/src/main/java/tectech/mechanics/tesla/ITeslaConnectable.java b/src/main/java/tectech/mechanics/tesla/ITeslaConnectable.java new file mode 100644 index 0000000000..27fa829bad --- /dev/null +++ b/src/main/java/tectech/mechanics/tesla/ITeslaConnectable.java @@ -0,0 +1,184 @@ +package tectech.mechanics.tesla; + +import static java.lang.Math.sqrt; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +import com.google.common.collect.Multimap; + +import tectech.mechanics.spark.ThaumSpark; + +public interface ITeslaConnectable extends ITeslaConnectableSimple { + + // Map with all Teslas in the same dimension and the distance to them //TODO Range + Multimap<Integer, ITeslaConnectableSimple> getTeslaNodeMap(); + + // ThaumCraft lighting coordinate pairs, so we can send them in bursts and save on lag + HashSet<ThaumSpark> getSparkList(); + + // -128 to -1 disables capability + // 0 means any source or target + // 1 to 127 must match on source and target or source/target must be 0 + byte getTeslaTransmissionCapability(); + + // Transmission Range is typically 16+ in blocks + int getTeslaTransmissionRange(); + + boolean isOverdriveEnabled(); + + int getTeslaEnergyLossPerBlock(); + + float getTeslaOverdriveLossCoefficient(); + + long getTeslaOutputVoltage(); + + long getTeslaOutputCurrent(); + + boolean teslaDrainEnergy(long teslaVoltageDrained); + + class TeslaUtil { + + private static final HashSet<ITeslaConnectableSimple> teslaSimpleNodeSet = new HashSet<>(); // Targets for power + // transmission + private static final HashSet<ITeslaConnectable> teslaNodeSet = new HashSet<>(); // Sources of power transmission + private static final List<ITeslaConnectableSimple> scheduledRemove = new ArrayList<>(); + + public static void teslaSimpleNodeSetAdd(ITeslaConnectableSimple target) { + if (!teslaSimpleNodeSet.contains(target)) { + teslaSimpleNodeSet.add(target); + teslaNodeSet.forEach(origin -> addTargetToTeslaOrigin(target, origin)); + } + } + + public static void teslaSimpleNodeSetRemove(ITeslaConnectableSimple target) { + teslaSimpleNodeSet.remove(target); + if (target instanceof ITeslaConnectable) teslaNodeSet.remove(target); + teslaNodeSet.forEach(origin -> removeTargetFromTeslaOrigin(target, origin)); + } + + public static void teslaSimpleNodeSetRemoveScheduled(ITeslaConnectableSimple target) { + scheduledRemove.add(target); + } + + public static void housekeep() { + for (ITeslaConnectableSimple e : scheduledRemove) { + teslaSimpleNodeSet.remove(e); + } + scheduledRemove.clear(); + } + + private static void addTargetToTeslaOrigin(ITeslaConnectableSimple target, ITeslaConnectable origin) { + if (origin.equals(target) || !origin.getTeslaDimension() + .equals(target.getTeslaDimension())) { + // Skip if looking at myself and skip if not in the same dimension + // TODO, INTERDIM? + return; + } else if (origin.getTeslaTransmissionCapability() != 0 && origin.getTeslaReceptionCapability() != 0 + && origin.getTeslaTransmissionCapability() != origin.getTeslaReceptionCapability()) { + // Skip if incompatible + return; + } + // Range calc + int distance = (int) sqrt( + origin.getTeslaPosition() + .distanceSq(target.getTeslaPosition())); + if (distance > origin.getTeslaTransmissionRange() * target.getTeslaReceptionCoefficient()) { + // Skip if the range is too vast + return; + } + origin.getTeslaNodeMap() + .put(distance, target); + } + + private static void removeTargetFromTeslaOrigin(ITeslaConnectableSimple target, ITeslaConnectable origin) { + // Range calc TODO Remove duplicate? + int distance = (int) sqrt( + origin.getTeslaPosition() + .distanceSq(target.getTeslaPosition())); + origin.getTeslaNodeMap() + .remove(distance, target); + } + + public static void generateTeslaNodeMap(ITeslaConnectable origin) { + origin.getTeslaNodeMap() + .clear(); + for (ITeslaConnectableSimple target : teslaSimpleNodeSet) { + // Sanity checks + if (target == null) { + // The Tesla Covers do not remove themselves from the list and this is the code that does + teslaSimpleNodeSet.remove(null); + continue; + } + addTargetToTeslaOrigin(target, origin); + } + teslaNodeSet.add(origin); + } + + public static long powerTeslaNodeMap(ITeslaConnectable origin) { + long remainingAmperes = origin.getTeslaOutputCurrent(); + boolean canSendPower = !origin.isTeslaReadyToReceive() && remainingAmperes > 0; + + if (canSendPower) { + for (Map.Entry<Integer, ITeslaConnectableSimple> Rx : origin.getTeslaNodeMap() + .entries()) { + // Do we still have power left to send kind of check + if (origin.getTeslaStoredEnergy() + < (origin.isOverdriveEnabled() ? origin.getTeslaOutputVoltage() * 2 + : origin.getTeslaOutputVoltage())) + break; + // Explicit words for the important fields + ITeslaConnectableSimple target = Rx.getValue(); + int distance = Rx.getKey(); + // Can our target receive energy? + if (!target.isTeslaReadyToReceive()) continue; + + // Calculate the voltage output + long outputVoltageInjectable; + long outputVoltageConsumption; + if (origin.isOverdriveEnabled()) { + outputVoltageInjectable = origin.getTeslaOutputVoltage(); + outputVoltageConsumption = origin.getTeslaOutputVoltage() + + ((long) distance * origin.getTeslaEnergyLossPerBlock()) + + (long) Math + .round(origin.getTeslaOutputVoltage() * origin.getTeslaOverdriveLossCoefficient()); + } else { + outputVoltageInjectable = origin.getTeslaOutputVoltage() + - ((long) distance * origin.getTeslaEnergyLossPerBlock()); + outputVoltageConsumption = origin.getTeslaOutputVoltage(); + } + + // Break out of the loop if the cost is too high + // Since the next target will have an even higher cost, just quit now. + if (origin.getTeslaStoredEnergy() < outputVoltageConsumption) break; + + // Now shove in as many packets as will fit~ + while (canSendPower) { + if (target.teslaInjectEnergy(outputVoltageInjectable)) { + origin.teslaDrainEnergy(outputVoltageConsumption); + origin.getSparkList() + .add( + new ThaumSpark( + origin.getTeslaPosition(), + target.getTeslaPosition(), + origin.getTeslaDimension())); + remainingAmperes--; + // Update the can send power flag each time we send power + canSendPower = (origin.getTeslaStoredEnergy() < outputVoltageConsumption + || remainingAmperes > 0); + } else { + // Breaks out when I can't send anymore power + break; + } + } + + // Break out if we can't send power anymore + if (!canSendPower) break; + } + } + return origin.getTeslaOutputCurrent() - remainingAmperes; + } + } +} diff --git a/src/main/java/tectech/mechanics/tesla/ITeslaConnectableSimple.java b/src/main/java/tectech/mechanics/tesla/ITeslaConnectableSimple.java new file mode 100644 index 0000000000..8cbbd75ca0 --- /dev/null +++ b/src/main/java/tectech/mechanics/tesla/ITeslaConnectableSimple.java @@ -0,0 +1,24 @@ +package tectech.mechanics.tesla; + +import com.gtnewhorizon.structurelib.util.Vec3Impl; + +public interface ITeslaConnectableSimple { + + // -128 to -1 disables capability + // 0 means any source or target + // 1 to 127 must match on source and target or source/target must be 0 + byte getTeslaReceptionCapability(); + + // Reception Coefficient is a range extension, typical is 1 + float getTeslaReceptionCoefficient(); + + boolean isTeslaReadyToReceive(); + + long getTeslaStoredEnergy(); + + boolean teslaInjectEnergy(long teslaVoltageInjected); + + Vec3Impl getTeslaPosition(); + + Integer getTeslaDimension(); +} diff --git a/src/main/java/tectech/mechanics/tesla/TeslaCoverConnection.java b/src/main/java/tectech/mechanics/tesla/TeslaCoverConnection.java new file mode 100644 index 0000000000..0ab421361f --- /dev/null +++ b/src/main/java/tectech/mechanics/tesla/TeslaCoverConnection.java @@ -0,0 +1,81 @@ +package tectech.mechanics.tesla; + +import static tectech.mechanics.tesla.ITeslaConnectable.TeslaUtil.teslaSimpleNodeSetRemoveScheduled; + +import net.minecraftforge.common.util.ForgeDirection; + +import com.google.common.base.Objects; +import com.gtnewhorizon.structurelib.util.Vec3Impl; + +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; + +public class TeslaCoverConnection implements ITeslaConnectableSimple { + + private final IGregTechTileEntity IGT; + private final Vec3Impl pos; + private final byte teslaReceptionCapability; + + public TeslaCoverConnection(IGregTechTileEntity IGT, byte teslaReceptionCapability) { + this.IGT = IGT; + this.pos = new Vec3Impl(IGT.getXCoord(), IGT.getYCoord(), IGT.getZCoord()); + + this.teslaReceptionCapability = teslaReceptionCapability; + } + + @Override + public byte getTeslaReceptionCapability() { + return teslaReceptionCapability; + } + + @Override + public float getTeslaReceptionCoefficient() { + return 1; + } + + @Override + public boolean isTeslaReadyToReceive() { + return true; + } + + @Override + public long getTeslaStoredEnergy() { + return IGT.getStoredEU(); + } + + @Override + public Vec3Impl getTeslaPosition() { + return pos; + } + + @Override + public Integer getTeslaDimension() { + return IGT.getWorld().provider.dimensionId; + } + + @Override + public boolean teslaInjectEnergy(long teslaVoltageInjected) { + // Same as in the microwave transmitters, this does not account for amp limits + boolean output = false; + + if (!IGT.isDead()) { + output = IGT.injectEnergyUnits(ForgeDirection.UP, teslaVoltageInjected, 1L) > 0L; + } else { + teslaSimpleNodeSetRemoveScheduled(this); + } + + return output; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + TeslaCoverConnection that = (TeslaCoverConnection) o; + return Objects.equal(IGT, that.IGT); + } + + @Override + public int hashCode() { + return Objects.hashCode(IGT); + } +} |
