diff options
Diffstat (limited to 'src/main/java/gregtech/api')
3 files changed, 195 insertions, 12 deletions
diff --git a/src/main/java/gregtech/api/graphs/paths/PowerNodePath.java b/src/main/java/gregtech/api/graphs/paths/PowerNodePath.java index a232822b26..8a869c333e 100644 --- a/src/main/java/gregtech/api/graphs/paths/PowerNodePath.java +++ b/src/main/java/gregtech/api/graphs/paths/PowerNodePath.java @@ -2,9 +2,11 @@ package gregtech.api.graphs.paths; import net.minecraft.server.MinecraftServer; +import gregtech.api.enums.TickTime; import gregtech.api.metatileentity.BaseMetaPipeEntity; import gregtech.api.metatileentity.MetaPipeEntity; import gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Cable; +import gregtech.api.util.AveragePerTickCounter; // path for cables // all calculations like amp and voltage happens here @@ -18,6 +20,9 @@ public class PowerNodePath extends NodePath { int mTick = 0; boolean mCountUp = true; + private AveragePerTickCounter avgAmperageCounter = new AveragePerTickCounter(TickTime.SECOND); + private AveragePerTickCounter avgVoltageCounter = new AveragePerTickCounter(TickTime.SECOND); + public PowerNodePath(MetaPipeEntity[] aCables) { super(aCables); } @@ -27,6 +32,9 @@ public class PowerNodePath extends NodePath { } public void applyVoltage(long aVoltage, boolean aCountUp) { + + avgVoltageCounter.addValue(Math.max(aVoltage - mLoss, 0)); + int tNewTime = MinecraftServer.getServer() .getTickCounter(); if (mTick != tNewTime) { @@ -60,6 +68,9 @@ public class PowerNodePath extends NodePath { } public void addAmps(long aAmps) { + + avgAmperageCounter.addValue(aAmps); + this.mAmps += aAmps; if (this.mAmps > mMaxAmps * 40) { lock.addTileEntity(null); @@ -76,6 +87,7 @@ public class PowerNodePath extends NodePath { // if no amps pass through for more than 0.5 second reduce them to minimize wrong results // but still allow the player to see if activity is happening + @Deprecated public long getAmps() { int tTime = MinecraftServer.getServer() .getTickCounter() - 10; @@ -86,6 +98,7 @@ public class PowerNodePath extends NodePath { return mAmps; } + @Deprecated public long getVoltage(MetaPipeEntity aCable) { int tLoss = 0; if (mCountUp) { @@ -108,6 +121,22 @@ public class PowerNodePath extends NodePath { return -1; } + public long getAmperage() { + return avgAmperageCounter.getLast(); + } + + public double getAvgAmperage() { + return avgAmperageCounter.getAverage(); + } + + public long getVoltage() { + return avgVoltageCounter.getLast(); + } + + public double getAvgVoltage() { + return avgVoltageCounter.getAverage(); + } + @Override protected void processPipes() { super.processPipes(); diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Cable.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Cable.java index 1185dbcc37..db4ead0932 100644 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Cable.java +++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Cable.java @@ -190,11 +190,12 @@ public class GT_MetaPipeEntity_Cable extends MetaPipeEntity implements IMetaTile if (isCoverOnSide(baseEntity, livingEntity)) return; if ((baseEntity.mConnections & IConnectable.HAS_HARDENEDFOAM) == 1) return; - final long amperage = powerPath.getAmps(); + final long amperage = powerPath.getAmperage(); + final long voltage = powerPath.getVoltage(); if (amperage == 0L) return; - GT_Utility.applyElectricityDamage(livingEntity, mVoltage, amperage); + GT_Utility.applyElectricityDamage(livingEntity, voltage, amperage); } @Override @@ -475,12 +476,18 @@ public class GT_MetaPipeEntity_Cable extends MetaPipeEntity implements IMetaTile public String[] getInfoData() { final BaseMetaPipeEntity base = (BaseMetaPipeEntity) getBaseMetaTileEntity(); final PowerNodePath path = (PowerNodePath) base.getNodePath(); - long amps = 0; - long volts = 0; - if (path != null) { - amps = path.getAmps(); - volts = path.getVoltage(this); - } + + if (path == null) + return new String[] { EnumChatFormatting.RED + "Failed to get Power Node info" + EnumChatFormatting.RESET }; + + final long currAmp = path.getAmperage(); + final long currVoltage = path.getVoltage(); + + final double avgAmp = path.getAvgAmperage(); + final double avgVoltage = path.getAvgVoltage(); + + final long maxVoltageOut = (mVoltage - mCableLossPerMeter) * mAmperage; + return new String[] { "Heat: " + EnumChatFormatting.RED + GT_Utility.formatNumbers(mOverheat) @@ -490,19 +497,27 @@ public class GT_MetaPipeEntity_Cable extends MetaPipeEntity implements IMetaTile + GT_Utility.formatNumbers(mMaxOverheat) + EnumChatFormatting.RESET, "Amperage: " + EnumChatFormatting.GREEN - + GT_Utility.formatNumbers(amps) + + GT_Utility.formatNumbers(currAmp) + EnumChatFormatting.RESET + " / " + EnumChatFormatting.YELLOW + GT_Utility.formatNumbers(mAmperage) + EnumChatFormatting.RESET + " A", - "Max Output: " + EnumChatFormatting.GREEN - + GT_Utility.formatNumbers(volts) + "Voltage Out: " + EnumChatFormatting.GREEN + + GT_Utility.formatNumbers(currVoltage) + EnumChatFormatting.RESET + " / " + EnumChatFormatting.YELLOW - + GT_Utility.formatNumbers(mVoltage) + + GT_Utility.formatNumbers(maxVoltageOut) + + EnumChatFormatting.RESET + + " EU/t", + "Avg Amperage (20t): " + EnumChatFormatting.YELLOW + + GT_Utility.formatNumbers(avgAmp) + + EnumChatFormatting.RESET + + " A", + "Avg Output (20t): " + EnumChatFormatting.YELLOW + + GT_Utility.formatNumbers(avgVoltage) + EnumChatFormatting.RESET + " EU/t" }; } diff --git a/src/main/java/gregtech/api/util/AveragePerTickCounter.java b/src/main/java/gregtech/api/util/AveragePerTickCounter.java new file mode 100644 index 0000000000..c9b1275deb --- /dev/null +++ b/src/main/java/gregtech/api/util/AveragePerTickCounter.java @@ -0,0 +1,139 @@ +package gregtech.api.util; + +import java.security.InvalidParameterException; +import java.util.ArrayDeque; + +import net.minecraft.server.MinecraftServer; + +public class AveragePerTickCounter { + + /** + * Averages a value over a certain amount of ticks + * + * @param period amount of ticks to average (20 for 1 second) + * + */ + public AveragePerTickCounter(int period) throws InvalidParameterException { + + if (period <= 0) throw new InvalidParameterException("period should be a positive non-zero number"); + + this.period = period; + values = new ArrayDeque<>(period); + } + + public void addValue(long value) { + + if (value == 0) return; + + final int currTick = getWorldTimeInTicks(); + + if (values.isEmpty()) { + values.addLast(new Measurement(currTick, value)); + isCachedAverageValid = false; + return; + } + + Measurement lastMeasurement = values.peekLast(); + final int lastMeasurementTick = lastMeasurement.TimestampInWorldTicks; + + /// sums up values added in the same tick + /// for example a cable had an amp running through it multiple times in the same tick + if (currTick == lastMeasurementTick) { + lastMeasurement.Value = lastMeasurement.Value + value; + isCachedAverageValid = false; + return; + } + + if (currTick > lastMeasurementTick) { + trimIrrelevantData(currTick); + + values.addLast(new Measurement(currTick, value)); + isCachedAverageValid = false; + return; + } + } + + public double getAverage() { + + if (values.isEmpty()) return 0; + + final int currTick = getWorldTimeInTicks(); + + Measurement lastMeasurement = values.peekLast(); + final int lastMeasurementTick = lastMeasurement.TimestampInWorldTicks; + + if (currTick < lastMeasurementTick) return 0; + + if (currTick > lastMeasurementTick) { + trimIrrelevantData(currTick); + } + + if (isCachedAverageValid) return cachedAverage; + + return calculateAverage(); + } + + public long getLast() { + + if (values.isEmpty()) return 0; + + final int currTick = getWorldTimeInTicks(); + + Measurement lastMeasurement = values.peekLast(); + final int lastMeasurementTick = lastMeasurement.TimestampInWorldTicks; + + if (currTick == lastMeasurementTick) return values.getLast().Value; + + return 0; + } + + private double calculateAverage() { + + isCachedAverageValid = true; + long sum = 0; + + for (Measurement measurement : values) { + sum += measurement.Value; + } + + return sum / (double) period; + } + + private void trimIrrelevantData(int currWorldTimeInTicks) { + + if (values.isEmpty()) return; + + int firstMeasurementTick = values.peekFirst().TimestampInWorldTicks; + + while (currWorldTimeInTicks - firstMeasurementTick >= period) { + values.removeFirst(); + isCachedAverageValid = false; + + if (values.isEmpty()) return; + + firstMeasurementTick = values.peekFirst().TimestampInWorldTicks; + } + } + + private int getWorldTimeInTicks() { + return MinecraftServer.getServer() + .getTickCounter(); + } + + private ArrayDeque<Measurement> values; + private int period; + + private double cachedAverage = 0; + private boolean isCachedAverageValid = true; + + private class Measurement { + + public int TimestampInWorldTicks; + public long Value; + + public Measurement(int timestampInWorldTicks, long value) { + this.TimestampInWorldTicks = timestampInWorldTicks; + this.Value = value; + } + } +} |