From 6dc33084007f0f867d0e461fe4f40a1232682e67 Mon Sep 17 00:00:00 2001 From: RecursivePineapple Date: Mon, 22 Jul 2024 22:40:19 -0400 Subject: [PATCH] added ability for coolants to store more than 1 HU --- .../nuclear_horizons/CommonProxy.java | 2 + .../reactors/fluids/CoolantRegistry.java | 59 +++++ .../reactors/fluids/FluidList.java | 25 ++- .../reactors/tile/TileFluidPort.java | 48 ++--- .../reactors/tile/TileReactorCore.java | 204 ++++++------------ 5 files changed, 167 insertions(+), 171 deletions(-) create mode 100644 src/main/java/com/recursive_pineapple/nuclear_horizons/reactors/fluids/CoolantRegistry.java diff --git a/src/main/java/com/recursive_pineapple/nuclear_horizons/CommonProxy.java b/src/main/java/com/recursive_pineapple/nuclear_horizons/CommonProxy.java index e43b0a8..e14bad3 100644 --- a/src/main/java/com/recursive_pineapple/nuclear_horizons/CommonProxy.java +++ b/src/main/java/com/recursive_pineapple/nuclear_horizons/CommonProxy.java @@ -29,6 +29,8 @@ public void init(FMLInitializationEvent event) { // PacketDispatcher.TileEntityUpdatedMessage.init(); SimulationItems.init(); + + FluidList.registerCoolants(); } // postInit "Handle interaction with other mods, complete your setup based on this." (Remove if not needed) diff --git a/src/main/java/com/recursive_pineapple/nuclear_horizons/reactors/fluids/CoolantRegistry.java b/src/main/java/com/recursive_pineapple/nuclear_horizons/reactors/fluids/CoolantRegistry.java new file mode 100644 index 0000000..e5a05db --- /dev/null +++ b/src/main/java/com/recursive_pineapple/nuclear_horizons/reactors/fluids/CoolantRegistry.java @@ -0,0 +1,59 @@ +package com.recursive_pineapple.nuclear_horizons.reactors.fluids; + +import java.util.HashMap; +import java.util.Objects; + +import net.minecraftforge.fluids.Fluid; + +public class CoolantRegistry { + + private static final HashMap coolantsByColdFluid = new HashMap<>(); + private static final HashMap coolantsByHotFluid = new HashMap<>(); + private static final HashMap coolantsByFluid = new HashMap<>(); + + private CoolantRegistry() { + + } + + /** + * Registers a coolant that can be used to cool a nuclear reactor + * @param cold The cold input coolant + * @param hot The heated output coolant + * @param specificHeatCapacity The amount of HU that can be stored in one mB of coolant + */ + public static void registerCoolant(Fluid cold, Fluid hot, int specificHeatCapacity) { + Objects.requireNonNull(cold); + Objects.requireNonNull(hot); + if(specificHeatCapacity <= 0) throw new IllegalArgumentException("specificHeatCapacity"); + + Coolant coolant = new Coolant(cold, hot, specificHeatCapacity); + + coolantsByColdFluid.put(cold, coolant); + coolantsByHotFluid.put(hot, coolant); + coolantsByFluid.put(cold, coolant); + coolantsByFluid.put(hot, coolant); + } + + public static boolean isColdCoolant(Fluid fluid) { + return coolantsByColdFluid.containsKey(fluid); + } + + public static boolean isHotCoolant(Fluid fluid) { + return coolantsByHotFluid.containsKey(fluid); + } + + public static Coolant getCoolantInfo(Fluid fluid) { + return coolantsByFluid.get(fluid); + } + + public static class Coolant { + public final Fluid cold, hot; + public final int specificHeatCapacity; + + public Coolant(Fluid cold, Fluid hot, int specificHeatCapacity) { + this.cold = cold; + this.hot = hot; + this.specificHeatCapacity = specificHeatCapacity; + } + } +} diff --git a/src/main/java/com/recursive_pineapple/nuclear_horizons/reactors/fluids/FluidList.java b/src/main/java/com/recursive_pineapple/nuclear_horizons/reactors/fluids/FluidList.java index 71c80e4..273405c 100644 --- a/src/main/java/com/recursive_pineapple/nuclear_horizons/reactors/fluids/FluidList.java +++ b/src/main/java/com/recursive_pineapple/nuclear_horizons/reactors/fluids/FluidList.java @@ -9,9 +9,11 @@ public class FluidList { public static final String COOLANT_NAME = "nh_coolant"; public static final String HOT_COOLANT_NAME = "nh_hot_coolant"; + public static final String HOT_SUPER_COOLANT_NAME = "nh_hot_super_coolant"; public static Fluid COOLANT; public static Fluid HOT_COOLANT; + public static Fluid HOT_SUPER_COOLANT; public static void registerFluids() { COOLANT = new Fluid(COOLANT_NAME) { @@ -36,9 +38,30 @@ public net.minecraft.util.IIcon getFlowingIcon() { }; }; + // Temporary, will probably be removed + HOT_SUPER_COOLANT = new Fluid(HOT_SUPER_COOLANT_NAME) { + + public net.minecraft.util.IIcon getStillIcon() { + return BlockList.COOLANT_BLOCK.stillIcon; + }; + + public net.minecraft.util.IIcon getFlowingIcon() { + return BlockList.COOLANT_BLOCK.flowingIcon; + }; + }; + FluidRegistry.registerFluid(COOLANT); - HOT_COOLANT.setTemperature(500); + HOT_COOLANT.setTemperature(273 + 500); FluidRegistry.registerFluid(HOT_COOLANT); + + HOT_SUPER_COOLANT.setTemperature(273 + 1000); + FluidRegistry.registerFluid(HOT_SUPER_COOLANT); + } + + public static void registerCoolants() { + CoolantRegistry.registerCoolant(COOLANT, HOT_COOLANT, 1); + + CoolantRegistry.registerCoolant(FluidRegistry.getFluid("supercoolant"), HOT_SUPER_COOLANT, 5); } } diff --git a/src/main/java/com/recursive_pineapple/nuclear_horizons/reactors/tile/TileFluidPort.java b/src/main/java/com/recursive_pineapple/nuclear_horizons/reactors/tile/TileFluidPort.java index ff2ca07..e70acd2 100644 --- a/src/main/java/com/recursive_pineapple/nuclear_horizons/reactors/tile/TileFluidPort.java +++ b/src/main/java/com/recursive_pineapple/nuclear_horizons/reactors/tile/TileFluidPort.java @@ -13,7 +13,7 @@ import net.minecraftforge.fluids.FluidTankInfo; import net.minecraftforge.fluids.IFluidHandler; -import com.recursive_pineapple.nuclear_horizons.reactors.fluids.FluidList; +import com.recursive_pineapple.nuclear_horizons.reactors.fluids.CoolantRegistry; public class TileFluidPort extends TileEntity implements IFluidHandler, IReactorBlock { @@ -94,16 +94,15 @@ public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { return 0; } - if (resource.getFluid() == FluidList.COOLANT) { - int remaining = reactor.maxCoolant - reactor.storedCoolant; + // this should only be called a few times a second, so we don't need to cache it + if(!CoolantRegistry.isColdCoolant(resource.getFluid())) { + return 0; + } - int consumed = Math.min(remaining, resource.amount); + var tank = reactor.coolantTank; - if (doFill) { - reactor.storedCoolant += consumed; - } - - return consumed; + if(tank.getFluid() == null || resource.getFluid() == tank.getFluid().getFluid()) { + return tank.fill(resource, doFill); } else { return 0; } @@ -117,14 +116,10 @@ public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrai return null; } - if (resource.getFluid() == FluidList.HOT_COOLANT) { - int consumed = Math.min(reactor.storedHotCoolant, resource.amount); + var tank = reactor.hotCoolantTank; - if (doDrain) { - reactor.storedHotCoolant -= consumed; - } - - return new FluidStack(FluidList.HOT_COOLANT, consumed); + if(tank.getFluid() != null && resource.getFluid() == tank.getFluid().getFluid()) { + return tank.drain(resource.amount, doDrain); } else { return null; } @@ -138,23 +133,23 @@ public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) { return null; } - int consumed = Math.min(reactor.storedHotCoolant, maxDrain); + var tank = reactor.hotCoolantTank; - if (doDrain) { - reactor.storedHotCoolant -= consumed; + if(tank.getFluid() != null) { + return tank.drain(maxDrain, doDrain); + } else { + return null; } - - return new FluidStack(FluidList.HOT_COOLANT, consumed); } @Override public boolean canFill(ForgeDirection from, Fluid fluid) { - return fluid == FluidList.COOLANT; + return CoolantRegistry.isColdCoolant(fluid); } @Override public boolean canDrain(ForgeDirection from, Fluid fluid) { - return fluid == FluidList.HOT_COOLANT; + return CoolantRegistry.isHotCoolant(fluid); } @Override @@ -166,9 +161,8 @@ public FluidTankInfo[] getTankInfo(ForgeDirection from) { } return new FluidTankInfo[] { - new FluidTankInfo(new FluidStack(FluidList.COOLANT, reactor.storedCoolant), reactor.maxCoolant), - new FluidTankInfo( - new FluidStack(FluidList.HOT_COOLANT, reactor.storedHotCoolant), - reactor.maxHotCoolant), }; + reactor.coolantTank.getInfo(), + reactor.hotCoolantTank.getInfo() + }; } } diff --git a/src/main/java/com/recursive_pineapple/nuclear_horizons/reactors/tile/TileReactorCore.java b/src/main/java/com/recursive_pineapple/nuclear_horizons/reactors/tile/TileReactorCore.java index f6cddbc..39335f6 100644 --- a/src/main/java/com/recursive_pineapple/nuclear_horizons/reactors/tile/TileReactorCore.java +++ b/src/main/java/com/recursive_pineapple/nuclear_horizons/reactors/tile/TileReactorCore.java @@ -21,8 +21,7 @@ import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.FluidTankInfo; -import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.FluidTank; import com.gtnewhorizons.modularui.api.ModularUITextures; import com.gtnewhorizons.modularui.api.drawable.AdaptableUITexture; @@ -45,7 +44,8 @@ import com.recursive_pineapple.nuclear_horizons.reactors.components.ComponentRegistry; import com.recursive_pineapple.nuclear_horizons.reactors.components.IComponentAdapter; import com.recursive_pineapple.nuclear_horizons.reactors.components.IReactorGrid; -import com.recursive_pineapple.nuclear_horizons.reactors.fluids.FluidList; +import com.recursive_pineapple.nuclear_horizons.reactors.fluids.CoolantRegistry; +import com.recursive_pineapple.nuclear_horizons.reactors.fluids.CoolantRegistry.Coolant; import com.recursive_pineapple.nuclear_horizons.reactors.tile.IReactorBlock.ReactorEnableState; import com.recursive_pineapple.nuclear_horizons.utils.DirectionUtil; @@ -78,17 +78,16 @@ public class TileReactorCore extends TileEntity int storedHeat = 0; int addedHeat = 0; + int roundedHeat = 0; int voltage = 0; int maxStoredEU = 4_194_304; // 2 ^ 22 int storedEU = 0; int addedEU = 0; - int storedCoolant = 0; - int maxCoolant = 10_000; - - int storedHotCoolant = 0; - int maxHotCoolant = 10_000; + Coolant coolantCache; + FluidTank coolantTank = new FluidTank(10_000); + FluidTank hotCoolantTank = new FluidTank(10_000); private ArrayList reactorBlocks = new ArrayList<>(); @@ -96,112 +95,6 @@ public TileReactorCore() { } - // #region Fluid Tanks - - IFluidTank coolantTank = new IFluidTank() { - - @Override - public FluidStack getFluid() { - return new FluidStack(FluidList.COOLANT, storedCoolant); - } - - @Override - public int getFluidAmount() { - return storedCoolant; - } - - @Override - public int getCapacity() { - return maxCoolant; - } - - @Override - public FluidTankInfo getInfo() { - return new FluidTankInfo(getFluid(), getCapacity()); - } - - @Override - public int fill(FluidStack resource, boolean doFill) { - if (resource.getFluid() == FluidList.COOLANT) { - int remaining = maxCoolant - storedCoolant; - - int consumed = Math.min(remaining, resource.amount); - - if (doFill) { - storedCoolant += consumed; - } - - return consumed; - } else { - return 0; - } - } - - @Override - public FluidStack drain(int maxDrain, boolean doDrain) { - int consumed = Math.min(storedCoolant, maxDrain); - - if (doDrain) { - storedCoolant -= consumed; - } - - return new FluidStack(FluidList.COOLANT, consumed); - } - }; - - IFluidTank hotCoolantTank = new IFluidTank() { - - @Override - public FluidStack getFluid() { - return new FluidStack(FluidList.HOT_COOLANT, storedHotCoolant); - } - - @Override - public int getFluidAmount() { - return storedHotCoolant; - } - - @Override - public int getCapacity() { - return maxHotCoolant; - } - - @Override - public FluidTankInfo getInfo() { - return new FluidTankInfo(getFluid(), getCapacity()); - } - - @Override - public int fill(FluidStack resource, boolean doFill) { - if (resource.getFluid() == FluidList.HOT_COOLANT) { - int remaining = getCapacity() - getFluidAmount(); - - int consumed = Math.min(remaining, resource.amount); - - if (doFill) { - storedHotCoolant += consumed; - } - - return consumed; - } else { - return 0; - } - } - - @Override - public FluidStack drain(int maxDrain, boolean doDrain) { - int consumed = Math.min(getFluidAmount(), maxDrain); - - if (doDrain) { - storedHotCoolant -= consumed; - } - - return new FluidStack(FluidList.HOT_COOLANT, consumed); - } - }; - - // #endregion - // #region UI private static Widget padding(int width, int height) { @@ -263,10 +156,8 @@ public ModularWindow createWindow(UIBuildContext buildContext) { new FakeSyncWidget.IntegerSyncer(() -> this.storedHeat, v -> this.storedHeat = v), new FakeSyncWidget.IntegerSyncer(() -> this.addedEU, v -> this.addedEU = v), new FakeSyncWidget.BooleanSyncer(() -> this.isFluid, v -> this.isFluid = v), - new FakeSyncWidget.IntegerSyncer(() -> this.storedCoolant, v -> this.storedCoolant = v), - new FakeSyncWidget.IntegerSyncer(() -> this.storedHotCoolant, v -> this.storedHotCoolant = v), - new FakeSyncWidget.IntegerSyncer(() -> this.maxCoolant, v -> this.maxCoolant = v), - new FakeSyncWidget.IntegerSyncer(() -> this.maxHotCoolant, v -> this.maxHotCoolant = v)); + new FakeSyncWidget.FluidStackSyncer(this.coolantTank::getFluid, this.coolantTank::setFluid), + new FakeSyncWidget.FluidStackSyncer(this.hotCoolantTank::getFluid, this.hotCoolantTank::setFluid)); return builder.build(); } @@ -325,15 +216,14 @@ public void writeToNBT(NBTTagCompound compound) { compound.setInteger("version", 1); compound.setInteger("heat", this.storedHeat); + compound.setInteger("roundedHeat", this.roundedHeat); compound.setInteger("storedEU", this.storedEU); compound.setInteger("tickCooldown", this.tickCounter); compound.setBoolean("isActive", this.isActive); compound.setBoolean("isFluid", this.isFluid); - compound.setInteger("storedCoolant", this.storedCoolant); - compound.setInteger("storedHotCoolant", this.storedHotCoolant); - compound.setInteger("maxCoolant", this.maxCoolant); - compound.setInteger("maxHotCoolant", this.maxHotCoolant); + compound.setTag("coolantTank", coolantTank.writeToNBT(new NBTTagCompound())); + compound.setTag("hotCoolantTank", hotCoolantTank.writeToNBT(new NBTTagCompound())); var grid = new NBTTagCompound(); @@ -356,15 +246,23 @@ public void readFromNBT(NBTTagCompound compound) { switch (version) { case 1: { this.storedHeat = compound.getInteger("heat"); + this.roundedHeat = compound.getInteger("roundedHeat"); this.storedEU = compound.getInteger("storedEU"); this.tickCounter = compound.getInteger("tickCooldown"); this.isActive = compound.getBoolean("isActive"); this.isFluid = compound.getBoolean("isFluid"); - this.storedCoolant = compound.getInteger("storedCoolant"); - this.storedHotCoolant = compound.getInteger("storedHotCoolant"); - this.maxCoolant = compound.getInteger("maxCoolant"); - this.maxHotCoolant = compound.getInteger("maxHotCoolant"); + this.coolantTank.readFromNBT(compound.getCompoundTag("coolantTank")); + this.hotCoolantTank.readFromNBT(compound.getCompoundTag("hotCoolantTank")); + + if(this.coolantTank.getFluid() != null && !CoolantRegistry.isColdCoolant(this.coolantTank.getFluid().getFluid())) { + // TODO: figure out if there's a mechanism to migrate fluids + this.coolantTank.setFluid(null); + } + + if(this.hotCoolantTank.getFluid() != null && !CoolantRegistry.isHotCoolant(this.hotCoolantTank.getFluid().getFluid())) { + this.hotCoolantTank.setFluid(null); + } var grid = compound.getCompoundTag("grid"); @@ -456,13 +354,12 @@ public Packet getDescriptionPacket() { data.setBoolean("isActive", isActive); data.setInteger("storedEU", storedEU); data.setInteger("storedHeat", storedHeat); + data.setInteger("roundedHeat", this.roundedHeat); data.setInteger("addedHeat", addedHeat); data.setInteger("addedEU", addedEU); data.setBoolean("isFluid", isFluid); - data.setInteger("storedCoolant", storedCoolant); - data.setInteger("storedHotCoolant", storedHotCoolant); - data.setInteger("maxCoolant", maxCoolant); - data.setInteger("maxHotCoolant", maxHotCoolant); + data.setTag("coolantTank", coolantTank.writeToNBT(new NBTTagCompound())); + data.setTag("hotCoolantTank", hotCoolantTank.writeToNBT(new NBTTagCompound())); return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, blockMetadata, data); } @@ -475,13 +372,12 @@ public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { this.isActive = data.getBoolean("isActive"); this.storedEU = data.getInteger("storedEU"); this.storedHeat = data.getInteger("storedHeat"); + this.roundedHeat = data.getInteger("roundedHeat"); this.addedHeat = data.getInteger("addedHeat"); this.addedEU = data.getInteger("addedEU"); this.isFluid = data.getBoolean("isFluid"); - this.storedCoolant = data.getInteger("storedCoolant"); - this.storedHotCoolant = data.getInteger("storedHotCoolant"); - this.maxCoolant = data.getInteger("maxCoolant"); - this.maxHotCoolant = data.getInteger("maxHotCoolant"); + this.coolantTank.readFromNBT(data.getCompoundTag("coolantTank")); + this.hotCoolantTank.readFromNBT(data.getCompoundTag("hotCoolantTank")); } public static int getAttachedChambers(World worldIn, int x, int y, int z) { @@ -720,8 +616,6 @@ public boolean isItemValidForSlot(int index, ItemStack stack) { // #region Reactor Grid Logic private void doHeatTick() { - this.storedCoolant = 10000; - this.storedHotCoolant = 0; this.addedHeat = 0; for (int row = 0; row < ROW_COUNT; row++) { @@ -877,16 +771,40 @@ public void addHullHeat(int delta) { } @Override - public int addAirHeat(int delta) { + public int addAirHeat(int airHeat) { if (this.isFluid) { - int emptyHotCoolant = this.maxHotCoolant - this.storedHotCoolant; - int consumed = Math.min(Math.min(delta, this.storedCoolant / 2), emptyHotCoolant / 2); + if(this.coolantTank.getFluidAmount() == 0) { + return airHeat; + } - this.storedCoolant -= consumed * 2; - this.storedHotCoolant += consumed * 2; - this.addedHeat += consumed * 2; + // cache this because it will be called several times a second - may not be completely necessary though + if((coolantCache == null || coolantCache.cold != this.coolantTank.getFluid().getFluid())) { + if(this.coolantTank.getFluidAmount() == 0) { + coolantCache = null; + } else { + coolantCache = CoolantRegistry.getCoolantInfo(this.coolantTank.getFluid().getFluid()); + } + } + + if(coolantCache == null) { + return airHeat; + } + + this.roundedHeat += airHeat * 2; - return delta - consumed; + int heatableCoolant = Math.min( + this.coolantTank.getFluidAmount(), + this.hotCoolantTank.getCapacity() - this.hotCoolantTank.getFluidAmount() + ); + + int consumedCoolant = Math.min(roundedHeat / coolantCache.specificHeatCapacity, heatableCoolant); + this.roundedHeat -= consumedCoolant * coolantCache.specificHeatCapacity; + this.addedHeat += consumedCoolant * coolantCache.specificHeatCapacity; + + this.coolantTank.drain(consumedCoolant, true); + this.hotCoolantTank.fill(new FluidStack(coolantCache.hot, consumedCoolant), true); + + return 0; } else { return 0; }