From 385a1d29f6421214ed41db457d7e88344fc13652 Mon Sep 17 00:00:00 2001 From: Ben Spiers <ben.spiers22@gmail.com> Date: Thu, 8 Jan 2015 05:26:53 +0000 Subject: [PATCH] Make a start on the boiler. It's currently causing odd issues with the heat simulator and has various issues such as balance not existing yet. Also improve the specification of a load of the multiblock generics to reduce needless casting. --- src/main/java/mekanism/common/Mekanism.java | 4 + .../mekanism/common/block/BlockBasic.java | 18 +- .../common/content/boiler/BoilerCache.java | 80 ++- .../content/boiler/BoilerSteamTank.java | 25 + .../common/content/boiler/BoilerTank.java | 198 +++++++ .../content/boiler/BoilerUpdateProtocol.java | 109 +++- .../content/boiler/BoilerWaterTank.java | 25 + .../boiler/SynchronizedBoilerData.java | 131 ++++- .../matrix/SynchronizedMatrixData.java | 2 +- .../common/multiblock/IMultiblock.java | 4 +- .../common/multiblock/MultiblockCache.java | 2 +- .../common/multiblock/MultiblockManager.java | 4 +- .../common/multiblock/SynchronizedData.java | 5 +- .../common/multiblock/UpdateProtocol.java | 16 +- .../common/tile/TileEntityBoiler.java | 554 ++++++++++++++++++ .../common/tile/TileEntityBoilerValve.java | 74 +++ .../common/tile/TileEntityDynamicTank.java | 4 +- .../common/tile/TileEntityDynamicValve.java | 6 +- .../common/tile/TileEntityMultiblock.java | 8 +- .../java/mekanism/common/util/HeatUtils.java | 3 +- .../common/tile/TileEntityHeatGenerator.java | 2 +- .../textures/blocks/ctm/BoilerValve-ctm.png | Bin 0 -> 1414 bytes .../textures/blocks/ctm/BoilerValve.png | Bin 0 -> 1288 bytes .../textures/blocks/ctm/SteamBoiler-ctm.png | Bin 0 -> 1277 bytes .../textures/blocks/ctm/SteamBoiler.png | Bin 0 -> 1202 bytes 25 files changed, 1236 insertions(+), 38 deletions(-) create mode 100644 src/main/java/mekanism/common/content/boiler/BoilerSteamTank.java create mode 100644 src/main/java/mekanism/common/content/boiler/BoilerTank.java create mode 100644 src/main/java/mekanism/common/content/boiler/BoilerWaterTank.java create mode 100644 src/main/java/mekanism/common/tile/TileEntityBoiler.java create mode 100644 src/main/java/mekanism/common/tile/TileEntityBoilerValve.java create mode 100644 src/main/resources/assets/mekanism/textures/blocks/ctm/BoilerValve-ctm.png create mode 100644 src/main/resources/assets/mekanism/textures/blocks/ctm/BoilerValve.png create mode 100644 src/main/resources/assets/mekanism/textures/blocks/ctm/SteamBoiler-ctm.png create mode 100644 src/main/resources/assets/mekanism/textures/blocks/ctm/SteamBoiler.png diff --git a/src/main/java/mekanism/common/Mekanism.java b/src/main/java/mekanism/common/Mekanism.java index 67290da21..5403697de 100644 --- a/src/main/java/mekanism/common/Mekanism.java +++ b/src/main/java/mekanism/common/Mekanism.java @@ -62,6 +62,8 @@ import mekanism.common.recipe.inputs.ItemStackInput; import mekanism.common.recipe.machines.SmeltingRecipe; import mekanism.common.recipe.outputs.ItemStackOutput; import mekanism.common.tile.TileEntityAdvancedBoundingBlock; +import mekanism.common.tile.TileEntityBoiler; +import mekanism.common.tile.TileEntityBoilerValve; import mekanism.common.tile.TileEntityBoundingBlock; import mekanism.common.tile.TileEntityCardboardBox; import mekanism.common.tile.TileEntityElectricBlock; @@ -950,6 +952,8 @@ public class Mekanism GameRegistry.registerTileEntity(TileEntitySalinationValve.class, "SalinationValve"); GameRegistry.registerTileEntity(TileEntitySalinationBlock.class, "SalinationTank"); GameRegistry.registerTileEntity(TileEntityEntangledBlock.class, "EntangledBlock"); + GameRegistry.registerTileEntity(TileEntityBoiler.class, "SteamBoiler"); + GameRegistry.registerTileEntity(TileEntityBoilerValve.class, "BoilerValve"); //Load tile entities that have special renderers. proxy.registerSpecialTileEntities(); diff --git a/src/main/java/mekanism/common/block/BlockBasic.java b/src/main/java/mekanism/common/block/BlockBasic.java index 18798a2ef..ed5485773 100644 --- a/src/main/java/mekanism/common/block/BlockBasic.java +++ b/src/main/java/mekanism/common/block/BlockBasic.java @@ -20,6 +20,8 @@ import mekanism.common.inventory.InventoryBin; import mekanism.common.network.PacketTileEntity.TileEntityMessage; import mekanism.common.tile.TileEntityBasicBlock; import mekanism.common.tile.TileEntityBin; +import mekanism.common.tile.TileEntityBoiler; +import mekanism.common.tile.TileEntityBoilerValve; import mekanism.common.tile.TileEntityDynamicTank; import mekanism.common.tile.TileEntityDynamicValve; import mekanism.common.tile.TileEntitySalinationBlock; @@ -71,6 +73,8 @@ import cpw.mods.fml.relauncher.SideOnly; * 0:14: Salination Controller * 0:15: Salination Valve * 1:0: Salination Block + * 1:1: Steam Boiler + * 1:2: Boiler Valve * @author AidanBrady * */ @@ -150,8 +154,12 @@ public class BlockBasic extends Block implements IBlockCTM break; case BASIC_BLOCK_2: ctms[0][0] = new CTMData("ctm/SalinationBlock", this, Arrays.asList(0)).addOtherBlockConnectivities(MekanismBlocks.BasicBlock, Arrays.asList(14, 15)).registerIcons(register); + ctms[1][0] = new CTMData("ctm/SteamBoiler", this, Arrays.asList(1, 2)).registerIcons(register); + ctms[2][0] = new CTMData("ctm/BoilerValve", this, Arrays.asList(2, 1)).registerIcons(register); icons[0][0] = ctms[0][0].mainTextureData.icon; + icons[1][0] = ctms[1][0].mainTextureData.icon; + icons[2][0] = ctms[2][0].mainTextureData.icon; break; } } @@ -265,7 +273,7 @@ public class BlockBasic extends Block implements IBlockCTM } break; case BASIC_BLOCK_2: - for(int i = 0; i < 1; i++) + for(int i = 0; i < 3; i++) { list.add(new ItemStack(item, 1, i)); } @@ -642,6 +650,8 @@ public class BlockBasic extends Block implements IBlockCTM switch(metadata) { case 0: + case 1: + case 2: return true; default: return false; @@ -679,6 +689,10 @@ public class BlockBasic extends Block implements IBlockCTM { case 0: return new TileEntitySalinationBlock(); + case 1: + return new TileEntityBoiler(); + case 2: + return new TileEntityBoilerValve(); default: return null; } @@ -745,7 +759,7 @@ public class BlockBasic extends Block implements IBlockCTM } @Override - public ItemStack getPickBlock(MovingObjectPosition target, World world, int x, int y, int z) + public ItemStack getPickBlock(MovingObjectPosition target, World world, int x, int y, int z, EntityPlayer player) { ItemStack ret = new ItemStack(this, 1, world.getBlockMetadata(x, y, z)); diff --git a/src/main/java/mekanism/common/content/boiler/BoilerCache.java b/src/main/java/mekanism/common/content/boiler/BoilerCache.java index 3cb9c3db4..1f8ad6606 100644 --- a/src/main/java/mekanism/common/content/boiler/BoilerCache.java +++ b/src/main/java/mekanism/common/content/boiler/BoilerCache.java @@ -1,32 +1,98 @@ package mekanism.common.content.boiler; +import mekanism.common.content.tank.SynchronizedTankData; import mekanism.common.multiblock.MultiblockCache; +import mekanism.common.util.FluidContainerUtils.ContainerEditMode; +import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraftforge.common.util.Constants.NBT; +import net.minecraftforge.fluids.FluidStack; public class BoilerCache extends MultiblockCache<SynchronizedBoilerData> { + public ItemStack[] inventory = new ItemStack[2]; + + public FluidStack water; + public FluidStack steam; + + public ContainerEditMode editMode = ContainerEditMode.BOTH; + @Override - public void apply(SynchronizedBoilerData data) + public void apply(SynchronizedBoilerData data) { - + data.inventory = inventory; + data.waterStored = water; + data.steamStored = steam; + data.editMode = editMode; } @Override - public void sync(SynchronizedBoilerData data) + public void sync(SynchronizedBoilerData data) { - + inventory = data.inventory; + water = data.waterStored; + steam = data.steamStored; + editMode = data.editMode; } @Override public void load(NBTTagCompound nbtTags) { - + editMode = ContainerEditMode.values()[nbtTags.getInteger("editMode")]; + + NBTTagList tagList = nbtTags.getTagList("Items", NBT.TAG_COMPOUND); + inventory = new ItemStack[2]; + + for(int tagCount = 0; tagCount < tagList.tagCount(); tagCount++) + { + NBTTagCompound tagCompound = (NBTTagCompound)tagList.getCompoundTagAt(tagCount); + byte slotID = tagCompound.getByte("Slot"); + + if(slotID >= 0 && slotID < 2) + { + inventory[slotID] = ItemStack.loadItemStackFromNBT(tagCompound); + } + } + + if(nbtTags.hasKey("cachedWater")) + { + water = FluidStack.loadFluidStackFromNBT(nbtTags.getCompoundTag("cachedWater")); + } + if(nbtTags.hasKey("cachedSteam")) + { + steam = FluidStack.loadFluidStackFromNBT(nbtTags.getCompoundTag("cachedSteam")); + } } @Override - public void save(NBTTagCompound nbtTags) + public void save(NBTTagCompound nbtTags) { - + nbtTags.setInteger("editMode", editMode.ordinal()); + + NBTTagList tagList = new NBTTagList(); + + for(int slotCount = 0; slotCount < 2; slotCount++) + { + if(inventory[slotCount] != null) + { + NBTTagCompound tagCompound = new NBTTagCompound(); + tagCompound.setByte("Slot", (byte)slotCount); + inventory[slotCount].writeToNBT(tagCompound); + tagList.appendTag(tagCompound); + } + } + + nbtTags.setTag("Items", tagList); + + if(water != null) + { + nbtTags.setTag("cachedWater", water.writeToNBT(new NBTTagCompound())); + } + if(steam != null) + { + nbtTags.setTag("cachedSteam", steam.writeToNBT(new NBTTagCompound())); + } } } diff --git a/src/main/java/mekanism/common/content/boiler/BoilerSteamTank.java b/src/main/java/mekanism/common/content/boiler/BoilerSteamTank.java new file mode 100644 index 000000000..a2c554440 --- /dev/null +++ b/src/main/java/mekanism/common/content/boiler/BoilerSteamTank.java @@ -0,0 +1,25 @@ +package mekanism.common.content.boiler; + +import mekanism.common.tile.TileEntityBoiler; + +import net.minecraftforge.fluids.FluidStack; + +public class BoilerSteamTank extends BoilerTank +{ + public BoilerSteamTank(TileEntityBoiler tileEntity) + { + super(tileEntity); + } + + @Override + public FluidStack getFluid() + { + return steamBoiler.structure != null ? steamBoiler.structure.steamStored : null; + } + + public void setFluid(FluidStack stack) + { + steamBoiler.structure.steamStored = stack; + } + +} diff --git a/src/main/java/mekanism/common/content/boiler/BoilerTank.java b/src/main/java/mekanism/common/content/boiler/BoilerTank.java new file mode 100644 index 000000000..c4e60e754 --- /dev/null +++ b/src/main/java/mekanism/common/content/boiler/BoilerTank.java @@ -0,0 +1,198 @@ +package mekanism.common.content.boiler; + +import mekanism.api.Coord4D; +import mekanism.common.content.boiler.SynchronizedBoilerData.ValveData; +import mekanism.common.tile.TileEntityBoiler; +import mekanism.common.util.MekanismUtils; + +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; +import net.minecraftforge.fluids.IFluidTank; + +public abstract class BoilerTank implements IFluidTank +{ + public TileEntityBoiler steamBoiler; + + public BoilerTank(TileEntityBoiler tileEntity) + { + steamBoiler = tileEntity; + } + + public abstract void setFluid(FluidStack stack); + + @Override + public int getCapacity() + { + return steamBoiler.structure != null ? steamBoiler.structure.volume * BoilerUpdateProtocol.WATER_PER_TANK : 0; + } + + @Override + public int fill(FluidStack resource, boolean doFill) + { + if(steamBoiler.structure != null && !steamBoiler.getWorldObj().isRemote) + { + if(resource == null || resource.fluidID <= 0) + { + return 0; + } + + if(getFluid() == null || getFluid().fluidID <= 0) + { + if(resource.amount <= getCapacity()) + { + if(doFill) + { + setFluid(resource.copy()); + } + + if(resource.amount > 0 && doFill) + { + MekanismUtils.saveChunk(steamBoiler); + updateValveData(true); + steamBoiler.sendPacketToRenderer(); + updateValveData(false); + } + + return resource.amount; + } + else { + if(doFill) + { + setFluid(resource.copy()); + getFluid().amount = getCapacity(); + } + + if(getCapacity() > 0 && doFill) + { + MekanismUtils.saveChunk(steamBoiler); + updateValveData(true); + steamBoiler.sendPacketToRenderer(); + updateValveData(false); + } + + return getCapacity(); + } + } + + if(!getFluid().isFluidEqual(resource)) + { + return 0; + } + + int space = getCapacity() - getFluid().amount; + + if(resource.amount <= space) + { + if(doFill) + { + getFluid().amount += resource.amount; + } + + if(resource.amount > 0 && doFill) + { + MekanismUtils.saveChunk(steamBoiler); + updateValveData(true); + steamBoiler.sendPacketToRenderer(); + updateValveData(false); + } + + return resource.amount; + } + else { + if(doFill) + { + getFluid().amount = getCapacity(); + } + + if(space > 0 && doFill) + { + MekanismUtils.saveChunk(steamBoiler); + updateValveData(true); + steamBoiler.sendPacketToRenderer(); + updateValveData(false); + } + + return space; + } + } + + return 0; + } + + public void updateValveData(boolean value) + { + if(steamBoiler.structure != null) + { + for(ValveData data : steamBoiler.structure.valves) + { + if(data.location.equals(Coord4D.get(steamBoiler))) + { + data.serverFluid = value; + } + } + } + } + + @Override + public FluidStack drain(int maxDrain, boolean doDrain) + { + if(steamBoiler.structure != null && !steamBoiler.getWorldObj().isRemote) + { + if(getFluid() == null || getFluid().fluidID <= 0) + { + return null; + } + + if(getFluid().amount <= 0) + { + return null; + } + + int used = maxDrain; + + if(getFluid().amount < used) + { + used = getFluid().amount; + } + + if(doDrain) + { + getFluid().amount -= used; + } + + FluidStack drained = new FluidStack(getFluid().fluidID, used); + + if(getFluid().amount <= 0) + { + setFluid(null); + } + + if(drained.amount > 0 && doDrain) + { + MekanismUtils.saveChunk(steamBoiler); + steamBoiler.sendPacketToRenderer(); + } + + return drained; + } + + return null; + } + + @Override + public int getFluidAmount() + { + if(steamBoiler.structure != null) + { + return getFluid().amount; + } + + return 0; + } + + @Override + public FluidTankInfo getInfo() + { + return new FluidTankInfo(this); + } +} diff --git a/src/main/java/mekanism/common/content/boiler/BoilerUpdateProtocol.java b/src/main/java/mekanism/common/content/boiler/BoilerUpdateProtocol.java index 85384343d..eeb0e1078 100644 --- a/src/main/java/mekanism/common/content/boiler/BoilerUpdateProtocol.java +++ b/src/main/java/mekanism/common/content/boiler/BoilerUpdateProtocol.java @@ -1,6 +1,111 @@ package mekanism.common.content.boiler; -public class BoilerUpdateProtocol -{ +import java.util.List; +import mekanism.api.Coord4D; +import mekanism.api.util.StackUtils; +import mekanism.common.Mekanism; +import mekanism.common.MekanismBlocks; +import mekanism.common.content.boiler.SynchronizedBoilerData.ValveData; +import mekanism.common.multiblock.MultiblockCache; +import mekanism.common.multiblock.MultiblockManager; +import mekanism.common.multiblock.UpdateProtocol; +import mekanism.common.tile.TileEntityBoiler; +import mekanism.common.tile.TileEntityBoilerValve; + +import net.minecraft.item.ItemStack; + +public class BoilerUpdateProtocol extends UpdateProtocol<SynchronizedBoilerData> +{ + public static final int WATER_PER_TANK = 16000; + public static final int STEAM_PER_TANK = 160000; + + public BoilerUpdateProtocol(TileEntityBoiler tileEntity) + { + super(tileEntity); + } + + @Override + protected boolean isValidFrame(int x, int y, int z) + { + return pointer.getWorldObj().getBlock(x, y, z) == MekanismBlocks.BasicBlock2 && pointer.getWorldObj().getBlockMetadata(x, y, z) == 1; + } + + @Override + protected BoilerCache getNewCache() + { + return new BoilerCache(); + } + + @Override + protected SynchronizedBoilerData getNewStructure() + { + return new SynchronizedBoilerData(); + } + + @Override + protected MultiblockManager<SynchronizedBoilerData> getManager() + { + return Mekanism.boilerManager; + } + + @Override + protected void mergeCaches(List<ItemStack> rejectedItems, MultiblockCache<SynchronizedBoilerData> cache, MultiblockCache<SynchronizedBoilerData> merge) + { + if(((BoilerCache)cache).water == null) + { + ((BoilerCache)cache).water = ((BoilerCache)merge).water; + } + else if(((BoilerCache)merge).water != null && ((BoilerCache)cache).water.isFluidEqual(((BoilerCache)merge).water)) + { + ((BoilerCache)cache).water.amount += ((BoilerCache)merge).water.amount; + } + + if(((BoilerCache)cache).steam == null) + { + ((BoilerCache)cache).steam = ((BoilerCache)merge).steam; + } + else if(((BoilerCache)merge).steam != null && ((BoilerCache)cache).steam.isFluidEqual(((BoilerCache)merge).steam)) + { + ((BoilerCache)cache).steam.amount += ((BoilerCache)merge).steam.amount; + } + + List<ItemStack> rejects = StackUtils.getMergeRejects(((BoilerCache)cache).inventory, ((BoilerCache)merge).inventory); + + if(!rejects.isEmpty()) + { + rejectedItems.addAll(rejects); + } + + StackUtils.merge(((BoilerCache)cache).inventory, ((BoilerCache)merge).inventory); + } + + @Override + protected void onFormed() + { + if((structureFound).waterStored != null) + { + (structureFound).waterStored.amount = Math.min((structureFound).waterStored.amount, structureFound.volume*WATER_PER_TANK); + } + if((structureFound).steamStored != null) + { + (structureFound).steamStored.amount = Math.min((structureFound).waterStored.amount, structureFound.volume*STEAM_PER_TANK); + } + } + + @Override + protected void onStructureCreated(SynchronizedBoilerData structure, int origX, int origY, int origZ, int xmin, int xmax, int ymin, int ymax, int zmin, int zmax) + { + for(Coord4D obj : structure.locations) + { + if(obj.getTileEntity(pointer.getWorldObj()) instanceof TileEntityBoilerValve) + { + ValveData data = new ValveData(); + data.location = obj; + data.side = getSide(obj, origX+xmin, origX+xmax, origY+ymin, origY+ymax, origZ+zmin, origZ+zmax); + + ((SynchronizedBoilerData)structure).valves.add(data); + } + } + } } diff --git a/src/main/java/mekanism/common/content/boiler/BoilerWaterTank.java b/src/main/java/mekanism/common/content/boiler/BoilerWaterTank.java new file mode 100644 index 000000000..bbe231061 --- /dev/null +++ b/src/main/java/mekanism/common/content/boiler/BoilerWaterTank.java @@ -0,0 +1,25 @@ +package mekanism.common.content.boiler; + +import mekanism.common.tile.TileEntityBoiler; + +import net.minecraftforge.fluids.FluidStack; + +public class BoilerWaterTank extends BoilerTank +{ + public BoilerWaterTank(TileEntityBoiler tileEntity) + { + super(tileEntity); + } + + @Override + public FluidStack getFluid() + { + return steamBoiler.structure != null ? steamBoiler.structure.waterStored : null; + } + + public void setFluid(FluidStack stack) + { + steamBoiler.structure.waterStored = stack; + } + +} diff --git a/src/main/java/mekanism/common/content/boiler/SynchronizedBoilerData.java b/src/main/java/mekanism/common/content/boiler/SynchronizedBoilerData.java index 93eafdfe7..61335983f 100644 --- a/src/main/java/mekanism/common/content/boiler/SynchronizedBoilerData.java +++ b/src/main/java/mekanism/common/content/boiler/SynchronizedBoilerData.java @@ -1,8 +1,137 @@ package mekanism.common.content.boiler; +import java.util.HashSet; +import java.util.Set; + +import mekanism.api.Coord4D; +import mekanism.api.IHeatTransfer; import mekanism.common.multiblock.SynchronizedData; +import mekanism.common.util.FluidContainerUtils.ContainerEditMode; -public class SynchronizedBoilerData extends SynchronizedData<SynchronizedBoilerData> +import net.minecraft.item.ItemStack; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; + +public class SynchronizedBoilerData extends SynchronizedData<SynchronizedBoilerData> implements IHeatTransfer { + public FluidStack waterStored; + public FluidStack steamStored; + + public double temperature; + + public double heatToAbsorb; + + public double heatCapacity = 100; + + public double enthalpyOfVaporization = 10; + + public ContainerEditMode editMode = ContainerEditMode.BOTH; + + public ItemStack[] inventory = new ItemStack[2]; + + public Set<ValveData> valves = new HashSet<ValveData>(); + + @Override + public ItemStack[] getInventory() + { + return inventory; + } + + @Override + public double getTemp() + { + return temperature; + } + + @Override + public double getInverseConductionCoefficient() + { + return 100; + } + + @Override + public double getInsulationCoefficient(ForgeDirection side) + { + return 100; + } + + @Override + public void transferHeatTo(double heat) + { + heatToAbsorb = heat; + } + + @Override + public double[] simulateHeat() + { + return new double[0]; + } + + @Override + public double applyTemperatureChange() + { + + if(temperature < 100 + IHeatTransfer.AMBIENT_TEMP) + { + double temperatureDeficit = 100 + IHeatTransfer.AMBIENT_TEMP - temperature; + double heatNeeded = temperatureDeficit * volume * heatCapacity * 16; + double heatProvided = Math.min(heatToAbsorb, heatNeeded); + heatToAbsorb -= heatProvided; + temperature += heatProvided / (volume * heatCapacity * 16); + } + if(temperature >= 100 + IHeatTransfer.AMBIENT_TEMP && waterStored != null) + { + int amountToBoil = (int)Math.floor(heatToAbsorb / enthalpyOfVaporization); + amountToBoil = Math.min(amountToBoil, waterStored.amount); + waterStored.amount -= amountToBoil; + if(steamStored == null) + { + steamStored = new FluidStack(FluidRegistry.getFluid("steam"), amountToBoil); + } + else + { + steamStored.amount += amountToBoil; + } + + heatToAbsorb -= amountToBoil * enthalpyOfVaporization; + } + heatToAbsorb *= 0.2; + return temperature; + } + + @Override + public boolean canConnectHeat(ForgeDirection side) + { + return false; + } + + @Override + public IHeatTransfer getAdjacent(ForgeDirection side) + { + return null; + } + + public static class ValveData + { + public ForgeDirection side; + public Coord4D location; + public boolean serverFluid; + + @Override + public int hashCode() + { + int code = 1; + code = 31 * code + side.ordinal(); + code = 31 * code + location.hashCode(); + return code; + } + + @Override + public boolean equals(Object obj) + { + return obj instanceof ValveData && ((ValveData)obj).side == side && ((ValveData)obj).location.equals(location); + } + } } diff --git a/src/main/java/mekanism/common/content/matrix/SynchronizedMatrixData.java b/src/main/java/mekanism/common/content/matrix/SynchronizedMatrixData.java index a786867f4..3112707b1 100644 --- a/src/main/java/mekanism/common/content/matrix/SynchronizedMatrixData.java +++ b/src/main/java/mekanism/common/content/matrix/SynchronizedMatrixData.java @@ -5,7 +5,7 @@ import mekanism.common.multiblock.SynchronizedData; import net.minecraft.item.ItemStack; -public class SynchronizedMatrixData extends SynchronizedData<SynchronizedTankData> +public class SynchronizedMatrixData extends SynchronizedData<SynchronizedMatrixData> { public ItemStack[] inventory = new ItemStack[2]; diff --git a/src/main/java/mekanism/common/multiblock/IMultiblock.java b/src/main/java/mekanism/common/multiblock/IMultiblock.java index 1cdbbc52a..dc2ae616b 100644 --- a/src/main/java/mekanism/common/multiblock/IMultiblock.java +++ b/src/main/java/mekanism/common/multiblock/IMultiblock.java @@ -1,6 +1,6 @@ package mekanism.common.multiblock; -public interface IMultiblock<T> +public interface IMultiblock<T extends SynchronizedData<T>> { - public SynchronizedData<T> getSynchronizedData(); + public T getSynchronizedData(); } diff --git a/src/main/java/mekanism/common/multiblock/MultiblockCache.java b/src/main/java/mekanism/common/multiblock/MultiblockCache.java index df3f56388..3836889f8 100644 --- a/src/main/java/mekanism/common/multiblock/MultiblockCache.java +++ b/src/main/java/mekanism/common/multiblock/MultiblockCache.java @@ -6,7 +6,7 @@ import mekanism.api.Coord4D; import net.minecraft.nbt.NBTTagCompound; -public abstract class MultiblockCache<T> +public abstract class MultiblockCache<T extends SynchronizedData<T>> { public HashSet<Coord4D> locations = new HashSet<Coord4D>(); diff --git a/src/main/java/mekanism/common/multiblock/MultiblockManager.java b/src/main/java/mekanism/common/multiblock/MultiblockManager.java index fa4e30075..c94f2e2cf 100644 --- a/src/main/java/mekanism/common/multiblock/MultiblockManager.java +++ b/src/main/java/mekanism/common/multiblock/MultiblockManager.java @@ -16,7 +16,7 @@ import net.minecraft.world.World; import net.minecraft.world.WorldSavedData; import net.minecraftforge.common.util.Constants.NBT; -public class MultiblockManager<T> +public class MultiblockManager<T extends SynchronizedData<T>> { private static Set<MultiblockManager> managers = new HashSet<MultiblockManager>(); @@ -80,8 +80,6 @@ public class MultiblockManager<T> /** * Updates a dynamic tank cache with the defined inventory ID with the parameterized values. - * @param inventoryID - inventory ID of the dynamic tank - * @param cache - cache of the dynamic tank * @param multiblock - dynamic tank TileEntity */ public void updateCache(IMultiblock<T> multiblock) diff --git a/src/main/java/mekanism/common/multiblock/SynchronizedData.java b/src/main/java/mekanism/common/multiblock/SynchronizedData.java index f3ffed487..cab4f5e3f 100644 --- a/src/main/java/mekanism/common/multiblock/SynchronizedData.java +++ b/src/main/java/mekanism/common/multiblock/SynchronizedData.java @@ -7,7 +7,7 @@ import mekanism.api.Coord4D; import net.minecraft.item.ItemStack; -public abstract class SynchronizedData<T> +public abstract class SynchronizedData<T extends SynchronizedData<T>> { public Set<Coord4D> locations = new HashSet<Coord4D>(); @@ -26,6 +26,9 @@ public abstract class SynchronizedData<T> public boolean hasRenderer; public Coord4D renderLocation; + + public Coord4D minLocation; + public Coord4D maxLocation; public ItemStack[] getInventory() { diff --git a/src/main/java/mekanism/common/multiblock/UpdateProtocol.java b/src/main/java/mekanism/common/multiblock/UpdateProtocol.java index 5b8770d70..a7b0a86bb 100644 --- a/src/main/java/mekanism/common/multiblock/UpdateProtocol.java +++ b/src/main/java/mekanism/common/multiblock/UpdateProtocol.java @@ -14,13 +14,13 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; -public abstract class UpdateProtocol<T> +public abstract class UpdateProtocol<T extends SynchronizedData<T>> { /** The multiblock nodes that have already been iterated over. */ public Set<TileEntityMultiblock<T>> iteratedNodes = new HashSet<TileEntityMultiblock<T>>(); /** The structures found, all connected by some nodes to the pointer. */ - public SynchronizedData<T> structureFound = null; + public T structureFound = null; /** The original block the calculation is getting run from. */ public TileEntityMultiblock<T> pointer; @@ -178,13 +178,15 @@ public abstract class UpdateProtocol<T> { if(rightBlocks && rightFrame && isHollow && isCorner) { - SynchronizedData<T> structure = getNewStructure(); + T structure = getNewStructure(); structure.locations = locations; structure.volLength = Math.abs(xmax-xmin)+1; structure.volHeight = Math.abs(ymax-ymin)+1; structure.volWidth = Math.abs(zmax-zmin)+1; structure.volume = volume; structure.renderLocation = Coord4D.get(tile).translate(0, 1, 0); + structure.minLocation = Coord4D.get(tile).translate(xmin, ymin, zmin); + structure.maxLocation = Coord4D.get(tile).translate(xmax, ymax, zmax); onStructureCreated(structure, origX, origY, origZ, xmin, xmax, ymin, ymax, zmin, zmax); @@ -346,7 +348,7 @@ public abstract class UpdateProtocol<T> protected abstract MultiblockCache<T> getNewCache(); - protected abstract SynchronizedData<T> getNewStructure(); + protected abstract T getNewStructure(); protected abstract MultiblockManager<T> getManager(); @@ -354,7 +356,7 @@ public abstract class UpdateProtocol<T> protected void onFormed() {} - protected void onStructureCreated(SynchronizedData<T> structure, int origX, int origY, int origZ, int xmin, int xmax, int ymin, int ymax, int zmin, int zmax) {} + protected void onStructureCreated(T structure, int origX, int origY, int origZ, int xmin, int xmax, int ymin, int ymax, int zmin, int zmax) {} /** * Runs the protocol and updates all tanks that make a part of the dynamic tank. @@ -371,7 +373,7 @@ public abstract class UpdateProtocol<T> { for(TileEntity tile : iteratedNodes) { - ((TileEntityMultiblock<T>)tileEntity).structure = null; + ((TileEntityMultiblock<T>)tile).structure = null; } return; @@ -406,7 +408,7 @@ public abstract class UpdateProtocol<T> cache = (MultiblockCache<T>)Mekanism.tankManager.pullInventory(pointer.getWorldObj(), id); } else { - mergeCaches(rejectedItems, cache, (MultiblockCache<T>)getManager().pullInventory(pointer.getWorldObj(), id)); + mergeCaches(rejectedItems, cache, getManager().pullInventory(pointer.getWorldObj(), id)); } idToUse = id; diff --git a/src/main/java/mekanism/common/tile/TileEntityBoiler.java b/src/main/java/mekanism/common/tile/TileEntityBoiler.java new file mode 100644 index 000000000..dd253d1f6 --- /dev/null +++ b/src/main/java/mekanism/common/tile/TileEntityBoiler.java @@ -0,0 +1,554 @@ +package mekanism.common.tile; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import mekanism.api.Coord4D; +import mekanism.api.IHeatTransfer; +import mekanism.api.Range4D; +import mekanism.common.Mekanism; +import mekanism.common.base.IFluidContainerManager; +import mekanism.common.content.boiler.BoilerUpdateProtocol; +import mekanism.common.content.boiler.SynchronizedBoilerData; +import mekanism.common.content.boiler.SynchronizedBoilerData.ValveData; +import mekanism.common.multiblock.MultiblockManager; +import mekanism.common.network.PacketTileEntity.TileEntityMessage; +import mekanism.common.util.FluidContainerUtils; +import mekanism.common.util.FluidContainerUtils.ContainerEditMode; +import mekanism.common.util.HeatUtils; + +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidContainerRegistry; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidContainerItem; + +import io.netty.buffer.ByteBuf; + +public class TileEntityBoiler extends TileEntityMultiblock<SynchronizedBoilerData> implements IFluidContainerManager, IHeatTransfer +{ + /** A client-sided and server-sided map of valves on this tank's structure, used on the client for rendering fluids. */ + public Map<ValveData, Integer> valveViewing = new HashMap<ValveData, Integer>(); + + /** The capacity this tank has on the client-side. */ + public int clientWaterCapacity; + public int clientSteamCapacity; + + public float prevWaterScale; + public float prevSteamScale; + + public ForgeDirection innerSide; + + public double temperature; + public double heatToAbsorb; + public double invHeatCapacity = 10; + + public TileEntityBoiler() + { + this("SteamBoiler"); + } + + public TileEntityBoiler(String name) + { + super(name); + inventory = new ItemStack[2]; + } + + @Override + public void onUpdate() + { + super.onUpdate(); + + if(worldObj.isRemote) + { + if(structure != null && clientHasStructure && isRendering) + { + for(ValveData data : valveViewing.keySet()) + { + if(valveViewing.get(data) > 0) + { + valveViewing.put(data, valveViewing.get(data)-1); + } + } + + float targetScale = (float)(structure.waterStored != null ? structure.waterStored.amount : 0)/clientWaterCapacity; + + if(Math.abs(prevWaterScale - targetScale) > 0.01) + { + prevWaterScale = (9*prevWaterScale + targetScale)/10; + } + + targetScale = (float)(structure.steamStored != null ? structure.steamStored.amount : 0)/clientSteamCapacity; + + if(Math.abs(prevSteamScale - targetScale) > 0.01) + { + prevSteamScale = (9*prevSteamScale+ targetScale)/10; + } + } + + if(!clientHasStructure || !isRendering) + { + for(ValveData data : valveViewing.keySet()) + { + TileEntityDynamicTank tileEntity = (TileEntityDynamicTank)data.location.getTileEntity(worldObj); + + if(tileEntity != null) + { + tileEntity.clientHasStructure = false; + } + } + + valveViewing.clear(); + } + } + + if(!worldObj.isRemote) + { + if(structure != null) + { + manageInventory(); + } + + simulateHeat(); + applyTemperatureChange(); + if(structure != null) + { + structure.applyTemperatureChange(); + } + } + } + + public void manageInventory() + { + int max = structure.volume * BoilerUpdateProtocol.WATER_PER_TANK; + + if(structure.inventory[0] != null) + { + if(structure.inventory[0].getItem() instanceof IFluidContainerItem) + { + if(structure.editMode == ContainerEditMode.FILL && structure.waterStored != null) + { + int prev = structure.waterStored.amount; + + structure.waterStored.amount -= FluidContainerUtils.insertFluid(structure.waterStored, structure.inventory[0]); + + if(prev == structure.waterStored.amount || structure.waterStored.amount == 0) + { + if(structure.inventory[1] == null) + { + structure.inventory[1] = structure.inventory[0].copy(); + structure.inventory[0] = null; + + markDirty(); + } + } + + if(structure.waterStored.amount == 0) + { + structure.waterStored = null; + } + } + else if(structure.editMode == ContainerEditMode.EMPTY) + { + if(structure.waterStored != null) + { + FluidStack received = FluidContainerUtils.extractFluid(max-structure.waterStored.amount, structure.inventory[0], structure.waterStored.getFluid()); + + if(received != null) + { + structure.waterStored.amount += received.amount; + } + } + else { + structure.waterStored = FluidContainerUtils.extractFluid(max, structure.inventory[0], null); + } + + int newStored = structure.waterStored != null ? structure.waterStored.amount : 0; + + if(((IFluidContainerItem)structure.inventory[0].getItem()).getFluid(structure.inventory[0]) == null || newStored == max) + { + if(structure.inventory[1] == null) + { + structure.inventory[1] = structure.inventory[0].copy(); + structure.inventory[0] = null; + + markDirty(); + } + } + } + } + else if(FluidContainerRegistry.isEmptyContainer(structure.inventory[0]) && (structure.editMode == ContainerEditMode.BOTH || structure.editMode == ContainerEditMode.FILL)) + { + if(structure.waterStored != null && structure.waterStored.amount >= FluidContainerRegistry.BUCKET_VOLUME) + { + ItemStack filled = FluidContainerRegistry.fillFluidContainer(structure.waterStored, structure.inventory[0]); + + if(filled != null) + { + if(structure.inventory[1] == null || (structure.inventory[1].isItemEqual(filled) && structure.inventory[1].stackSize+1 <= filled.getMaxStackSize())) + { + structure.inventory[0].stackSize--; + + if(structure.inventory[0].stackSize <= 0) + { + structure.inventory[0] = null; + } + + if(structure.inventory[1] == null) + { + structure.inventory[1] = filled; + } + else { + structure.inventory[1].stackSize++; + } + + markDirty(); + + structure.waterStored.amount -= FluidContainerRegistry.getFluidForFilledItem(filled).amount; + + if(structure.waterStored.amount == 0) + { + structure.waterStored = null; + } + + Mekanism.packetHandler.sendToReceivers(new TileEntityMessage(Coord4D.get(this), getNetworkedData(new ArrayList())), new Range4D(Coord4D.get(this))); + } + } + } + } + else if(FluidContainerRegistry.isFilledContainer(structure.inventory[0]) && (structure.editMode == ContainerEditMode.BOTH || structure.editMode == ContainerEditMode.EMPTY)) + { + FluidStack itemFluid = FluidContainerRegistry.getFluidForFilledItem(structure.inventory[0]); + + if((structure.waterStored == null && itemFluid.amount <= max) || structure.waterStored.amount+itemFluid.amount <= max) + { + if(structure.waterStored != null && !structure.waterStored.isFluidEqual(itemFluid)) + { + return; + } + + ItemStack containerItem = structure.inventory[0].getItem().getContainerItem(structure.inventory[0]); + + boolean filled = false; + + if(containerItem != null) + { + if(structure.inventory[1] == null || (structure.inventory[1].isItemEqual(containerItem) && structure.inventory[1].stackSize+1 <= containerItem.getMaxStackSize())) + { + structure.inventory[0] = null; + + if(structure.inventory[1] == null) + { + structure.inventory[1] = containerItem; + } + else { + structure.inventory[1].stackSize++; + } + + filled = true; + } + } + else { + structure.inventory[0].stackSize--; + + if(structure.inventory[0].stackSize == 0) + { + structure.inventory[0] = null; + } + + filled = true; + } + + if(filled) + { + if(structure.waterStored == null) + { + structure.waterStored = itemFluid.copy(); + } + else { + structure.waterStored.amount += itemFluid.amount; + } + + markDirty(); + } + + Mekanism.packetHandler.sendToReceivers(new TileEntityMessage(Coord4D.get(this), getNetworkedData(new ArrayList())), new Range4D(Coord4D.get(this))); + } + } + } + } + + @Override + protected SynchronizedBoilerData getNewStructure() + { + return new SynchronizedBoilerData(); + } + + @Override + protected BoilerUpdateProtocol getProtocol() + { + return new BoilerUpdateProtocol(this); + } + + @Override + public MultiblockManager<SynchronizedBoilerData> getManager() + { + return Mekanism.boilerManager; + } + + @Override + public ArrayList getNetworkedData(ArrayList data) + { + super.getNetworkedData(data); + + if(structure != null) + { + data.add(structure.volume*BoilerUpdateProtocol.WATER_PER_TANK); + data.add(structure.volume*BoilerUpdateProtocol.STEAM_PER_TANK); + data.add(structure.editMode.ordinal()); + } + + if(structure != null && structure.waterStored != null) + { + data.add(1); + data.add(structure.waterStored.fluidID); + data.add(structure.waterStored.amount); + } + else { + data.add(0); + } + + if(structure != null && structure.steamStored != null) + { + data.add(1); + data.add(structure.steamStored.fluidID); + data.add(structure.steamStored.amount); + } + else { + data.add(0); + } + + if(structure != null && isRendering) + { + data.add(structure.valves.size()); + + for(ValveData valveData : structure.valves) + { + valveData.location.write(data); + + data.add(valveData.side.ordinal()); + data.add(valveData.serverFluid); + } + } + + return data; + } + + @Override + public void handlePacketData(ByteBuf dataStream) + { + super.handlePacketData(dataStream); + + if(clientHasStructure) + { + clientWaterCapacity = dataStream.readInt(); + clientSteamCapacity = dataStream.readInt(); + structure.editMode = ContainerEditMode.values()[dataStream.readInt()]; + } + + if(dataStream.readInt() == 1) + { + structure.waterStored = new FluidStack(dataStream.readInt(), dataStream.readInt()); + } + else { + structure.waterStored = null; + } + + if(dataStream.readInt() == 1) + { + structure.steamStored = new FluidStack(dataStream.readInt(), dataStream.readInt()); + } + else { + structure.steamStored = null; + } + + if(clientHasStructure && isRendering) + { + int size = dataStream.readInt(); + + for(int i = 0; i < size; i++) + { + ValveData data = new ValveData(); + data.location = Coord4D.read(dataStream); + data.side = ForgeDirection.getOrientation(dataStream.readInt()); + int viewingTicks = 0; + + if(dataStream.readBoolean()) + { + viewingTicks = 30; + } + + if(viewingTicks == 0) + { + if(valveViewing.containsKey(data) && valveViewing.get(data) > 0) + { + continue; + } + } + + valveViewing.put(data, viewingTicks); + + TileEntityBoiler tileEntity = (TileEntityBoiler)data.location.getTileEntity(worldObj); + + if(tileEntity != null) + { + tileEntity.clientHasStructure = true; + } + } + } + } + + public int getScaledWaterLevel(int i) + { + if(clientWaterCapacity == 0 || structure.waterStored == null) + { + return 0; + } + + return structure.waterStored.amount*i / clientWaterCapacity; + } + + public int getScaledSteamLevel(int i) + { + if(clientSteamCapacity == 0 || structure.steamStored == null) + { + return 0; + } + + return structure.steamStored.amount*i / clientSteamCapacity; + } + + @Override + public ContainerEditMode getContainerEditMode() + { + if(structure != null) + { + return structure.editMode; + } + + return ContainerEditMode.BOTH; + } + + @Override + public void setContainerEditMode(ContainerEditMode mode) + { + if(structure == null) + { + return; + } + + structure.editMode = mode; + } + + @Override + public double getTemp() + { + return temperature; + } + + @Override + public double getInverseConductionCoefficient() + { + return 10; + } + + @Override + public double getInsulationCoefficient(ForgeDirection side) + { + return 10; + } + + @Override + public void transferHeatTo(double heat) + { + heatToAbsorb += heat; + } + + @Override + public double[] simulateHeat() + { + innerSide = null; + return HeatUtils.simulate(this); + } + + @Override + public double applyTemperatureChange() + { + temperature += invHeatCapacity * heatToAbsorb; + heatToAbsorb = 0; + return temperature; + } + + @Override + public boolean canConnectHeat(ForgeDirection side) + { + return structure == null || !isInnerSide(side); + } + + @Override + public IHeatTransfer getAdjacent(ForgeDirection side) + { + if(structure != null && isInnerSide(side)) + { + return structure; + } + else + { + TileEntity adj = Coord4D.get(this).getFromSide(side).getTileEntity(worldObj); + if(adj instanceof IHeatTransfer) + { + return (IHeatTransfer)adj; + } + } + + return null; + } + + public boolean isInnerSide(ForgeDirection side) + { + if(innerSide != null) + { + return side == innerSide; + } + + if(!Coord4D.get(this).getFromSide(side).getBlock(worldObj).isAir(worldObj, xCoord, yCoord, zCoord)) + { + return false; + } + + if(structure == null || structure.minLocation == null || structure.maxLocation == null) + { + return false; + } + + switch(side) + { + case DOWN: + return yCoord == structure.maxLocation.yCoord; + case UP: + return yCoord == structure.minLocation.yCoord; + case NORTH: + return zCoord == structure.maxLocation.zCoord; + case SOUTH: + return zCoord == structure.minLocation.zCoord; + case WEST: + return xCoord == structure.maxLocation.xCoord; + case EAST: + return xCoord == structure.minLocation.xCoord; + default: + return false; + } + } +} diff --git a/src/main/java/mekanism/common/tile/TileEntityBoilerValve.java b/src/main/java/mekanism/common/tile/TileEntityBoilerValve.java new file mode 100644 index 000000000..edfcc374e --- /dev/null +++ b/src/main/java/mekanism/common/tile/TileEntityBoilerValve.java @@ -0,0 +1,74 @@ +package mekanism.common.tile; + +import mekanism.common.content.boiler.BoilerSteamTank; +import mekanism.common.content.boiler.BoilerTank; +import mekanism.common.content.boiler.BoilerWaterTank; +import mekanism.common.util.PipeUtils; + +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; +import net.minecraftforge.fluids.IFluidHandler; + +public class TileEntityBoilerValve extends TileEntityBoiler implements IFluidHandler +{ + public BoilerTank waterTank; + public BoilerTank steamTank; + + public TileEntityBoilerValve() + { + super("Boiler Valve"); + waterTank = new BoilerWaterTank(this); + steamTank = new BoilerSteamTank(this); + } + + @Override + public FluidTankInfo[] getTankInfo(ForgeDirection from) + { + return ((!worldObj.isRemote && structure != null) || (worldObj.isRemote && clientHasStructure)) ? new FluidTankInfo[] {waterTank.getInfo(), steamTank.getInfo()} : PipeUtils.EMPTY; + } + + @Override + public int fill(ForgeDirection from, FluidStack resource, boolean doFill) + { + return waterTank.fill(resource, doFill); + } + + @Override + public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) + { + if(structure != null && structure.steamStored != null) + { + if(resource.getFluid() == structure.steamStored.getFluid()) + { + return steamTank.drain(resource.amount, doDrain); + } + } + + return null; + } + + @Override + public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) + { + if(structure != null) + { + return steamTank.drain(maxDrain, doDrain); + } + + return null; + } + + @Override + public boolean canFill(ForgeDirection from, Fluid fluid) + { + return true; + } + + @Override + public boolean canDrain(ForgeDirection from, Fluid fluid) + { + return true; + } +} diff --git a/src/main/java/mekanism/common/tile/TileEntityDynamicTank.java b/src/main/java/mekanism/common/tile/TileEntityDynamicTank.java index ddcb2b6c5..030b9ac12 100644 --- a/src/main/java/mekanism/common/tile/TileEntityDynamicTank.java +++ b/src/main/java/mekanism/common/tile/TileEntityDynamicTank.java @@ -25,7 +25,7 @@ import net.minecraftforge.fluids.IFluidContainerItem; import io.netty.buffer.ByteBuf; -public class TileEntityDynamicTank extends TileEntityMultiblock<SynchronizedTankData> implements IFluidContainerManager, IMultiblock<SynchronizedTankData> +public class TileEntityDynamicTank extends TileEntityMultiblock<SynchronizedTankData> implements IFluidContainerManager { /** A client-sided and server-sided map of valves on this tank's structure, used on the client for rendering fluids. */ public Map<ValveData, Integer> valveViewing = new HashMap<ValveData, Integer>(); @@ -98,7 +98,7 @@ public class TileEntityDynamicTank extends TileEntityMultiblock<SynchronizedTank public void manageInventory() { - int max = structure.volume*TankUpdateProtocol.FLUID_PER_TANK; + int max = structure.volume * TankUpdateProtocol.FLUID_PER_TANK; if(structure.inventory[0] != null) { diff --git a/src/main/java/mekanism/common/tile/TileEntityDynamicValve.java b/src/main/java/mekanism/common/tile/TileEntityDynamicValve.java index 7405c3a72..2554e8d57 100644 --- a/src/main/java/mekanism/common/tile/TileEntityDynamicValve.java +++ b/src/main/java/mekanism/common/tile/TileEntityDynamicValve.java @@ -34,9 +34,9 @@ public class TileEntityDynamicValve extends TileEntityDynamicTank implements IFl @Override public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) { - if(fluidTank.dynamicTank.structure != null && fluidTank.dynamicTank.structure.fluidStored != null) + if(structure != null && structure.fluidStored != null) { - if(resource.getFluid() == fluidTank.dynamicTank.structure.fluidStored.getFluid()) + if(resource.getFluid() == structure.fluidStored.getFluid()) { return fluidTank.drain(resource.amount, doDrain); } @@ -48,7 +48,7 @@ public class TileEntityDynamicValve extends TileEntityDynamicTank implements IFl @Override public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) { - if(fluidTank.dynamicTank.structure != null) + if(structure != null) { return fluidTank.drain(maxDrain, doDrain); } diff --git a/src/main/java/mekanism/common/tile/TileEntityMultiblock.java b/src/main/java/mekanism/common/tile/TileEntityMultiblock.java index 6d4ffecb8..12ba3e5a2 100644 --- a/src/main/java/mekanism/common/tile/TileEntityMultiblock.java +++ b/src/main/java/mekanism/common/tile/TileEntityMultiblock.java @@ -20,7 +20,7 @@ import cpw.mods.fml.relauncher.SideOnly; import io.netty.buffer.ByteBuf; -public abstract class TileEntityMultiblock<T> extends TileEntityContainerBlock implements IMultiblock<T> +public abstract class TileEntityMultiblock<T extends SynchronizedData<T>> extends TileEntityContainerBlock implements IMultiblock<T> { /** The tank data for this structure. */ public T structure; @@ -138,7 +138,7 @@ public abstract class TileEntityMultiblock<T> extends TileEntityContainerBlock i { for(Coord4D obj : getSynchronizedData().locations) { - TileEntityDynamicTank tileEntity = (TileEntityDynamicTank)obj.getTileEntity(worldObj); + TileEntityMultiblock<T> tileEntity = (TileEntityMultiblock<T>)obj.getTileEntity(worldObj); if(tileEntity != null && tileEntity.isRendering) { @@ -244,8 +244,8 @@ public abstract class TileEntityMultiblock<T> extends TileEntityContainerBlock i } @Override - public SynchronizedData<T> getSynchronizedData() + public T getSynchronizedData() { - return (SynchronizedData<T>)structure; + return structure; } } diff --git a/src/main/java/mekanism/common/util/HeatUtils.java b/src/main/java/mekanism/common/util/HeatUtils.java index 4dbd279f6..6c5013e80 100644 --- a/src/main/java/mekanism/common/util/HeatUtils.java +++ b/src/main/java/mekanism/common/util/HeatUtils.java @@ -26,7 +26,8 @@ public class HeatUtils continue; } //Transfer to air otherwise - double heatToTransfer = source.getTemp() / (IHeatTransfer.AIR_INVERSE_COEFFICIENT+source.getInsulationCoefficient(side)+source.getInverseConductionCoefficient()); + double invConduction = IHeatTransfer.AIR_INVERSE_COEFFICIENT + source.getInsulationCoefficient(side) + source.getInverseConductionCoefficient(); + double heatToTransfer = source.getTemp() / invConduction; source.transferHeatTo(-heatToTransfer); heatTransferred[1] += heatToTransfer; } diff --git a/src/main/java/mekanism/generators/common/tile/TileEntityHeatGenerator.java b/src/main/java/mekanism/generators/common/tile/TileEntityHeatGenerator.java index 14a7b7f6f..cb31091d1 100644 --- a/src/main/java/mekanism/generators/common/tile/TileEntityHeatGenerator.java +++ b/src/main/java/mekanism/generators/common/tile/TileEntityHeatGenerator.java @@ -432,7 +432,7 @@ public class TileEntityHeatGenerator extends TileEntityGenerator implements IFlu @Override public IHeatTransfer getAdjacent(ForgeDirection side) { - if(side == ForgeDirection.DOWN) + if(canConnectHeat(side)) { TileEntity adj = Coord4D.get(this).getFromSide(side).getTileEntity(worldObj); if(adj instanceof IHeatTransfer) diff --git a/src/main/resources/assets/mekanism/textures/blocks/ctm/BoilerValve-ctm.png b/src/main/resources/assets/mekanism/textures/blocks/ctm/BoilerValve-ctm.png new file mode 100644 index 0000000000000000000000000000000000000000..51847a8995692fd044c7ed626d8ff3bb3c9a81c0 GIT binary patch literal 1414 zcmV;11$p|3P)<h;3K|Lk000e1NJLTq002M$002M;1^@s6s%dfF000B@X+uL$Nkc;* zP;zf(X>4Tx0C?Jsl+SMzWf;dlyYtSh2{;E+0gJ(jKY)-zwqTG3L3g{$wouDv+hW_8 znC<M_-Lccz@txW7BRz4^8>oMPiX1$ccrw9X5iY<%0|`MxY)DKvl=ve=5-x_+!%TMv zXvO#R%=3Pq@AvyW?~{Sd=T+Z#(-zEnp{kVf*7(GvmAOHhXIMiwYpQnO=gQ?FfU57i zJaX>+ObX!I_LcAd^Q@`Kz=qTlK(iLuvyeIlx@-F?1mhO4=V<7Mka-s9QsWbokjVmF z^(Za?T~kp!4s@x}N<U;=z_c6H8f4~yo~cB>o`@q40Cbh4CzWGcl~Ud+tLC)h%7op= zT>sBA>$aBlHUVpcnUO=lR!ALdsDVlxe_~gQBfyK0y6lJf3a}Ycf3#-Ca=<o7KQ*lm zj79kLt0x+xZvyKeU30?0(Kvs?n;JeG)uzwPG!Io`%w;?1p9G$V^v#AG9E$vC)MTLu z^nkXh(He;PwS&RjNO76xM5BK=;?dMQ)q`cA8?^UTvvN4{teuf=sS@#P7yYmtd(aj= zcX%k`6s8P{Bg^@)F**>{irt|ajcdi^v~yrE#?Sk1c_{KG&Z<^rEXG`|s$wbP5r0c> zEaucV)T)I;zz)#&b0k$o(qsyWjmLc~DwN1$;iG6Wje|=GiHAhtq@H93XBAu-iHhS6 zqK?F45ru=j3MNvx9b=key~v7PA}jWaA+b;F5q((VHSxOGFA5?n`o!LLZ8@QDQRjA> z=UrMzEGir!f4aN1wWD`Zz3tdnPThH+y7`D_x$Gx70Rm>)$nDAgFU^0qp~G=qoO|oq z+Dr2se%yTZTl%7YUB9K@&=)!g{a1ZKU(j!m!^NeJWEP2oha^ZiNcM06myjwhzv0nL z;2uz%_D*+qZtN?k?#TCs?+tUZr<2Y8lKnG#J^N|)Z1(quro7^mw2!o}wC}aAwQsZ^ zv9$Br1?>mzqV}csZQ`v~-;eg&lS_0f@m8F*#5MEgM)L);U_NKQWDa%s%=KokIbd!v z3+Bf5yCwCKy*NzZwx_zXR)ibF!{I0rML-o7kK+&Re_Sm#iC!`I(AMq|dqvx&Q8Wrh z4$IhP^clUzK_l1kXKXPFMxU|8C_b=t_9`971S;9*cBYU7%%E_XL*f!3LwPI&=x_SR zl~Zqo*3NA96)WfauCxX{dq<B|bzMt2^+p(2N(NHR$=VLaCnl}v7k#%v3P`QH(#eHy zz`nmgyV}W3w&05Z*1z1zZS97qKZbL=?UtI0|M{uZPY_J++8KSV&4Ye(Y3c4}$b1O* zKUiA&=giX5{m(#Kfb;IZSpac()l@2R00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru-vI~(3>JyPJ+lA+0TW3?K~#9!?b{&^gfI|5(b)}# z;7}+GqK5l$3NFA&xLQMc0R%|ou3ABMSI`Wtm_LpZGUZWPnhcL|9AA<#LI~1zU6$O= zIeCil00000000000002MY7{Zw?p0O&J>N9V?Ry8!{Feca<B+y(rLOC*bIY>a{=~HN z7crgK_g&_BKDABLlx)~)=4TQFfK?zahG94zZ`+o%<68Nn0M>Q=*;bZilAG7ee;J_f z`>aD&J3o^k000000000000011cZ1G3+W_8svp4U(=M?||0000000000u=^=|^#bYx zs1Kk%fJqPl%d5aAs1NwjMtwknpgw>}5C8xG00000002N~GZaF|-ichl&x?q>0lndJ Uu*PGi>Hq)$07*qoM6N<$g5$}k*#H0l literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/mekanism/textures/blocks/ctm/BoilerValve.png b/src/main/resources/assets/mekanism/textures/blocks/ctm/BoilerValve.png new file mode 100644 index 0000000000000000000000000000000000000000..f60ee83dd24df729a5db3fd55349336496c342d9 GIT binary patch literal 1288 zcmV+j1^4=iP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F8000B@X+uL$Nkc;* zP;zf(X>4Tx0C?Jsl+SMzWf;dlyYtSh2{;E+0gJ(jKY)-zwqTG3L3g{$wouDv+hW_8 znC<M_-Lccz@txW7BRz4^8>oMPiX1$ccrw9X5iY<%0|`MxY)DKvl=ve=5-x_+!%TMv zXvO#R%=3Pq@AvyW?~{Sd=T+Z#(-zEnp{kVf*7(GvmAOHhXIMiwYpQnO=gQ?FfU57i zJaX>+ObX!I_LcAd^Q@`Kz=qTlK(iLuvyeIlx@-F?1mhO4=V<7Mka-s9QsWbokjVmF z^(Za?T~kp!4s@x}N<U;=z_c6H8f4~yo~cB>o`@q40Cbh4CzWGcl~Ud+tLC)h%7op= zT>sBA>$aBlHUVpcnUO=lR!ALdsDVlxe_~gQBfyK0y6lJf3a}Ycf3#-Ca=<o7KQ*lm zj79kLt0x+xZvyKeU30?0(Kvs?n;JeG)uzwPG!Io`%w;?1p9G$V^v#AG9E$vC)MTLu z^nkXh(He;PwS&RjNO76xM5BK=;?dMQ)q`cA8?^UTvvN4{teuf=sS@#P7yYmtd(aj= zcX%k`6s8P{Bg^@)F**>{irt|ajcdi^v~yrE#?Sk1c_{KG&Z<^rEXG`|s$wbP5r0c> zEaucV)T)I;zz)#&b0k$o(qsyWjmLc~DwN1$;iG6Wje|=GiHAhtq@H93XBAu-iHhS6 zqK?F45ru=j3MNvx9b=key~v7PA}jWaA+b;F5q((VHSxOGFA5?n`o!LLZ8@QDQRjA> z=UrMzEGir!f4aN1wWD`Zz3tdnPThH+y7`D_x$Gx70Rm>)$nDAgFU^0qp~G=qoO|oq z+Dr2se%yTZTl%7YUB9K@&=)!g{a1ZKU(j!m!^NeJWEP2oha^ZiNcM06myjwhzv0nL z;2uz%_D*+qZtN?k?#TCs?+tUZr<2Y8lKnG#J^N|)Z1(quro7^mw2!o}wC}aAwQsZ^ zv9$Br1?>mzqV}csZQ`v~-;eg&lS_0f@m8F*#5MEgM)L);U_NKQWDa%s%=KokIbd!v z3+Bf5yCwCKy*NzZwx_zXR)ibF!{I0rML-o7kK+&Re_Sm#iC!`I(AMq|dqvx&Q8Wrh z4$IhP^clUzK_l1kXKXPFMxU|8C_b=t_9`971S;9*cBYU7%%E_XL*f!3LwPI&=x_SR zl~Zqo*3NA96)WfauCxX{dq<B|bzMt2^+p(2N(NHR$=VLaCnl}v7k#%v3P`QH(#eHy zz`nmgyV}W3w&05Z*1z1zZS97qKZbL=?UtI0|M{uZPY_J++8KSV&4Ye(Y3c4}$b1O* zKUiA&=giX5{m(#Kfb;IZSpac()l@2R00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru-vI~(3>)`zK@I=_0F_BZK~z}7?bjg=Lm><X;D5_A z1cyRlYq$@m-~yb4yOCZ10TQ{XiI;6+$ymi&M;pSIri5_GIp2r~QgJY|*x^KkD}+M< z3Q&Lo!~w^r8<-i^+P8J@{a(OY3n2tJ=bmb<wf!9cfH@~>t*2ZmMThWDZowl`N~iT0 y<9C4G`^%g$W<Mats6(g#1t>rP-+zoGf5>+`x*?%3r13NW0000<MNUMnLSTZ^%5|Cm literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/mekanism/textures/blocks/ctm/SteamBoiler-ctm.png b/src/main/resources/assets/mekanism/textures/blocks/ctm/SteamBoiler-ctm.png new file mode 100644 index 0000000000000000000000000000000000000000..352d7b87be1f849e32d16e9eb38968905ac8bfad GIT binary patch literal 1277 zcmaKs`#aMM9LK-Juri@sr&FnD93`nKx3$q+l2)X$lV@gl$YOFiVw{z=IkG}Wl3YSo zifk%7GP!3i6AqKxoMTSR9%h?y<nRylc|Y&Z=XqYw`~B;O=Ie7-8*Bmw06^OVjlyhR z*DY&;Ha9aodK>_@Er%nKz8*;AUf&oZAv`h!01^b5IlaVPAx7;k9BI!hEx5)-m5e5u zODf|`T@V9=i05?G`F0UTaie*8;`!0BnlB@ZPe+!_ouc`sFUYBMsAFEjv8L;~HeAFu zEd(+W?G4XaF-Pgyqz^QE$7_VODwcWDlxGsfnxiB;jVJP(i2q{1`?Z*vvoy5Q@;vtg zB0n?$c`||-H!1r3&%RWqgyR^qu<i|>6v%TW8`4*mo!s;Reb-up;abKiP<_N2Ol{hr zS`;=*Wh5HRVy5-88J((FnWYVYy?DV95?jglbioI5S*C*~_?fiAO4P@~d*(VoZ0>W5 z+~8}um~q(48P@dYJ7evE8@+aOb&q5xR3a#kA0WB@XtRhHX`WCr?sA4XH-k|>PgR1e zjWJ{vp)H1c0_|d71^L}=W%;FrNhwivZZDSfsfiCKe|lo#3>_@*<sH}Y!|_5+&puNt zq%L=-L!tEl!Upign#-wmm3)(XN;akGD?0kI2vtgk3;6@52Pq*%rYwbDZ47+r)zb%2 zm3oU2hU?YPq&@?u_ykMguJRpp^Dbqz?WvuE^s!=-%!t;%S)`z&ZM|zziIz);dYJwp z)@^}ROx$6iF4>D{Ju`4}fO!|mh4d*%2mIXn@nBkJd$Khwrz3c(H0)R=#Y>AuMNK^~ z#DhY22O87p(~y$;Ey22XDGlI5nD=JE`M8D-I(EO6oW8H-{Jd^*fY5%ie)tG@ztw8X zc-#$#V&Vl++!GP@D%u(b-AAtHu-T>Ym<I9iWuLLcqI%`M&=2z#4l1eyL5H~W`;l() zyW-|(Y(dhTK;R{XrhL6EyS7@Af^96D=rcT}xqdkralMboXl^aLk2j!Es0Yw+wEU*Z z9}JjH;}qX}a*uC;+$TOhYTl}1p+k`_(I&mE$nO6BaNRD+X)RnHDOXU-{}kr1vRH3e z680N5k@ZszODa$oYlutaW%3)sD*uTr`DnIRtkt4_0lURsI^!-?uMKhz{fLL$TH(nE zZybW6Y`4#}$vFpQ4;$d#lXVsKZ~gC>HaAaM>bbe@Hq4sV5t9RdK0*7%cBOA<K{v^5 zwCuuhusft{n6PZz(1tMoYcVv^7VQ44rq$B9`j#AK)}aO)5yh1=)ObZV^N>Qly~sps zwOQh7d+tTzouQsc`ED!G+G`fbDd}vM-z}_{gUsD1z!QY&?i4`UEDlx88YaIx14dVI z`aACuxgQ%{IfBk}b(0yuP~+Fm8{+f|mvj<G{3t(TLs>a+ey6uYV4PglO-Uhz|GPlw zxUH#h3Anl{;`R5h_qtw7l`b@10iqKIFTtWW-v9{bbruC|Y^kWBB72i)-9%p@0l;?s zEvo?e1xA}tBi7@bo5qBSruvRORAYA9CZc<w5SJ1J;?Wvy?omwup_iy{=q*Y+oOjT; zSzWO`$fsnP)T0#Q#>|o=R<(9^<3@WnTR)t<zR$c7z|THT$&69`VG_vWe_NQ#dM`_M b-Y?WRzXQVC_06+!tK#A2gL-`?=(qm?B7Rrq literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/mekanism/textures/blocks/ctm/SteamBoiler.png b/src/main/resources/assets/mekanism/textures/blocks/ctm/SteamBoiler.png new file mode 100644 index 0000000000000000000000000000000000000000..a341a84e96217d211c566d553836051dfd9433a1 GIT binary patch literal 1202 zcmV;j1Wo&iP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F8000B@X+uL$Nkc;* zP;zf(X>4Tx0C?Jsl+SMzWf;dlyYtSh2{;E+0gJ(jKY)-zwqTG3L3g{$wouDv+hW_8 znC<M_-Lccz@txW7BRz4^8>oMPiX1$ccrw9X5iY<%0|`MxY)DKvl=ve=5-x_+!%TMv zXvO#R%=3Pq@AvyW?~{Sd=T+Z#(-zEnp{kVf*7(GvmAOHhXIMiwYpQnO=gQ?FfU57i zJaX>+ObX!I_LcAd^Q@`Kz=qTlK(iLuvyeIlx@-F?1mhO4=V<7Mka-s9QsWbokjVmF z^(Za?T~kp!4s@x}N<U;=z_c6H8f4~yo~cB>o`@q40Cbh4CzWGcl~Ud+tLC)h%7op= zT>sBA>$aBlHUVpcnUO=lR!ALdsDVlxe_~gQBfyK0y6lJf3a}Ycf3#-Ca=<o7KQ*lm zj79kLt0x+xZvyKeU30?0(Kvs?n;JeG)uzwPG!Io`%w;?1p9G$V^v#AG9E$vC)MTLu z^nkXh(He;PwS&RjNO76xM5BK=;?dMQ)q`cA8?^UTvvN4{teuf=sS@#P7yYmtd(aj= zcX%k`6s8P{Bg^@)F**>{irt|ajcdi^v~yrE#?Sk1c_{KG&Z<^rEXG`|s$wbP5r0c> zEaucV)T)I;zz)#&b0k$o(qsyWjmLc~DwN1$;iG6Wje|=GiHAhtq@H93XBAu-iHhS6 zqK?F45ru=j3MNvx9b=key~v7PA}jWaA+b;F5q((VHSxOGFA5?n`o!LLZ8@QDQRjA> z=UrMzEGir!f4aN1wWD`Zz3tdnPThH+y7`D_x$Gx70Rm>)$nDAgFU^0qp~G=qoO|oq z+Dr2se%yTZTl%7YUB9K@&=)!g{a1ZKU(j!m!^NeJWEP2oha^ZiNcM06myjwhzv0nL z;2uz%_D*+qZtN?k?#TCs?+tUZr<2Y8lKnG#J^N|)Z1(quro7^mw2!o}wC}aAwQsZ^ zv9$Br1?>mzqV}csZQ`v~-;eg&lS_0f@m8F*#5MEgM)L);U_NKQWDa%s%=KokIbd!v z3+Bf5yCwCKy*NzZwx_zXR)ibF!{I0rML-o7kK+&Re_Sm#iC!`I(AMq|dqvx&Q8Wrh z4$IhP^clUzK_l1kXKXPFMxU|8C_b=t_9`971S;9*cBYU7%%E_XL*f!3LwPI&=x_SR zl~Zqo*3NA96)WfauCxX{dq<B|bzMt2^+p(2N(NHR$=VLaCnl}v7k#%v3P`QH(#eHy zz`nmgyV}W3w&05Z*1z1zZS97qKZbL=?UtI0|M{uZPY_J++8KSV&4Ye(Y3c4}$b1O* zKUiA&=giX5{m(#Kfb;IZSpac()l@2R00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru-vI~(3>a>D5VQaQ06$4YK~z}7?bksO05A*!LE4EI z)FC-qS{Z!q46t8Ll4o13W_N4jwslnw0000000000000000000ONoqdi570LVqUWc) Qk^lez07*qoM6N<$g1;z6MgRZ+ literal 0 HcmV?d00001