diff --git a/src/main/java/api/hbm/energymk2/PowerNetMK2.java b/src/main/java/api/hbm/energymk2/PowerNetMK2.java index eedacae92..467d3bbb5 100644 --- a/src/main/java/api/hbm/energymk2/PowerNetMK2.java +++ b/src/main/java/api/hbm/energymk2/PowerNetMK2.java @@ -9,6 +9,7 @@ import java.util.List; import java.util.Set; import java.util.Map.Entry; +import api.hbm.energymk2.IEnergyReceiverMK2.ConnectionPriority; import api.hbm.energymk2.Nodespace.PowerNode; public class PowerNetMK2 { @@ -111,10 +112,10 @@ public class PowerNetMK2 { this.energyTracker = 0; } + protected static int timeout = 3_000; + public void transferPower() { - int timeout = 3_000; - if(providerEntries.isEmpty()) return; if(receiverEntries.isEmpty()) return; @@ -123,11 +124,12 @@ public class PowerNetMK2 { long supply = 0; long demand = 0; + long[] priorityDemand = new long[ConnectionPriority.values().length]; Iterator> provIt = providerEntries.entrySet().iterator(); while(provIt.hasNext()) { Entry entry = provIt.next(); - if(timestamp - entry.getValue() > timeout) provIt.remove(); + if(timestamp - entry.getValue() > timeout) { provIt.remove(); continue; } supply += Math.min(entry.getKey().getPower(), entry.getKey().getProviderSpeed()); } @@ -136,15 +138,13 @@ public class PowerNetMK2 { Iterator> recIt = receiverEntries.entrySet().iterator(); while(recIt.hasNext()) { Entry entry = recIt.next(); - if(timestamp - entry.getValue() > timeout) recIt.remove(); - demand += Math.min(entry.getKey().getMaxPower() - entry.getKey().getPower(), entry.getKey().getReceiverSpeed()); + if(timestamp - entry.getValue() > timeout) { recIt.remove(); continue; } + long rec = Math.min(entry.getKey().getMaxPower() - entry.getKey().getPower(), entry.getKey().getReceiverSpeed()); + demand += rec; + for(int i = 0; i <= entry.getKey().getPriority().ordinal(); i++) priorityDemand[i] += rec; } - double drainScale = 1D; - - if(supply > demand) { - drainScale = (double) demand / (double) supply; - } + if(demand <= 0) return; long toTransfer = Math.min(supply, demand); if(toTransfer > transferCap) toTransfer = transferCap; @@ -165,16 +165,18 @@ public class PowerNetMK2 { IEnergyProviderMK2 src = providers.get(0); IEnergyReceiverMK2 dest = receivers.get(0); - - long receiverShare = Math.min((long) ((double) (dest.getMaxPower() - dest.getPower()) * (double) supply / (double) demand), dest.getReceiverSpeed()) - prevDest; - long providerShare = Math.min((long) ((double) src.getPower() * (double) demand / (double) supply), src.getProviderSpeed()) - prevSrc; - long toDrain = Math.min((long) (src.getPower() * drainScale), providerShare); + long pd = priorityDemand[dest.getPriority().ordinal()]; + + long receiverShare = Math.min((long) Math.ceil((double) Math.min(dest.getMaxPower() - dest.getPower(), dest.getReceiverSpeed()) * (double) supply / (double) pd), dest.getReceiverSpeed()) - prevDest; + long providerShare = Math.min((long) Math.ceil((double) Math.min(src.getPower(), src.getProviderSpeed()) * (double) demand / (double) supply), src.getProviderSpeed()) - prevSrc; + + long toDrain = Math.min((long) (src.getPower()), providerShare); long toFill = Math.min(dest.getMaxPower() - dest.getPower(), receiverShare); long finalTransfer = Math.min(toDrain, toFill); - if(toDrain <= 0) { providers.remove(0); prevSrc = 0; continue; } + if(src.getPower() <= 0) { providers.remove(0); prevSrc = 0; continue; } if(toFill <= 0) { receivers.remove(0); prevDest = 0; continue; } finalTransfer -= dest.transferPower(finalTransfer); @@ -182,6 +184,9 @@ public class PowerNetMK2 { prevSrc += finalTransfer; prevDest += finalTransfer; + + if(prevSrc >= src.getProviderSpeed()) { providers.remove(0); prevSrc = 0; continue; } + if(prevDest >= dest.getReceiverSpeed()) { receivers.remove(0); prevDest = 0; continue; } toTransfer -= finalTransfer; this.energyTracker += finalTransfer; @@ -189,7 +194,36 @@ public class PowerNetMK2 { } public long sendPowerDiode(long power) { - return power; + + long timestamp = System.currentTimeMillis(); + long demand = 0; + long[] priorityDemand = new long[ConnectionPriority.values().length]; + + Iterator> recIt = receiverEntries.entrySet().iterator(); + while(recIt.hasNext()) { + Entry entry = recIt.next(); + if(timestamp - entry.getValue() > timeout) { recIt.remove(); continue; } + long rec = Math.min(entry.getKey().getMaxPower() - entry.getKey().getPower(), entry.getKey().getReceiverSpeed()); + demand += rec; + for(int i = 0; i <= entry.getKey().getPriority().ordinal(); i++) priorityDemand[i] += rec; + } + + if(demand <= 0) return power; + + long finalRemainder = power; + + for(IEnergyReceiverMK2 dest : receiverEntries.keySet()) { + long pd = priorityDemand[dest.getPriority().ordinal()]; + long toFill = Math.min((long) ((double) (Math.min(dest.getMaxPower() - dest.getPower(), dest.getReceiverSpeed())) * (double) power / (double) pd), dest.getReceiverSpeed()); + toFill = Math.min(toFill, power); + long remainder = dest.transferPower(toFill); + long transferred = toFill - remainder; + finalRemainder -= transferred; + this.energyTracker += transferred; + if(finalRemainder <= 0) break; + } + + return finalRemainder; } public static final ReceiverComparator COMP = new ReceiverComparator(); diff --git a/src/main/java/com/hbm/blocks/network/CableDiode.java b/src/main/java/com/hbm/blocks/network/CableDiode.java index ad16ef673..246094666 100644 --- a/src/main/java/com/hbm/blocks/network/CableDiode.java +++ b/src/main/java/com/hbm/blocks/network/CableDiode.java @@ -7,11 +7,12 @@ import com.hbm.blocks.ILookOverlay; import com.hbm.blocks.ITooltipProvider; import com.hbm.tileentity.TileEntityLoadedBase; import com.hbm.util.BobMathUtil; +import com.hbm.util.Compat; import com.hbm.util.I18nUtil; -import com.hbm.util.fauxpointtwelve.DirPos; import api.hbm.block.IToolable; import api.hbm.energymk2.IEnergyConnectorBlock; +import api.hbm.energymk2.IEnergyConnectorMK2; import api.hbm.energymk2.IEnergyReceiverMK2; import api.hbm.energymk2.Nodespace; import api.hbm.energymk2.Nodespace.PowerNode; @@ -101,7 +102,7 @@ public class CableDiode extends BlockContainer implements IEnergyConnectorBlock, if(tool == ToolType.DEFUSER) { int p = te.priority.ordinal() + 1; - if(p > 2) p = 0; + if(p > 4) p = 0; te.priority = ConnectionPriority.values()[p]; te.markDirty(); world.markBlockForUpdate(x, y, z); @@ -186,6 +187,9 @@ public class CableDiode extends BlockContainer implements IEnergyConnectorBlock, this.trySubscribe(worldObj, xCoord + dir.offsetX, yCoord + dir.offsetY, zCoord + dir.offsetZ, dir); } + + pulses = 0; + this.setPower(0); //tick is over, reset our allowed transfe } } @@ -197,7 +201,6 @@ public class CableDiode extends BlockContainer implements IEnergyConnectorBlock, /** Used as an intra-tick tracker for how much energy has been transmitted, resets to 0 each tick and maxes out based on transfer */ private long power; private boolean recursionBrake = false; - private long lastTransfer = 0; private int pulses = 0; public ConnectionPriority priority = ConnectionPriority.NORMAL; @@ -208,30 +211,40 @@ public class CableDiode extends BlockContainer implements IEnergyConnectorBlock, return power; pulses++; - - if(lastTransfer != worldObj.getTotalWorldTime()) { - lastTransfer = worldObj.getTotalWorldTime(); - pulses = 0; - this.setPower(0); //tick is over, reset our allowed transfe - } - if(this.getPower() >= this.getMaxPower() || pulses > 10) return power; //if we have already maxed out transfer or max pulses, abort recursionBrake = true; ForgeDirection dir = getDir(); PowerNode node = Nodespace.getNode(worldObj, xCoord + dir.offsetX, yCoord + dir.offsetY, zCoord + dir.offsetZ); + TileEntity te = Compat.getTileStandard(worldObj, xCoord + dir.offsetX, yCoord + dir.offsetY, zCoord + dir.offsetZ); - if(node.hasValidNet() && Nodespace.checkConnection(node, new DirPos(xCoord, yCoord, zCoord, dir), false)) { - long prevPower = power; - power = node.net.sendPowerDiode(power); - this.power += (prevPower - power); + if(node != null && !node.expired && node.hasValidNet() && te instanceof IEnergyConnectorMK2 && ((IEnergyConnectorMK2) te).canConnect(dir.getOpposite())) { + long toTransfer = Math.min(power, this.getReceiverSpeed()); + long remainder = node.net.sendPowerDiode(toTransfer); + long transferred = (toTransfer - remainder); + this.power += transferred; + power -= transferred; + + } else if(te instanceof IEnergyReceiverMK2 && te != this) { + IEnergyReceiverMK2 rec = (IEnergyReceiverMK2) te; + if(rec.canConnect(dir.getOpposite())) { + long toTransfer = Math.min(power, rec.getReceiverSpeed()); + long remainder = rec.transferPower(toTransfer); + power -= (toTransfer - remainder); + recursionBrake = false; + return power; + } } recursionBrake = false; return power; } + @Override + public long getReceiverSpeed() { + return this.getMaxPower() - this.getPower(); + } @Override public long getMaxPower() { diff --git a/src/main/java/com/hbm/tileentity/network/TileEntityCableSwitch.java b/src/main/java/com/hbm/tileentity/network/TileEntityCableSwitch.java index 0f7adcda1..acdffcd99 100644 --- a/src/main/java/com/hbm/tileentity/network/TileEntityCableSwitch.java +++ b/src/main/java/com/hbm/tileentity/network/TileEntityCableSwitch.java @@ -6,7 +6,7 @@ public class TileEntityCableSwitch extends TileEntityCableBaseNT { @Override public boolean canUpdate() { - return this.worldObj != null && this.getBlockMetadata() == 1 && super.canUpdate(); + return super.canUpdate(); } public void updateState() {