diff --git a/src/api/java/blusunrize/immersiveengineering/api/wires/localhandlers/EnergyTransferHandler.java b/src/api/java/blusunrize/immersiveengineering/api/wires/localhandlers/EnergyTransferHandler.java index 7741b01588..766a5f762d 100644 --- a/src/api/java/blusunrize/immersiveengineering/api/wires/localhandlers/EnergyTransferHandler.java +++ b/src/api/java/blusunrize/immersiveengineering/api/wires/localhandlers/EnergyTransferHandler.java @@ -41,6 +41,7 @@ public class EnergyTransferHandler extends LocalNetworkHandler implements IWorld private final Map sinks = new HashMap<>(); private final List transferPaths = new ArrayList<>(); private boolean sourceSinkMapInitialized = true; + HashMap> limits = new HashMap<>(); public EnergyTransferHandler(LocalWireNetwork net, GlobalWireNetwork global) { @@ -119,6 +120,7 @@ private void reset() sources.clear(); transferPaths.clear(); sourceSinkMapInitialized = false; + limits.clear();; } public Map getSources() @@ -163,6 +165,9 @@ private void updateSourcesAndSinks() sinks.put(cp, energyIIC); if(energyIIC.isSource(cp)) sources.put(cp, energyIIC); + if(energyIIC instanceof LimitingEnergyConnector limiting) + for(Connection c : localNet.getConnections(cp)) + limits.put(c, Arrays.asList(limiting.getPowerLimit(), limiting.getPowerLimit())); } } for(Entry source : sources.entrySet()) @@ -220,6 +225,7 @@ private void runDijkstraWithSource(ConnectionPoint source, Consumer output private void transferPower() { updateSourcesAndSinks(); + resetLimits(); for(SinkPathsFromSource sourceData : transferPaths) { ConnectionPoint sourceCp = sourceData.sourceCP(); @@ -234,11 +240,21 @@ record OutputData(double amount, Path path, EnergyConnector output) List maxOut = new ArrayList<>(sourceData.paths().size()); for(SinkPath sinkEntry : sourceData.paths()) { + double limit = Double.MAX_VALUE; + Connection conn = null; + for(Connection c : sinkEntry.pathTo().conns) + if (limits.containsKey(c)) + { + limit = limits.get(c).get(1); + conn = c; + } EnergyConnector sink = sinkEntry.sinkConnector(); - int requested = sink.getRequestedEnergy(); + int requested = (int)Math.min(sink.getRequestedEnergy(), limit*(1-sinkEntry.pathTo().loss)); if(requested <= 0) continue; double requiredAtSource = Math.min(requested/(1-sinkEntry.pathTo().loss), available); + if(conn!=null) + limits.put(conn, Arrays.asList(limits.get(conn).get(0), limit-requiredAtSource)); maxOut.add(new OutputData(requiredAtSource, sinkEntry.pathTo(), sink)); maxSum += requiredAtSource; } @@ -304,6 +320,12 @@ else if(c.type instanceof IEnergyWire energyWire) return Double.POSITIVE_INFINITY; } + private void resetLimits() + { + if (limits.isEmpty()) return; + limits.replaceAll((p, v) -> Arrays.asList(limits.get(p).get(0), limits.get(p).get(0))); + } + public static class Path { public final Connection[] conns; @@ -410,6 +432,11 @@ default void onEnergyPassedThrough(double amount) } } + public interface LimitingEnergyConnector extends EnergyConnector + { + double getPowerLimit(); + } + private record SinkPath(ConnectionPoint sinkCP, EnergyConnector sinkConnector, Path pathTo) { } diff --git a/src/main/java/blusunrize/immersiveengineering/common/blocks/metal/AbstractTransformerBlockEntity.java b/src/main/java/blusunrize/immersiveengineering/common/blocks/metal/AbstractTransformerBlockEntity.java index cbc314d698..c033057431 100644 --- a/src/main/java/blusunrize/immersiveengineering/common/blocks/metal/AbstractTransformerBlockEntity.java +++ b/src/main/java/blusunrize/immersiveengineering/common/blocks/metal/AbstractTransformerBlockEntity.java @@ -13,6 +13,8 @@ import blusunrize.immersiveengineering.api.wires.ConnectionPoint; import blusunrize.immersiveengineering.api.wires.IImmersiveConnectable; import blusunrize.immersiveengineering.api.wires.WireType; +import blusunrize.immersiveengineering.api.wires.localhandlers.EnergyTransferHandler.IEnergyWire; +import blusunrize.immersiveengineering.api.wires.localhandlers.EnergyTransferHandler.LimitingEnergyConnector; import blusunrize.immersiveengineering.api.wires.utils.WireUtils; import blusunrize.immersiveengineering.common.blocks.IEBlockInterfaces.IStateBasedDirectional; import blusunrize.immersiveengineering.common.blocks.generic.ImmersiveConnectableBlockEntity; @@ -36,7 +38,7 @@ import static blusunrize.immersiveengineering.api.wires.WireType.MV_CATEGORY; public abstract class AbstractTransformerBlockEntity extends ImmersiveConnectableBlockEntity - implements IStateBasedDirectional + implements IStateBasedDirectional, LimitingEnergyConnector { protected static final int RIGHT_INDEX = 0; protected static final int LEFT_INDEX = 1; @@ -75,6 +77,12 @@ public String getHigherWiretype() return MV_CATEGORY; } + @Override + public double getPowerLimit() { + if (leftType==null||rightType==null) return 0; + return Math.min(((IEnergyWire)leftType).getTransferRate(), ((IEnergyWire)rightType).getTransferRate()); + } + @Override public Collection getConnectionPoints() { @@ -177,4 +185,16 @@ public boolean canConnect() protected void updateMirrorState() { } + + @Override + public boolean isSource(ConnectionPoint cp) + { + return false; + } + + @Override + public boolean isSink(ConnectionPoint cp) + { + return false; + } }