From 9ad76d3bccb202d4db8a9078212574e8a0e2c2b8 Mon Sep 17 00:00:00 2001 From: 70000hp <105080577+70000hp@users.noreply.github.com> Date: Sat, 2 Dec 2023 09:24:46 -0500 Subject: [PATCH] core strand caster stuffs --- .../blocks/machine/MachineStrandCaster.java | 189 +++++++++++++++++ .../container/ContainerStrandCaster.java | 74 +++++++ .../hbm/inventory/gui/GUIStrandCaster.java | 102 +++++++++ .../hbm/tileentity/TileEntityProxyCombo.java | 6 +- .../machine/TileEntityFoundryCastingBase.java | 3 +- .../TileEntityMachineStrandCaster.java | 195 ++++++++++++++++++ .../gui/processing/gui_strand_caster.png | Bin 0 -> 16344 bytes 7 files changed, 567 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/hbm/blocks/machine/MachineStrandCaster.java create mode 100644 src/main/java/com/hbm/inventory/container/ContainerStrandCaster.java create mode 100644 src/main/java/com/hbm/inventory/gui/GUIStrandCaster.java create mode 100644 src/main/java/com/hbm/tileentity/machine/TileEntityMachineStrandCaster.java create mode 100644 src/main/resources/assets/hbm/textures/gui/processing/gui_strand_caster.png diff --git a/src/main/java/com/hbm/blocks/machine/MachineStrandCaster.java b/src/main/java/com/hbm/blocks/machine/MachineStrandCaster.java new file mode 100644 index 000000000..7d45b7911 --- /dev/null +++ b/src/main/java/com/hbm/blocks/machine/MachineStrandCaster.java @@ -0,0 +1,189 @@ +package com.hbm.blocks.machine; + +import api.hbm.block.ICrucibleAcceptor; +import api.hbm.block.IToolable; +import com.hbm.blocks.BlockDummyable; +import com.hbm.blocks.ILookOverlay; +import com.hbm.handler.MultiblockHandlerXR; +import com.hbm.inventory.material.Mats; +import com.hbm.items.ModItems; +import com.hbm.items.machine.ItemMold; +import com.hbm.items.machine.ItemScraps; +import com.hbm.tileentity.TileEntityProxyCombo; +import com.hbm.tileentity.machine.TileEntityCrucible; +import com.hbm.tileentity.machine.TileEntityFoundryCastingBase; +import com.hbm.tileentity.machine.TileEntityMachineStrandCaster; +import com.hbm.util.I18nUtil; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.item.ItemTool; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.world.World; +import net.minecraftforge.client.event.RenderGameOverlayEvent; +import net.minecraftforge.common.util.ForgeDirection; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class MachineStrandCaster extends BlockDummyable implements ICrucibleAcceptor, ILookOverlay { + + public MachineStrandCaster() { + super(Material.iron); + } + //reminder, if the machine is a solid brick, get dimensions will already handle it without the need to use fillSapce + //the order is up, down, forward, backward, left, right + //x is for left(-)/right(+), z is for forward(+)/backward(-), y you already know + @Override + public int[] getDimensions() {return new int[]{0, 0, 6, 0, 1, 0};} + + @Override + public int getOffset() { + return 0; + } + + @Override + public TileEntity createNewTileEntity(World world, int meta) { + + if(meta >= 12) return new TileEntityMachineStrandCaster(); + if(meta >= 6) return new TileEntityProxyCombo(true, false, true).moltenMetal(); + return null; + } + + @Override + public void fillSpace(World world, int x, int y, int z, ForgeDirection dir, int o) { + super.fillSpace(world, x, y, z, dir, o); + + x += dir.offsetX * o; + z += dir.offsetZ * o; + + MultiblockHandlerXR.fillSpace(world, x, y, z, new int[]{1, 0, 1, 0, 1, 0}, this, dir); + + this.makeExtra(world, x - dir.offsetX, y, z); + this.makeExtra(world, x, y, z + dir.offsetX * 5); + this.makeExtra(world, x- dir.offsetX, y, z + dir.offsetX * 5); + } + + @Override + public boolean canAcceptPartialPour(World world, int x, int y, int z, double dX, double dY, double dZ, ForgeDirection side, Mats.MaterialStack stack) { + + TileEntity poured = world.getTileEntity(x, y, z); + if(!(poured instanceof TileEntityProxyCombo && ((TileEntityProxyCombo)poured).moltenMetal)) return false; + + int[] pos = this.findCore(world, x, y, z); + if(pos == null) return false; + TileEntity tile = world.getTileEntity(pos[0], pos[1], pos[2]); + if(!(tile instanceof TileEntityMachineStrandCaster)) return false; + TileEntityMachineStrandCaster caster = (TileEntityMachineStrandCaster) tile; + + return caster.canAcceptPartialPour(world, x, y, z, dX, dY, dZ, side, stack); + } + + @Override + public Mats.MaterialStack pour(World world, int x, int y, int z, double dX, double dY, double dZ, ForgeDirection side, Mats.MaterialStack stack) { + + TileEntity poured = world.getTileEntity(x, y, z); + if(!(poured instanceof TileEntityProxyCombo && ((TileEntityProxyCombo)poured).moltenMetal)) return stack; + + int[] pos = this.findCore(world, x, y, z); + if(pos == null) return stack; + TileEntity tile = world.getTileEntity(pos[0], pos[1], pos[2]); + if(!(tile instanceof TileEntityMachineStrandCaster)) return stack; + TileEntityMachineStrandCaster caster = (TileEntityMachineStrandCaster) tile; + + return caster.pour(world, x, y, z, dX, dY, dZ, side, stack); + } + + @Override + public boolean canAcceptPartialFlow(World world, int x, int y, int z, ForgeDirection side, Mats.MaterialStack stack) { + return false; + } + + @Override + public Mats.MaterialStack flow(World world, int x, int y, int z, ForgeDirection side, Mats.MaterialStack stack) { + return null; + } + ///entirety of foundry base code here, because dual inheritance is evil apparently + + @Override + public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) { + if(world.isRemote) { + return true; + } + + TileEntityFoundryCastingBase cast = (TileEntityFoundryCastingBase) world.getTileEntity(x, y, z); + + //insert mold + if(player.getHeldItem() != null && player.getHeldItem().getItem() == ModItems.mold && cast.slots[0] == null) { + cast.slots[0] = player.getHeldItem().copy(); + cast.slots[0].stackSize = 1; + player.getHeldItem().stackSize--; + world.playSoundEffect(x + 0.5, y + 0.5, z + 0.5, "hbm:item.upgradePlug", 1.0F, 1.0F); + cast.markDirty(); + world.markBlockForUpdate(x, y, z); + return true; + + } + + if(player.getHeldItem() != null && player.getHeldItem().getItem() instanceof ItemTool && player.getHeldItem().getItem().getToolClasses(player.getHeldItem()).contains("shovel")) { + if(cast.amount > 0) { + ItemStack scrap = ItemScraps.create(new Mats.MaterialStack(cast.type, cast.amount)); + if(!player.inventory.addItemStackToInventory(scrap)) { + EntityItem item = new EntityItem(world, x + 0.5, y + this.maxY, z + 0.5, scrap); + world.spawnEntityInWorld(item); + } else { + player.inventoryContainer.detectAndSendChanges(); + } + cast.amount = 0; + cast.type = null; + cast.markDirty(); + world.markBlockForUpdate(x, y, z); + } + return true; + } + + return this.standardOpenBehavior(world, x, y, z, player, 0); + } + + @Override + public void breakBlock(World world, int x, int y, int z, Block b, int i) { + + TileEntityFoundryCastingBase cast = (TileEntityFoundryCastingBase) world.getTileEntity(x, y, z); + if(cast.amount > 0) { + ItemStack scrap = ItemScraps.create(new Mats.MaterialStack(cast.type, cast.amount)); + EntityItem item = new EntityItem(world, x + 0.5, y + this.maxY, z + 0.5, scrap); + world.spawnEntityInWorld(item); + cast.amount = 0; //just for safety + } + + for(ItemStack stack : cast.slots) { + if(stack != null) { + EntityItem drop = new EntityItem(world, x + 0.5, y + this.maxY, z + 0.5, stack.copy()); + world.spawnEntityInWorld(drop); + } + } + + super.breakBlock(world, x, y, z, b, i); + } + + public void printHook(RenderGameOverlayEvent.Pre event, World world, int x, int y, int z) { + TileEntityFoundryCastingBase cast = (TileEntityFoundryCastingBase) world.getTileEntity(x, y, z); + List text = new ArrayList(); + + if(cast.slots[0] == null) { + text.add(EnumChatFormatting.RED + I18nUtil.resolveKey("foundry.noCast")); + } else if(cast.slots[0].getItem() == ModItems.mold){ + ItemMold.Mold mold = ((ItemMold) cast.slots[0].getItem()).getMold(cast.slots[0]); + text.add(EnumChatFormatting.BLUE + mold.getTitle()); + } + + ILookOverlay.printGeneric(event, I18nUtil.resolveKey(this.getUnlocalizedName() + ".name"), 0xFF4000, 0x401000, text); + } +} + diff --git a/src/main/java/com/hbm/inventory/container/ContainerStrandCaster.java b/src/main/java/com/hbm/inventory/container/ContainerStrandCaster.java new file mode 100644 index 000000000..f87f592d0 --- /dev/null +++ b/src/main/java/com/hbm/inventory/container/ContainerStrandCaster.java @@ -0,0 +1,74 @@ +package com.hbm.inventory.container; + +import com.hbm.inventory.SlotNonRetarded; +import com.hbm.tileentity.machine.TileEntityMachineStrandCaster; +import com.hbm.util.InventoryUtil; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; + +public class ContainerStrandCaster extends Container { + + protected TileEntityMachineStrandCaster caster; + + public ContainerStrandCaster(InventoryPlayer invPlayer, TileEntityMachineStrandCaster caster) { + this.caster = caster; + + //the wretched mold + this.addSlotToContainer(new SlotNonRetarded(this.caster, 0, 57, 62)); + + //input + for(int i = 0; i < 3; i++) { + for(int j = 0; j < 2; j++) { + this.addSlotToContainer(new SlotNonRetarded(this.caster, j + i * 3 + 1, 125 + j * 18, 26 + i * 18)); + } + } + + for(int i = 0; i < 3; i++) { + for(int j = 0; j < 9; j++) { + this.addSlotToContainer(new Slot(invPlayer, j + i * 9 + 9, 8 + j * 18, 132 + i * 18)); + } + } + + for(int i = 0; i < 9; i++) { + this.addSlotToContainer(new Slot(invPlayer, i, 8 + i * 18, 190)); + } + } + + @Override + public ItemStack transferStackInSlot(EntityPlayer player, int index) { + ItemStack stack = null; + Slot slot = (Slot) this.inventorySlots.get(index); + + if(slot != null && slot.getHasStack()) { + ItemStack originalStack = slot.getStack(); + stack = originalStack.copy(); + + if(index <= 6) { + if(!this.mergeItemStack(originalStack, 10, this.inventorySlots.size(), true)) { + return null; + } + + slot.onSlotChange(originalStack, stack); + + } else if(!InventoryUtil.mergeItemStack(this.inventorySlots, originalStack, 0, 10, false)) { + return null; + } + + if(originalStack.stackSize == 0) { + slot.putStack((ItemStack) null); + } else { + slot.onSlotChanged(); + } + } + + return stack; + } + + @Override + public boolean canInteractWith(EntityPlayer player) { + return caster.isUseableByPlayer(player); + } +} diff --git a/src/main/java/com/hbm/inventory/gui/GUIStrandCaster.java b/src/main/java/com/hbm/inventory/gui/GUIStrandCaster.java new file mode 100644 index 000000000..9d31e4b1f --- /dev/null +++ b/src/main/java/com/hbm/inventory/gui/GUIStrandCaster.java @@ -0,0 +1,102 @@ +package com.hbm.inventory.gui; + +import com.hbm.inventory.container.ContainerStrandCaster; +import com.hbm.inventory.material.Mats; +import com.hbm.inventory.material.Mats.MaterialStack; +import com.hbm.inventory.material.NTMMaterial; +import com.hbm.inventory.material.NTMMaterial.SmeltingBehavior; +import com.hbm.lib.RefStrings; +import com.hbm.tileentity.machine.TileEntityMachineStrandCaster; +import com.hbm.util.I18nUtil; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.input.Keyboard; +import org.lwjgl.opengl.GL11; + +import java.awt.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +public class GUIStrandCaster extends GuiInfoContainer { + + private static ResourceLocation texture = new ResourceLocation(RefStrings.MODID + ":textures/gui/processing/gui_strand_caster.png"); + private TileEntityMachineStrandCaster caster; + + public GUIStrandCaster(InventoryPlayer invPlayer, TileEntityMachineStrandCaster tedf) { + super(new ContainerStrandCaster(invPlayer, tedf)); + caster = tedf; + + this.xSize = 176; + this.ySize = 214; + } + + @Override + public void drawScreen(int x, int y, float interp) { + super.drawScreen(x, y, interp); + + drawStackInfo(x, y, 16, 17); + + caster.water.renderTankInfo(this, x, y, guiLeft + 82, guiTop + 38, 16, 24); + caster.steam.renderTankInfo(this, x, y, guiLeft + 82, guiTop + 89, 16, 24); + } + + @Override + protected void drawGuiContainerForegroundLayer(int i, int j) { + String name = this.caster.hasCustomInventoryName() ? this.caster.getInventoryName() : I18n.format(this.caster.getInventoryName()); + + this.fontRendererObj.drawString(name, this.xSize / 2 - this.fontRendererObj.getStringWidth(name) / 2, 6, 0xffffff); + this.fontRendererObj.drawString(I18n.format("container.inventory"), 8, this.ySize - 96 + 2, 4210752); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_) { + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + Minecraft.getMinecraft().getTextureManager().bindTexture(texture); + drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize); + + caster.water.renderTank(guiLeft + 82, guiTop + 38, this.zLevel, 16, 24); + caster.steam.renderTank(guiLeft + 82, guiTop + 89, this.zLevel, 16, 24); + + if (caster.amount != 0) { + + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE); + + int targetHeight = (caster.amount) * 79 / caster.getCapacity(); + int offset = caster.type.smeltable == SmeltingBehavior.ADDITIVE ? 34 : 0; //additives use a differnt texture + + int hex = caster.type.moltenColor; + //hex = 0xC18336; + Color color = new Color(hex); + GL11.glColor3f(color.getRed() / 255F, color.getGreen() / 255F, color.getBlue() / 255F); + drawTexturedModalRect(guiLeft + 17, guiTop + 92 - targetHeight, 176 + offset, 89 - targetHeight, 34, targetHeight); + GL11.glEnable(GL11.GL_BLEND); + GL11.glColor4f(1F, 1F, 1F, 0.3F); + drawTexturedModalRect(guiLeft + 17, guiTop + 92 - targetHeight, 176 + offset, 89 - targetHeight, 34, targetHeight); + GL11.glDisable(GL11.GL_BLEND); + } + + OpenGlHelper.glBlendFunc(770, 771, 1, 0); + GL11.glColor3f(255, 255, 255); + } + + + + protected void drawStackInfo(int mouseX, int mouseY, int x, int y) { + + List list = new ArrayList(); + + if(caster.type == null) list.add(EnumChatFormatting.RED + "Empty"); + else list.add(EnumChatFormatting.YELLOW + I18nUtil.resolveKey(caster.type.getUnlocalizedName()) + ": " + Mats.formatAmount(caster.amount, Keyboard.isKeyDown(Keyboard.KEY_LSHIFT))); + + this.drawCustomInfoStat(mouseX, mouseY, guiLeft + x, guiTop + y, 36, 81, mouseX, mouseY, list); + } + + + + +} diff --git a/src/main/java/com/hbm/tileentity/TileEntityProxyCombo.java b/src/main/java/com/hbm/tileentity/TileEntityProxyCombo.java index eb4a603e0..593a33505 100644 --- a/src/main/java/com/hbm/tileentity/TileEntityProxyCombo.java +++ b/src/main/java/com/hbm/tileentity/TileEntityProxyCombo.java @@ -23,6 +23,7 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy boolean power; boolean fluid; boolean heat; + public boolean moltenMetal; public TileEntityProxyCombo() { } @@ -41,7 +42,10 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy this.power = true; return this; } - + public TileEntityProxyCombo moltenMetal() { + this.moltenMetal = true; + return this; + } public TileEntityProxyCombo fluid() { this.fluid = true; return this; diff --git a/src/main/java/com/hbm/tileentity/machine/TileEntityFoundryCastingBase.java b/src/main/java/com/hbm/tileentity/machine/TileEntityFoundryCastingBase.java index bf2e63a95..fd3916492 100644 --- a/src/main/java/com/hbm/tileentity/machine/TileEntityFoundryCastingBase.java +++ b/src/main/java/com/hbm/tileentity/machine/TileEntityFoundryCastingBase.java @@ -22,7 +22,8 @@ public abstract class TileEntityFoundryCastingBase extends TileEntityFoundryBase public ItemStack slots[] = new ItemStack[2]; public int cooloff = 100; - + + @Override public void updateEntity() { super.updateEntity(); diff --git a/src/main/java/com/hbm/tileentity/machine/TileEntityMachineStrandCaster.java b/src/main/java/com/hbm/tileentity/machine/TileEntityMachineStrandCaster.java new file mode 100644 index 000000000..cf09975e3 --- /dev/null +++ b/src/main/java/com/hbm/tileentity/machine/TileEntityMachineStrandCaster.java @@ -0,0 +1,195 @@ +package com.hbm.tileentity.machine; + +import api.hbm.block.ICrucibleAcceptor; +import api.hbm.fluid.IFluidStandardTransceiver; +import com.hbm.blocks.BlockDummyable; +import com.hbm.inventory.container.ContainerAssemfac; +import com.hbm.inventory.container.ContainerStrandCaster; +import com.hbm.inventory.fluid.Fluids; +import com.hbm.inventory.fluid.tank.FluidTank; +import com.hbm.inventory.gui.GUIAssemfac; +import com.hbm.inventory.gui.GUIStrandCaster; +import com.hbm.items.ModItems; +import com.hbm.items.machine.ItemMold; +import com.hbm.packet.NBTPacket; +import com.hbm.packet.PacketDispatcher; +import com.hbm.tileentity.IGUIProvider; +import com.hbm.tileentity.INBTPacketReceiver; +import com.hbm.util.fauxpointtwelve.DirPos; +import cpw.mods.fml.common.network.NetworkRegistry; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +//god thank you bob for this base class +public class TileEntityMachineStrandCaster extends TileEntityFoundryCastingBase implements IGUIProvider, ICrucibleAcceptor,ISidedInventory, IFluidStandardTransceiver, INBTPacketReceiver { + public FluidTank water; + public FluidTank steam; + + public ItemStack[] slots = new ItemStack[6]; + + public TileEntityMachineStrandCaster() { + + water = new FluidTank(Fluids.WATER, 64_000); + steam = new FluidTank(Fluids.SPENTSTEAM, 64_000); + } + int cooldown = 10; + @Override + public void updateEntity() { + super.updateEntity(); + + if(!worldObj.isRemote) { + + if(this.amount > this.getCapacity()) { + this.amount = this.getCapacity(); + } + + if(this.amount == 0) { + this.type = null; + } + + if(worldObj.getTotalWorldTime() % 20 == 0) { + this.updateConnections(); + } + + for(DirPos pos : getConPos()) { + this.sendFluid(steam, worldObj, pos.getX(), pos.getY(), pos.getZ(), pos.getDir()); + } + + ItemMold.Mold mold = this.getInstalledMold(); + + if(mold != null && this.amount >= this.getCapacity() && slots[1] == null && water.getFill() >= getWaterRequired() ) { + cooldown--; + + if(cooldown <= 0) { + this.amount -= mold.getCost(); + + ItemStack out = mold.getOutput(type); + + for(int i = 1; i < 7; i++) { + if(slots[i].isItemEqual(out) && slots[i].stackSize + out.stackSize <= out.getMaxStackSize()) { + continue; + } + + if(slots[i] == null) { + slots[i] = out.copy(); + } else { + slots[i].stackSize += out.stackSize; + } + } + } + + water.setFill(water.getFill() - getWaterRequired()); + steam.setFill(steam.getFill() + getWaterRequired()); + + cooldown = 20; + } + NBTTagCompound data = new NBTTagCompound(); + + water.writeToNBT(data, "w"); + steam.writeToNBT(data, "s"); + + this.networkPack(data, 150); + + } else { + cooldown = 20; + } + } + + + public DirPos[] getConPos() { + + ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata() - BlockDummyable.offset); + ForgeDirection rot = dir.getRotation(ForgeDirection.UP); + + return new DirPos[] { + new DirPos(xCoord - dir.offsetX, yCoord, zCoord, rot), + new DirPos(xCoord, yCoord, zCoord + dir.offsetX, rot), + new DirPos(xCoord, yCoord, zCoord + dir.offsetX * 5, rot.getOpposite()), + new DirPos(xCoord- dir.offsetX, yCoord, zCoord + dir.offsetX * 5, rot.getOpposite()), + }; + } + @Override + public int getMoldSize() { + return getInstalledMold().size; + } + + @Override + public int getCapacity() { + ItemMold.Mold mold = this.getInstalledMold(); + return mold == null ? 0 : mold.getCost() * 10; + } + private int getWaterRequired() { + return getInstalledMold() != null ? 5 * getInstalledMold().getCost() : 10; + } + private void updateConnections() { + for(DirPos pos : getConPos()) { + this.trySubscribe(water.getTankType(), worldObj, pos.getX(), pos.getY(), pos.getZ(), pos.getDir()); + } + } + + @Override + public FluidTank[] getSendingTanks() { + return new FluidTank[] { steam }; + } + + @Override + public FluidTank[] getReceivingTanks() { + return new FluidTank[] { water }; + } + + @Override + public FluidTank[] getAllTanks() { + return new FluidTank[] { water, steam }; + } + + @Override + public Container provideContainer(int ID, EntityPlayer player, World world, int x, int y, int z) { + return new ContainerStrandCaster(player.inventory, this); + } + + @Override + @SideOnly(Side.CLIENT) + public GuiScreen provideGUI(int ID, EntityPlayer player, World world, int x, int y, int z) { + return new GUIStrandCaster(player.inventory, this); + } + public void networkPack(NBTTagCompound nbt, int range) { + + if(!worldObj.isRemote) + PacketDispatcher.wrapper.sendToAllAround(new NBTPacket(nbt, xCoord, yCoord, zCoord), new NetworkRegistry.TargetPoint(this.worldObj.provider.dimensionId, xCoord, yCoord, zCoord, range)); + } + @Override + public void networkUnpack(NBTTagCompound nbt) { + water.readFromNBT(nbt, "w"); + steam.readFromNBT(nbt, "s"); + } + @Override + public boolean isItemValidForSlot(int i, ItemStack stack) { + + if(i == 0) { + return stack.getItem() == ModItems.mold; + } + + return false; + } + + @Override + @SideOnly(Side.CLIENT) + public double getMaxRenderDistanceSquared() { + return 65536.0D; + } + + @Override + public int[] getAccessibleSlotsFromSide(int meta) { + return new int[] { 1, 2, 3, 4, 5, 6}; + } + +} diff --git a/src/main/resources/assets/hbm/textures/gui/processing/gui_strand_caster.png b/src/main/resources/assets/hbm/textures/gui/processing/gui_strand_caster.png new file mode 100644 index 0000000000000000000000000000000000000000..9f3253374240386f1091cfcace39043063e5c338 GIT binary patch literal 16344 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