aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/Ic2ExpReactorPlanner/Reactor.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/Ic2ExpReactorPlanner/Reactor.java')
-rw-r--r--src/main/java/Ic2ExpReactorPlanner/Reactor.java763
1 files changed, 763 insertions, 0 deletions
diff --git a/src/main/java/Ic2ExpReactorPlanner/Reactor.java b/src/main/java/Ic2ExpReactorPlanner/Reactor.java
new file mode 100644
index 0000000000..e611189317
--- /dev/null
+++ b/src/main/java/Ic2ExpReactorPlanner/Reactor.java
@@ -0,0 +1,763 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package Ic2ExpReactorPlanner;
+
+import static Ic2ExpReactorPlanner.BundleHelper.formatI18n;
+import static Ic2ExpReactorPlanner.BundleHelper.getI18n;
+import Ic2ExpReactorPlanner.components.ReactorItem;
+import java.awt.HeadlessException;
+import javax.swing.JOptionPane;
+
+/**
+ * Represents an IndustrialCraft2 Nuclear Reactor.
+ * @author Brian McCloud
+ */
+public class Reactor {
+
+ private final ReactorItem[][] grid = new ReactorItem[6][9];
+
+ private double currentEUoutput = 0.0;
+
+ private double currentHeat = 0.0;
+
+ private double maxHeat = 10000.0;
+
+ private double ventedHeat = 0.0;
+
+ private boolean fluid = false;
+
+ private boolean pulsed = false;
+
+ private boolean automated = false;
+
+ private boolean usingReactorCoolantInjectors = false;
+
+ private static final int DEFAULT_ON_PULSE = (int)5e6;
+
+ private int onPulse = DEFAULT_ON_PULSE;
+
+ private static final int DEFAULT_OFF_PULSE = 0;
+
+ private int offPulse = DEFAULT_OFF_PULSE;
+
+ private static final int DEFAULT_SUSPEND_TEMP = (int)120e3;
+
+ private int suspendTemp = DEFAULT_SUSPEND_TEMP;
+
+ private static final int DEFAULT_RESUME_TEMP = (int)120e3;
+
+ private int resumeTemp = DEFAULT_RESUME_TEMP;
+
+ private int maxSimulationTicks = (int)5e6;
+
+ // maximum paramatter types for a reactor component (current initial heat, automation threshold, reactor pause
+ private static final int MAX_PARAM_TYPES = 3;
+
+ public static final int MAX_COMPONENT_HEAT = 1_080_000;
+
+ public ReactorItem getComponentAt(final int row, final int column) {
+ if (row >= 0 && row < grid.length && column >= 0 && column < grid[row].length) {
+ return grid[row][column];
+ }
+ return null;
+ }
+
+ public void setComponentAt(final int row, final int column, final ReactorItem component) {
+ if (row >= 0 && row < grid.length && column >= 0 && column < grid[row].length) {
+ if (grid[row][column] != null) {
+ grid[row][column].removeFromReactor();
+ }
+ grid[row][column] = component;
+ if (component != null) {
+ component.addToReactor(this, row, column);
+ }
+ }
+ }
+
+ public void clearGrid() {
+ for (int row = 0; row < grid.length; row++) {
+ for (int col = 0; col < grid[row].length; col++) {
+ setComponentAt(row, col, null);
+ }
+ }
+ }
+
+ /**
+ * @return the amount of EU output in the reactor tick just simulated.
+ */
+ public double getCurrentEUoutput() {
+ return currentEUoutput;
+ }
+
+ /**
+ * @return the current heat level of the reactor.
+ */
+ public double getCurrentHeat() {
+ return currentHeat;
+ }
+
+ /**
+ * @return the maximum heat of the reactor.
+ */
+ public double getMaxHeat() {
+ return maxHeat;
+ }
+
+ /**
+ * Adjust the maximum heat
+ * @param adjustment the adjustment amount (negative values decrease the max heat).
+ */
+ public void adjustMaxHeat(final double adjustment) {
+ maxHeat += adjustment;
+ }
+
+ /**
+ * Set the current heat of the reactor. Mainly to be used for simulating a pre-heated reactor, or for resetting to 0 for a new simulation.
+ * @param currentHeat the heat to set
+ */
+ public void setCurrentHeat(final double currentHeat) {
+ this.currentHeat = currentHeat;
+ }
+
+ /**
+ * Adjusts the reactor's current heat by a specified amount
+ * @param adjustment the adjustment amount.
+ */
+ public void adjustCurrentHeat(final double adjustment) {
+ currentHeat += adjustment;
+ if (currentHeat < 0.0) {
+ currentHeat = 0.0;
+ }
+ }
+
+ /**
+ * add some EU output.
+ * @param amount the amount of EU to output over 1 reactor tick (20 game ticks).
+ */
+ public void addEUOutput(final double amount) {
+ currentEUoutput += amount;
+ }
+
+ /**
+ * clears the EU output (presumably to start simulating a new reactor tick).
+ */
+ public void clearEUOutput() {
+ currentEUoutput = 0.0;
+ }
+
+ /**
+ * Gets a list of the materials needed to build the components.
+ * @return a list of the materials needed to build the components.
+ */
+ public MaterialsList getMaterials() {
+ MaterialsList result = new MaterialsList();
+ for (int col = 0; col < grid[0].length; col++) {
+ for (int row = 0; row < grid.length; row++) {
+ if (getComponentAt(row, col) != null) {
+ result.add(MaterialsList.getMaterialsForComponent(getComponentAt(row, col)));
+ }
+ }
+ }
+ return result;
+ }
+
+ public MaterialsList getComponentList() {
+ MaterialsList result = new MaterialsList();
+ for (int col = 0; col < grid[0].length; col++) {
+ for (int row = 0; row < grid.length; row++) {
+ if (getComponentAt(row, col) != null) {
+ result.add(getComponentAt(row, col).name);
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * @return the amount of heat vented this reactor tick.
+ */
+ public double getVentedHeat() {
+ return ventedHeat;
+ }
+
+ /**
+ * Adds to the amount of heat vented this reactor tick, in case it is a new-style reactor with a pressure vessel and outputting heat to fluid instead of EU.
+ * @param amount the amount to add.
+ */
+ public void ventHeat(final double amount) {
+ ventedHeat += amount;
+ }
+
+ /**
+ * Clears the amount of vented heat, in case a new reactor tick is starting.
+ */
+ public void clearVentedHeat() {
+ ventedHeat = 0;
+ }
+
+ /**
+ * Get a code that represents the component set, which can be passed between forum users, etc.
+ * @return a code representing some ids for the components and arrangement. Passing the same code to setCode() should re-create an identical reactor setup, even if other changes have happened in the meantime.
+ */
+ public String getCode() {
+ return "erp=" + buildCodeString();
+ }
+
+ /**
+ * Sets a code to configure the entire grid all at once. Expects the code to have originally been output by getCode().
+ * @param code the code of the reactor setup to use.
+ */
+ public void setCode(final String code) {
+ int pos = 0;
+ int[][] ids = new int[grid.length][grid[0].length];
+ char[][][] paramTypes = new char[grid.length][grid[0].length][MAX_PARAM_TYPES];
+ int[][][] params = new int[grid.length][grid[0].length][MAX_PARAM_TYPES];
+ if (code.startsWith("erp=")) {
+ readCodeString(code.substring(4));
+ } else if (code.length() >= 108 && code.matches("[0-9A-Za-z(),|]+")) { //NOI18N
+ try {
+ for (int row = 0; row < grid.length; row++) {
+ for (int col = 0; col < grid[row].length; col++) {
+ ids[row][col] = Integer.parseInt(code.substring(pos, pos + 2), 16);
+ pos += 2;
+ int paramNum = 0;
+ if (pos + 1 < code.length() && code.charAt(pos) == '(') {
+ paramTypes[row][col][paramNum] = code.charAt(pos + 1);
+ int tempPos = pos + 2;
+ StringBuilder param = new StringBuilder(10);
+ while (tempPos < code.length() && code.charAt(tempPos) != ')') {
+ if (code.charAt(tempPos) == ',') {
+ params[row][col][paramNum] = Integer.parseInt(param.toString(), 36);
+ paramNum++;
+ if (tempPos + 1 < code.length()) {
+ tempPos++;
+ paramTypes[row][col][paramNum] = code.charAt(tempPos);
+ }
+ param.setLength(0);
+ } else {
+ param.append(code.charAt(tempPos));
+ }
+ tempPos++;
+ }
+ params[row][col][paramNum] = Integer.parseInt(param.toString(), 36);
+ pos = tempPos + 1;
+ }
+ }
+ }
+ for (int row = 0; row < grid.length; row++) {
+ for (int col = 0; col < grid[row].length; col++) {
+ final ReactorItem component = ComponentFactory.createComponent(ids[row][col]);
+ for (int paramNum = 0; paramNum < MAX_PARAM_TYPES; paramNum++) {
+ switch (paramTypes[row][col][paramNum]) {
+ case 'h':
+ component.setInitialHeat(params[row][col][paramNum]);
+ break;
+ case 'a':
+ component.setAutomationThreshold(params[row][col][paramNum]);
+ break;
+ case 'p':
+ component.setReactorPause(params[row][col][paramNum]);
+ break;
+ default:
+ break;
+ }
+ }
+ setComponentAt(row, col, component);
+ }
+ }
+ if (code.split("\\|").length > 1) {
+ String extraCode = code.split("\\|")[1];
+ switch (extraCode.charAt(0)) {
+ case 'f':
+ fluid = true;
+ break;
+ case 'e':
+ fluid = false;
+ break;
+ default:
+ break;
+ }
+ switch (extraCode.charAt(1)) {
+ case 's':
+ pulsed = false;
+ automated = false;
+ break;
+ case 'p':
+ pulsed = true;
+ automated = false;
+ break;
+ case 'a':
+ pulsed = true;
+ automated = true;
+ break;
+ default:
+ break;
+ }
+ switch (extraCode.charAt(2)) {
+ case 'i':
+ usingReactorCoolantInjectors = true;
+ break;
+ case 'n':
+ usingReactorCoolantInjectors = false;
+ break;
+ default:
+ break;
+ }
+ if (extraCode.length() > 3) {
+ currentHeat = Integer.parseInt(extraCode.substring(3), 36);
+ } else {
+ currentHeat = 0;
+ }
+ }
+ if (code.split("\\|").length > 2) {
+ String[] moreCodes = code.split("\\|");
+ for (int i = 2; i < moreCodes.length; i++) {
+ switch (moreCodes[i].charAt(0)) {
+ case 'n':
+ onPulse = Integer.parseInt(moreCodes[i].substring(1), 36);
+ break;
+ case 'f':
+ offPulse = Integer.parseInt(moreCodes[i].substring(1), 36);
+ break;
+ case 's':
+ suspendTemp = Integer.parseInt(moreCodes[i].substring(1), 36);
+ break;
+ case 'r':
+ resumeTemp = Integer.parseInt(moreCodes[i].substring(1), 36);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ } catch (NumberFormatException e) {
+ e.printStackTrace();
+ }
+ } else {
+ String tempCode = code;
+ if (code.startsWith("http://www.talonfiremage.pwp.blueyonder.co.uk/v3/reactorplanner.html?")) { //NOI18N
+ tempCode = code.replace("http://www.talonfiremage.pwp.blueyonder.co.uk/v3/reactorplanner.html?", ""); //NOI18N
+ }
+ if (tempCode.matches("[0-9a-z]+")) { //NOI18N
+ // Possibly a code from Talonius's old planner
+ handleTaloniusCode(tempCode);
+ } else if (code.matches("[0-9A-Za-z+/=]+")) { //NOI18N
+ // Try to handle it as a newer code with the "erp=" prefix stripped
+ readCodeString(code);
+ } else if (!code.isEmpty()) {
+ JOptionPane.showMessageDialog(null, String.format(getI18n("Warning.InvalidReactorCode"), code), getI18n("Warning.Title"), JOptionPane.WARNING_MESSAGE);
+ }
+ }
+ }
+
+ private void handleTaloniusCode(String tempCode) throws HeadlessException {
+ StringBuilder warnings = new StringBuilder(500);
+ TaloniusDecoder decoder = new TaloniusDecoder(tempCode);
+ // initial heat, in multiples of 100
+ currentHeat = 100 * decoder.readInt(10);
+ // reactor grid
+ for (int x = 8; x >= 0; x--) {
+ for (int y = 5; y >= 0; y--) {
+ int nextValue = decoder.readInt(7);
+
+ // items are no longer stackable in IC2 reactors, but stack sizes from the planner code still need to be handled
+ if (nextValue > 64) {
+ nextValue = decoder.readInt(7);
+ }
+
+ switch (nextValue) {
+ case 0:
+ setComponentAt(y, x, null);
+ break;
+ case 1:
+ setComponentAt(y, x, ComponentFactory.createComponent("fuelRodUranium"));
+ break;
+ case 2:
+ setComponentAt(y, x, ComponentFactory.createComponent("dualFuelRodUranium"));
+ break;
+ case 3:
+ setComponentAt(y, x, ComponentFactory.createComponent("quadFuelRodUranium"));
+ break;
+ case 4:
+ warnings.append(formatI18n("Warning.DepletedIsotope", y, x));
+ break;
+ case 5:
+ setComponentAt(y, x, ComponentFactory.createComponent("neutronReflector"));
+ break;
+ case 6:
+ setComponentAt(y, x, ComponentFactory.createComponent("thickNeutronReflector"));
+ break;
+ case 7:
+ setComponentAt(y, x, ComponentFactory.createComponent("heatVent"));
+ break;
+ case 8:
+ setComponentAt(y, x, ComponentFactory.createComponent("reactorHeatVent"));
+ break;
+ case 9:
+ setComponentAt(y, x, ComponentFactory.createComponent("overclockedHeatVent"));
+ break;
+ case 10:
+ setComponentAt(y, x, ComponentFactory.createComponent("advancedHeatVent"));
+ break;
+ case 11:
+ setComponentAt(y, x, ComponentFactory.createComponent("componentHeatVent"));
+ break;
+ case 12:
+ setComponentAt(y, x, ComponentFactory.createComponent("rshCondensator"));
+ break;
+ case 13:
+ setComponentAt(y, x, ComponentFactory.createComponent("lzhCondensator"));
+ break;
+ case 14:
+ setComponentAt(y, x, ComponentFactory.createComponent("heatExchanger"));
+ break;
+ case 15:
+ setComponentAt(y, x, ComponentFactory.createComponent("coreHeatExchanger"));
+ break;
+ case 16:
+ setComponentAt(y, x, ComponentFactory.createComponent("componentHeatExchanger"));
+ break;
+ case 17:
+ setComponentAt(y, x, ComponentFactory.createComponent("advancedHeatExchanger"));
+ break;
+ case 18:
+ setComponentAt(y, x, ComponentFactory.createComponent("reactorPlating"));
+ break;
+ case 19:
+ setComponentAt(y, x, ComponentFactory.createComponent("heatCapacityReactorPlating"));
+ break;
+ case 20:
+ setComponentAt(y, x, ComponentFactory.createComponent("containmentReactorPlating"));
+ break;
+ case 21:
+ setComponentAt(y, x, ComponentFactory.createComponent("coolantCell10k"));
+ break;
+ case 22:
+ setComponentAt(y, x, ComponentFactory.createComponent("coolantCell30k"));
+ break;
+ case 23:
+ setComponentAt(y, x, ComponentFactory.createComponent("coolantCell60k"));
+ break;
+ case 24:
+ warnings.append(formatI18n("Warning.Heating", y, x));
+ break;
+ case 32:
+ setComponentAt(y, x, ComponentFactory.createComponent("fuelRodThorium"));
+ break;
+ case 33:
+ setComponentAt(y, x, ComponentFactory.createComponent("dualFuelRodThorium"));
+ break;
+ case 34:
+ setComponentAt(y, x, ComponentFactory.createComponent("quadFuelRodThorium"));
+ break;
+ case 35:
+ warnings.append(formatI18n("Warning.Plutonium", y, x));
+ break;
+ case 36:
+ warnings.append(formatI18n("Warning.DualPlutonium", y, x));
+ break;
+ case 37:
+ warnings.append(formatI18n("Warning.QuadPlutonium", y, x));
+ break;
+ case 38:
+ setComponentAt(y, x, ComponentFactory.createComponent("iridiumNeutronReflector"));
+ break;
+ case 39:
+ setComponentAt(y, x, ComponentFactory.createComponent("coolantCellHelium60k"));
+ break;
+ case 40:
+ setComponentAt(y, x, ComponentFactory.createComponent("coolantCellHelium180k"));
+ break;
+ case 41:
+ setComponentAt(y, x, ComponentFactory.createComponent("coolantCellHelium360k"));
+ break;
+ case 42:
+ setComponentAt(y, x, ComponentFactory.createComponent("coolantCellNak60k"));
+ break;
+ case 43:
+ setComponentAt(y, x, ComponentFactory.createComponent("coolantCellNak180k"));
+ break;
+ case 44:
+ setComponentAt(y, x, ComponentFactory.createComponent("coolantCellNak360k"));
+ break;
+ default:
+ warnings.append(formatI18n("Warning.Unrecognized", nextValue, y, x));
+ break;
+ }
+ }
+ }
+ if (warnings.length() > 0) {
+ warnings.setLength(warnings.length() - 1); // to remove last newline character
+ JOptionPane.showMessageDialog(null, warnings, getI18n("Warning.Title"), JOptionPane.WARNING_MESSAGE);
+ }
+ }
+
+ // reads a Base64 code string for the reactor, after stripping the prefix.
+ private void readCodeString(final String code) {
+ BigintStorage storage = BigintStorage.inputBase64(code);
+ // read the code revision from the code itself instead of making it part of the prefix.
+ int codeRevision = storage.extract(255);
+ int maxComponentHeat;
+ if (codeRevision == 3)
+ maxComponentHeat = (int)1080e3;
+ else
+ maxComponentHeat = (int)360e3;
+ // Check if the code revision is supported yet.
+ if (codeRevision > 3) {
+ throw new IllegalArgumentException("Unsupported code revision in reactor code.");
+ }
+ // for code revision 1 or newer, read whether the reactor is pulsed and/or automated next.
+ if (codeRevision >= 1) {
+ pulsed = storage.extract(1) > 0;
+ automated = storage.extract(1) > 0;
+ }
+ // read the grid next
+ for (int row = 0; row < grid.length; row++) {
+ for (int col = 0; col < grid[row].length; col++) {
+ int componentId = 0;
+ // Changes may be coming to the number of components available, so make sure to check the code revision number.
+ if (codeRevision <= 1) {
+ componentId = storage.extract(38);
+ } else if (codeRevision == 2) {
+ componentId = storage.extract(44);
+ } else {
+ componentId = storage.extract(58);
+ }
+ if (componentId != 0) {
+ ReactorItem component = ComponentFactory.createComponent(componentId);
+ int hasSpecialAutomationConfig = storage.extract(1);
+ if (hasSpecialAutomationConfig > 0) {
+ component.setInitialHeat(storage.extract(maxComponentHeat));
+ if (codeRevision == 0 || (codeRevision >= 1 && automated)) {
+ component.setAutomationThreshold(storage.extract(maxComponentHeat));
+ component.setReactorPause(storage.extract((int)10e3));
+ }
+ }
+ setComponentAt(row, col, component);
+ } else {
+ setComponentAt(row, col, null);
+ }
+ }
+ }
+ // next, read the inital temperature and other details.
+ currentHeat = storage.extract((int)120e3);
+ if (codeRevision == 0 || (codeRevision >= 1 && pulsed)) {
+ onPulse = storage.extract((int)5e6);
+ offPulse = storage.extract((int)5e6);
+ suspendTemp = storage.extract((int)120e3);
+ resumeTemp = storage.extract((int)120e3);
+ }
+ fluid = storage.extract(1) > 0;
+ usingReactorCoolantInjectors = storage.extract(1) > 0;
+ if (codeRevision == 0) {
+ pulsed = storage.extract(1) > 0;
+ automated = storage.extract(1) > 0;
+ }
+ maxSimulationTicks = storage.extract((int)5e6);
+ }
+
+ // builds a Base64 code string, not including the prefix.
+ private String buildCodeString() {
+ BigintStorage storage = new BigintStorage();
+ // first, store the extra details, in reverse order of expected reading.
+ storage.store(maxSimulationTicks, (int)5e6);
+ storage.store(usingReactorCoolantInjectors ? 1 : 0, 1);
+ storage.store(fluid ? 1 : 0, 1);
+ if (pulsed) {
+ storage.store(resumeTemp, (int)120e3);
+ storage.store(suspendTemp, (int)120e3);
+ storage.store(offPulse, (int)5e6);
+ storage.store(onPulse, (int)5e6);
+ }
+ storage.store((int)currentHeat, (int)120e3);
+ // grid is read (almost) first, so written (almost) last, and in reverse order
+ for (int row = grid.length - 1; row >= 0; row--) {
+ for (int col = grid[row].length - 1; col >= 0; col--) {
+ ReactorItem component = grid[row][col];
+ if (component != null) {
+ int id = component.id;
+ // only store automation details for a component if non-default, and add a flag bit to indicate their presence. null components don't even need the flag bit.
+ if (component.getInitialHeat() > 0 || component.getAutomationThreshold() != ComponentFactory.getDefaultComponent(id).getAutomationThreshold() || component.getReactorPause() != ComponentFactory.getDefaultComponent(id).getReactorPause()) {
+ if (automated) {
+ storage.store(component.getReactorPause(), (int)10e3);
+ storage.store(component.getAutomationThreshold(), (int)1080e3);
+ }
+ storage.store((int)component.getInitialHeat(), (int)1080e3);
+ storage.store(1, 1);
+ } else {
+ storage.store(0, 1);
+ }
+ storage.store(id, 58);
+ } else {
+ storage.store(0, 58);
+ }
+ }
+ }
+ storage.store(automated ? 1 : 0, 1);
+ storage.store(pulsed ? 1 : 0, 1);
+ // store the code revision, allowing values up to 255 (8 bits) before adjusting how it is stored in the code.
+ storage.store(3, 255);
+ return storage.outputBase64();
+ }
+
+ // Get an old-style (pre-2.3.1) code for the reactor, for pasting into older versions of the planner.
+ public String getOldCode() {
+ StringBuilder result = new StringBuilder(108);
+ for (int row = 0; row < grid.length; row++) {
+ for (int col = 0; col < grid[row].length; col++) {
+ final ReactorItem component = getComponentAt(row, col);
+ final int id = (component != null) ? component.id : 0;
+ result.append(String.format("%02X", id)); //NOI18N
+ if (component != null && (component.getInitialHeat() > 0
+ || (automated && component.getAutomationThreshold() != ComponentFactory.getDefaultComponent(id).getAutomationThreshold())
+ || (automated && component.getReactorPause() != ComponentFactory.getDefaultComponent(id).getReactorPause()))) {
+ result.append("(");
+ if (component.getInitialHeat() > 0) {
+ result.append(String.format("h%s,", Integer.toString((int) component.getInitialHeat(), 36))); //NOI18N
+ }
+ if (automated && component.getAutomationThreshold() != ComponentFactory.getDefaultComponent(id).getAutomationThreshold()) {
+ result.append(String.format("a%s,", Integer.toString(component.getAutomationThreshold(), 36))); //NOI18N
+ }
+ if (automated && component.getReactorPause() != ComponentFactory.getDefaultComponent(id).getReactorPause()) {
+ result.append(String.format("p%s,", Integer.toString(component.getReactorPause(), 36))); //NOI18N
+ }
+ result.setLength(result.length() - 1); // remove the last comma, whichever parameter it came from.
+ result.append(")");
+ }
+ }
+ }
+ result.append('|');
+ if (fluid) {
+ result.append('f');
+ } else {
+ result.append('e');
+ }
+ if (automated) {
+ result.append('a');
+ } else if (pulsed) {
+ result.append('p');
+ } else {
+ result.append('s');
+ }
+ if (usingReactorCoolantInjectors) {
+ result.append('i');
+ } else {
+ result.append('n');
+ }
+ if (currentHeat > 0) {
+ result.append(Integer.toString((int) currentHeat, 36));
+ }
+ if (pulsed && onPulse != DEFAULT_ON_PULSE) {
+ result.append(String.format("|n%s", Integer.toString(onPulse, 36)));
+ }
+ if (pulsed && offPulse != DEFAULT_OFF_PULSE) {
+ result.append(String.format("|f%s", Integer.toString(offPulse, 36)));
+ }
+ if (pulsed && suspendTemp != DEFAULT_SUSPEND_TEMP) {
+ result.append(String.format("|s%s", Integer.toString(suspendTemp, 36)));
+ }
+ if (pulsed && resumeTemp != DEFAULT_SUSPEND_TEMP) {
+ result.append(String.format("|r%s", Integer.toString(resumeTemp, 36)));
+ }
+ return result.toString();
+ }
+
+ /**
+ * Checks whether the reactor is to simulate a fluid-style reactor, rather than a direct EU-output reactor.
+ * @return true if this was set to be a fluid-style reactor, false if this was set to be direct EU-output reactor.
+ */
+ public boolean isFluid() {
+ return fluid;
+ }
+
+ /**
+ * Sets whether the reactor is to simulate a fluid-style reactor, rather than a direct EU-output reactor.
+ * @param fluid true if this is to be a fluid-style reactor, false if this is to be direct EU-output reactor.
+ */
+ public void setFluid(final boolean fluid) {
+ this.fluid = fluid;
+ }
+
+ /**
+ * Checks whether the reactor is using Reactor Coolant Injectors (RCIs)
+ * @return true if this reactor was set to use RCIs, false otherwise.
+ */
+ public boolean isUsingReactorCoolantInjectors() {
+ return usingReactorCoolantInjectors;
+ }
+
+ /**
+ * Sets whether the reactor is to use Reactor Coolant Injectors (RCIs)
+ * @param usingReactorCoolantInjectors true if this reactor should use RCIs, false otherwise.
+ */
+ public void setUsingReactorCoolantInjectors(final boolean usingReactorCoolantInjectors) {
+ this.usingReactorCoolantInjectors = usingReactorCoolantInjectors;
+ }
+
+ public int getOnPulse() {
+ return onPulse;
+ }
+
+ public void setOnPulse(final int onPulse) {
+ this.onPulse = onPulse;
+ }
+
+ public int getOffPulse() {
+ return offPulse;
+ }
+
+ public void setOffPulse(final int offPulse) {
+ this.offPulse = offPulse;
+ }
+
+ public int getSuspendTemp() {
+ return suspendTemp;
+ }
+
+ public void setSuspendTemp(final int suspendTemp) {
+ this.suspendTemp = suspendTemp;
+ }
+
+ public int getResumeTemp() {
+ return resumeTemp;
+ }
+
+ public void setResumeTemp(final int resumeTemp) {
+ this.resumeTemp = resumeTemp;
+ }
+
+ public boolean isPulsed() {
+ return pulsed;
+ }
+
+ public void setPulsed(boolean pulsed) {
+ this.pulsed = pulsed;
+ }
+
+ public boolean isAutomated() {
+ return automated;
+ }
+
+ public void setAutomated(boolean automated) {
+ this.automated = automated;
+ }
+
+ public int getMaxSimulationTicks() {
+ return maxSimulationTicks;
+ }
+
+ public void setMaxSimulationTicks(int maxSimulationTicks) {
+ this.maxSimulationTicks = maxSimulationTicks;
+ }
+
+ public void resetPulseConfig() {
+ onPulse = DEFAULT_ON_PULSE;
+ offPulse = DEFAULT_OFF_PULSE;
+ suspendTemp = DEFAULT_SUSPEND_TEMP;
+ resumeTemp = DEFAULT_RESUME_TEMP;
+ }
+
+}