Merge pull request #1629 from BallOfEnergy1/OC_bugfix

OC Flixes
This commit is contained in:
HbmMods 2024-08-19 15:48:05 +02:00 committed by GitHub
commit 2f727690b0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 515 additions and 84 deletions

View File

@ -1,21 +1,30 @@
package com.hbm.handler;
import com.hbm.blocks.ModBlocks;
import com.hbm.inventory.RecipesCommon;
import com.hbm.inventory.fluid.FluidType;
import com.hbm.inventory.fluid.Fluids;
import com.hbm.tileentity.TileEntityProxyCombo;
import com.hbm.lib.RefStrings;
import com.hbm.main.MainRegistry;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.Optional;
import li.cil.oc.api.Items;
import li.cil.oc.api.fs.FileSystem;
import li.cil.oc.api.machine.Arguments;
import li.cil.oc.api.machine.Context;
import li.cil.oc.api.network.*;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ChatComponentTranslation;
import net.minecraft.util.ChatStyle;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.util.ForgeDirection;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.lang.reflect.Array;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.Callable;
import static com.hbm.main.CraftingManager.addShapelessAuto;
import static li.cil.oc.api.FileSystem.asReadOnly;
import static li.cil.oc.api.FileSystem.fromClass;
/**
* General handler for OpenComputers compatibility.
@ -23,13 +32,29 @@ import java.lang.reflect.Array;
*/
public class CompatHandler {
/**
* Used for converting a steam type to an integer (compression levels).
* @param type Steam type.
* @return Object[] array containing an int with the "compression level"
*/
public static Object[] steamTypeToInt(FluidType type) {
if(type == Fluids.STEAM) {return new Object[] {0};}
else if(type == Fluids.HOTSTEAM) {return new Object[] {1};}
else if(type == Fluids.SUPERHOTSTEAM) {return new Object[] {2};}
return new Object[] {3};
switch(type.getID()) {
default:
return new Object[] {0};
case(4): // Fluids.HOTSTEAM
return new Object[] {1};
case(5): // Fluids.SUPERHOTSTEAM
return new Object[] {2};
case(6): // Fluids.ULTRAHOTSTEAM
return new Object[] {3};
}
}
/**
* Used for converting a compression level to a steam type.
* @param arg Steam compression level.
* @return FluidType of the steam type based on the compression level.
*/
public static FluidType intToSteamType(int arg) {
switch(arg) {
default:
@ -43,6 +68,134 @@ public class CompatHandler {
}
}
/**
* Allows for easy creation of read-only filesystems. Primarily for floppy disks.
* (Though maybe reading directly from VOTV drives as filesystems could be implemented. :3)
**/
private static class ReadOnlyFileSystem implements Callable<FileSystem> {
private final String name;
ReadOnlyFileSystem(String name) {
this.name = name;
}
@Override
@Optional.Method(modid = "OpenComputers")
public li.cil.oc.api.fs.FileSystem call() throws Exception {
return asReadOnly(fromClass(MainRegistry.class, RefStrings.MODID, "disks/" + FloppyDisk.sanitizeName(name)));
}
}
// Floppy disk class.
public static class FloppyDisk {
// Specifies the callable ReadOnlyFileSystem to allow OC to access the floppy.
public final ReadOnlyFileSystem fs;
// Specifies the color of the floppy disk (0-16 colors defined by OC).
public final Byte color;
// Set after loading the disk; allows for adding a recipe to the item.
public ItemStack item;
FloppyDisk(String name, int color) {
this.fs = new ReadOnlyFileSystem(FloppyDisk.sanitizeName(name));
this.color = (byte) color;
}
// Disk names will be sanitized before the FileSystem is created.
// This only affects the location/directory, not the display name.
// (Prevents filesystems from breaking/crashing due to having file separators, wildcards, etc.
public static String sanitizeName(String input) {
return input.toLowerCase().replaceAll("\\W", "");
}
}
/**
* Simple enum for mapping OC color ordinals to a nicer format for adding new disks.
*/
public enum OCColors {
BLACK, //0x444444
RED, //0xB3312C
GREEN, //0x339911
BROWN, //0x51301A
BLUE, //0x6666FF
PURPLE, //0x7B2FBE
CYAN, //0x66FFFF
LIGHTGRAY, //0xABABAB
GRAY, //0x666666
PINK, //0xD88198
LIME, //0x66FF66
YELLOW, //0xFFFF66
LIGHTBLUE, //0xAAAAFF
MAGENTA, //0xC354CD
ORANGE, //0xEB8844
WHITE //0xF0F0F0
}
// Where all disks are stored with their name and `FloppyDisk` class.
public static HashMap<String, FloppyDisk> disks = new HashMap<>();
/**
* Called in the FML PostLoad stage, after the OC API loads.
* <br>
* Loads various parts of OC compatibility.
*/
public static void init() {
if(Loader.isModLoaded("OpenComputers")) {
/*
For anyone wanting to add their own floppy disks,
read the README found in assets.hbm.disks.
*/
// Idea/Code by instantnootles
disks.put("PWRangler", new FloppyDisk("PWRangler", OCColors.CYAN.ordinal()));
// begin registering disks
Logger logger = LogManager.getLogger("HBM");
logger.info("Loading OpenComputers disks...");
if(disks.size() == 0) {
logger.info("No disks registered; see com.hbm.handler.CompatHandler.disks");
return;
}
disks.forEach((s, disk) -> {
// Test if the disk path even exists.
FileSystem fs = fromClass(MainRegistry.class, RefStrings.MODID, "disks/" + disk.fs.name);
if (fs == null) { // Disk path does NOT exist, and it should not be loaded.
logger.error("Error loading disk: " + s + " at /assets/" + RefStrings.MODID + "/disks/" + disk.fs.name);
logger.error("This is likely due to the path to the disk being non-existent.");
} else { // Disk path DOES exist, and it should be loaded.
disk.item = Items.registerFloppy(s, disk.color, disk.fs); // The big part, actually registering the floppies!
logger.info("Registered disk: " + s + " at /assets/" + RefStrings.MODID + "/disks/" + disk.fs.name);
}
});
logger.info("OpenComputers disks registered.");
// OC disk recipes!
List<ItemStack> floppyDisks = new RecipesCommon.OreDictStack("oc:floppy").toStacks();
if(floppyDisks.size() > 0) { //check that floppy disks even exist in oredict.
// Recipes must be initialized here, since if they were initialized in `CraftingManager` then the disk item would not be created yet.
addShapelessAuto(disks.get("PWRangler").item, new Object[] {"oc:floppy", new ItemStack(ModBlocks.pwr_casing)});
logger.info("OpenComputers disk recipe added for PWRangler.");
} else {
logger.info("OpenComputers floppy disk oredict not found, recipes cannot be loaded!");
}
// boom, OC disks loaded
logger.info("OpenComputers disks loaded.");
}
}
// Null component name, default to this if broken to avoid NullPointerExceptions.
public static final String nullComponent = "ntm_null";
/**
* This is an interface made specifically for adding OC compatibility to NTM machines. The {@link li.cil.oc.api.network.SimpleComponent} interface must also be implemented in the TE.
* <br>
@ -54,11 +207,10 @@ public class CompatHandler {
@Optional.InterfaceList({
@Optional.Interface(iface = "li.cil.oc.api.network.SimpleComponent", modid = "OpenComputers"),
@Optional.Interface(iface = "li.cil.oc.api.network.SidedComponent", modid = "OpenComputers"),
@Optional.Interface(iface = "li.cil.oc.api.network.Analyzable", modid = "OpenComputers"),
@Optional.Interface(iface = "li.cil.oc.api.network.ManagedPeripheral", modid = "OpenComputers"),
})
@SimpleComponent.SkipInjection // make sure OC doesn't inject this shit into the interface and crash
public interface OCComponent extends SimpleComponent, SidedComponent, Analyzable, ManagedPeripheral {
public interface OCComponent extends SimpleComponent, SidedComponent, ManagedPeripheral {
/**
* Must be overridden in the implemented TE, or it will default to "ntm_null".
@ -69,7 +221,7 @@ public class CompatHandler {
@Override
@Optional.Method(modid = "OpenComputers")
default String getComponentName() {
return "ntm_null";
return nullComponent;
}
/**
@ -83,31 +235,6 @@ public class CompatHandler {
return true;
}
/**
* Function to give more information when analyzing the block. Multiple entries in the array will be sent to the user in the order of the array.
* @return Additional text to add in the form of lang entries (ex: "analyze.basic2").
*/
@Optional.Method(modid = "OpenComputers")
default String[] getExtraInfo() {return new String[] {"analyze.noInfo"};}
@Override
@Optional.Method(modid = "OpenComputers")
default Node[] onAnalyze(EntityPlayer player, int side, float hitX, float hitY, float hitZ) {
player.addChatComponentMessage(new ChatComponentTranslation("analyze.basic1").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GOLD)));
player.addChatComponentMessage(new ChatComponentTranslation("analyze.basic2").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.YELLOW)));
player.addChatComponentMessage(new ChatComponentTranslation("analyze.basic3").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GOLD)));
player.addChatComponentMessage(new ChatComponentTranslation("analyze.name", this.getComponentName()).setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GOLD)));
String[] extraInfo = getExtraInfo();
for (String info : extraInfo) {
if(!info.equals(""))
player.addChatComponentMessage(new ChatComponentTranslation(info).setChatStyle(new ChatStyle().setColor(EnumChatFormatting.YELLOW)));
}
TileEntity te = (TileEntity) this;
if((Array.getLength(this.methods()) == 0 && te instanceof TileEntityProxyCombo) || this.getComponentName().equals("ntm_null"))
player.addChatComponentMessage(new ChatComponentTranslation("analyze.error").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED)));
return null;
}
/**
* Standard methods array from {@link li.cil.oc.api.network.ManagedPeripheral} extending {@link li.cil.oc.api.network.SimpleComponent}.
* @return Array of methods to expose to the computer.

View File

@ -161,7 +161,7 @@ public class RefineryRecipeHandler extends TemplateRecipeHandler implements ICom
transferRectsGui = new LinkedList<RecipeTransferRect>();
guiGui = new LinkedList<Class<? extends GuiContainer>>();
transferRects.add(new RecipeTransferRect(new Rectangle(48, 5, 31, 101), "refinery"));
transferRects.add(new RecipeTransferRect(new Rectangle(138 - 1 - 36 - 27, 23, 36, 18), "refinery"));
transferRectsGui.add(new RecipeTransferRect(new Rectangle(48, 5, 31, 101), "refinery"));
guiGui.add(GUIMachineRefinery.class);
RecipeTransferRectHandler.registerRectsToGuis(getRecipeTransferRectGuis(), transferRects);

View File

@ -28,7 +28,7 @@ public class GUIMachineRefinery extends GuiInfoContainer {
super(new ContainerMachineRefinery(invPlayer, tedf));
refinery = tedf;
this.xSize = 209;
this.xSize = 210;
this.ySize = 231;
}
@ -84,35 +84,39 @@ public class GUIMachineRefinery extends GuiInfoContainer {
// pipes
Tuple.Quintet<FluidStack, FluidStack, FluidStack, FluidStack, ItemStack> recipe = RefineryRecipes.getRefinery(inputOil.getTankType());
if(recipe != null) {
GL11.glEnable(GL11.GL_BLEND);
if(recipe == null) {
func_146110_a(guiLeft + 52, guiTop + 63, 247, 1, 33, 48, 350, 256);
func_146110_a(guiLeft + 52, guiTop + 32, 247, 50, 66, 52, 350, 256);
func_146110_a(guiLeft + 52, guiTop + 24, 247, 145, 86, 35, 350, 256);
func_146110_a(guiLeft + 36, guiTop + 16, 211, 119, 122, 25, 350, 256);
} else {
// Heavy Oil Products
Color color = new Color(recipe.getV().type.getColor());
GL11.glEnable(GL11.GL_BLEND);
GL11.glColor4f(color.getRed() / 255F, color.getGreen() / 255F, color.getBlue() / 255F, 1F);
func_146110_a(guiLeft + 52, guiTop + 63, 247, 1, 33, 48, 350, 256);
// Naphtha Oil Products
color = new Color(recipe.getW().type.getColor());
GL11.glColor4f(color.getRed() / 255F, color.getGreen() / 255F, color.getBlue() / 255F, 1F);
func_146110_a(guiLeft + 52, guiTop + 32, 247, 50, 66, 52, 350, 256);
// Light Oil Products
color = new Color(recipe.getX().type.getColor());
GL11.glColor4f(color.getRed() / 255F, color.getGreen() / 255F, color.getBlue() / 255F, 1F);
func_146110_a(guiLeft + 52, guiTop + 24, 247, 145, 86, 35, 350, 256);
// Gaseous Products
color = new Color(recipe.getY().type.getColor());
GL11.glColor4f(color.getRed() / 255F, color.getGreen() / 255F, color.getBlue() / 255F, 1F);
func_146110_a(guiLeft + 36, guiTop + 16, 211, 119, 122, 25, 350, 256);
GL11.glColor4f(1F, 1F, 1F, 1F);
GL11.glDisable(GL11.GL_BLEND);
GL11.glColor4f(1F, 1F, 1F, 1F);
}
// output tanks
refinery.tanks[1].renderTank(guiLeft + 86, guiTop + 95, this.zLevel, 16, 52);

View File

@ -877,7 +877,10 @@ public class MainRegistry {
proxy.registerMissileItems();
BlockMotherOfAllOres.init();
// Load compatibility for OC.
CompatHandler.init();
//expand for the largest entity we have (currently Quackos who is 17.5m in diameter, that's one fat duck)
World.MAX_ENTITY_RADIUS = Math.max(World.MAX_ENTITY_RADIUS, 8.75);

View File

@ -1,6 +1,7 @@
package com.hbm.tileentity;
import api.hbm.block.ICrucibleAcceptor;
import com.hbm.handler.CompatHandler;
import com.hbm.handler.CompatHandler.OCComponent;
import com.hbm.inventory.fluid.FluidType;
@ -8,6 +9,7 @@ import api.hbm.energymk2.IEnergyReceiverMK2;
import api.hbm.fluid.IFluidConnector;
import api.hbm.tile.IHeatSource;
import com.hbm.inventory.material.Mats;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.Optional;
import li.cil.oc.api.machine.Arguments;
import li.cil.oc.api.machine.Context;
@ -32,7 +34,11 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
boolean fluid;
boolean heat;
public boolean moltenMetal;
// due to some issues with OC deciding that it's gonna call the component name function before the worldObj is loaded
// the component name must be cached to prevent it from shitting itself
String componentName = CompatHandler.nullComponent;
public TileEntityProxyCombo() { }
public TileEntityProxyCombo(boolean inventory, boolean power, boolean fluid) {
@ -344,6 +350,9 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
this.fluid = nbt.getBoolean("fluid");
this.moltenMetal = nbt.getBoolean("metal");
this.heat = nbt.getBoolean("heat");
if(Loader.isModLoaded("OpenComputers"))
this.componentName = nbt.getString("ocname");
}
@Override
@ -355,6 +364,8 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
nbt.setBoolean("fluid", fluid);
nbt.setBoolean("metal", moltenMetal);
nbt.setBoolean("heat", heat);
if(Loader.isModLoaded("OpenComputers"))
nbt.setString("ocname", componentName);
}
@Override
@ -452,27 +463,27 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
@Override // please work
@Optional.Method(modid = "OpenComputers")
public String getComponentName() {
if(this.getTile() instanceof OCComponent)
return ((OCComponent) this.getTile()).getComponentName();
if(this.worldObj == null) // OC is going too fast, grab from NBT!
return componentName;
if(this.getTile() instanceof OCComponent) {
if (componentName == null || componentName.equals(OCComponent.super.getComponentName())) {
componentName = ((OCComponent) this.getTile()).getComponentName();
}
return componentName;
}
return OCComponent.super.getComponentName();
}
@Override
@Optional.Method(modid = "OpenComputers")
public boolean canConnectNode(ForgeDirection side) { //thank you vaer
public boolean canConnectNode(ForgeDirection side) {
if(this.getTile() instanceof OCComponent)
return (this.getTile().getBlockMetadata() & 6) == 6 && ((OCComponent) this.getTile()).canConnectNode(side);
return (this.getBlockMetadata() >= 6 && this.getBlockMetadata() <= 11)
&& (power || fluid) &&
((OCComponent) this.getTile()).canConnectNode(side);
return OCComponent.super.canConnectNode(null);
}
@Override
@Optional.Method(modid = "OpenComputers")
public String[] getExtraInfo() {
if(this.getTile() instanceof OCComponent)
return new String[] {"analyze.dummy"};
return OCComponent.super.getExtraInfo();
}
@Override
@Optional.Method(modid = "OpenComputers")
public String[] methods() {

View File

@ -33,6 +33,9 @@ import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import java.util.ArrayList;
import java.util.List;
@Optional.InterfaceList({@Optional.Interface(iface = "li.cil.oc.api.network.SimpleComponent", modid = "OpenComputers")})
public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBMKFluxReceiver, IRBMKLoadable, SimpleComponent, IInfoProviderEC, CompatHandler.OCComponent {
@ -464,25 +467,21 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM
@Callback(direct = true)
@Optional.Method(modid = "OpenComputers")
public Object[] getInfo(Context context, Arguments args) {
Object OC_enrich_buf;
Object OC_poison_buf;
Object OC_hull_buf;
Object OC_core_buf;
String OC_type;
List<Object> returnValues = new ArrayList<>();
if(slots[0] != null && slots[0].getItem() instanceof ItemRBMKRod) {
OC_enrich_buf = ItemRBMKRod.getEnrichment(slots[0]);
OC_poison_buf = ItemRBMKRod.getPoison(slots[0]);
OC_hull_buf = ItemRBMKRod.getHullHeat(slots[0]);
OC_core_buf = ItemRBMKRod.getCoreHeat(slots[0]);
OC_type = slots[0].getItem().getUnlocalizedName();
} else {
OC_enrich_buf = "N/A";
OC_poison_buf = "N/A";
OC_hull_buf = "N/A";
OC_core_buf = "N/A";
OC_type = "N/A";
}
return new Object[] {heat, OC_hull_buf, OC_core_buf, fluxSlow, fluxFast, OC_enrich_buf, OC_poison_buf, OC_type, ((RBMKRod)this.getBlockType()).moderated, xCoord, yCoord, zCoord};
returnValues.add(ItemRBMKRod.getHullHeat(slots[0]));
returnValues.add(ItemRBMKRod.getCoreHeat(slots[0]));
returnValues.add(ItemRBMKRod.getEnrichment(slots[0]));
returnValues.add(ItemRBMKRod.getPoison(slots[0]));
returnValues.add(slots[0].getItem().getUnlocalizedName());
} else
for (int i = 0; i < 5; i++)
returnValues.add("N/A");
return new Object[] {
heat, returnValues.get(0), returnValues.get(1),
fluxSlow, fluxFast, returnValues.get(2), returnValues.get(3), returnValues.get(4),
((RBMKRod)this.getBlockType()).moderated, xCoord, yCoord, zCoord};
}
@Callback(direct = true)

View File

@ -0,0 +1,13 @@
# OpenComputers Floppy Disks
This directory is where the contents of floppy disks registered by `com.hbm.handler.CompatHandler` reside.
New floppy disks can be added by:
1. Adding a line inside the `init()` function in the `CompatHandler` class to add the floppy disk to the list of disks to register
(actually registering the disks is done automatically by the handler.)
2. Adding the Lua (Preferably 5.3) files to the directory path based on the name you chose for your floppy disk.
<br>Note: the names of drives are "sanitized", meaning the directory path will be the name you selected but all lowercase and stripped of any non-word character.
(A-Z, a-z, 0-9, _)
3. Add a recipe to the disk at the end of the `init()` function in the `CompatHandler` class, though this step is not required.
After those steps are complete, a new floppy disk should be registered into OC with a recipe (if added).

View File

@ -0,0 +1,274 @@
local component = require "component"
local event = require "event"
local gpu = component.gpu
local call = component.invoke
colorGradient = {0x00FF00, 0x6BEE00, 0x95DB00, 0xB0C800, 0xC5B400, 0xD79F00, 0xE68700, 0xF46900, 0xFC4700, 0xFF0000}
coreHeatESTOP = true
coolantLossESTOP = true
runSig = true
coldCoolantLevel = 0
coldCoolantOutflow = 0
prevCoolantFlow = 0
hotCoolantLevel = 0
hotCoolantOutflow = 0
prevHotCoolantFlow = 0
gpu.fill(1,1,160,160," ")
-- Button Bullshit
function newButton(x, y, width, height, colorUp, colorDown, func)
local button = {xpos = 0, ypos = 0, width = 0, height = 0, colorUp = 0, colorDown = 0, func = nil}
button.xpos = x
button.ypos = y
button.width = width
button.height = height
button.colorUp = colorUp
button.colorDown = colorDown
button.func = func
return button
end
function drawButton(button, color)
component.gpu.setBackground(color)
component.gpu.fill(button.xpos, button.ypos, button.width, button.height, " ")
component.gpu.setBackground(0x000000)
end
pressedButton = nil
function buttonPress(_, _, x, y, _, _)
for _, b in pairs(buttons) do
if((x>=b.xpos) and (x<(b.xpos+b.width)) and (y>=b.ypos) and (y<(b.ypos+b.height)) ) then
drawButton(b, b.colorDown)
pressedButton = b
end
end
end
function buttonRelease(_, _, x, y, _, _)
drawButton(pressedButton, pressedButton.colorUp)
pressedButton.func()
pressedButton = nil
end
--Button bullshit ends
buttons = {}
buttons[1] = newButton(61, 6, 6, 2, 0xFFFFFF, 0xAAAAAA, function() component.proxy(pwrController).setLevel(call(pwrController, "getLevel")+1) end)
buttons[2] = newButton(68, 6, 6, 2, 0xFFFFFF, 0xAAAAAA, function() component.proxy(pwrController).setLevel(call(pwrController, "getLevel")+5) end)
buttons[3] = newButton(75, 6, 6, 2, 0xFFFFFF, 0xAAAAAA, function() component.proxy(pwrController).setLevel(call(pwrController, "getLevel")+10) end)
buttons[4] = newButton(61, 9, 6, 2, 0xFFFFFF, 0xAAAAAA, function() component.proxy(pwrController).setLevel(call(pwrController, "getLevel")-1) end)
buttons[5] = newButton(68, 9, 6, 2, 0xFFFFFF, 0xAAAAAA, function() component.proxy(pwrController).setLevel(call(pwrController, "getLevel")-5) end)
buttons[6] = newButton(75, 9, 6, 2, 0xFFFFFF, 0xAAAAAA, function() component.proxy(pwrController).setLevel(call(pwrController, "getLevel")-10) end)
buttons[7] = newButton(82, 6, 11, 5, 0xFF0000, 0xAA0000, function() component.proxy(pwrController).setLevel(100) end)
buttons[8] = newButton(94, 6, 12, 2, 0x00FF00, 0x00AA00, function() coreHeatESTOP = not coreHeatESTOP if coreHeatESTOP == true then buttons[8].colorUp = 0x00FF00 buttons[8].colorDown = 0x00AA00 else buttons[8].colorUp = 0xFF0000 buttons[8].colorDown = 0xAA0000 end end)
buttons[9] = newButton(94, 9, 12, 2, 0x00FF00, 0x00AA00, function() coolantLossESTOP = not coolantLossESTOP if coolantLossESTOP == true then buttons[9].colorUp = 0x00FF00 buttons[9].colorDown = 0x00AA00 else buttons[9].colorUp = 0xFF0000 buttons[9].colorDown = 0xAA0000 end end)
buttons[10] = newButton(107, 8, 5, 3, 0xFF0000, 0xAA0000, function() runSig = false end)
for address, _ in component.list("ntm_pwr_control") do
pwrController = address
end
gpu.setForeground(0xAAAAAA)
--Control rods
gpu.fill(60,4,54,8,"")
--Outlet
gpu.fill(91,13,16,8,"")
--Inlet
gpu.fill(91,30,16,8,"")
gpu.set(61,13," █████████████████████")
gpu.set(61,14," █ █ █ █ █ █ █ █ █ █")
gpu.set(61,15," █ █ █▄█▄█▄█▄█▄█ █ █")
gpu.set(61,16," ▄█████▀█▀█▀█▀█▀█████▄")
gpu.set(61,17," ▄███▀█ █ █ █ █ █ █ █▀███▄")
gpu.set(61,18," ▄██ █ █ █ █ █ █ █ █ █ █ ██▄")
gpu.set(61,19," ██ ██")
gpu.set(61,20,"██▀ █████████████████████ ▀██")
gpu.set(61,21,"██ █████████████████████ ██▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄")
gpu.set(61,22,"██ █ █ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀")
gpu.set(61,23,"██ █████████████████████ → → → → → → → → → →")
gpu.set(61,24,"██ █ █ ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄")
gpu.set(61,25,"██ █████████████████████ ██▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀")
gpu.set(61,26,"██ █ █ ██")
gpu.set(61,27,"██ █████████████████████ ██")
gpu.set(61,28,"██ █ █ ██")
gpu.set(61,29,"██ █████████████████████ ██")
gpu.set(61,30,"██ █ █ ██")
gpu.set(61,31,"██ █████████████████████ ██")
gpu.set(61,32,"██ ██")
gpu.set(61,33,"██ ██")
gpu.set(61,34,"██ ██")
gpu.set(61,35,"██ ██")
gpu.set(61,36,"██ ██")
gpu.set(61,37,"██ ██")
gpu.set(61,38,"██ ██▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄")
gpu.set(61,39,"██ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀")
gpu.set(61,40,"██ ← ← ← ← ← ← ← ← ← ←")
gpu.set(61,41,"██ ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄")
gpu.set(61,42,"██ ██▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀")
gpu.set(61,43,"██▄ ▄██")
gpu.set(61,44," ██ ██")
gpu.set(61,45," ▀██ ██▀")
gpu.set(61,46," ▀██▄▄ ▄▄██▀")
gpu.set(61,47," ▀▀███▄▄▄▄▄▄▄▄▄▄▄███▀▀")
gpu.set(61,48," ▀▀▀▀▀▀▀▀▀▀▀▀")
gpu.setBackground(0xAAAAAA)
gpu.setForeground(0x000000)
gpu.set(70,4,"CONTROL RODS")
gpu.set(61,5,"INS+1 INS+5 INS+10")
gpu.set(61,8,"RET+1 RET+5 RET+10")
gpu.set(85,5,"ESTOP")
gpu.set(107,5,"LEVEL")
gpu.set(107,7,"QUIT")
gpu.set(94,5,"OVHEAT ESTOP")
gpu.set(94,8,"NOCOOL ESTOP")
gpu.set(95,13,"OUTFLOW")
gpu.set(92,14,"BUFFER")
gpu.set(99,14,"HOTΔ")
gpu.set(95,30,"INFLOW")
gpu.set(92,31,"BUFFER")
gpu.set(99,31,"COOLΔ")
gpu.set(69,20,"REACTOR CORE")
gpu.set(71,21,"CORE HEAT:")
gpu.set(71,23,"HULL HEAT:")
gpu.set(71,25,"CORE FLUX:")
gpu.set(68,27,"COLD HEATEX LVL:")
gpu.set(69,29,"HOT HEATEX LVL:")
gpu.setBackground(0x000000)
gpu.setForeground(0xFFFFFF)
gpu.fill(107,6,5,1,"")
--Outflow Buffer
gpu.fill(92,15,6,5,"")
--CoolDelta
gpu.fill(99,15,7,1,"")
--HotDelta
gpu.set(66,19,"┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃")
gpu.fill(66,22,19,1,"")
gpu.fill(66,24,19,1,"")
gpu.fill(66,26,19,1,"")
gpu.fill(66,28,19,1,"")
gpu.fill(66,30,19,1,"")
gpu.set(66,32,"┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃")
gpu.setForeground(0xAAAAAA)
gpu.setForeground(0x000000)
gpu.setBackground(0xFFFFFF)
gpu.set(83,22,"TU")
gpu.set(83,24,"TU")
gpu.setForeground(0xFFFFFF)
gpu.setBackground(0x000000)
event.listen("touch", buttonPress)
event.listen("drop", buttonRelease)
while (runSig == true) do
rodLevel = call(pwrController, "getLevel")
coreHeat, _ = call(pwrController, "getHeat")
coreHeat = coreHeat//1000000
for _, b in pairs(buttons) do
drawButton(b, b.colorUp)
end
for j=rodLevel//10,10 do
gpu.fill(64+(j*2), 33, 1, 10, " ")
end
for j=1,rodLevel//10 do
gpu.fill(64+(j*2), 33, 1, 10, "")
end
gpu.fill(64+(math.ceil(rodLevel/10)*2), 33, 1, math.fmod(rodLevel,10), "")
for j=0,20,2 do
gpu.setForeground(colorGradient[coreHeat+1])
gpu.fill(65+j, 33, 1, 9, "")
gpu.setForeground(0xAAAAAA)
end
gpu.setBackground(0xFFFFFF)
gpu.setForeground(0xFFFFFF)
gpu.fill(66,22,19,1,"")
gpu.fill(66,24,19,1,"")
gpu.fill(66,26,19,1,"")
gpu.fill(66,28,19,1,"")
gpu.fill(66,30,19,1,"")
gpu.fill(92,15,6,5,"")
gpu.fill(92,32,6,5,"")
gpu.fill(99,15,7,1,"")
gpu.fill(99,32,7,1,"")
prevCoolantFlow = coldCoolantLevel
prevHotCoolantFlow = hotCoolantLevel
fullCoreHeat, fullHullHeat = call(pwrController, "getHeat")
coldCoolantLevel, _, hotCoolantLevel, _ = call(pwrController, "getCoolantInfo")
coldCoolantOutflow = coldCoolantLevel - prevCoolantFlow
hotCoolantOutflow = hotCoolantLevel - prevHotCoolantFlow
gpu.setForeground(0xFF0099)
gpu.fill(92,15+(5-hotCoolantLevel//25600),6,hotCoolantLevel//25600, "")
gpu.setForeground(0x000000)
gpu.setForeground(0x00FFFF)
gpu.fill(92,32+(5-coldCoolantLevel//25600),6,coldCoolantLevel//25600, "")
gpu.setForeground(0x000000)
gpu.set(66,22,tostring(fullCoreHeat))
gpu.set(66,24,tostring(fullHullHeat))
gpu.set(66,26,tostring(call(pwrController, "getFlux")))
gpu.set(66,28,tostring(coldCoolantLevel))
gpu.set(66,30,tostring(hotCoolantLevel))
gpu.set(99,15,tostring(hotCoolantOutflow))
gpu.set(99,32,tostring(coldCoolantOutflow))
gpu.set(107,6," ")
gpu.set(107,6,tostring(call(pwrController, "getLevel")))
gpu.setBackground(0x000000)
gpu.setForeground(0xFFFFFF)
if (coreHeatESTOP == true) and (fullCoreHeat) > 9000000 then
component.proxy(pwrController).setLevel(100)
end
if (coolantLossESTOP == true) and (coldCoolantLevel) < 10000 then
component.proxy(pwrController).setLevel(100)
end
os.sleep(0.25)
end
event.ignore("touch", buttonPress)
event.ignore("drop", buttonRelease)
gpu.fill(1,1,160,160," ")