diff --git a/src/main/java/api/hbm/block/ICrucibleAcceptor.java b/src/main/java/api/hbm/block/ICrucibleAcceptor.java new file mode 100644 index 000000000..3d7724972 --- /dev/null +++ b/src/main/java/api/hbm/block/ICrucibleAcceptor.java @@ -0,0 +1,25 @@ +package api.hbm.block; + +import com.hbm.inventory.material.Mats.MaterialStack; + +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +public interface ICrucibleAcceptor { + + /* + * Pouring: The metal leaves the channel/crucible and usually (but not always) falls down. The additional double coords give a more precise impact location. + * Also useful for entities like large crucibles since they are filled from the top. + */ + public boolean canAcceptPour(World world, int x, int y, int z, double dX, double dY, double dZ, ForgeDirection side, MaterialStack stack); + public MaterialStack canAcceptPartialPour(World world, int x, int y, int z, double dX, double dY, double dZ, ForgeDirection side, MaterialStack stack); + public void pour(World world, int x, int y, int z, double dX, double dY, double dZ, ForgeDirection side, MaterialStack stack); + + /* + * Flowing: The "safe" transfer of metal using a channel or other means, usually from block to block and usually horizontally (but not necessarily). + * May also be used for entities like minecarts that could be loaded from the side. + */ + public boolean canAcceptFlow(World world, int x, int y, int z, ForgeDirection side, MaterialStack stack); + public MaterialStack canAcceptPartialFlow(World world, int x, int y, int z, ForgeDirection side, MaterialStack stack); + public void flow(World world, int x, int y, int z, ForgeDirection side, MaterialStack stack); +} diff --git a/src/main/java/com/hbm/inventory/container/ContainerCrucible.java b/src/main/java/com/hbm/inventory/container/ContainerCrucible.java index 3f9fb375f..7d7074a47 100644 --- a/src/main/java/com/hbm/inventory/container/ContainerCrucible.java +++ b/src/main/java/com/hbm/inventory/container/ContainerCrucible.java @@ -1,6 +1,7 @@ package com.hbm.inventory.container; import com.hbm.tileentity.machine.TileEntityCrucible; +import com.hbm.util.InventoryUtil; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; @@ -15,16 +16,16 @@ public class ContainerCrucible extends Container { public ContainerCrucible(InventoryPlayer invPlayer, TileEntityCrucible crucible) { this.crucible = crucible; + //template + this.addSlotToContainer(new Slot(crucible, 0, 107, 81)); + //input for(int i = 0; i < 3; i++) { for(int j = 0; j < 3; j++) { - this.addSlotToContainer(new Slot(crucible, j + i * 3, 107 + j * 18, 18 + i * 18)); + this.addSlotToContainer(new Slot(crucible, j + i * 3 + 1, 107 + j * 18, 18 + i * 18)); } } - //template - this.addSlotToContainer(new Slot(crucible, 9, 107, 81)); - 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)); @@ -52,7 +53,7 @@ public class ContainerCrucible extends Container { slot.onSlotChange(originalStack, stack); - } else if(!this.mergeItemStack(originalStack, 0, 10, false)) { + } else if(!InventoryUtil.mergeItemStack(this.inventorySlots, originalStack, 0, 10, false)) { return null; } diff --git a/src/main/java/com/hbm/inventory/gui/GUICrucible.java b/src/main/java/com/hbm/inventory/gui/GUICrucible.java index a41d3c199..959394c0e 100644 --- a/src/main/java/com/hbm/inventory/gui/GUICrucible.java +++ b/src/main/java/com/hbm/inventory/gui/GUICrucible.java @@ -1,17 +1,22 @@ package com.hbm.inventory.gui; +import java.awt.Color; +import java.util.ArrayList; import java.util.List; import org.lwjgl.opengl.GL11; import com.hbm.inventory.container.ContainerCrucible; +import com.hbm.inventory.material.Mats; import com.hbm.inventory.material.Mats.MaterialStack; +import com.hbm.inventory.material.NTMMaterial.SmeltingBehavior; import com.hbm.lib.RefStrings; import com.hbm.tileentity.machine.TileEntityCrucible; import net.minecraft.client.Minecraft; import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.ResourceLocation; public class GUICrucible extends GuiInfoContainer { @@ -30,6 +35,12 @@ public class GUICrucible extends GuiInfoContainer { @Override public void drawScreen(int x, int y, float interp) { super.drawScreen(x, y, interp); + + drawStackInfo(crucible.wasteStack, x, y, 16, 17); + drawStackInfo(crucible.recipeStack, x, y, 61, 17); + + this.drawCustomInfoStat(x, y, guiLeft + 125, guiTop + 81, 34, 7, x, y, new String[] { String.format("%,d", crucible.progress) + " / " + String.format("%,d", crucible.processTime) + "TU" }); + this.drawCustomInfoStat(x, y, guiLeft + 125, guiTop + 90, 34, 7, x, y, new String[] { String.format("%,d", crucible.heat) + " / " + String.format("%,d", crucible.maxHeat) + "TU" }); } @Override @@ -51,11 +62,47 @@ public class GUICrucible extends GuiInfoContainer { int hGauge = crucible.heat * 33 / crucible.maxHeat; if(hGauge > 0) drawTexturedModalRect(guiLeft + 126, guiTop + 91, 176, 5, hGauge, 5); - if(!crucible.recipeStack.isEmpty()) drawStack(crucible.recipeStack, 62, 97); - if(!crucible.wasteStack.isEmpty()) drawStack(crucible.wasteStack, 17, 97); + if(!crucible.recipeStack.isEmpty()) drawStack(crucible.recipeStack, crucible.recipeCapacity, 62, 97); + if(!crucible.wasteStack.isEmpty()) drawStack(crucible.wasteStack, crucible.wasteCapacity, 17, 97); } - protected void drawStack(List stack, int x, int y) { + protected void drawStackInfo(List stack, int mouseX, int mouseY, int x, int y) { + List list = new ArrayList(); + + if(stack.isEmpty()) + list.add(EnumChatFormatting.RED + "Empty"); + + for(MaterialStack sta : stack) { + list.add(EnumChatFormatting.YELLOW + sta.material.names[0] + ": " + Mats.formatAmount(sta.amount)); + } + + this.drawCustomInfoStat(mouseX, mouseY, guiLeft + x, guiTop + y, 36, 81, mouseX, mouseY, list); + } + + protected void drawStack(List stack, int capacity, int x, int y) { + + if(stack.isEmpty()) return; + + int lastHeight = 0; + int lastQuant = 0; + + for(MaterialStack sta : stack) { + + int targetHeight = (lastQuant + sta.amount) * 79 / capacity; + + if(lastHeight == targetHeight) continue; //skip draw calls that would be 0 pixels high + + int offset = sta.material.smeltable == SmeltingBehavior.ADDITIVE ? 34 : 0; //additives use a differnt texture + + Color color = new Color(sta.material.moltenColor); + GL11.glColor3f(color.getRed() / 255F, color.getGreen() / 255F, color.getBlue() / 255F); + drawTexturedModalRect(guiLeft + x, guiTop + y - targetHeight, 176 + offset, 89 - targetHeight, 34, targetHeight - lastHeight); + + lastQuant += sta.amount; + lastHeight = targetHeight; + } + + GL11.glColor3f(255, 255, 255); } } diff --git a/src/main/java/com/hbm/inventory/gui/GUICrystallizer.java b/src/main/java/com/hbm/inventory/gui/GUICrystallizer.java index 6f1a1d418..e9b03cea8 100644 --- a/src/main/java/com/hbm/inventory/gui/GUICrystallizer.java +++ b/src/main/java/com/hbm/inventory/gui/GUICrystallizer.java @@ -3,7 +3,6 @@ package com.hbm.inventory.gui; import org.lwjgl.opengl.GL11; import com.hbm.inventory.container.ContainerCrystallizer; -import com.hbm.inventory.fluid.tank.FluidTank; import com.hbm.lib.RefStrings; import com.hbm.tileentity.machine.TileEntityMachineCrystallizer; import com.hbm.util.I18nUtil; diff --git a/src/main/java/com/hbm/inventory/gui/GUIFurnaceSteel.java b/src/main/java/com/hbm/inventory/gui/GUIFurnaceSteel.java index cad0be5e6..a7dcb6eb8 100644 --- a/src/main/java/com/hbm/inventory/gui/GUIFurnaceSteel.java +++ b/src/main/java/com/hbm/inventory/gui/GUIFurnaceSteel.java @@ -32,7 +32,6 @@ public class GUIFurnaceSteel extends GuiInfoContainer { this.drawCustomInfoStat(x, y, guiLeft + 53, guiTop + 17 + 18 * i, 70, 7, x, y, new String[] { String.format("%,d", furnace.progress[i]) + " / " + String.format("%,d", furnace.processTime) + "TU" }); this.drawCustomInfoStat(x, y, guiLeft + 53, guiTop + 26 + 18 * i, 70, 7, x, y, new String[] { "Bonus: " + furnace.bonus[i] + "%" }); } - //this.drawCustomInfoStat(x, y, guiLeft + 52, guiTop + 44, 71, 7, x, y, new String[] { (furnace.burnTime / 20) + "s" }); this.drawCustomInfoStat(x, y, guiLeft + 151, guiTop + 18, 9, 50, x, y, new String[] { String.format("%,d", furnace.heat) + " / " + String.format("%,d", furnace.maxHeat) + "TU" }); } diff --git a/src/main/java/com/hbm/tileentity/machine/TileEntityCrucible.java b/src/main/java/com/hbm/tileentity/machine/TileEntityCrucible.java index fd5ce804d..d16a8a914 100644 --- a/src/main/java/com/hbm/tileentity/machine/TileEntityCrucible.java +++ b/src/main/java/com/hbm/tileentity/machine/TileEntityCrucible.java @@ -19,6 +19,7 @@ import api.hbm.tile.IHeatSource; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.client.gui.GuiScreen; +import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.Container; import net.minecraft.item.ItemStack; @@ -60,6 +61,31 @@ public class TileEntityCrucible extends TileEntityMachineBase implements IGUIPro if(!worldObj.isRemote) { tryPullHeat(); + if(worldObj.getTotalWorldTime() % 5 == 0) { + List list = worldObj.getEntitiesWithinAABB(EntityItem.class, AxisAlignedBB.getBoundingBox(xCoord - 0.5, yCoord + 0.5, zCoord - 0.5, xCoord + 1.5, yCoord + 1, zCoord + 1.5)); + + for(EntityItem item : list) { + ItemStack stack = item.getEntityItem(); + if(this.isItemSmeltable(stack)) { + + for(int i = 1; i < 10; i++) { + if(slots[i] == null) { + + if(stack.stackSize == 1) { + slots[i] = stack.copy(); + } else { + slots[i] = stack.copy(); + slots[i].stackSize = 1; + stack.stackSize--; + } + + this.markChanged(); + } + } + } + } + } + if(!trySmelt()) { this.progress = 0; } @@ -90,7 +116,7 @@ public class TileEntityCrucible extends TileEntityMachineBase implements IGUIPro int[] was = nbt.getIntArray("was"); for(int i = 0; i < was.length / 2; i++) { - recipeStack.add(new MaterialStack(Mats.matById.get(was[i * 2]), was[i * 2 + 1])); + wasteStack.add(new MaterialStack(Mats.matById.get(was[i * 2]), was[i * 2 + 1])); } this.progress = nbt.getInteger("progress"); diff --git a/src/main/java/com/hbm/tileentity/machine/TileEntityFoundryBase.java b/src/main/java/com/hbm/tileentity/machine/TileEntityFoundryBase.java new file mode 100644 index 000000000..5b4aa28ae --- /dev/null +++ b/src/main/java/com/hbm/tileentity/machine/TileEntityFoundryBase.java @@ -0,0 +1,70 @@ +package com.hbm.tileentity.machine; + +import com.hbm.inventory.material.Mats; +import com.hbm.inventory.material.NTMMaterial; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.Packet; +import net.minecraft.network.play.server.S35PacketUpdateTileEntity; +import net.minecraft.tileentity.TileEntity; + +/** + * Base class for all foundry channel type blocks - channels, casts, basins, tanks, etc. + * Foundry type blocks can only hold one type at a time and usually either store or move it around. + * @author hbm + * + */ +public abstract class TileEntityFoundryBase extends TileEntity { + + public NTMMaterial type; + protected NTMMaterial lastType; + public int amount; + protected int lastAmount; + + @Override + public void updateEntity() { + + if(worldObj.isRemote) { + + if(this.lastType != this.type || this.lastAmount != this.amount) { + worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); + this.lastType = this.type; + this.lastAmount = this.amount; + } + } + } + + @Override + public Packet getDescriptionPacket() { + NBTTagCompound nbt = new NBTTagCompound(); + this.writeToNBT(nbt); + return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, 0, nbt); + } + + @Override + public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { + this.readFromNBT(pkt.func_148857_g()); + } + + @Override + public void readFromNBT(NBTTagCompound nbt) { + super.readFromNBT(nbt); + this.type = Mats.matById.get(nbt.getInteger("type")); + this.amount = nbt.getInteger("amount"); + } + + @Override + public void writeToNBT(NBTTagCompound nbt) { + super.writeToNBT(nbt); + + if(this.type == null) + nbt.setInteger("type", -1); + else + nbt.setInteger("type", this.type.id); + + nbt.setInteger("amount", this.amount); + } + + public abstract int getCapacity(); +} diff --git a/src/main/java/com/hbm/util/InventoryUtil.java b/src/main/java/com/hbm/util/InventoryUtil.java index 8132c728a..492ce36f2 100644 --- a/src/main/java/com/hbm/util/InventoryUtil.java +++ b/src/main/java/com/hbm/util/InventoryUtil.java @@ -448,6 +448,15 @@ public class InventoryUtil { return true; } + /** + * A fixed re-implementation of the original Container.mergeItemStack that repects stack size and slot restrictions. + * @param slots + * @param stack + * @param start + * @param end + * @param reverse + * @return + */ public static boolean mergeItemStack(List slots, ItemStack stack, int start, int end, boolean reverse) { boolean success = false; diff --git a/src/main/resources/assets/hbm/textures/gui/processing/gui_crystallizer_alt.png b/src/main/resources/assets/hbm/textures/gui/processing/gui_crystallizer_alt.png index a427d1652..ae0884951 100644 Binary files a/src/main/resources/assets/hbm/textures/gui/processing/gui_crystallizer_alt.png and b/src/main/resources/assets/hbm/textures/gui/processing/gui_crystallizer_alt.png differ