From 53b758ac637026a57068a4470a9cabcb41124ed4 Mon Sep 17 00:00:00 2001 From: MauveCloud Date: Sat, 11 Apr 2015 09:18:26 -0700 Subject: [PATCH] Added extra features listed in Issue #5 --- nbproject/private/private.xml | 7 +- .../AdvancedHeatExchanger.java | 10 +- .../AdvancedHeatVent.java | 13 +- .../ComponentHeatExchanger.java | 10 +- .../ComponentHeatVent.java | 32 ++++- src/Ic2ExpReactorPlanner/CoolantCell10k.java | 7 + src/Ic2ExpReactorPlanner/CoolantCell30k.java | 7 + src/Ic2ExpReactorPlanner/CoolantCell60k.java | 7 + src/Ic2ExpReactorPlanner/DualFuelRodMox.java | 8 +- .../DualFuelRodUranium.java | 8 +- src/Ic2ExpReactorPlanner/FuelRodMox.java | 8 +- src/Ic2ExpReactorPlanner/FuelRodUranium.java | 8 +- src/Ic2ExpReactorPlanner/HeatExchanger.java | 10 +- src/Ic2ExpReactorPlanner/HeatVent.java | 13 +- src/Ic2ExpReactorPlanner/LzhCondensator.java | 13 ++ .../NeutronReflector.java | 3 +- .../OverclockedHeatVent.java | 13 +- src/Ic2ExpReactorPlanner/QuadFuelRodMox.java | 8 +- .../QuadFuelRodUranium.java | 8 +- .../ReactorComponent.java | 78 +++++++++-- src/Ic2ExpReactorPlanner/ReactorHeatVent.java | 13 +- .../ReactorPlannerFrame.java | 8 +- src/Ic2ExpReactorPlanner/RshCondensator.java | 13 ++ src/Ic2ExpReactorPlanner/Simulator.java | 128 +++++++++++++++++- 24 files changed, 375 insertions(+), 58 deletions(-) diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml index 1f90176..76d8150 100644 --- a/nbproject/private/private.xml +++ b/nbproject/private/private.xml @@ -3,12 +3,7 @@ - file:/E:/GitHub/Ic2ExpReactorPlanner/src/Ic2ExpReactorPlanner/AdvancedHeatExchanger.java - file:/E:/GitHub/Ic2ExpReactorPlanner/src/Ic2ExpReactorPlanner/CoolantCell60k.java - file:/E:/GitHub/Ic2ExpReactorPlanner/src/Ic2ExpReactorPlanner/CoolantCell10k.java - file:/E:/GitHub/Ic2ExpReactorPlanner/src/Ic2ExpReactorPlanner/ReactorPlannerFrame.java - file:/E:/GitHub/Ic2ExpReactorPlanner/src/Ic2ExpReactorPlanner/Reactor.java - file:/E:/GitHub/Ic2ExpReactorPlanner/src/Ic2ExpReactorPlanner/Simulator.java + file:/E:/GitHub/Ic2ExpReactorPlanner/src/Ic2ExpReactorPlanner/ReactorComponent.java diff --git a/src/Ic2ExpReactorPlanner/AdvancedHeatExchanger.java b/src/Ic2ExpReactorPlanner/AdvancedHeatExchanger.java index bc37378..49d750d 100644 --- a/src/Ic2ExpReactorPlanner/AdvancedHeatExchanger.java +++ b/src/Ic2ExpReactorPlanner/AdvancedHeatExchanger.java @@ -66,12 +66,12 @@ public void transfer() { heatableNeighbors.add(component); } // Code adapted from decompiled IC2 code, class ItemReactorHeatSwitch, with permission from Thunderdark. - int myHeat = 0; + double myHeat = 0.0; for (ReactorComponent heatableNeighbor : heatableNeighbors) { double mymed = getCurrentHeat() * 100.0 / getMaxHeat(); double heatablemed = heatableNeighbor.getCurrentHeat() * 100.0 / heatableNeighbor.getMaxHeat(); - int add = (int) (heatableNeighbor.getMaxHeat() / 100.0 * (heatablemed + mymed / 2.0)); + double add = (int) (heatableNeighbor.getMaxHeat() / 100.0 * (heatablemed + mymed / 2.0)); if (add > switchSide) { add = switchSide; } @@ -92,9 +92,9 @@ public void transfer() { } else if (Math.round(heatablemed * 10.0) / 10.0 == Math.round(mymed * 10.0) / 10.0) { add = 0; } - double tempAdd = Math.max(-heatableNeighbor.getCurrentHeat(), add); - myHeat -= tempAdd; - heatableNeighbor.adjustCurrentHeat(tempAdd); + myHeat -= add; + add = heatableNeighbor.adjustCurrentHeat(add); + myHeat += add; } double mymed = getCurrentHeat() * 100.0 / getMaxHeat(); double Reactormed = parentReactor.getCurrentHeat() * 100.0 / parentReactor.getMaxHeat(); diff --git a/src/Ic2ExpReactorPlanner/AdvancedHeatVent.java b/src/Ic2ExpReactorPlanner/AdvancedHeatVent.java index 71d1d97..7e58f40 100644 --- a/src/Ic2ExpReactorPlanner/AdvancedHeatVent.java +++ b/src/Ic2ExpReactorPlanner/AdvancedHeatVent.java @@ -41,13 +41,20 @@ public boolean isHeatAcceptor() { @Override public void dissipate() { - getParent().ventHeat(Math.min(12, getCurrentHeat())); - adjustCurrentHeat(-Math.min(12, getCurrentHeat())); + final double currentDissipation = Math.min(12, getCurrentHeat()); + getParent().ventHeat(currentDissipation); + adjustCurrentHeat(-currentDissipation); + effectiveVentCooling = Math.max(effectiveVentCooling, currentDissipation); } @Override public MaterialsList getMaterials() { return MATERIALS; } - + + @Override + public double getVentCoolingCapacity() { + return 12; + } + } diff --git a/src/Ic2ExpReactorPlanner/ComponentHeatExchanger.java b/src/Ic2ExpReactorPlanner/ComponentHeatExchanger.java index b115e8d..cab3a70 100644 --- a/src/Ic2ExpReactorPlanner/ComponentHeatExchanger.java +++ b/src/Ic2ExpReactorPlanner/ComponentHeatExchanger.java @@ -66,12 +66,12 @@ public void transfer() { heatableNeighbors.add(component); } // Code adapted from decompiled IC2 code, class ItemReactorHeatSwitch, with permission from Thunderdark. - int myHeat = 0; + double myHeat = 0.0; for (ReactorComponent heatableNeighbor : heatableNeighbors) { double mymed = getCurrentHeat() * 100.0 / getMaxHeat(); double heatablemed = heatableNeighbor.getCurrentHeat() * 100.0 / heatableNeighbor.getMaxHeat(); - int add = (int) (heatableNeighbor.getMaxHeat() / 100.0 * (heatablemed + mymed / 2.0)); + double add = (int) (heatableNeighbor.getMaxHeat() / 100.0 * (heatablemed + mymed / 2.0)); if (add > switchSide) { add = switchSide; } @@ -92,9 +92,9 @@ public void transfer() { } else if (Math.round(heatablemed * 10.0) / 10.0 == Math.round(mymed * 10.0) / 10.0) { add = 0; } - double tempAdd = Math.max(-heatableNeighbor.getCurrentHeat(), add); - myHeat -= tempAdd; - heatableNeighbor.adjustCurrentHeat(tempAdd); + myHeat -= add; + add = heatableNeighbor.adjustCurrentHeat(add); + myHeat += add; } adjustCurrentHeat(myHeat); } diff --git a/src/Ic2ExpReactorPlanner/ComponentHeatVent.java b/src/Ic2ExpReactorPlanner/ComponentHeatVent.java index 9e3dac4..d649f7a 100644 --- a/src/Ic2ExpReactorPlanner/ComponentHeatVent.java +++ b/src/Ic2ExpReactorPlanner/ComponentHeatVent.java @@ -52,16 +52,42 @@ public void dissipate() { if (component != null && component.isHeatAcceptor()) { heatableNeighbors.add(component); } + double dissipatedHeat = 0.0; for (ReactorComponent heatableNeighbor : heatableNeighbors) { - parentReactor.ventHeat(Math.min(4, heatableNeighbor.getCurrentHeat())); - heatableNeighbor.adjustCurrentHeat(-Math.min(4, heatableNeighbor.getCurrentHeat())); + double rejectedCooling = heatableNeighbor.adjustCurrentHeat(-4.0); + double tempDissipatedHeat = 4 + rejectedCooling; + parentReactor.ventHeat(tempDissipatedHeat); + dissipatedHeat += tempDissipatedHeat; } - + effectiveVentCooling = Math.max(effectiveVentCooling, dissipatedHeat); } @Override public MaterialsList getMaterials() { return MATERIALS; } + + @Override + public double getVentCoolingCapacity() { + double result = 0.0; + final Reactor parentReactor = getParent(); + ReactorComponent component = parentReactor.getComponentAt(getRow() + 1, getColumn()); + if (component != null && component.isHeatAcceptor() && !(component instanceof RshCondensator) && !(component instanceof LzhCondensator)) { + result += 4.0; + } + component = parentReactor.getComponentAt(getRow() - 1, getColumn()); + if (component != null && component.isHeatAcceptor() && !(component instanceof RshCondensator) && !(component instanceof LzhCondensator)) { + result += 4.0; + } + component = parentReactor.getComponentAt(getRow(), getColumn() - 1); + if (component != null && component.isHeatAcceptor() && !(component instanceof RshCondensator) && !(component instanceof LzhCondensator)) { + result += 4.0; + } + component = parentReactor.getComponentAt(getRow(), getColumn() + 1); + if (component != null && component.isHeatAcceptor() && !(component instanceof RshCondensator) && !(component instanceof LzhCondensator)) { + result += 4.0; + } + return result; + } } diff --git a/src/Ic2ExpReactorPlanner/CoolantCell10k.java b/src/Ic2ExpReactorPlanner/CoolantCell10k.java index 2827037..e4009e3 100644 --- a/src/Ic2ExpReactorPlanner/CoolantCell10k.java +++ b/src/Ic2ExpReactorPlanner/CoolantCell10k.java @@ -43,5 +43,12 @@ public boolean isHeatAcceptor() { public MaterialsList getMaterials() { return MATERIALS; } + + @Override + public double adjustCurrentHeat(double heat) { + currentCellCooling += heat; + bestCellCooling = Math.max(currentCellCooling, bestCellCooling); + return super.adjustCurrentHeat(heat); + } } diff --git a/src/Ic2ExpReactorPlanner/CoolantCell30k.java b/src/Ic2ExpReactorPlanner/CoolantCell30k.java index 34cc5ff..3fb05af 100644 --- a/src/Ic2ExpReactorPlanner/CoolantCell30k.java +++ b/src/Ic2ExpReactorPlanner/CoolantCell30k.java @@ -44,4 +44,11 @@ public MaterialsList getMaterials() { return MATERIALS; } + @Override + public double adjustCurrentHeat(double heat) { + currentCellCooling += heat; + bestCellCooling = Math.max(currentCellCooling, bestCellCooling); + return super.adjustCurrentHeat(heat); + } + } diff --git a/src/Ic2ExpReactorPlanner/CoolantCell60k.java b/src/Ic2ExpReactorPlanner/CoolantCell60k.java index cf8352f..8c0c0a8 100644 --- a/src/Ic2ExpReactorPlanner/CoolantCell60k.java +++ b/src/Ic2ExpReactorPlanner/CoolantCell60k.java @@ -44,4 +44,11 @@ public MaterialsList getMaterials() { return MATERIALS; } + @Override + public double adjustCurrentHeat(double heat) { + currentCellCooling += heat; + bestCellCooling = Math.max(currentCellCooling, bestCellCooling); + return super.adjustCurrentHeat(heat); + } + } diff --git a/src/Ic2ExpReactorPlanner/DualFuelRodMox.java b/src/Ic2ExpReactorPlanner/DualFuelRodMox.java index 3635ef2..601f470 100644 --- a/src/Ic2ExpReactorPlanner/DualFuelRodMox.java +++ b/src/Ic2ExpReactorPlanner/DualFuelRodMox.java @@ -31,7 +31,7 @@ public String toString() { } @Override - public void generateHeat() { + public double generateHeat() { int pulses = countNeutronNeighbors() + 2; int heat = 4 * pulses * (pulses + 1); final Reactor parentReactor = getParent(); @@ -40,6 +40,7 @@ public void generateHeat() { } handleHeat(heat); applyDamage(1.0); + return heat; } @Override @@ -55,4 +56,9 @@ public MaterialsList getMaterials() { return MATERIALS; } + @Override + public int getRodCount() { + return 2; + } + } diff --git a/src/Ic2ExpReactorPlanner/DualFuelRodUranium.java b/src/Ic2ExpReactorPlanner/DualFuelRodUranium.java index ad9181d..79051da 100644 --- a/src/Ic2ExpReactorPlanner/DualFuelRodUranium.java +++ b/src/Ic2ExpReactorPlanner/DualFuelRodUranium.java @@ -31,11 +31,12 @@ public String toString() { } @Override - public void generateHeat() { + public double generateHeat() { int pulses = countNeutronNeighbors() + 2; int heat = 4 * pulses * (pulses + 1); handleHeat(heat); applyDamage(1.0); + return heat; } @Override @@ -51,4 +52,9 @@ public MaterialsList getMaterials() { return MATERIALS; } + @Override + public int getRodCount() { + return 2; + } + } diff --git a/src/Ic2ExpReactorPlanner/FuelRodMox.java b/src/Ic2ExpReactorPlanner/FuelRodMox.java index dabac1a..30874ac 100644 --- a/src/Ic2ExpReactorPlanner/FuelRodMox.java +++ b/src/Ic2ExpReactorPlanner/FuelRodMox.java @@ -31,7 +31,7 @@ public String toString() { } @Override - public void generateHeat() { + public double generateHeat() { int pulses = countNeutronNeighbors() + 1; int heat = 2 * pulses * (pulses + 1); final Reactor parentReactor = getParent(); @@ -40,6 +40,7 @@ public void generateHeat() { } handleHeat(heat); applyDamage(1.0); + return heat; } @Override @@ -55,4 +56,9 @@ public MaterialsList getMaterials() { return MATERIALS; } + @Override + public int getRodCount() { + return 1; + } + } diff --git a/src/Ic2ExpReactorPlanner/FuelRodUranium.java b/src/Ic2ExpReactorPlanner/FuelRodUranium.java index 18caf81..3160be6 100644 --- a/src/Ic2ExpReactorPlanner/FuelRodUranium.java +++ b/src/Ic2ExpReactorPlanner/FuelRodUranium.java @@ -61,11 +61,12 @@ protected int countNeutronNeighbors() { } @Override - public void generateHeat() { + public double generateHeat() { int pulses = countNeutronNeighbors() + 1; int heat = 2 * pulses * (pulses + 1); handleHeat(heat); applyDamage(1.0); + return heat; } @Override @@ -110,5 +111,10 @@ protected void handleHeat(final int heat) { public MaterialsList getMaterials() { return MATERIALS; } + + @Override + public int getRodCount() { + return 1; + } } diff --git a/src/Ic2ExpReactorPlanner/HeatExchanger.java b/src/Ic2ExpReactorPlanner/HeatExchanger.java index b5b1890..2fa8870 100644 --- a/src/Ic2ExpReactorPlanner/HeatExchanger.java +++ b/src/Ic2ExpReactorPlanner/HeatExchanger.java @@ -66,12 +66,12 @@ public void transfer() { heatableNeighbors.add(component); } // Code adapted from decompiled IC2 code, class ItemReactorHeatSwitch, with permission from Thunderdark. - int myHeat = 0; + double myHeat = 0; for (ReactorComponent heatableNeighbor : heatableNeighbors) { double mymed = getCurrentHeat() * 100.0 / getMaxHeat(); double heatablemed = heatableNeighbor.getCurrentHeat() * 100.0 / heatableNeighbor.getMaxHeat(); - int add = (int) (heatableNeighbor.getMaxHeat() / 100.0 * (heatablemed + mymed / 2.0)); + double add = (int) (heatableNeighbor.getMaxHeat() / 100.0 * (heatablemed + mymed / 2.0)); if (add > switchSide) { add = switchSide; } @@ -92,9 +92,9 @@ public void transfer() { } else if (Math.round(heatablemed * 10.0) / 10.0 == Math.round(mymed * 10.0) / 10.0) { add = 0; } - double tempAdd = Math.max(-heatableNeighbor.getCurrentHeat(), add); - myHeat -= tempAdd; - heatableNeighbor.adjustCurrentHeat(tempAdd); + myHeat -= add; + add = heatableNeighbor.adjustCurrentHeat(add); + myHeat += add; } double mymed = getCurrentHeat() * 100.0 / getMaxHeat(); double Reactormed = parentReactor.getCurrentHeat() * 100.0 / parentReactor.getMaxHeat(); diff --git a/src/Ic2ExpReactorPlanner/HeatVent.java b/src/Ic2ExpReactorPlanner/HeatVent.java index d256e13..4d7a1ef 100644 --- a/src/Ic2ExpReactorPlanner/HeatVent.java +++ b/src/Ic2ExpReactorPlanner/HeatVent.java @@ -41,13 +41,20 @@ public boolean isHeatAcceptor() { @Override public void dissipate() { - getParent().ventHeat(Math.min(6, getCurrentHeat())); - adjustCurrentHeat(-Math.min(6, getCurrentHeat())); + final double currentDissipation = Math.min(6, getCurrentHeat()); + getParent().ventHeat(currentDissipation); + adjustCurrentHeat(-currentDissipation); + effectiveVentCooling = Math.max(effectiveVentCooling, currentDissipation); } @Override public MaterialsList getMaterials() { return MATERIALS; } - + + @Override + public double getVentCoolingCapacity() { + return 6; + } + } diff --git a/src/Ic2ExpReactorPlanner/LzhCondensator.java b/src/Ic2ExpReactorPlanner/LzhCondensator.java index d8bff44..01a1e86 100644 --- a/src/Ic2ExpReactorPlanner/LzhCondensator.java +++ b/src/Ic2ExpReactorPlanner/LzhCondensator.java @@ -43,5 +43,18 @@ public boolean isHeatAcceptor() { public MaterialsList getMaterials() { return MATERIALS; } + + @Override + public double adjustCurrentHeat(final double heat) { + if (heat < 0.0) { + return heat; + } + currentCondensatorCooling += heat; + bestCondensatorCooling = Math.max(currentCondensatorCooling, bestCondensatorCooling); + double acceptedHeat = Math.min(heat, getMaxHeat() - heat); + double result = heat - acceptedHeat; + currentHeat += acceptedHeat; + return result; + } } diff --git a/src/Ic2ExpReactorPlanner/NeutronReflector.java b/src/Ic2ExpReactorPlanner/NeutronReflector.java index b46dc6e..684be91 100644 --- a/src/Ic2ExpReactorPlanner/NeutronReflector.java +++ b/src/Ic2ExpReactorPlanner/NeutronReflector.java @@ -36,7 +36,7 @@ public boolean isNeutronReflector() { } @Override - public void generateHeat() { + public double generateHeat() { final Reactor parentReactor = getParent(); ReactorComponent component = parentReactor.getComponentAt(getRow() + 1, getColumn()); if (component != null && component.isNeutronReflector()) { @@ -54,6 +54,7 @@ public void generateHeat() { if (component != null && component.isNeutronReflector()) { handleFuelRodDamage(component); } + return 0.0; } private void handleFuelRodDamage(ReactorComponent component) { diff --git a/src/Ic2ExpReactorPlanner/OverclockedHeatVent.java b/src/Ic2ExpReactorPlanner/OverclockedHeatVent.java index f89545e..4c276fd 100644 --- a/src/Ic2ExpReactorPlanner/OverclockedHeatVent.java +++ b/src/Ic2ExpReactorPlanner/OverclockedHeatVent.java @@ -45,13 +45,20 @@ public void dissipate() { double deltaHeat = Math.min(36, parentReactor.getCurrentHeat()); parentReactor.adjustCurrentHeat(-deltaHeat); this.adjustCurrentHeat(deltaHeat); - parentReactor.ventHeat(Math.min(20, getCurrentHeat())); - adjustCurrentHeat(-Math.min(20, getCurrentHeat())); + final double currentDissipation = Math.min(20, getCurrentHeat()); + parentReactor.ventHeat(currentDissipation); + adjustCurrentHeat(-currentDissipation); + effectiveVentCooling = Math.max(effectiveVentCooling, currentDissipation); } @Override public MaterialsList getMaterials() { return MATERIALS; } - + + @Override + public double getVentCoolingCapacity() { + return 20; + } + } diff --git a/src/Ic2ExpReactorPlanner/QuadFuelRodMox.java b/src/Ic2ExpReactorPlanner/QuadFuelRodMox.java index 03cf830..15578fb 100644 --- a/src/Ic2ExpReactorPlanner/QuadFuelRodMox.java +++ b/src/Ic2ExpReactorPlanner/QuadFuelRodMox.java @@ -31,7 +31,7 @@ public String toString() { } @Override - public void generateHeat() { + public double generateHeat() { int pulses = countNeutronNeighbors() + 3; int heat = 8 * pulses * (pulses + 1); final Reactor parentReactor = getParent(); @@ -40,6 +40,7 @@ public void generateHeat() { } handleHeat(heat); applyDamage(1.0); + return heat; } @Override @@ -55,4 +56,9 @@ public MaterialsList getMaterials() { return MATERIALS; } + @Override + public int getRodCount() { + return 4; + } + } diff --git a/src/Ic2ExpReactorPlanner/QuadFuelRodUranium.java b/src/Ic2ExpReactorPlanner/QuadFuelRodUranium.java index 1a56541..b305ecb 100644 --- a/src/Ic2ExpReactorPlanner/QuadFuelRodUranium.java +++ b/src/Ic2ExpReactorPlanner/QuadFuelRodUranium.java @@ -31,11 +31,12 @@ public String toString() { } @Override - public void generateHeat() { + public double generateHeat() { int pulses = countNeutronNeighbors() + 3; int heat = 8 * pulses * (pulses + 1); handleHeat(heat); applyDamage(1.0); + return heat; } @Override @@ -51,4 +52,9 @@ public MaterialsList getMaterials() { return MATERIALS; } + @Override + public int getRodCount() { + return 4; + } + } diff --git a/src/Ic2ExpReactorPlanner/ReactorComponent.java b/src/Ic2ExpReactorPlanner/ReactorComponent.java index 6c11abe..879217c 100644 --- a/src/Ic2ExpReactorPlanner/ReactorComponent.java +++ b/src/Ic2ExpReactorPlanner/ReactorComponent.java @@ -19,7 +19,7 @@ public class ReactorComponent { private int column = -10; private double initialHeat = 0.0; - private double currentHeat = 0.0; + protected double currentHeat = 0.0; private double maxHeat = 1.0; private double currentDamage = 0.0; @@ -27,6 +27,16 @@ public class ReactorComponent { private Reactor parent = null; + protected double effectiveVentCooling = 0.0; + + protected double bestCondensatorCooling = 0.0; + + protected double bestCellCooling = 0.0; + + protected double currentCondensatorCooling = 0.0; + + protected double currentCellCooling = 0.0; + /** * Get the image to show in the planner for this component. * @return the image. @@ -71,6 +81,10 @@ public final void setColumn(int column) { this.column = column; } + /** + * Checks if this component can accept heat. (e.g. from adjacent fuel rods, or from an exchanger) + * @return true if this component can accept heat, false otherwise. + */ public boolean isHeatAcceptor() { return false; } @@ -79,11 +93,20 @@ public boolean isNeutronReflector() { return false; } + /** + * Prepare for a new reactor tick. + */ + public void preReactorTick() { + currentCellCooling = 0.0; + currentCondensatorCooling = 0.0; + } + /** * Generate heat if appropriate for component type, and spread to reactor or adjacent cells. + * @return the amount of heat generated by this component. */ - public void generateHeat() { - // do nothing by default. + public double generateHeat() { + return 0.0; } /** @@ -133,17 +156,32 @@ public final double getCurrentHeat() { */ public final void clearCurrentHeat() { currentHeat = initialHeat; + effectiveVentCooling = 0.0; + bestCondensatorCooling = 0.0; + bestCellCooling = 0.0; } /** * Adjusts the component heat up or down * @param heat the amount of heat to adjust by (positive to add heat, negative to remove heat). + * @return the amount of heat adjustment refused. (e.g. due to going below minimum heat, breaking due to excessive heat, or attempting to remove heat from a condensator) */ - public final void adjustCurrentHeat(final double heat) { - currentHeat += heat; - if (currentHeat < 0.0) { - currentHeat = 0.0; + public double adjustCurrentHeat(final double heat) { + if (isHeatAcceptor()) { + double result = 0.0; + double tempHeat = getCurrentHeat(); + tempHeat += heat; + if (tempHeat > getMaxHeat()) { + result = getMaxHeat() - tempHeat + 1; + tempHeat = getMaxHeat(); + } else if (tempHeat < 0.0) { + result = tempHeat; + tempHeat = 0.0; + } + currentHeat = tempHeat; + return result; } + return heat; } /** @@ -221,7 +259,7 @@ public void setParent(Reactor parent) { * @return true if the component has broken either from damage (e.g. neutron reflectors, fuel rods) or from heat (e.g. heat vents, coolant cells), false otherwise. */ public boolean isBroken() { - return currentHeat > maxHeat || currentDamage > maxDamage; + return currentHeat >= maxHeat || currentDamage > maxDamage; } /** @@ -252,4 +290,28 @@ public void setInitialHeat(double initialHeat) { } } + public double getEffectiveVentCooling() { + return effectiveVentCooling; + } + + public double getVentCoolingCapacity() { + return 0; + } + + public double getBestCondensatorCooling() { + return bestCondensatorCooling; + } + + public double getBestCellCooling() { + return bestCellCooling; + } + + /** + * The number of fuel rods in this component (0 for non-fuel-rod components). + * @return The number of fuel rods in this component, or 0 if this component has no fuel rods. + */ + public int getRodCount() { + return 0; + } + } diff --git a/src/Ic2ExpReactorPlanner/ReactorHeatVent.java b/src/Ic2ExpReactorPlanner/ReactorHeatVent.java index 4cb39fc..8314308 100644 --- a/src/Ic2ExpReactorPlanner/ReactorHeatVent.java +++ b/src/Ic2ExpReactorPlanner/ReactorHeatVent.java @@ -45,13 +45,20 @@ public void dissipate() { double deltaHeat = Math.min(5, parentReactor.getCurrentHeat()); parentReactor.adjustCurrentHeat(-deltaHeat); this.adjustCurrentHeat(deltaHeat); - parentReactor.ventHeat(Math.min(5, getCurrentHeat())); - adjustCurrentHeat(-Math.min(5, getCurrentHeat())); + final double currentDissipation = Math.min(5, getCurrentHeat()); + parentReactor.ventHeat(currentDissipation); + adjustCurrentHeat(-currentDissipation); + effectiveVentCooling = Math.max(effectiveVentCooling, currentDissipation); } @Override public MaterialsList getMaterials() { return MATERIALS; } - + + @Override + public double getVentCoolingCapacity() { + return 5; + } + } diff --git a/src/Ic2ExpReactorPlanner/ReactorPlannerFrame.java b/src/Ic2ExpReactorPlanner/ReactorPlannerFrame.java index 2c1b4f8..6c8203a 100644 --- a/src/Ic2ExpReactorPlanner/ReactorPlannerFrame.java +++ b/src/Ic2ExpReactorPlanner/ReactorPlannerFrame.java @@ -62,7 +62,7 @@ public void actionPerformed(ActionEvent e) { reactor.setComponentAt(finalRow, finalCol, componentToPlace); materialsArea.setText(reactor.getMaterials().toString()); maxHeatLabel.setText(String.format("/%,.0f", reactor.getMaxHeat())); - temperatureEffectsLabel.setText(String.format("Burn: %,d Evaporate: %,d Hurt: %,d Lava: %,d Explode: %,d", (int) (reactor.getMaxHeat() * 0.3), (int) (reactor.getMaxHeat() * 0.5), (int) (reactor.getMaxHeat() * 0.7), (int) (reactor.getMaxHeat() * 0.85), (int) (reactor.getMaxHeat() * 1.0))); + temperatureEffectsLabel.setText(String.format("Burn: %,d Evaporate: %,d Hurt: %,d Lava: %,d Explode: %,d", (int) (reactor.getMaxHeat() * 0.4), (int) (reactor.getMaxHeat() * 0.5), (int) (reactor.getMaxHeat() * 0.7), (int) (reactor.getMaxHeat() * 0.85), (int) (reactor.getMaxHeat() * 1.0))); SpinnerModel model = heatSpinner.getModel(); if (model instanceof SpinnerNumberModel) { ((SpinnerNumberModel)model).setMaximum(reactor.getMaxHeat()); @@ -96,7 +96,7 @@ public void mouseClicked(MouseEvent e) { reactor.setComponentAt(finalRow, finalCol, null); materialsArea.setText(reactor.getMaterials().toString()); maxHeatLabel.setText(String.format("/%,.0f", reactor.getMaxHeat())); - temperatureEffectsLabel.setText(String.format("Burn: %,d Evaporate: %,d Hurt: %,d Lava: %,d Explode: %,d", (int) (reactor.getMaxHeat() * 0.3), (int) (reactor.getMaxHeat() * 0.5), (int) (reactor.getMaxHeat() * 0.7), (int) (reactor.getMaxHeat() * 0.85), (int) (reactor.getMaxHeat() * 1.0))); + temperatureEffectsLabel.setText(String.format("Burn: %,d Evaporate: %,d Hurt: %,d Lava: %,d Explode: %,d", (int) (reactor.getMaxHeat() * 0.4), (int) (reactor.getMaxHeat() * 0.5), (int) (reactor.getMaxHeat() * 0.7), (int) (reactor.getMaxHeat() * 0.85), (int) (reactor.getMaxHeat() * 1.0))); SpinnerModel model = heatSpinner.getModel(); if (model instanceof SpinnerNumberModel) { ((SpinnerNumberModel) model).setMaximum(reactor.getMaxHeat()); @@ -650,7 +650,7 @@ private void clearGridButtonActionPerformed(java.awt.event.ActionEvent evt) {//G outputArea.setText(null); materialsArea.setText(reactor.getMaterials().toString()); maxHeatLabel.setText(String.format("/%,.0f", reactor.getMaxHeat())); - temperatureEffectsLabel.setText(String.format("Burn: %,d Evaporate: %,d Hurt: %,d Lava: %,d Explode: %,d", (int)(reactor.getMaxHeat() * 0.3), (int)(reactor.getMaxHeat() * 0.5), (int)(reactor.getMaxHeat() * 0.7), (int)(reactor.getMaxHeat() * 0.85), (int)(reactor.getMaxHeat() * 1.0))); + temperatureEffectsLabel.setText(String.format("Burn: %,d Evaporate: %,d Hurt: %,d Lava: %,d Explode: %,d", (int)(reactor.getMaxHeat() * 0.4), (int)(reactor.getMaxHeat() * 0.5), (int)(reactor.getMaxHeat() * 0.7), (int)(reactor.getMaxHeat() * 0.85), (int)(reactor.getMaxHeat() * 1.0))); SpinnerModel model = heatSpinner.getModel(); if (model instanceof SpinnerNumberModel) { ((SpinnerNumberModel) model).setMaximum(reactor.getMaxHeat()); @@ -716,7 +716,7 @@ private void updateReactorButtons() { } materialsArea.setText(reactor.getMaterials().toString()); maxHeatLabel.setText(String.format("/%,.0f", reactor.getMaxHeat())); - temperatureEffectsLabel.setText(String.format("Burn: %,d Evaporate: %,d Hurt: %,d Lava: %,d Explode: %,d", (int)(reactor.getMaxHeat() * 0.3), (int)(reactor.getMaxHeat() * 0.5), (int)(reactor.getMaxHeat() * 0.7), (int)(reactor.getMaxHeat() * 0.85), (int)(reactor.getMaxHeat() * 1.0))); + temperatureEffectsLabel.setText(String.format("Burn: %,d Evaporate: %,d Hurt: %,d Lava: %,d Explode: %,d", (int)(reactor.getMaxHeat() * 0.4), (int)(reactor.getMaxHeat() * 0.5), (int)(reactor.getMaxHeat() * 0.7), (int)(reactor.getMaxHeat() * 0.85), (int)(reactor.getMaxHeat() * 1.0))); SpinnerModel model = heatSpinner.getModel(); if (model instanceof SpinnerNumberModel) { ((SpinnerNumberModel) model).setMaximum(reactor.getMaxHeat()); diff --git a/src/Ic2ExpReactorPlanner/RshCondensator.java b/src/Ic2ExpReactorPlanner/RshCondensator.java index 52a90bb..51a21a2 100644 --- a/src/Ic2ExpReactorPlanner/RshCondensator.java +++ b/src/Ic2ExpReactorPlanner/RshCondensator.java @@ -44,4 +44,17 @@ public MaterialsList getMaterials() { return MATERIALS; } + @Override + public double adjustCurrentHeat(final double heat) { + if (heat < 0.0) { + return heat; + } + currentCondensatorCooling += heat; + bestCondensatorCooling = Math.max(currentCondensatorCooling, bestCondensatorCooling); + double acceptedHeat = Math.min(heat, getMaxHeat() - heat); + double result = heat - acceptedHeat; + currentHeat += acceptedHeat; + return result; + } + } diff --git a/src/Ic2ExpReactorPlanner/Simulator.java b/src/Ic2ExpReactorPlanner/Simulator.java index c9ad91c..211267f 100644 --- a/src/Ic2ExpReactorPlanner/Simulator.java +++ b/src/Ic2ExpReactorPlanner/Simulator.java @@ -51,11 +51,78 @@ protected Void doInBackground() throws Exception { long startTime = System.nanoTime(); int reactorTicks = 0; int cooldownTicks = 0; + int totalRodCount = 0; try { publish(""); publish("Simulation started.\n"); + // Checking for temperature thresholds only reactor.setCurrentHeat(initialHeat); reactor.clearVentedHeat(); + for (int row = 0; row < 6; row++) { + for (int col = 0; col < 9; col++) { + ReactorComponent component = reactor.getComponentAt(row, col); + if (component != null) { + component.clearCurrentHeat(); + component.clearDamage(); + } + } + } + double minReactorHeat = initialHeat; + double maxReactorHeat = initialHeat; + boolean reachedBurn = initialHeat >= 0.4 * reactor.getMaxHeat(); + boolean reachedEvaporate = initialHeat >= 0.5 * reactor.getMaxHeat(); + boolean reachedHurt = initialHeat >= 0.7 * reactor.getMaxHeat(); + boolean reachedLava = initialHeat >= 0.85 * reactor.getMaxHeat(); + boolean reachedExplode = false; + do { + reactor.clearEUOutput(); + reactor.clearVentedHeat(); + reactorTicks++; + for (int row = 0; row < 6; row++) { + for (int col = 0; col < 9; col++) { + ReactorComponent component = reactor.getComponentAt(row, col); + if (component != null && !component.isBroken()) { + component.generateHeat(); + maxReactorHeat = Math.max(reactor.getCurrentHeat(), maxReactorHeat); + minReactorHeat = Math.min(reactor.getCurrentHeat(), minReactorHeat); + component.dissipate(); + maxReactorHeat = Math.max(reactor.getCurrentHeat(), maxReactorHeat); + minReactorHeat = Math.min(reactor.getCurrentHeat(), minReactorHeat); + component.transfer(); + maxReactorHeat = Math.max(reactor.getCurrentHeat(), maxReactorHeat); + minReactorHeat = Math.min(reactor.getCurrentHeat(), minReactorHeat); + } + if (maxReactorHeat >= 0.4 * reactor.getMaxHeat() && !reachedBurn) { + publish(String.format("Reactor will reach \"Burn\" temperature at %d seconds.\n", reactorTicks)); + reachedBurn = true; + } + if (maxReactorHeat >= 0.5 * reactor.getMaxHeat() && !reachedEvaporate) { + publish(String.format("Reactor will reach \"Evaporate\" temperature at %d seconds.\n", reactorTicks)); + reachedEvaporate = true; + } + if (maxReactorHeat >= 0.7 * reactor.getMaxHeat() && !reachedHurt) { + publish(String.format("Reactor will reach \"Hurt\" temperature at %d seconds.\n", reactorTicks)); + reachedHurt = true; + } + if (maxReactorHeat >= 0.85 * reactor.getMaxHeat() && !reachedLava) { + publish(String.format("Reactor will reach \"Lava\" temperature at %d seconds.\n", reactorTicks)); + reachedLava = true; + } + if (maxReactorHeat >= reactor.getMaxHeat() && !reachedExplode) { + publish(String.format("Reactor will explode at %d seconds.\n", reactorTicks)); + reachedExplode = true; + } + } + } + } while (reactor.getCurrentHeat() <= reactor.getMaxHeat() && reactorTicks <= 20000); + publish(String.format("Reactor minimum temperature: %,.2f\n", minReactorHeat)); + publish(String.format("Reactor maximum temperature (if unchecked): %,.2f\n", maxReactorHeat)); + // full simulation + reactorTicks = 0; + reactor.setCurrentHeat(initialHeat); + reactor.clearVentedHeat(); + minReactorHeat = initialHeat; + maxReactorHeat = initialHeat; for (int row = 0; row < 6; row++) { for (int col = 0; col < 9; col++) { ReactorComponent component = reactor.getComponentAt(row, col); @@ -63,6 +130,7 @@ protected Void doInBackground() throws Exception { component.clearCurrentHeat(); component.clearDamage(); publish(String.format("R%dC%d:%s", row, col, component.toString())); + totalRodCount += component.getRodCount(); } else { publish(String.format("R%dC%d:", row, col)); } @@ -73,19 +141,36 @@ protected Void doInBackground() throws Exception { double totalEUoutput = 0.0; double lastHeatOutput = 0.0; double totalHeatOutput = 0.0; + double maxGeneratedHeat = 0.0; do { reactor.clearEUOutput(); reactor.clearVentedHeat(); + for (int row = 0; row < 6; row++) { + for (int col = 0; col < 9; col++) { + ReactorComponent component = reactor.getComponentAt(row, col); + if (component != null) { + component.preReactorTick(); + } + } + } + double generatedHeat = 0.0; for (int row = 0; row < 6; row++) { for (int col = 0; col < 9; col++) { ReactorComponent component = reactor.getComponentAt(row, col); if (component != null && !component.isBroken()) { - component.generateHeat(); + generatedHeat += component.generateHeat(); + maxReactorHeat = Math.max(reactor.getCurrentHeat(), maxReactorHeat); + minReactorHeat = Math.min(reactor.getCurrentHeat(), minReactorHeat); component.dissipate(); + maxReactorHeat = Math.max(reactor.getCurrentHeat(), maxReactorHeat); + minReactorHeat = Math.min(reactor.getCurrentHeat(), minReactorHeat); component.transfer(); + maxReactorHeat = Math.max(reactor.getCurrentHeat(), maxReactorHeat); + minReactorHeat = Math.min(reactor.getCurrentHeat(), minReactorHeat); } } } + maxGeneratedHeat = Math.max(generatedHeat, maxGeneratedHeat); for (int row = 0; row < 6; row++) { for (int col = 0; col < 9; col++) { ReactorComponent component = reactor.getComponentAt(row, col); @@ -121,8 +206,10 @@ protected Void doInBackground() throws Exception { if (reactorTicks > 0) { if (reactor.isFluid()) { publish(String.format("Average heat output before fuel rods stopped: %.2f Hu/s\nMinimum heat output: %.2f Hu/s\nMaximum heat output: %.2f Hu/s\n", 2 * totalHeatOutput / reactorTicks, 2 * minHeatOutput, 2 * maxHeatOutput)); + publish(String.format("Efficiency: %.2f average, %.2f minimum, %.2f maximum\n", totalHeatOutput / reactorTicks / 4 / totalRodCount, minHeatOutput / 4 / totalRodCount, maxHeatOutput / 4 / totalRodCount)); } else { publish(String.format("Total EU output: %,.0f (%.2f EU/t min, %.2f EU/t max, %.2f EU/t average)\n", totalEUoutput, minEUoutput / 20.0, maxEUoutput / 20.0, totalEUoutput / (reactorTicks * 20))); + publish(String.format("Efficiency: %.2f average, %.2f minimum, %.2f maximum\n", totalEUoutput / reactorTicks / 100 / totalRodCount, minEUoutput / 100 / totalRodCount, maxEUoutput / 100 / totalRodCount)); } } lastHeatOutput = 0.0; @@ -209,12 +296,47 @@ protected Void doInBackground() throws Exception { if (reactor.isFluid() && reactor.getCurrentHeat() < reactor.getMaxHeat()) { publish(String.format("Average heat output after fuel rods stopped: %.2f Hu/s\nMinimum heat output: %.2f Hu/s\nMaximum heat output: %.2f Hu/s\n", 2 * totalHeatOutput / cooldownTicks, 2 * minHeatOutput, 2 * maxHeatOutput)); } + double totalEffectiveVentCooling = 0.0; + double totalVentCoolingCapacity = 0.0; + double totalCellCooling = 0.0; + double totalCondensatorCooling = 0.0; + + for (int row = 0; row < 6; row++) { + for (int col = 0; col < 9; col++) { + ReactorComponent component = reactor.getComponentAt(row, col); + if (component != null) { + if (component.getVentCoolingCapacity() > 0) { + publish(String.format("R%dC%d:+ (%.2f of %.2f cooling)", row, col, component.getEffectiveVentCooling(), component.getVentCoolingCapacity())); + totalEffectiveVentCooling += component.getEffectiveVentCooling(); + totalVentCoolingCapacity += component.getVentCoolingCapacity(); + } else if (component.getBestCellCooling() > 0) { + publish(String.format("R%dC%d:+ (received at most %.2f heat per reactor tick)", row, col, component.getBestCellCooling())); + totalCellCooling += component.getBestCellCooling(); + } else if (component.getBestCondensatorCooling() > 0) { + publish(String.format("R%dC%d:+ (received at most %.2f heat per reactor tick)", row, col, component.getBestCondensatorCooling())); + totalCondensatorCooling += component.getBestCondensatorCooling(); + } + } + } + } + + publish(String.format("Total Vent Cooling: %,.2f of %,.2f\n", totalEffectiveVentCooling, totalVentCoolingCapacity)); + publish(String.format("Total Cell Cooling: %,.2f\n", totalCellCooling)); + publish(String.format("Total Condensator Cooling: %,.2f\n", totalCondensatorCooling)); + publish(String.format("Max Heat Generated: %.2f\n", maxGeneratedHeat)); + publish(String.format("Reactor maximum temperature (when limited by settings): %,.2f\n", maxReactorHeat)); + double totalCooling = totalEffectiveVentCooling + totalCellCooling + totalCondensatorCooling; + if (totalCooling >= maxGeneratedHeat) { + publish(String.format("Excess cooling: %.2f\n", totalCooling - maxGeneratedHeat)); + } else { + publish(String.format("Excess heating: %.2f\n", maxGeneratedHeat - totalCooling)); + } //return null; } catch (Throwable e) { if (cooldownTicks == 0) { - publish(String.format("Error at reactor tick %d", reactorTicks)); + publish(String.format("Error at reactor tick %d\n", reactorTicks)); } else { - publish(String.format("Error at cooldown tick %d", cooldownTicks)); + publish(String.format("Error at cooldown tick %d\n", cooldownTicks)); } publish(e.toString(), " ", Arrays.toString(e.getStackTrace())); }