From 48aa499cfb5a1730d5cebbbc63bf26899d7f42db Mon Sep 17 00:00:00 2001 From: Boblet Date: Wed, 11 Aug 2021 10:26:07 +0200 Subject: [PATCH] RBMK reasim boiler functionality --- .../crafting/handlers/MKUCraftingHandler.java | 80 ++++++++++++++++ .../java/com/hbm/main/CraftingManager.java | 1 + .../tileentity/machine/rbmk/RBMKDials.java | 11 +++ .../machine/rbmk/TileEntityRBMKBase.java | 51 ++++++++++- .../machine/rbmk/TileEntityRBMKInlet.java | 67 ++++++++++++-- .../machine/rbmk/TileEntityRBMKOutlet.java | 91 ++++++++++++++----- 6 files changed, 267 insertions(+), 34 deletions(-) create mode 100644 src/main/java/com/hbm/crafting/handlers/MKUCraftingHandler.java diff --git a/src/main/java/com/hbm/crafting/handlers/MKUCraftingHandler.java b/src/main/java/com/hbm/crafting/handlers/MKUCraftingHandler.java new file mode 100644 index 000000000..6a68f07ec --- /dev/null +++ b/src/main/java/com/hbm/crafting/handlers/MKUCraftingHandler.java @@ -0,0 +1,80 @@ +package com.hbm.crafting.handlers; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Random; + +import com.hbm.items.ModItems; + +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.world.World; + +public class MKUCraftingHandler implements IRecipe { + + public static ItemStack[] MKURecipe; + private static long lastSeed; + + @Override + public boolean matches(InventoryCrafting inventory, World world) { + + if(world == null) + return false; + + if(MKURecipe == null || world.getSeed() != lastSeed) + generateRecipe(world); + + for(int i = 0; i < 9; i++) { + ItemStack stack = inventory.getStackInRowAndColumn(i % 3, i / 3); + ItemStack recipe = MKURecipe[i]; + + if(stack == null && recipe == null) + continue; + + if(stack != null && recipe != null && stack.getItem() == recipe.getItem() && stack.getItemDamage() == recipe.getItemDamage()) + continue; + + return false; + } + + return true; + } + + public static void generateRecipe(World world) { + Random rand = new Random(world.getSeed()); + lastSeed = world.getSeed(); + + List list = Arrays.asList(new ItemStack[] { + new ItemStack(ModItems.powder_iodine), + new ItemStack(ModItems.powder_fire), + new ItemStack(ModItems.dust), + new ItemStack(ModItems.nugget_mercury), + new ItemStack(ModItems.morning_glory), + new ItemStack(ModItems.syringe_metal_empty), + null, + null, + null + }); + + Collections.shuffle(list, rand); + + MKURecipe = list.toArray(new ItemStack[9]); + } + + @Override + public int getRecipeSize() { + return 6; + } + + @Override + public ItemStack getCraftingResult(InventoryCrafting inventory) { + return getRecipeOutput(); + } + + @Override + public ItemStack getRecipeOutput() { + return new ItemStack(ModItems.syringe_mkunicorn); + } +} diff --git a/src/main/java/com/hbm/main/CraftingManager.java b/src/main/java/com/hbm/main/CraftingManager.java index 81f0020ac..1af1e80b7 100644 --- a/src/main/java/com/hbm/main/CraftingManager.java +++ b/src/main/java/com/hbm/main/CraftingManager.java @@ -43,6 +43,7 @@ public class CraftingManager { GameRegistry.addRecipe(new TestCraftingHandler(new ItemStack(ModItems.lignite), new ItemStack(ModItems.powder_coal, 1))); GameRegistry.addRecipe(new RBMKFuelCraftingHandler()); + GameRegistry.addRecipe(new MKUCraftingHandler()); } public static void AddCraftingRec() { diff --git a/src/main/java/com/hbm/tileentity/machine/rbmk/RBMKDials.java b/src/main/java/com/hbm/tileentity/machine/rbmk/RBMKDials.java index ba2df79c9..2004ac09c 100644 --- a/src/main/java/com/hbm/tileentity/machine/rbmk/RBMKDials.java +++ b/src/main/java/com/hbm/tileentity/machine/rbmk/RBMKDials.java @@ -23,6 +23,7 @@ public class RBMKDials { public static final String KEY_REASIM_COUNT = "dialReasimCount"; public static final String KEY_REASIM_MOD = "dialReasimOutputMod"; public static final String KEY_REASIM_BOILERS = "dialReasimBoilers"; + public static final String KEY_REASIM_BOILER_SPEED = "dialReasimBoilerSpeed"; public static void createDials(World world) { GameRules rules = world.getGameRules(); @@ -45,6 +46,7 @@ public class RBMKDials { rules.setOrCreateGameRule(KEY_REASIM_COUNT, "6"); rules.setOrCreateGameRule(KEY_REASIM_MOD, "1.0"); rules.setOrCreateGameRule(KEY_REASIM_BOILERS, "false"); + rules.setOrCreateGameRule(KEY_REASIM_BOILER_SPEED, "0.25"); } } @@ -192,6 +194,15 @@ public class RBMKDials { return world.getGameRules().getGameRuleBooleanValue(KEY_REASIM_BOILERS); } + /** + * How much % of the possible steam ends up being produced per tick + * @param world + * @return [0;1] + */ + public static double getReaSimBoilerSpeed(World world) { + return MathHelper.clamp_double(shittyWorkaroundParseDouble(world.getGameRules().getGameRuleStringValue(KEY_REASIM_BOILER_SPEED), 1.0D), 0.0D, 1.0D); + } + //why make the double representation accessible in a game rule when you can just force me to add a second pointless parsing operation? public static double shittyWorkaroundParseDouble(String s, double def) { diff --git a/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKBase.java b/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKBase.java index ba601de34..da4d7415b 100644 --- a/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKBase.java +++ b/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKBase.java @@ -13,6 +13,7 @@ import com.hbm.blocks.machine.rbmk.RBMKBase; import com.hbm.entity.effect.EntitySpear; import com.hbm.entity.projectile.EntityRBMKDebris; import com.hbm.entity.projectile.EntityRBMKDebris.DebrisType; +import com.hbm.interfaces.Untested; import com.hbm.main.MainRegistry; import com.hbm.packet.AuxParticlePacketNT; import com.hbm.packet.NBTPacket; @@ -46,6 +47,11 @@ import net.minecraftforge.common.util.ForgeDirection; public abstract class TileEntityRBMKBase extends TileEntity implements INBTPacketReceiver { public double heat; + + public int water; + public static final int maxWater = 16000; + public int steam; + public static final int maxSteam = 16000; public boolean hasLid() { @@ -90,6 +96,7 @@ public abstract class TileEntityRBMKBase extends TileEntity implements INBTPacke if(!worldObj.isRemote) { moveHeat(); + if(RBMKDials.getReasimBoilers(worldObj)) boilWater(); coolPassively(); NBTTagCompound data = new NBTTagCompound(); @@ -98,6 +105,27 @@ public abstract class TileEntityRBMKBase extends TileEntity implements INBTPacke } } + /** + * The ReaSim boiler dial causes all RBMK parts to behave like boilers + */ + @Untested //none of the new reasim boiler stuff has been tested yet + private void boilWater() { + + if(heat < 100D) + return; + + double heatConsumption = RBMKDials.getBoilerHeatConsumption(worldObj); + double availableHeat = (this.heat - 100) / heatConsumption; + double availableWater = this.water; + double availableSpace = this.maxSteam - this.steam; + + int processedWater = (int)Math.floor(Math.min(availableHeat, Math.min(availableWater, availableSpace)) * RBMKDials.getReaSimBoilerSpeed(worldObj)); + + this.water -= processedWater; + this.steam += processedWater; + this.heat -= processedWater * heatConsumption; + } + public static final ForgeDirection[] heatDirs = new ForgeDirection[] { ForgeDirection.NORTH, ForgeDirection.EAST, @@ -115,6 +143,8 @@ public abstract class TileEntityRBMKBase extends TileEntity implements INBTPacke List rec = new ArrayList(); rec.add(this); double heatTot = this.heat; + int waterTot = this.water; + int steamTot = this.steam; int index = 0; for(ForgeDirection dir : heatDirs) { @@ -139,6 +169,8 @@ public abstract class TileEntityRBMKBase extends TileEntity implements INBTPacke if(base != null) { rec.add(base); heatTot += base.heat; + waterTot += base.water; + steamTot += base.steam; } } @@ -149,11 +181,24 @@ public abstract class TileEntityRBMKBase extends TileEntity implements INBTPacke double targetHeat = heatTot / (double)members; + int tWater = waterTot / 5; + int rWater = waterTot % 5; + int tSteam = steamTot / 5; + int rSteam = steamTot % 5; + for(TileEntityRBMKBase rbmk : rec) { double delta = targetHeat - rbmk.heat; rbmk.heat += delta * stepSize; + + //set to the averages, rounded down + rbmk.water = tWater; + rbmk.steam = tSteam; } + //add the modulo to make up for the losses coming from rounding + this.water += rWater; + this.steam += rSteam; + this.markDirty(); } } @@ -174,8 +219,10 @@ public abstract class TileEntityRBMKBase extends TileEntity implements INBTPacke if(!diag) { super.readFromNBT(nbt); } - + this.heat = nbt.getDouble("heat"); + this.water = nbt.getInteger("water"); + this.steam = nbt.getInteger("steam"); } @Override @@ -186,6 +233,8 @@ public abstract class TileEntityRBMKBase extends TileEntity implements INBTPacke } nbt.setDouble("heat", this.heat); + nbt.setInteger("water", this.water); + nbt.setInteger("steam", this.steam); } public void networkPack(NBTTagCompound nbt, int range) { diff --git a/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKInlet.java b/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKInlet.java index 0b4739e0f..8077e1856 100644 --- a/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKInlet.java +++ b/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKInlet.java @@ -2,47 +2,94 @@ package com.hbm.tileentity.machine.rbmk; import java.util.List; +import com.hbm.blocks.machine.rbmk.RBMKBase; import com.hbm.handler.FluidTypeHandler.FluidType; import com.hbm.interfaces.IFluidAcceptor; import com.hbm.inventory.FluidTank; +import net.minecraft.block.Block; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.common.util.ForgeDirection; +import scala.actors.threadpool.Arrays; public class TileEntityRBMKInlet extends TileEntity implements IFluidAcceptor { + + public FluidTank water; + + public TileEntityRBMKInlet() { + water = new FluidTank(FluidType.WATER, 128000, 0); + } + + @Override + public void updateEntity() { + + if(!worldObj.isRemote) { + + for(int i = 2; i < 6; i++) { + ForgeDirection dir = ForgeDirection.getOrientation(i); + Block b = worldObj.getBlock(xCoord + dir.offsetX, yCoord, zCoord + dir.offsetZ); + + if(b instanceof RBMKBase) { + int[] pos = ((RBMKBase)b).findCore(worldObj, xCoord + dir.offsetX, yCoord, zCoord + dir.offsetZ); + + if(pos != null) { + TileEntity te = worldObj.getTileEntity(pos[0], pos[1], pos[2]); + + if(te instanceof TileEntityRBMKBase) { + TileEntityRBMKBase rbmk = (TileEntityRBMKBase) te; + + int prov = Math.min(rbmk.maxWater - rbmk.water, water.getFill()); + rbmk.water += prov; + water.setFill(water.getFill() - prov); + } + } + } + } + } + } + + @Override + public void readFromNBT(NBTTagCompound nbt) { + super.readFromNBT(nbt); + this.water.readFromNBT(nbt, "tank"); + } + + @Override + public void writeToNBT(NBTTagCompound nbt) { + super.writeToNBT(nbt); + this.water.writeToNBT(nbt, "tank"); + } @Override public void setFillstate(int fill, int index) { - // TODO Auto-generated method stub - + if(index == 0) water.setFill(fill); } @Override public void setFluidFill(int fill, FluidType type) { - // TODO Auto-generated method stub - + if(type == FluidType.WATER) water.setFill(fill); } @Override public void setType(FluidType type, int index) { - // TODO Auto-generated method stub - + if(index == 0) water.setTankType(type); } @Override public List getTanks() { - // TODO Auto-generated method stub - return null; + return Arrays.asList(new FluidTank[] {water}); } @Override public int getFluidFill(FluidType type) { - // TODO Auto-generated method stub + if(type == FluidType.WATER) return water.getFill(); return 0; } @Override public int getMaxFluidFill(FluidType type) { - // TODO Auto-generated method stub + if(type == FluidType.WATER) return water.getMaxFill(); return 0; } diff --git a/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKOutlet.java b/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKOutlet.java index b8cb680e2..26ccfb58e 100644 --- a/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKOutlet.java +++ b/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKOutlet.java @@ -1,74 +1,119 @@ package com.hbm.tileentity.machine.rbmk; +import java.util.ArrayList; import java.util.List; +import com.hbm.blocks.ModBlocks; +import com.hbm.blocks.machine.rbmk.RBMKBase; import com.hbm.handler.FluidTypeHandler.FluidType; import com.hbm.interfaces.IFluidAcceptor; import com.hbm.interfaces.IFluidSource; import com.hbm.inventory.FluidTank; +import com.hbm.lib.Library; +import net.minecraft.block.Block; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.common.util.ForgeDirection; +import scala.actors.threadpool.Arrays; public class TileEntityRBMKOutlet extends TileEntity implements IFluidSource { + + public List list = new ArrayList(); + public FluidTank steam; + + public TileEntityRBMKOutlet() { + steam = new FluidTank(FluidType.SUPERHOTSTEAM, 128000, 0); + } + + @Override + public void updateEntity() { + + if(!worldObj.isRemote) { + + for(int i = 2; i < 6; i++) { + ForgeDirection dir = ForgeDirection.getOrientation(i); + Block b = worldObj.getBlock(xCoord + dir.offsetX, yCoord, zCoord + dir.offsetZ); + + if(b instanceof RBMKBase) { + int[] pos = ((RBMKBase)b).findCore(worldObj, xCoord + dir.offsetX, yCoord, zCoord + dir.offsetZ); + + if(pos != null) { + TileEntity te = worldObj.getTileEntity(pos[0], pos[1], pos[2]); + + if(te instanceof TileEntityRBMKBase) { + TileEntityRBMKBase rbmk = (TileEntityRBMKBase) te; + + int prov = Math.min(steam.getMaxFill() - steam.getFill(), rbmk.steam); + rbmk.steam -= prov; + steam.setFill(steam.getFill() + prov); + } + } + } + } + } + } + + @Override + public void readFromNBT(NBTTagCompound nbt) { + super.readFromNBT(nbt); + this.steam.readFromNBT(nbt, "tank"); + } + + @Override + public void writeToNBT(NBTTagCompound nbt) { + super.writeToNBT(nbt); + this.steam.writeToNBT(nbt, "tank"); + } @Override public void setFillstate(int fill, int index) { - // TODO Auto-generated method stub - + steam.setFill(fill); } @Override public void setFluidFill(int fill, FluidType type) { - // TODO Auto-generated method stub - + steam.setFill(fill); } @Override public void setType(FluidType type, int index) { - // TODO Auto-generated method stub - + steam.setTankType(type); } @Override public List getTanks() { - // TODO Auto-generated method stub - return null; + return Arrays.asList(new FluidTank[] {steam}); } @Override public int getFluidFill(FluidType type) { - // TODO Auto-generated method stub - return 0; + return steam.getFill(); } @Override public void fillFluidInit(FluidType type) { - // TODO Auto-generated method stub - + for(ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) + fillFluid(this.xCoord + dir.offsetX, this.yCoord + dir.offsetY, this.zCoord + dir.offsetZ, getTact(), type); } @Override public void fillFluid(int x, int y, int z, boolean newTact, FluidType type) { - // TODO Auto-generated method stub - + Library.transmitFluid(x, y, z, newTact, this, worldObj, type); } - + @Override - public boolean getTact() { - // TODO Auto-generated method stub - return false; - } + @Deprecated + public boolean getTact() { return worldObj.getTotalWorldTime() % 2 == 0; } @Override public List getFluidList(FluidType type) { - // TODO Auto-generated method stub - return null; + return this.list; } @Override public void clearFluidList(FluidType type) { - // TODO Auto-generated method stub - + this.list.clear(); } }