diff --git a/src/main/java/tconstruct/smeltery/SmelteryProxyClient.java b/src/main/java/tconstruct/smeltery/SmelteryProxyClient.java index d84e22abb4c..de2f33ddd98 100644 --- a/src/main/java/tconstruct/smeltery/SmelteryProxyClient.java +++ b/src/main/java/tconstruct/smeltery/SmelteryProxyClient.java @@ -117,6 +117,8 @@ public Object getClientGuiElement (int ID, EntityPlayer player, World world, int { if (PHConstruct.newSmeltery) return new AdaptiveSmelteryGui(player.inventory, (AdaptiveSmelteryLogic) world.getTileEntity(x, y, z), world, x, y, z); + else if(PHConstruct.oldSmeltery) + return new SmelteryGuiOld(player.inventory, (SmelteryLogicOld) world.getTileEntity(x, y, z), world, x, y, z); else return new SmelteryGui(player.inventory, (SmelteryLogic) world.getTileEntity(x, y, z), world, x, y, z); } diff --git a/src/main/java/tconstruct/smeltery/TinkerSmeltery.java b/src/main/java/tconstruct/smeltery/TinkerSmeltery.java index 392364bf98b..3a88fa07d90 100644 --- a/src/main/java/tconstruct/smeltery/TinkerSmeltery.java +++ b/src/main/java/tconstruct/smeltery/TinkerSmeltery.java @@ -707,8 +707,8 @@ public void preInit (FMLPreInitializationEvent event) } else { - if(PHConstruct.newerSmeltery) - GameRegistry.registerTileEntity(FlexibleSmelteryLogic.class, "TConstruct.Smeltery"); + if(PHConstruct.oldSmeltery) + GameRegistry.registerTileEntity(SmelteryLogicOld.class, "TConstruct.Smeltery"); else GameRegistry.registerTileEntity(SmelteryLogic.class, "TConstruct.Smeltery"); GameRegistry.registerTileEntity(SmelteryDrainLogic.class, "TConstruct.SmelteryDrain"); diff --git a/src/main/java/tconstruct/smeltery/blocks/SmelteryBlock.java b/src/main/java/tconstruct/smeltery/blocks/SmelteryBlock.java index 5be6aaac1b7..4d39ef70f3d 100644 --- a/src/main/java/tconstruct/smeltery/blocks/SmelteryBlock.java +++ b/src/main/java/tconstruct/smeltery/blocks/SmelteryBlock.java @@ -238,9 +238,9 @@ public TileEntity createNewTileEntity (World world, int metadata) { case 0: if (PHConstruct.newSmeltery) - return new FlexibleSmelteryLogic(); - else if(PHConstruct.newerSmeltery) - return new FlexibleSmelteryLogic(); + return new AdaptiveSmelteryLogic(); + else if(PHConstruct.oldSmeltery) + return new SmelteryLogicOld(); else return new SmelteryLogic(); diff --git a/src/main/java/tconstruct/smeltery/gui/SmelteryGuiOld.java b/src/main/java/tconstruct/smeltery/gui/SmelteryGuiOld.java new file mode 100644 index 00000000000..d4433eb42a5 --- /dev/null +++ b/src/main/java/tconstruct/smeltery/gui/SmelteryGuiOld.java @@ -0,0 +1,489 @@ +package tconstruct.smeltery.gui; + +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IIcon; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.StatCollector; +import net.minecraft.world.World; +import net.minecraftforge.fluids.FluidStack; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; +import tconstruct.TConstruct; +import tconstruct.client.gui.NewContainerGui; +import tconstruct.smeltery.inventory.ActiveContainer; +import tconstruct.smeltery.inventory.SmelteryContainer; +import tconstruct.smeltery.logic.SmelteryLogicOld; +import tconstruct.util.network.SmelteryPacket; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class SmelteryGuiOld extends NewContainerGui +{ + public SmelteryLogicOld logic; + String username; + boolean isScrolling = false; + boolean wasClicking; + float currentScroll = 0.0F; + int slotPos = 0; + int prevSlotPos = 0; + + public SmelteryGuiOld(InventoryPlayer inventoryplayer, SmelteryLogicOld smeltery, World world, int x, int y, int z) + { + super((ActiveContainer) smeltery.getGuiContainer(inventoryplayer, world, x, y, z)); + logic = smeltery; + username = inventoryplayer.player.getDisplayName(); + xSize = 248; + smeltery.updateFuelDisplay(); + } + + @Override + public void initGui () + { + super.initGui(); + + if (logic != null) + logic.updateFuelGague(); + } + + @Override + public void drawScreen (int mouseX, int mouseY, float par3) + { + super.drawScreen(mouseX, mouseY, par3); + updateScrollbar(mouseX, mouseY, par3); + } + + protected void updateScrollbar (int mouseX, int mouseY, float par3) + { + if (logic.layers > 2) + { + boolean mouseDown = Mouse.isButtonDown(0); + int lefto = this.guiLeft; + int topo = this.guiTop; + int xScroll = lefto + 67; + int yScroll = topo + 8; + int scrollWidth = xScroll + 14; + int scrollHeight = yScroll + 144; + + if (!this.wasClicking && mouseDown && mouseX >= xScroll && mouseY >= yScroll && mouseX < scrollWidth && mouseY < scrollHeight) + { + this.isScrolling = true; + } + + if (!mouseDown) + { + this.isScrolling = false; + } + + if (wasClicking && !isScrolling && slotPos != prevSlotPos) + { + prevSlotPos = slotPos; + } + + this.wasClicking = mouseDown; + + if (this.isScrolling) + { + this.currentScroll = (mouseY - yScroll - 7.5F) / (scrollHeight - yScroll - 15.0F); + + if (this.currentScroll < 0.0F) + { + this.currentScroll = 0.0F; + } + + if (this.currentScroll > 1.0F) + { + this.currentScroll = 1.0F; + } + + int s = ((SmelteryContainer) this.container).scrollTo(this.currentScroll); + if (s != -1) + slotPos = s; + } + } + } + + @Override + protected void drawGuiContainerForegroundLayer (int mouseX, int mouseY) + { + fontRendererObj.drawString(StatCollector.translateToLocal("crafters.Smeltery"), 86, 5, 0x404040); + fontRendererObj.drawString(StatCollector.translateToLocal("container.inventory"), 90, (ySize - 96) + 2, 0x404040); + + int base = 0; + int cornerX = (width - xSize) / 2 + 36; + int cornerY = (height - ySize) / 2; + + for (FluidStack liquid : logic.moltenMetal) + { + int basePos = 54; + int initialLiquidSize = 0; + int liquidSize = 0;// liquid.amount * 52 / liquidLayers; + if (logic.getCapacity() > 0) + { + int total = logic.getTotalLiquid(); + int liquidLayers = (total / 20000 + 1) * 20000; + if (liquidLayers > 0) + { + liquidSize = liquid.amount * 52 / liquidLayers; + if (liquidSize == 0) + liquidSize = 1; + base += liquidSize; + } + } + + int leftX = cornerX + basePos; + int topY = (cornerY + 68) - base; + int sizeX = 52; + int sizeY = liquidSize; + if (mouseX >= leftX && mouseX <= leftX + sizeX && mouseY >= topY && mouseY < topY + sizeY) + { + drawFluidStackTooltip(liquid, mouseX - cornerX + 36, mouseY - cornerY); + + } + } + if (logic.fuelGague > 0) + { + int leftX = cornerX + 117; + int topY = (cornerY + 68) - logic.getScaledFuelGague(52); + int sizeX = 12; + int sizeY = logic.getScaledFuelGague(52); + if (mouseX >= leftX && mouseX <= leftX + sizeX && mouseY >= topY && mouseY < topY + sizeY) + { + drawFluidStackTooltip(new FluidStack(-37, logic.fuelAmount), mouseX - cornerX + 36, mouseY - cornerY); + } + } + } + + private static final ResourceLocation background = new ResourceLocation("tinker", "textures/gui/smeltery.png"); + private static final ResourceLocation backgroundSide = new ResourceLocation("tinker", "textures/gui/smelteryside.png"); + private static final ResourceLocation terrain = new ResourceLocation("terrain.png"); + + @Override + protected void drawGuiContainerBackgroundLayer (float f, int mouseX, int mouseY) + { + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + this.mc.getTextureManager().bindTexture(background); + int cornerX = (width - xSize) / 2 + 36; + int cornerY = (height - ySize) / 2; + drawTexturedModalRect(cornerX + 46, cornerY, 0, 0, 176, ySize); + + // Fuel - Lava + this.mc.getTextureManager().bindTexture(TextureMap.locationBlocksTexture); + if (logic.fuelGague > 0) + { + IIcon lavaIcon = logic.getFuelIcon(); + int fuel = logic.getScaledFuelGague(52); + int count = 0; + while (fuel > 0) + { + int size = fuel >= 16 ? 16 : fuel; + fuel -= size; + drawLiquidRect(cornerX + 117, (cornerY + 68) - size - 16 * count, lavaIcon, 12, size); + count++; + } + } + + // Liquids - molten metal + int base = 0; + for (FluidStack liquid : logic.moltenMetal) + { + IIcon renderIndex = liquid.getFluid().getStillIcon(); + int basePos = 54; + if (logic.getCapacity() > 0) + { + int total = logic.getTotalLiquid(); + int liquidLayers = (total / 20000 + 1) * 20000; + if (liquidLayers > 0) + { + int liquidSize = liquid.amount * 52 / liquidLayers; + if (liquidSize == 0) + liquidSize = 1; + while (liquidSize > 0) + { + int size = liquidSize >= 16 ? 16 : liquidSize; + if (renderIndex != null) + { + drawLiquidRect(cornerX + basePos, (cornerY + 68) - size - base, renderIndex, 16, size); + drawLiquidRect(cornerX + basePos + 16, (cornerY + 68) - size - base, renderIndex, 16, size); + drawLiquidRect(cornerX + basePos + 32, (cornerY + 68) - size - base, renderIndex, 16, size); + drawLiquidRect(cornerX + basePos + 48, (cornerY + 68) - size - base, renderIndex, 4, size); + } + liquidSize -= size; + base += size; + } + } + } + } + + // Liquid gague + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + + this.mc.getTextureManager().bindTexture(background); + drawTexturedModalRect(cornerX + 54, cornerY + 16, 176, 76, 52, 52); + + // Side inventory + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + this.mc.getTextureManager().bindTexture(backgroundSide); + if (logic.layers > 0) + { + if (logic.layers == 1) + { + drawTexturedModalRect(cornerX - 46, cornerY, 0, 0, 98, 43); + drawTexturedModalRect(cornerX - 46, cornerY + 43, 0, 133, 98, 25); + } + else if (logic.layers == 2) + { + drawTexturedModalRect(cornerX - 46, cornerY, 0, 0, 98, 61); + drawTexturedModalRect(cornerX - 46, cornerY + 61, 0, 97, 98, 61); + } + else + { + drawTexturedModalRect(cornerX - 46, cornerY, 0, 0, 98, ySize - 8); + } + drawTexturedModalRect(cornerX + 32, (int) (cornerY + 8 + 127 * currentScroll), 98, 0, 12, 15); + } + + // Temperature + int slotSize = logic.layers * 9; + if (slotSize > 24) + slotSize = 24; + for (int iter = 0; iter < slotSize; iter++) + { + int slotTemp = logic.getTempForSlot(iter + slotPos * 3) - 20; + int maxTemp = logic.getMeltingPointForSlot(iter + slotPos * 3) - 20; + if (slotTemp > 0 && maxTemp > 0) + { + int size = 16 * slotTemp / maxTemp + 1; + drawTexturedModalRect(cornerX - 38 + (iter % 3 * 22), cornerY + 8 + (iter / 3 * 18) + 16 - size, 98, 15 + 16 - size, 5, size); + } + } + } + + protected void drawFluidStackTooltip (FluidStack par1ItemStack, int par2, int par3) + { + this.zLevel = 100; + List list = getLiquidTooltip(par1ItemStack, this.mc.gameSettings.advancedItemTooltips); + + for (int k = 0; k < list.size(); ++k) + { + list.set(k, EnumChatFormatting.GRAY + (String) list.get(k)); + } + + this.drawToolTip(list, par2, par3); + this.zLevel = 0; + } + + public List getLiquidTooltip (FluidStack liquid, boolean par2) + { + ArrayList list = new ArrayList(); + if (liquid.fluidID == -37) + { + list.add("\u00A7f" + StatCollector.translateToLocal("gui.smeltery.fuel")); + list.add("mB: " + liquid.amount); + } + else + { + String name = liquid.getFluid().getLocalizedName(); + list.add("\u00A7f" + name); + if (name.equals(StatCollector.translateToLocal("fluid.emerald.liquid"))) + { + list.add(StatCollector.translateToLocal("gui.smeltery.emerald") + liquid.amount / 640f); + } + else if (name.equals(StatCollector.translateToLocal("fluid.glass.molten"))) + { + int blocks = liquid.amount / 1000; + if (blocks > 0) + list.add(StatCollector.translateToLocal("gui.smeltery.glass.block") + blocks); + int panels = (liquid.amount % 1000) / 250; + if (panels > 0) + list.add(StatCollector.translateToLocal("gui.smeltery.glass.pannel") + panels); + int mB = (liquid.amount % 1000) % 250; + if (mB > 0) + list.add("mB: " + mB); + } + else if (name.equals(StatCollector.translateToLocal("fluid.stone.seared"))) + { + int ingots = liquid.amount / TConstruct.ingotLiquidValue; + if (ingots > 0) + list.add(StatCollector.translateToLocal("gui.smeltery.glass.block") + ingots); + int mB = liquid.amount % TConstruct.ingotLiquidValue; + if (mB > 0) + list.add("mB: " + mB); + } + else if (isMolten(name)) + { + int ingots = liquid.amount / TConstruct.ingotLiquidValue; + if (ingots > 0) + list.add(StatCollector.translateToLocal("gui.smeltery.metal.ingot") + ingots); + int mB = liquid.amount % TConstruct.ingotLiquidValue; + if (mB > 0) + { + int nuggets = mB / TConstruct.nuggetLiquidValue; + int junk = (mB % TConstruct.nuggetLiquidValue); + if (nuggets > 0) + list.add(StatCollector.translateToLocal("gui.smeltery.metal.nugget") + nuggets); + if (junk > 0) + list.add("mB: " + junk); + } + } + else + { + list.add("mB: " + liquid.amount); + } + } + return list; + } + + private boolean isMolten (String fluidName) + { + boolean molten = false; + String[] moltenNames = StatCollector.translateToLocal("gui.smeltery.molten.check").split(","); + + for (int i = 0; i < moltenNames.length; i++) + { + if (fluidName.contains(moltenNames[i].trim())) + { + molten = true; + break; + } + } + + return molten; + } + + protected void drawToolTip (List par1List, int par2, int par3) + { + if (!par1List.isEmpty()) + { + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + RenderHelper.disableStandardItemLighting(); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glDisable(GL11.GL_DEPTH_TEST); + int k = 0; + Iterator iterator = par1List.iterator(); + + while (iterator.hasNext()) + { + String s = (String) iterator.next(); + int l = this.fontRendererObj.getStringWidth(s); + + if (l > k) + { + k = l; + } + } + + int i1 = par2 + 12; + int j1 = par3 - 12; + int k1 = 8; + + if (par1List.size() > 1) + { + k1 += 2 + (par1List.size() - 1) * 10; + } + + if (i1 + k > this.width) + { + i1 -= 28 + k; + } + + if (j1 + k1 + 6 > this.height) + { + j1 = this.height - k1 - 6; + } + + this.zLevel = 300.0F; + itemRenderer.zLevel = 300.0F; + int l1 = -267386864; + this.drawGradientRect(i1 - 3, j1 - 4, i1 + k + 3, j1 - 3, l1, l1); + this.drawGradientRect(i1 - 3, j1 + k1 + 3, i1 + k + 3, j1 + k1 + 4, l1, l1); + this.drawGradientRect(i1 - 3, j1 - 3, i1 + k + 3, j1 + k1 + 3, l1, l1); + this.drawGradientRect(i1 - 4, j1 - 3, i1 - 3, j1 + k1 + 3, l1, l1); + this.drawGradientRect(i1 + k + 3, j1 - 3, i1 + k + 4, j1 + k1 + 3, l1, l1); + int i2 = 1347420415; + int j2 = (i2 & 16711422) >> 1 | i2 & -16777216; + this.drawGradientRect(i1 - 3, j1 - 3 + 1, i1 - 3 + 1, j1 + k1 + 3 - 1, i2, j2); + this.drawGradientRect(i1 + k + 2, j1 - 3 + 1, i1 + k + 3, j1 + k1 + 3 - 1, i2, j2); + this.drawGradientRect(i1 - 3, j1 - 3, i1 + k + 3, j1 - 3 + 1, i2, i2); + this.drawGradientRect(i1 - 3, j1 + k1 + 2, i1 + k + 3, j1 + k1 + 3, j2, j2); + + for (int k2 = 0; k2 < par1List.size(); ++k2) + { + String s1 = (String) par1List.get(k2); + this.fontRendererObj.drawStringWithShadow(s1, i1, j1, -1); + + if (k2 == 0) + { + j1 += 2; + } + + j1 += 10; + } + + this.zLevel = 0.0F; + itemRenderer.zLevel = 0.0F; + } + } + + public void drawLiquidRect (int startU, int startV, IIcon icon, int endU, int endV) + { + float top = icon.getInterpolatedV(16 - endV); + float bottom = icon.getMaxV(); + float left = icon.getMinU(); + float right = icon.getInterpolatedU(endU); + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(startU + 0, startV + endV, this.zLevel, left, bottom);//Bottom left + tessellator.addVertexWithUV(startU + endU, startV + endV, this.zLevel, right, bottom);//Bottom right + tessellator.addVertexWithUV(startU + endU, startV + 0, this.zLevel, right, top);//Top right + tessellator.addVertexWithUV(startU + 0, startV + 0, this.zLevel, left, top); //Top left + tessellator.draw(); + } + + @Override + public void mouseClicked (int mouseX, int mouseY, int mouseButton) + { + super.mouseClicked(mouseX, mouseY, mouseButton); + + int base = 0; + int cornerX = (width - xSize) / 2 + 36; + int cornerY = (height - ySize) / 2; + int fluidToBeBroughtUp = -1; + + for (FluidStack liquid : logic.moltenMetal) + { + int basePos = 54; + int initialLiquidSize = 0; + int liquidSize = 0;// liquid.amount * 52 / liquidLayers; + if (logic.getCapacity() > 0) + { + int total = logic.getTotalLiquid(); + int liquidLayers = (total / 20000 + 1) * 20000; + if (liquidLayers > 0) + { + liquidSize = liquid.amount * 52 / liquidLayers; + if (liquidSize == 0) + liquidSize = 1; + base += liquidSize; + } + } + + int leftX = cornerX + basePos; + int topY = (cornerY + 68) - base; + int sizeX = 52; + int sizeY = liquidSize; + if (mouseX >= leftX && mouseX <= leftX + sizeX && mouseY >= topY && mouseY < topY + sizeY) + { + fluidToBeBroughtUp = liquid.fluidID; + + TConstruct.packetPipeline.sendToServer(new SmelteryPacket(logic.getWorldObj().provider.dimensionId, logic.xCoord, logic.yCoord, logic.zCoord, this.isShiftKeyDown(), fluidToBeBroughtUp)); + } + } + } +} diff --git a/src/main/java/tconstruct/smeltery/inventory/SmelteryContainer.java b/src/main/java/tconstruct/smeltery/inventory/SmelteryContainer.java index 0816c22d9a0..7d0c2f77045 100644 --- a/src/main/java/tconstruct/smeltery/inventory/SmelteryContainer.java +++ b/src/main/java/tconstruct/smeltery/inventory/SmelteryContainer.java @@ -5,7 +5,6 @@ import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import tconstruct.smeltery.TinkerSmeltery; -import tconstruct.smeltery.logic.FlexibleSmelteryLogic; import tconstruct.smeltery.logic.SmelteryLogic; public class SmelteryContainer extends ActiveContainer @@ -24,30 +23,15 @@ public SmelteryContainer(InventoryPlayer inventoryplayer, SmelteryLogic smeltery /* Smeltery inventory */ // new rectangular smeltery - if(smeltery instanceof FlexibleSmelteryLogic) - { - FlexibleSmelteryLogic fs = (FlexibleSmelteryLogic) smeltery; - int xd = fs.maxPos.x - fs.minPos.x; - int zd = fs.maxPos.z - fs.minPos.z; - - int totalSlots = xd*zd*fs.layers; - int y = 0; + int totalSlots = smeltery.getBlockCapacity(); + int y = 0; - for(int i = 0; i < totalSlots; i++) - { - int x = i%3; - this.addDualSlotToContainer(new ActiveSlot(smeltery, x + y * 3, 2 + x * 22, 8 + y * 18, y < 8)); - if(x == 2) - y++; - } - } - // old 3x3 smeltery - else { - for (int y = 0; y < smeltery.layers * 3; y++) { - for (int x = 0; x < 3; x++) { - this.addDualSlotToContainer(new ActiveSlot(smeltery, x + y * 3, 2 + x * 22, 8 + y * 18, y < 8)); - } - } + for(int i = 0; i < totalSlots; i++) + { + int x = i%3; + this.addDualSlotToContainer(new ActiveSlot(smeltery, x + y * 3, 2 + x * 22, 8 + y * 18, y < 8)); + if(x == 2) + y++; } /* Player inventory */ diff --git a/src/main/java/tconstruct/smeltery/inventory/SmelteryContainerOld.java b/src/main/java/tconstruct/smeltery/inventory/SmelteryContainerOld.java new file mode 100644 index 00000000000..cb995d81e82 --- /dev/null +++ b/src/main/java/tconstruct/smeltery/inventory/SmelteryContainerOld.java @@ -0,0 +1,271 @@ +package tconstruct.smeltery.inventory; + +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; +import tconstruct.smeltery.TinkerSmeltery; +import tconstruct.smeltery.logic.SmelteryLogicOld; + +public class SmelteryContainerOld extends ActiveContainer +{ + public SmelteryLogicOld logic; + public InventoryPlayer playerInv; + public int fuel = 0; + int slotRow; + + public SmelteryContainerOld(InventoryPlayer inventoryplayer, SmelteryLogicOld smeltery) + { + logic = smeltery; + playerInv = inventoryplayer; + slotRow = 0; + + /* Smeltery inventory */ + for (int y = 0; y < smeltery.layers * 3; y++) { + for (int x = 0; x < 3; x++) { + this.addDualSlotToContainer(new ActiveSlot(smeltery, x + y * 3, 2 + x * 22, 8 + y * 18, y < 8)); + } + } + + /* Player inventory */ + for (int column = 0; column < 3; column++) + { + for (int row = 0; row < 9; row++) + { + this.addSlotToContainer(new Slot(inventoryplayer, row + column * 9 + 9, 90 + row * 18, 84 + column * 18)); + } + } + + for (int column = 0; column < 9; column++) + { + this.addSlotToContainer(new Slot(inventoryplayer, column, 90 + column * 18, 142)); + } + } + + public int updateRows (int invRow) + { + if (invRow != slotRow) + { + slotRow = invRow; + // TConstruct.logger.info(invRow); + int basePos = invRow * 3; + for (int iter = 0; iter < activeInventorySlots.size(); iter++) + { + ActiveSlot slot = (ActiveSlot) activeInventorySlots.get(iter); + if (slot.activeSlotNumber >= basePos && slot.activeSlotNumber < basePos + 24) + { + slot.setActive(true); + } + else + { + slot.setActive(false); + } + int xPos = (iter - basePos) % 3; + int yPos = (iter - basePos) / 3; + slot.xDisplayPosition = 2 + 22 * xPos; + slot.yDisplayPosition = 8 + 18 * yPos; + } + return slotRow; + } + return -1; + } + + public int scrollTo (float scrollPos) + { + float total = (logic.getSizeInventory() - 24) / 3; + int rowPos = (int) (total * scrollPos); + return updateRows(rowPos); + } + + @Override + public void detectAndSendChanges () // TODO: Sync with this + { + super.detectAndSendChanges(); + /* + * for (int i = 0; i < crafters.size(); i++) { ICrafting icrafting = + * (ICrafting)crafters.get(i); if (progress != logic.progress) { + * icrafting.sendProgressBarUpdate(this, 0, logic.progress); } if (fuel + * != logic.fuel) { icrafting.sendProgressBarUpdate(this, 1, + * logic.fuel); } if (fuelGague != logic.fuelGague) { + * icrafting.sendProgressBarUpdate(this, 2, logic.fuelGague); } } + * + * progress = logic.progress; fuel = logic.fuel; fuelGague = + * logic.fuelGague; + */ + } + + @Override + public void updateProgressBar (int id, int value) + { + if (id == 0) + { + logic.fuelGague = value; + } + /* + * if (id == 1) { logic.fuel = value; } + */ + /* + * if (id == 2) { logic.fuelGague = value; } + */ + } + + @Override + public boolean canInteractWith (EntityPlayer entityplayer) + { + Block block = logic.getWorldObj().getBlock(logic.xCoord, logic.yCoord, logic.zCoord); + if (block != TinkerSmeltery.smeltery && block != TinkerSmeltery.smelteryNether) + return false; + return logic.isUseableByPlayer(entityplayer); + } + + @Override + public ItemStack transferStackInSlot (EntityPlayer player, int slotID) + { + ItemStack stack = null; + Slot slot = (Slot) this.inventorySlots.get(slotID); + + if (slot != null && slot.getHasStack()) + { + ItemStack slotStack = slot.getStack(); + stack = slotStack.copy(); + + if (slotID < logic.getSizeInventory()) + { + if (!this.mergeItemStack(slotStack, logic.getSizeInventory(), this.inventorySlots.size(), true)) + { + return null; + } + } + else if (!this.mergeItemStack(slotStack, 0, logic.getSizeInventory(), false)) + { + return null; + } + + if (slotStack.stackSize == 0) + { + slot.putStack((ItemStack) null); + } + else + { + slot.onSlotChanged(); + } + } + + return stack; + } + + @Override + protected boolean mergeItemStack (ItemStack inputStack, int startSlot, int endSlot, boolean flag) + { + // TConstruct.logger.info("Merge"); + boolean merged = false; + int slotPos = startSlot; + + if (flag) + { + slotPos = endSlot - 1; + } + + Slot slot; + ItemStack slotStack; + + /* + * if (inputStack.isStackable() && startSlot >= + * logic.getSizeInventory()) { TConstruct.logger.info("Rawr!"); while + * (inputStack.stackSize > 0 && (!flag && slotPos < endSlot || flag && + * slotPos >= startSlot)) { slot = (Slot) + * this.inventorySlots.get(slotPos); slotStack = slot.getStack(); + * + * if (slotStack != null && ItemStack.areItemStacksEqual(inputStack, + * slotStack) && !inputStack.getHasSubtypes()) { int totalSize = + * slotStack.stackSize + inputStack.stackSize; + * + * if (totalSize <= inputStack.getMaxStackSize()) { inputStack.stackSize + * = 0; slotStack.stackSize = totalSize; slot.onSlotChanged(); merged = + * true; } else if (slotStack.stackSize < inputStack.getMaxStackSize()) + * { inputStack.stackSize -= inputStack.getMaxStackSize() - + * slotStack.stackSize; slotStack.stackSize = + * inputStack.getMaxStackSize(); slot.onSlotChanged(); merged = true; } + * } + * + * if (flag) { --slotPos; } else { ++slotPos; } } } + */ + + if (inputStack.isStackable() && startSlot >= logic.getSizeInventory()) + { + while (inputStack.stackSize > 0 && (!flag && slotPos < endSlot || flag && slotPos >= startSlot)) + { + slot = (Slot) this.inventorySlots.get(slotPos); + slotStack = slot.getStack(); + + if (slotStack != null && ItemStack.areItemStacksEqual(slotStack, inputStack)) + { + int l = slotStack.stackSize + inputStack.stackSize; + + if (l <= inputStack.getMaxStackSize()) + { + inputStack.stackSize = 0; + slotStack.stackSize = l; + slot.onSlotChanged(); + merged = true; + } + else if (slotStack.stackSize < inputStack.getMaxStackSize()) + { + inputStack.stackSize -= inputStack.getMaxStackSize() - slotStack.stackSize; + slotStack.stackSize = inputStack.getMaxStackSize(); + slot.onSlotChanged(); + merged = true; + } + } + + if (flag) + { + --slotPos; + } + else + { + ++slotPos; + } + } + } + + if (inputStack.stackSize > 0) + { + if (flag) + { + slotPos = endSlot - 1; + } + else + { + slotPos = startSlot; + } + + while (!flag && slotPos < endSlot || flag && slotPos >= startSlot) + { + slot = (Slot) this.inventorySlots.get(slotPos); + slotStack = slot.getStack(); + + if (slotStack == null) + { + slot.putStack(inputStack.copy()); + slot.onSlotChanged(); + inputStack.stackSize -= 1; + merged = true; + break; + } + + if (flag) + { + --slotPos; + } + else + { + ++slotPos; + } + } + } + + return merged; + } +} diff --git a/src/main/java/tconstruct/smeltery/logic/FlexibleSmelteryLogic.java b/src/main/java/tconstruct/smeltery/logic/FlexibleSmelteryLogic.java deleted file mode 100644 index 2faa84cb211..00000000000 --- a/src/main/java/tconstruct/smeltery/logic/FlexibleSmelteryLogic.java +++ /dev/null @@ -1,328 +0,0 @@ -package tconstruct.smeltery.logic; - -import mantle.blocks.abstracts.MultiServantLogic; -import mantle.blocks.iface.IServantLogic; -import mantle.world.CoordTuple; -import net.minecraft.block.Block; -import net.minecraft.init.Blocks; -import net.minecraft.tileentity.TileEntity; -import net.minecraftforge.common.util.ForgeDirection; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.IFluidHandler; -import tconstruct.library.crafting.Smeltery; -import tconstruct.smeltery.TinkerSmeltery; - -public class FlexibleSmelteryLogic extends SmelteryLogic { - private static final int MAX_SMELTERY_SIZE = 5; - - public CoordTuple minPos = new CoordTuple(0, 0, 0); - public CoordTuple maxPos = new CoordTuple(0, 0, 0); - - /* Multiblock */ - @Override - public void notifyChange (IServantLogic servant, int x, int y, int z) - { - checkValidPlacement(); - } - - public void checkValidPlacement () - { - switch (getRenderDirection()) - { - case 2: // +z - alignInitialPlacement(xCoord, yCoord, zCoord + 1); - break; - case 3: // -z - alignInitialPlacement(xCoord, yCoord, zCoord - 1); - break; - case 4: // +x - alignInitialPlacement(xCoord + 1, yCoord, zCoord); - break; - case 5: // -x - alignInitialPlacement(xCoord - 1, yCoord, zCoord); - break; - } - } - - // aligns the position given (inside the smeltery) to be the center of the smeltery - public void alignInitialPlacement (int x, int y, int z) - { - // x/y/z = the block behind the controller "inside the smeltery" - - // adjust the x-position of the block until the difference between the outer walls is at most 1 - // basically this means we center the block inside the smeltery on the x axis. - int xd1 = 1, xd2 = 1; // x-difference - for(int i = 1; i < MAX_SMELTERY_SIZE; i++) // don't check farther than needed - { - if(worldObj.getBlock(x - xd1, y, z) == null || worldObj.isAirBlock(x - xd1,y,z)) - xd1++; - if(worldObj.getBlock(x + xd2, y, z) == null || worldObj.isAirBlock(x + xd2,y,z)) - xd2++; - - // if one side hit a wall and the other didn't we might have to center our x-position again - if(xd1-xd2 > 1) - { - // move x and offsets to the -x - xd1--; - x--; - xd2++; - } - // or the right - if(xd2-xd1 > 1) - { - xd2--; - x++; - xd1++; - } - } - // same for z-axis - int zd1 = 1, zd2 = 1; - for(int i = 1; i < MAX_SMELTERY_SIZE; i++) // don't check farther than needed - { - if(worldObj.getBlock(x, y, z - zd1) == null || worldObj.isAirBlock(x, y, z - zd1)) - zd1++; - if(worldObj.getBlock(x, y, z + zd2) == null || worldObj.isAirBlock(x, y, z + zd2)) - zd2++; - - // if one side hit a wall and the other didn't we might have to center our x-position again - if(zd1-zd2 > 1) - { - // move x and offsets to the -x - zd1--; - z--; - zd2++; - } - // or the right - if(zd2-zd1 > 1) - { - zd2--; - z++; - zd1++; - } - } - - // do the check - int[] sides = new int[] {xd1, xd2, zd1, zd2}; - checkValidStructure(x, y, z, sides); - } - - /** - * - * @param x x-center of the smeltery +-1 - * @param y y-position of the controller block - * @param z z-center of the smeltery +-1 - * @param sides distance between the center point and the wall. [-x,+x,-z,+z] - */ - public void checkValidStructure (int x, int y, int z, int[] sides) - { - int checkLayers = 0; - //worldObj.setBlock(x,y,z, Blocks.redstone_block); - //worldObj.setBlock(x+sides[1]-sides[0],y+1,z+sides[3]-sides[2], Blocks.lapis_block); - - tempValidStructure = false; - // this piece of code here does the complete validity check. - if (checkSameLevel(x, y, z, sides)) - { - checkLayers++; - checkLayers += recurseStructureUp(x, y + 1, z, sides, 0); - checkLayers += recurseStructureDown(x, y - 1, z, sides, 0); - } - - // maxLiquid = capacity * 20000; - - if (tempValidStructure != validStructure || checkLayers != this.layers) - { - if (tempValidStructure) - { - // try to derive temperature from fueltank - activeLavaTank = null; - for (CoordTuple tank : lavaTanks) - { - TileEntity tankContainer = worldObj.getTileEntity(tank.x, tank.y, tank.z); - if (!(tankContainer instanceof IFluidHandler)) - continue; - - FluidStack liquid = ((IFluidHandler) tankContainer).getTankInfo(ForgeDirection.DOWN)[0].fluid; - if (liquid == null) - continue; - if (!Smeltery.isSmelteryFuel(liquid.getFluid())) - continue; - - internalTemp = Smeltery.getFuelPower(liquid.getFluid()); - activeLavaTank = tank; - break; - } - - // no tank with fuel. we reserve the first found one - if (activeLavaTank == null) - activeLavaTank = lavaTanks.get(0); - - // update other stuff - adjustLayers(checkLayers, false); - worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); - validStructure = true; - } - else - { - internalTemp = 20; - validStructure = false; - } - } - } - - public boolean checkBricksOnLevel(int x, int y, int z, int[] sides) - { - int numBricks = 0; - Block block; - int xMin = x - sides[0]; - int xMax = x + sides[1]; - int zMin = z - sides[2]; - int zMax = z + sides[3]; - - // Check inside - for (int xPos = xMin + 1; xPos <= xMax - 1; xPos++) - { - for (int zPos = zMin + 1; zPos <= zMax - 1; zPos++) - { - block = worldObj.getBlock(xPos, y, zPos); - if (block != null && !worldObj.isAirBlock(xPos, y, zPos)) - return false; - } - } - - // Check outer layer - for (int xPos = xMin + 1; xPos <= xMax - 1; xPos++) - { - numBricks += checkBricks(xPos, y, zMin); - numBricks += checkBricks(xPos, y, zMax); - } - - for (int zPos = zMin + 1; zPos <= zMax - 1; zPos++) - { - numBricks += checkBricks(xMin, y, zPos); - numBricks += checkBricks(xMax, y, zPos); - } - - int neededBricks = (xMax-xMin)*2 + (zMax-zMin)*2 - 4; // -4 because corners are not needed - - return numBricks == neededBricks; - } - - public boolean checkSameLevel(int x, int y, int z, int[] sides) - { - lavaTanks.clear(); - - boolean check = checkBricksOnLevel(x,y,z,sides); - - if (check && lavaTanks.size() > 0) - return true; - else - return false; - } - - public int recurseStructureUp (int x, int y, int z, int[] sides, int count) - { - boolean check = checkBricksOnLevel(x,y,z,sides); - - if(!check) - return count; - - count++; - return recurseStructureUp(x, y + 1, z, sides, count); - } - - public int recurseStructureDown (int x, int y, int z, int[] sides, int count) - { - boolean check = checkBricksOnLevel(x,y,z,sides); - - if(!check) { - // regular check failed, maybe it's the bottom? - Block block = worldObj.getBlock(x,y,z); - if (block != null && !worldObj.isAirBlock(x, y, z)) - if (validBlockID(block)) - return validateBottom(x, y, z, sides, count); - - return count; - } - - count++; - return recurseStructureDown(x, y - 1, z, sides, count); - } - - public int validateBottom (int x, int y, int z, int[] sides, int count) - { - int bottomBricks = 0; - int xMin = x - sides[0] + 1; - int xMax = x + sides[1] - 1; - int zMin = z - sides[2] + 1; - int zMax = z + sides[3] - 1; - - // Check inside - for (int xPos = xMin; xPos <= xMax; xPos++) - { - for (int zPos = zMin; zPos <= zMax; zPos++) - { - if (validBlockID(worldObj.getBlock(xPos, y, zPos)) && (worldObj.getBlockMetadata(xPos, y, zPos) >= 2)) - bottomBricks++; - } - } - - int neededBricks = (xMax+1-xMin) * (zMax+1-zMin); // +1 because we want inclusive the upper border - - if (bottomBricks == neededBricks) - { - tempValidStructure = true; - minPos = new CoordTuple(xMin, y+1, zMin); - maxPos = new CoordTuple(xMax, y+1, zMax); - } - return count; - } - - /* - * Returns whether the brick is a lava tank or not. Increments bricks, sets - * them as part of the structure, and adds tanks to the list. - */ - int checkBricks (int x, int y, int z) - { - int tempBricks = 0; - Block blockID = worldObj.getBlock(x, y, z); - if (validBlockID(blockID) || validTankID(blockID)) - { - TileEntity te = worldObj.getTileEntity(x, y, z); - if (te == this) - { - tempBricks++; - } - else if (te instanceof MultiServantLogic) - { - MultiServantLogic servant = (MultiServantLogic) te; - if (servant.hasValidMaster()) - { - if (servant.verifyMaster(this, worldObj, this.xCoord, this.yCoord, this.zCoord)) - tempBricks++; - } - else - { - servant.overrideMaster(this.xCoord, this.yCoord, this.zCoord); - tempBricks++; - } - - if (te instanceof LavaTankLogic) - { - lavaTanks.add(new CoordTuple(x, y, z)); - } - } - } - return tempBricks; - } - - boolean validBlockID (Block blockID) - { - return blockID == TinkerSmeltery.smeltery || blockID == TinkerSmeltery.smelteryNether; - } - - boolean validTankID (Block blockID) - { - return blockID == TinkerSmeltery.lavaTank || blockID == TinkerSmeltery.lavaTankNether; - } -} diff --git a/src/main/java/tconstruct/smeltery/logic/SmelteryLogic.java b/src/main/java/tconstruct/smeltery/logic/SmelteryLogic.java index 8f8a9cced31..3497b521b09 100644 --- a/src/main/java/tconstruct/smeltery/logic/SmelteryLogic.java +++ b/src/main/java/tconstruct/smeltery/logic/SmelteryLogic.java @@ -32,30 +32,33 @@ public class SmelteryLogic extends InventoryLogic implements IActiveLogic, IFacingLogic, IFluidTank, IMasterLogic { + private static final int MAX_SMELTERY_SIZE = 5; + public boolean validStructure; public boolean tempValidStructure; - byte direction; - int internalTemp; + protected byte direction; + + public CoordTuple minPos = new CoordTuple(0, 0, 0); + public CoordTuple maxPos = new CoordTuple(0, 0, 0); + public int layers; + public int maxBlockCapacity; + + protected int internalTemp; public int useTime; public int fuelGague; public int fuelAmount; - boolean inUse; + protected boolean inUse; - ArrayList lavaTanks; - CoordTuple activeLavaTank; - public CoordTuple centerPos = new CoordTuple(0, 0, 0); + protected ArrayList lavaTanks; + protected CoordTuple activeLavaTank; public int[] activeTemps; // values are multiplied by 10 public int[] meltingTemps; // values are multiplied by 10 - int tick; + private int tick; public ArrayList moltenMetal = new ArrayList(); - int maxLiquid; - int currentLiquid; - public int layers; - int slag; - - int numBricks; + public int maxLiquid; + public int currentLiquid; Random rand = new Random(); boolean needsUpdate; @@ -68,25 +71,39 @@ public SmelteryLogic() meltingTemps = new int[0]; } + public int getBlocksPerLayer() + { + int xd = maxPos.x - minPos.x + 1; + int zd = maxPos.z - minPos.z + 1; + return xd * zd; + } + + public int getBlockCapacity() + { + return maxBlockCapacity; + } + void adjustLayers (int lay, boolean forceAdjust) { if (lay != layers || forceAdjust) { needsUpdate = true; layers = lay; + maxBlockCapacity = getBlocksPerLayer() * layers; + maxLiquid = 20000 * lay; int[] tempActive = activeTemps; - activeTemps = new int[9 * lay]; + activeTemps = new int[maxBlockCapacity]; int activeLength = tempActive.length > activeTemps.length ? activeTemps.length : tempActive.length; System.arraycopy(tempActive, 0, activeTemps, 0, activeLength); int[] tempMelting = meltingTemps; - meltingTemps = new int[9 * lay]; + meltingTemps = new int[maxBlockCapacity]; int meltingLength = tempMelting.length > meltingTemps.length ? meltingTemps.length : tempMelting.length; System.arraycopy(tempMelting, 0, meltingTemps, 0, meltingLength); ItemStack[] tempInv = inventory; - inventory = new ItemStack[9 * lay]; + inventory = new ItemStack[maxBlockCapacity]; int invLength = tempInv.length > inventory.length ? inventory.length : tempInv.length; System.arraycopy(tempInv, 0, inventory, 0, invLength); @@ -291,6 +308,8 @@ public void updateEntity () void detectEntities () { + // todo: fix this with min-max pos instead of center pos + /* if (centerPos == null) return; @@ -364,6 +383,7 @@ else if (PHConstruct.throwableSmeltery && o instanceof EntityItem) handleItemEntity((EntityItem) o); } } + */ } private void handleItemEntity (EntityItem item) @@ -418,7 +438,7 @@ private void heatItems () int temperature = this.getInternalTemperature(); int speed = temperature / 100; int refTemp = temperature * 10; - for (int i = 0; i < 9 * layers; i++) + for (int i = 0; i < maxBlockCapacity; i++) { if (meltingTemps[i] > 200 && this.isStackInSlot(i)) { @@ -506,7 +526,7 @@ boolean addMoltenMetal (FluidStack liquid, boolean first) private void updateTemperatures () { inUse = true; - for (int i = 0; i < 9 * layers; i++) + for (int i = 0; i < maxBlockCapacity; i++) { meltingTemps[i] = Smeltery.getLiquifyTemperature(inventory[i]) * 10; // temperatures are *10 for more progress control } @@ -707,65 +727,103 @@ public void checkValidPlacement () { switch (getRenderDirection()) { - case 2: // +z - alignInitialPlacement(xCoord, yCoord, zCoord + 2); - break; - case 3: // -z - alignInitialPlacement(xCoord, yCoord, zCoord - 2); - break; - case 4: // +x - alignInitialPlacement(xCoord + 2, yCoord, zCoord); - break; - case 5: // -x - alignInitialPlacement(xCoord - 2, yCoord, zCoord); - break; + case 2: // +z + alignInitialPlacement(xCoord, yCoord, zCoord + 1); + break; + case 3: // -z + alignInitialPlacement(xCoord, yCoord, zCoord - 1); + break; + case 4: // +x + alignInitialPlacement(xCoord + 1, yCoord, zCoord); + break; + case 5: // -x + alignInitialPlacement(xCoord - 1, yCoord, zCoord); + break; } } + // aligns the position given (inside the smeltery) to be the center of the smeltery public void alignInitialPlacement (int x, int y, int z) { - Block northBlock = worldObj.getBlock(x, y, z + 1); - Block southBlock = worldObj.getBlock(x, y, z - 1); - Block eastBlock = worldObj.getBlock(x + 1, y, z); - Block westBlock = worldObj.getBlock(x - 1, y, z); + // x/y/z = the block behind the controller "inside the smeltery" - if ((northBlock == null || worldObj.isAirBlock(x, y, z + 1)) && (southBlock == null || worldObj.isAirBlock(x, y, z - 1)) && (eastBlock == null || worldObj.isAirBlock(x + 1, y, z)) && (westBlock == null || worldObj.isAirBlock(x - 1, y, z))) + // adjust the x-position of the block until the difference between the outer walls is at most 1 + // basically this means we center the block inside the smeltery on the x axis. + int xd1 = 1, xd2 = 1; // x-difference + for(int i = 1; i < MAX_SMELTERY_SIZE; i++) // don't check farther than needed { - checkValidStructure(x, y, z); - } - - else if ((northBlock != null && !worldObj.isAirBlock(x, y, z + 1)) && (southBlock == null || worldObj.isAirBlock(x, y, z - 1)) && (eastBlock == null || worldObj.isAirBlock(x + 1, y, z)) && (westBlock == null || worldObj.isAirBlock(x - 1, y, z))) - { - checkValidStructure(x, y, z - 1); - } + if(worldObj.getBlock(x - xd1, y, z) == null || worldObj.isAirBlock(x - xd1,y,z)) + xd1++; + if(worldObj.getBlock(x + xd2, y, z) == null || worldObj.isAirBlock(x + xd2,y,z)) + xd2++; - else if ((northBlock == null || worldObj.isAirBlock(x, y, z + 1)) && (southBlock != null && !worldObj.isAirBlock(x, y, z - 1)) && (eastBlock == null || worldObj.isAirBlock(x + 1, y, z)) && (westBlock == null || worldObj.isAirBlock(x - 1, y, z))) - { - checkValidStructure(x, y, z + 1); + // if one side hit a wall and the other didn't we might have to center our x-position again + if(xd1-xd2 > 1) + { + // move x and offsets to the -x + xd1--; + x--; + xd2++; + } + // or the right + if(xd2-xd1 > 1) + { + xd2--; + x++; + xd1++; + } } - - else if ((northBlock == null || worldObj.isAirBlock(x, y, z + 1)) && (southBlock == null || worldObj.isAirBlock(x, y, z - 1)) && (eastBlock != null && !worldObj.isAirBlock(x + 1, y, z)) && (westBlock == null || worldObj.isAirBlock(x - 1, y, z))) + // same for z-axis + int zd1 = 1, zd2 = 1; + for(int i = 1; i < MAX_SMELTERY_SIZE; i++) // don't check farther than needed { - checkValidStructure(x - 1, y, z); - } + if(worldObj.getBlock(x, y, z - zd1) == null || worldObj.isAirBlock(x, y, z - zd1)) + zd1++; + if(worldObj.getBlock(x, y, z + zd2) == null || worldObj.isAirBlock(x, y, z + zd2)) + zd2++; - else if ((northBlock == null || worldObj.isAirBlock(x, y, z + 1)) && (southBlock == null || worldObj.isAirBlock(x, y, z - 1)) && (eastBlock == null || worldObj.isAirBlock(x + 1, y, z)) && (westBlock != null && !worldObj.isAirBlock(x - 1, y, z))) - { - checkValidStructure(x + 1, y, z); + // if one side hit a wall and the other didn't we might have to center our x-position again + if(zd1-zd2 > 1) + { + // move x and offsets to the -x + zd1--; + z--; + zd2++; + } + // or the right + if(zd2-zd1 > 1) + { + zd2--; + z++; + zd1++; + } } - // Not valid, sorry + // do the check + int[] sides = new int[] {xd1, xd2, zd1, zd2}; + checkValidStructure(x, y, z, sides); } - public void checkValidStructure (int x, int y, int z) + /** + * + * @param x x-center of the smeltery +-1 + * @param y y-position of the controller block + * @param z z-center of the smeltery +-1 + * @param sides distance between the center point and the wall. [-x,+x,-z,+z] + */ + public void checkValidStructure (int x, int y, int z, int[] sides) { int checkLayers = 0; + //worldObj.setBlock(x,y,z, Blocks.redstone_block); + //worldObj.setBlock(x+sides[1]-sides[0],y+1,z+sides[3]-sides[2], Blocks.lapis_block); + tempValidStructure = false; - if (checkSameLevel(x, y, z)) + // this piece of code here does the complete validity check. + if (checkSameLevel(x, y, z, sides)) { checkLayers++; - checkLayers += recurseStructureUp(x, y + 1, z, 0); - checkLayers += recurseStructureDown(x, y - 1, z, 0); + checkLayers += recurseStructureUp(x, y + 1, z, sides, 0); + checkLayers += recurseStructureDown(x, y - 1, z, sides, 0); } // maxLiquid = capacity * 20000; @@ -810,16 +868,19 @@ public void checkValidStructure (int x, int y, int z) } } - public boolean checkSameLevel (int x, int y, int z) + public boolean checkBricksOnLevel(int x, int y, int z, int[] sides) { - numBricks = 0; - lavaTanks.clear(); + int numBricks = 0; Block block; + int xMin = x - sides[0]; + int xMax = x + sides[1]; + int zMin = z - sides[2]; + int zMax = z + sides[3]; // Check inside - for (int xPos = x - 1; xPos <= x + 1; xPos++) + for (int xPos = xMin + 1; xPos <= xMax - 1; xPos++) { - for (int zPos = z - 1; zPos <= z + 1; zPos++) + for (int zPos = zMin + 1; zPos <= zMax - 1; zPos++) { block = worldObj.getBlock(xPos, y, zPos); if (block != null && !worldObj.isAirBlock(xPos, y, zPos)) @@ -828,113 +889,89 @@ public boolean checkSameLevel (int x, int y, int z) } // Check outer layer - for (int xPos = x - 1; xPos <= x + 1; xPos++) + for (int xPos = xMin + 1; xPos <= xMax - 1; xPos++) { - numBricks += checkBricks(xPos, y, z - 2); - numBricks += checkBricks(xPos, y, z + 2); + numBricks += checkBricks(xPos, y, zMin); + numBricks += checkBricks(xPos, y, zMax); } - for (int zPos = z - 1; zPos <= z + 1; zPos++) + for (int zPos = zMin + 1; zPos <= zMax - 1; zPos++) { - numBricks += checkBricks(x - 2, y, zPos); - numBricks += checkBricks(x + 2, y, zPos); + numBricks += checkBricks(xMin, y, zPos); + numBricks += checkBricks(xMax, y, zPos); } - if (numBricks == 12 && lavaTanks.size() > 0) + int neededBricks = (xMax-xMin)*2 + (zMax-zMin)*2 - 4; // -4 because corners are not needed + + return numBricks == neededBricks; + } + + public boolean checkSameLevel(int x, int y, int z, int[] sides) + { + lavaTanks.clear(); + + boolean check = checkBricksOnLevel(x,y,z,sides); + + if (check && lavaTanks.size() > 0) return true; else return false; } - public int recurseStructureUp (int x, int y, int z, int count) + public int recurseStructureUp (int x, int y, int z, int[] sides, int count) { - numBricks = 0; - // Check inside - for (int xPos = x - 1; xPos <= x + 1; xPos++) - { - for (int zPos = z - 1; zPos <= z + 1; zPos++) - { - Block block = worldObj.getBlock(xPos, y, zPos); - if (block != null && !worldObj.isAirBlock(xPos, y, zPos)) - return count; - } - } - - // Check outer layer - for (int xPos = x - 1; xPos <= x + 1; xPos++) - { - numBricks += checkBricks(xPos, y, z - 2); - numBricks += checkBricks(xPos, y, z + 2); - } + boolean check = checkBricksOnLevel(x,y,z,sides); - for (int zPos = z - 1; zPos <= z + 1; zPos++) - { - numBricks += checkBricks(x - 2, y, zPos); - numBricks += checkBricks(x + 2, y, zPos); - } - - if (numBricks != 12) + if(!check) return count; count++; - return recurseStructureUp(x, y + 1, z, count); + return recurseStructureUp(x, y + 1, z, sides, count); } - public int recurseStructureDown (int x, int y, int z, int count) + public int recurseStructureDown (int x, int y, int z, int[] sides, int count) { - numBricks = 0; - // Check inside - for (int xPos = x - 1; xPos <= x + 1; xPos++) - { - for (int zPos = z - 1; zPos <= z + 1; zPos++) - { - Block blockID = worldObj.getBlock(xPos, y, zPos); - if (blockID != null && !worldObj.isAirBlock(xPos, y, zPos)) - { - if (validBlockID(blockID)) - return validateBottom(x, y, z, count); - else - return count; - } - } - } + boolean check = checkBricksOnLevel(x,y,z,sides); - // Check outer layer - for (int xPos = x - 1; xPos <= x + 1; xPos++) - { - numBricks += checkBricks(xPos, y, z - 2); - numBricks += checkBricks(xPos, y, z + 2); - } - - for (int zPos = z - 1; zPos <= z + 1; zPos++) - { - numBricks += checkBricks(x - 2, y, zPos); - numBricks += checkBricks(x + 2, y, zPos); - } + if(!check) { + // regular check failed, maybe it's the bottom? + Block block = worldObj.getBlock(x,y,z); + if (block != null && !worldObj.isAirBlock(x, y, z)) + if (validBlockID(block)) + return validateBottom(x, y, z, sides, count); - if (numBricks != 12) return count; + } count++; - return recurseStructureDown(x, y - 1, z, count); + return recurseStructureDown(x, y - 1, z, sides, count); } - public int validateBottom (int x, int y, int z, int count) + public int validateBottom (int x, int y, int z, int[] sides, int count) { int bottomBricks = 0; - for (int xPos = x - 1; xPos <= x + 1; xPos++) + int xMin = x - sides[0] + 1; + int xMax = x + sides[1] - 1; + int zMin = z - sides[2] + 1; + int zMax = z + sides[3] - 1; + + // Check inside + for (int xPos = xMin; xPos <= xMax; xPos++) { - for (int zPos = z - 1; zPos <= z + 1; zPos++) + for (int zPos = zMin; zPos <= zMax; zPos++) { if (validBlockID(worldObj.getBlock(xPos, y, zPos)) && (worldObj.getBlockMetadata(xPos, y, zPos) >= 2)) bottomBricks++; } } - if (bottomBricks == 9) + int neededBricks = (xMax+1-xMin) * (zMax+1-zMin); // +1 because we want inclusive the upper border + + if (bottomBricks == neededBricks) { tempValidStructure = true; - centerPos = new CoordTuple(x, y + 1, z); + minPos = new CoordTuple(xMin, y+1, zMin); + maxPos = new CoordTuple(xMax, y+1, zMax); } return count; } @@ -959,11 +996,12 @@ else if (te instanceof MultiServantLogic) MultiServantLogic servant = (MultiServantLogic) te; if (servant.hasValidMaster()) { - if (servant.verifyMaster(this, this.xCoord, this.yCoord, this.zCoord)) + if (servant.verifyMaster(this, worldObj, this.xCoord, this.yCoord, this.zCoord)) tempBricks++; } - else if (servant.setMaster(this.xCoord, this.yCoord, this.zCoord)) + else { + servant.overrideMaster(this.xCoord, this.yCoord, this.zCoord); tempBricks++; } @@ -986,6 +1024,8 @@ boolean validTankID (Block blockID) return blockID == TinkerSmeltery.lavaTank || blockID == TinkerSmeltery.lavaTankNether; } + + @Override public int getCapacity () { @@ -1106,19 +1146,26 @@ public FluidTankInfo[] getMultiTankInfo () public void readFromNBT (NBTTagCompound tags) { layers = tags.getInteger("Layers"); - inventory = new ItemStack[layers * 9]; + int[] pos = tags.getIntArray("MinPos"); + if (pos.length > 2) + minPos = new CoordTuple(pos[0], pos[1], pos[2]); + else + minPos = new CoordTuple(xCoord, yCoord, zCoord); + + pos = tags.getIntArray("MaxPos"); + if (pos.length > 2) + maxPos = new CoordTuple(pos[0], pos[1], pos[2]); + else + maxPos = new CoordTuple(xCoord, yCoord, zCoord); + + maxBlockCapacity = getBlocksPerLayer() * layers; + inventory = new ItemStack[maxBlockCapacity]; super.readFromNBT(tags); // validStructure = tags.getBoolean("ValidStructure"); internalTemp = tags.getInteger("InternalTemp"); inUse = tags.getBoolean("InUse"); - int[] center = tags.getIntArray("CenterPos"); - if (center.length > 2) - centerPos = new CoordTuple(center[0], center[1], center[2]); - else - centerPos = new CoordTuple(xCoord, yCoord, zCoord); - direction = tags.getByte("Direction"); useTime = tags.getInteger("UseTime"); currentLiquid = tags.getInteger("CurrentLiquid"); @@ -1149,12 +1196,18 @@ public void writeToNBT (NBTTagCompound tags) tags.setInteger("InternalTemp", internalTemp); tags.setBoolean("InUse", inUse); - int[] center = new int[3];// { centerPos.x, centerPos.y, centerPos.z }; - if (centerPos == null) - center = new int[] { xCoord, yCoord, zCoord }; + int[] pos; + if (minPos == null) + pos = new int[] { xCoord, yCoord, zCoord }; + else + pos = new int[] { minPos.x, minPos.y, minPos.z }; + tags.setIntArray("MinPos", pos); + + if (maxPos == null) + pos = new int[] { xCoord, yCoord, zCoord }; else - center = new int[] { centerPos.x, centerPos.y, centerPos.z }; - tags.setIntArray("CenterPos", center); + pos = new int[] { maxPos.x, maxPos.y, maxPos.z }; + tags.setIntArray("MaxPos", pos); tags.setByte("Direction", direction); tags.setInteger("UseTime", useTime); diff --git a/src/main/java/tconstruct/smeltery/logic/SmelteryLogicOld.java b/src/main/java/tconstruct/smeltery/logic/SmelteryLogicOld.java new file mode 100644 index 00000000000..d6b9f7594b5 --- /dev/null +++ b/src/main/java/tconstruct/smeltery/logic/SmelteryLogicOld.java @@ -0,0 +1,1237 @@ +package tconstruct.smeltery.logic; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import mantle.blocks.abstracts.InventoryLogic; +import mantle.blocks.abstracts.MultiServantLogic; +import mantle.blocks.iface.IActiveLogic; +import mantle.blocks.iface.IFacingLogic; +import mantle.blocks.iface.IMasterLogic; +import mantle.blocks.iface.IServantLogic; +import mantle.world.CoordTuple; +import net.minecraft.block.Block; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.monster.EntityEnderman; +import net.minecraft.entity.monster.EntityIronGolem; +import net.minecraft.entity.passive.EntityHorse; +import net.minecraft.entity.passive.EntityVillager; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.inventory.Container; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.Packet; +import net.minecraft.network.play.server.S35PacketUpdateTileEntity; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.IIcon; +import net.minecraft.util.MathHelper; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; +import net.minecraftforge.fluids.IFluidHandler; +import net.minecraftforge.fluids.IFluidTank; +import tconstruct.library.crafting.Smeltery; +import tconstruct.smeltery.SmelteryDamageSource; +import tconstruct.smeltery.TinkerSmeltery; +import tconstruct.smeltery.inventory.SmelteryContainerOld; +import tconstruct.util.config.PHConstruct; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +/* Simple class for storing items in the block + */ + +public class SmelteryLogicOld extends InventoryLogic implements IActiveLogic, IFacingLogic, IFluidTank, IMasterLogic +{ + public boolean validStructure; + public boolean tempValidStructure; + byte direction; + int internalTemp; + public int useTime; + public int fuelGague; + public int fuelAmount; + boolean inUse; + + ArrayList lavaTanks; + CoordTuple activeLavaTank; + public CoordTuple centerPos = new CoordTuple(0, 0, 0); + + public int[] activeTemps; // values are multiplied by 10 + public int[] meltingTemps; // values are multiplied by 10 + int tick; + + public ArrayList moltenMetal = new ArrayList(); + int maxLiquid; + int currentLiquid; + public int layers; + int slag; + + int numBricks; + + Random rand = new Random(); + boolean needsUpdate; + + public SmelteryLogicOld() + { + super(0); + lavaTanks = new ArrayList(); + activeTemps = new int[0]; + meltingTemps = new int[0]; + } + + void adjustLayers (int lay, boolean forceAdjust) + { + if (lay != layers || forceAdjust) + { + needsUpdate = true; + layers = lay; + maxLiquid = 20000 * lay; + int[] tempActive = activeTemps; + activeTemps = new int[9 * lay]; + int activeLength = tempActive.length > activeTemps.length ? activeTemps.length : tempActive.length; + System.arraycopy(tempActive, 0, activeTemps, 0, activeLength); + + int[] tempMelting = meltingTemps; + meltingTemps = new int[9 * lay]; + int meltingLength = tempMelting.length > meltingTemps.length ? meltingTemps.length : tempMelting.length; + System.arraycopy(tempMelting, 0, meltingTemps, 0, meltingLength); + + ItemStack[] tempInv = inventory; + inventory = new ItemStack[9 * lay]; + int invLength = tempInv.length > inventory.length ? inventory.length : tempInv.length; + System.arraycopy(tempInv, 0, inventory, 0, invLength); + + if (activeTemps.length > 0 && activeTemps.length > tempActive.length) + { + for (int i = tempActive.length; i < activeTemps.length; i++) + { + activeTemps[i] = 200; + meltingTemps[i] = 200; + } + } + + if (tempInv.length > inventory.length) + { + for (int i = inventory.length; i < tempInv.length; i++) + { + ItemStack stack = tempInv[i]; + if (stack != null) + { + float jumpX = rand.nextFloat() * 0.8F + 0.1F; + float jumpY = rand.nextFloat() * 0.8F + 0.1F; + float jumpZ = rand.nextFloat() * 0.8F + 0.1F; + + int offsetX = 0; + int offsetZ = 0; + switch (getRenderDirection()) + { + case 2: // +z + offsetZ = -1; + break; + case 3: // -z + offsetZ = 1; + break; + case 4: // +x + offsetX = -1; + break; + case 5: // -x + offsetX = 1; + break; + } + + while (stack.stackSize > 0) + { + int itemSize = rand.nextInt(21) + 10; + + if (itemSize > stack.stackSize) + { + itemSize = stack.stackSize; + } + + stack.stackSize -= itemSize; + EntityItem entityitem = new EntityItem(worldObj, (double) ((float) xCoord + jumpX + offsetX), (double) ((float) yCoord + jumpY), (double) ((float) zCoord + jumpZ + offsetZ), new ItemStack(stack.getItem(), itemSize, stack.getItemDamage())); + + if (stack.hasTagCompound()) + { + entityitem.getEntityItem().setTagCompound((NBTTagCompound) stack.getTagCompound().copy()); + } + + float offset = 0.05F; + entityitem.motionX = (double) ((float) rand.nextGaussian() * offset); + entityitem.motionY = (double) ((float) rand.nextGaussian() * offset + 0.2F); + entityitem.motionZ = (double) ((float) rand.nextGaussian() * offset); + worldObj.spawnEntityInWorld(entityitem); + } + } + } + } + } + } + + /* Misc */ + @Override + public String getDefaultName () + { + return "crafters.Smeltery"; + } + + @Override + public Container getGuiContainer (InventoryPlayer inventoryplayer, World world, int x, int y, int z) + { + return new SmelteryContainerOld(inventoryplayer, this); + } + + @Override + public byte getRenderDirection () + { + return direction; + } + + @Override + public ForgeDirection getForgeDirection () + { + return ForgeDirection.VALID_DIRECTIONS[direction]; + } + + @Override + public void setDirection (int side) + { + + } + + @Override + public void setDirection (float yaw, float pitch, EntityLivingBase player) + { + int facing = MathHelper.floor_double((double) (yaw / 360) + 0.5D) & 3; + switch (facing) + { + case 0: + direction = 2; + break; + + case 1: + direction = 5; + break; + + case 2: + direction = 3; + break; + + case 3: + direction = 4; + break; + } + } + + @Override + public boolean getActive () + { + return validStructure; + } + + @Override + public void setActive (boolean flag) + { + needsUpdate = true; + worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); + } + + public int getScaledFuelGague (int scale) + { + int ret = (fuelGague * scale) / 52; + if (ret < 1) + ret = 1; + return ret; + } + + public int getInternalTemperature () + { + if (!validStructure) + return 20; + + return internalTemp; + } + + public int getTempForSlot (int slot) + { + return activeTemps[slot] / 10; + } + + public int getMeltingPointForSlot (int slot) + { + return meltingTemps[slot] / 10; + } + + /* Updating */ + @Override + public void updateEntity () + { + /* + * if (worldObj.isRemote) return; + */ + tick++; + if (tick % 4 == 0) + heatItems(); + + if (tick % 20 == 0) + { + if (!validStructure) + checkValidPlacement(); + + if (useTime > 0 && inUse) + useTime -= 3; + + if (validStructure && useTime <= 0) + { + updateFuelGague(); + } + + if (needsUpdate) + { + needsUpdate = false; + worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); + } + } + + if (tick == 60) + { + tick = 0; + detectEntities(); + } + } + + void detectEntities () + { + if (centerPos == null) + return; + + AxisAlignedBB box = AxisAlignedBB.getBoundingBox(centerPos.x, centerPos.y, centerPos.z, centerPos.x + 1.0D, centerPos.y + 1.0D, centerPos.z + 1.0D).expand(1.0D, 0.0D, 1.0D); + + List list = worldObj.getEntitiesWithinAABB(Entity.class, box); + for (Object o : list) + { + if (moltenMetal.size() >= 1) + { + if (o instanceof EntityVillager) + { + EntityVillager villager = (EntityVillager) o; + if (villager.attackEntityFrom(new SmelteryDamageSource(), 5)) + { + if (currentLiquid + 40 < maxLiquid) + { + int amount = villager.isChild() ? 5 : 40; + this.fill(new FluidStack(TinkerSmeltery.moltenEmeraldFluid, amount), true); + } + } + } + else if (o instanceof EntityEnderman) + { + EntityEnderman villager = (EntityEnderman) o; + if (villager.attackEntityFrom(new SmelteryDamageSource(), 5)) + { + if (currentLiquid + 125 < maxLiquid) + { + this.fill(new FluidStack(TinkerSmeltery.moltenEnderFluid, 125), true); + } + } + } + else if (o instanceof EntityIronGolem) + { + EntityIronGolem golem = (EntityIronGolem) o; + if (golem.attackEntityFrom(new SmelteryDamageSource(), 5)) + { + if (currentLiquid + 40 < maxLiquid) + { + this.fill(new FluidStack(TinkerSmeltery.moltenIronFluid, 40), true); + } + } + } + else if (o instanceof EntityHorse) + { + EntityHorse horse = (EntityHorse) o; + if (PHConstruct.meltableHorses && horse.attackEntityFrom(new SmelteryDamageSource(), 5)) + { + if (currentLiquid + 108 < maxLiquid) + { + this.fill(new FluidStack(TinkerSmeltery.glueFluid, 108), true); + } + } + } + else if (o instanceof EntityLivingBase) + { + EntityLivingBase living = (EntityLivingBase) o; + if (living.attackEntityFrom(new SmelteryDamageSource(), 5)) + { + if (currentLiquid + 40 < maxLiquid) + { + int amount = (living.isChild() || living instanceof EntityPlayer) ? 5 : 40; + this.fill(new FluidStack(TinkerSmeltery.bloodFluid, amount), true); + } + } + } + } + else if (PHConstruct.throwableSmeltery && o instanceof EntityItem) + { + handleItemEntity((EntityItem) o); + } + } + } + + private void handleItemEntity (EntityItem item) + { + // Clients like to play merry hell with this and cause breakage (we + // update their inv on syncs) + if (worldObj.isRemote) + return; + + item.age = 0; + ItemStack istack = item.getEntityItem(); + if (istack == null || istack.stackSize <= 0) // Probably most definitely + // not necessary + return; + + int maxSlot = this.getSizeInventory(); + boolean itemDestroyed = false; + boolean itemAdded = false; + + for (int i = 0; i < maxSlot; i++) + { + ItemStack stack = this.getStackInSlot(i); + if (stack == null && istack.stackSize > 0) + { + ItemStack copy = istack.splitStack(1); + this.setInventorySlotContents(i, copy); + itemAdded = true; + if (istack.stackSize <= 0) + { + item.setDead(); + itemDestroyed = true; + break; + } + } + } + + if (!itemDestroyed) + item.setEntityItemStack(istack); + if (itemAdded) + { + this.needsUpdate = true; + //TODO 1.7.5 send description packet in better way to not cause render update + this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); + } + } + + private void heatItems () + { + if (useTime > 0) + { + boolean hasUse = false; + int temperature = this.getInternalTemperature(); + int speed = temperature / 100; + int refTemp = temperature * 10; + for (int i = 0; i < 9 * layers; i++) + { + if (meltingTemps[i] > 200 && this.isStackInSlot(i)) + { + hasUse = true; + if (activeTemps[i] < refTemp && activeTemps[i] < meltingTemps[i]) + { + activeTemps[i] += speed; // lava has temp of 1000. we increase by 10 per application. + } + else if (activeTemps[i] >= meltingTemps[i]) + { + if (!worldObj.isRemote) + { + FluidStack result = getResultFor(inventory[i]); + if (result != null) + { + if (addMoltenMetal(result, false)) + { + inventory[i] = null; + activeTemps[i] = 200; + ArrayList alloys = Smeltery.mixMetals(moltenMetal); + for (int al = 0; al < alloys.size(); al++) + { + FluidStack liquid = (FluidStack) alloys.get(al); + addMoltenMetal(liquid, true); + } + markDirty(); + } + } + } + } + + } + + else + activeTemps[i] = 200; + } + inUse = hasUse; + } + } + + boolean addMoltenMetal (FluidStack liquid, boolean first) + { + needsUpdate = true; + if (moltenMetal.size() == 0) + { + moltenMetal.add(liquid.copy()); + currentLiquid += liquid.amount; + return true; + } + else + { + if (liquid.amount + currentLiquid > maxLiquid) + return false; + + currentLiquid += liquid.amount; + // TConstruct.logger.info("Current liquid: "+currentLiquid); + boolean added = false; + for (int i = 0; i < moltenMetal.size(); i++) + { + FluidStack l = moltenMetal.get(i); + // if (l.itemID == liquid.itemID && l.itemMeta == + // liquid.itemMeta) + if (l.isFluidEqual(liquid)) + { + l.amount += liquid.amount; + added = true; + } + if (l.amount <= 0) + { + moltenMetal.remove(l); + i--; + } + } + if (!added) + { + if (first) + moltenMetal.add(0, liquid.copy()); + else + moltenMetal.add(liquid.copy()); + } + return true; + } + } + + private void updateTemperatures () + { + inUse = true; + for (int i = 0; i < 9 * layers; i++) + { + meltingTemps[i] = Smeltery.getLiquifyTemperature(inventory[i]) * 10; // temperatures are *10 for more progress control + } + } + + public void updateFuelDisplay () + { + if (activeLavaTank == null) + return; + + if (!worldObj.blockExists(activeLavaTank.x, activeLavaTank.y, activeLavaTank.z)) + { + fuelAmount = 0; + fuelGague = 0; + return; + } + + TileEntity tankContainer = worldObj.getTileEntity(activeLavaTank.x, activeLavaTank.y, activeLavaTank.z); + if (tankContainer == null) + { + fuelAmount = 0; + fuelGague = 0; + return; + } + + if (tankContainer instanceof IFluidHandler) + { + FluidStack liquid = ((IFluidHandler) tankContainer).drain(ForgeDirection.DOWN, 4000, false); + if (liquid != null && Smeltery.isSmelteryFuel(liquid.getFluid())) + { + FluidTankInfo[] info = ((IFluidHandler) tankContainer).getTankInfo(ForgeDirection.DOWN); + if (info.length > 0) + { + int capacity = info[0].capacity; + fuelAmount = liquid.amount; + fuelGague = liquid.amount * 52 / capacity; + } + } + else + { + fuelAmount = 0; + fuelGague = 0; + } + } + + } + + public void updateFuelGague () + { + if (activeLavaTank == null || useTime > 0) + return; + + if (!worldObj.blockExists(activeLavaTank.x, activeLavaTank.y, activeLavaTank.z)) + { + fuelAmount = 0; + fuelGague = 0; + return; + } + + TileEntity tankContainer = worldObj.getTileEntity(activeLavaTank.x, activeLavaTank.y, activeLavaTank.z); + if (tankContainer == null) + { + fuelAmount = 0; + fuelGague = 0; + return; + } + if (tankContainer instanceof IFluidHandler) + { + needsUpdate = true; + FluidStack liquid = ((IFluidHandler) tankContainer).drain(ForgeDirection.DOWN, 15, false); + if (liquid != null && Smeltery.isSmelteryFuel(liquid.getFluid())) + { + liquid = ((IFluidHandler) tankContainer).drain(ForgeDirection.DOWN, 15, true); + useTime += Smeltery.getFuelDuration(liquid.getFluid()); + internalTemp = Smeltery.getFuelPower(liquid.getFluid()); + + FluidTankInfo[] info = ((IFluidHandler) tankContainer).getTankInfo(ForgeDirection.DOWN); + liquid = info[0].fluid; + int capacity = info[0].capacity; + if (liquid != null) + { + fuelAmount = liquid.amount; + fuelGague = liquid.amount * 52 / capacity; + } + else + { + fuelAmount = 0; + fuelGague = 0; + } + } + else + { + boolean foundTank = false; + int iter = 0; + while (!foundTank) + { + CoordTuple possibleTank = lavaTanks.get(iter); + TileEntity newTankContainer = worldObj.getTileEntity(possibleTank.x, possibleTank.y, possibleTank.z); + if (newTankContainer instanceof IFluidHandler) + { + // TConstruct.logger.info("Tank: "+possibleTank.toString()); + FluidStack newliquid = ((IFluidHandler) newTankContainer).drain(ForgeDirection.UNKNOWN, 150, false); + if (newliquid != null && Smeltery.isSmelteryFuel(newliquid.getFluid()) && newliquid.amount > 0) + { + // TConstruct.logger.info("Tank: "+possibleTank.toString()); + foundTank = true; + activeLavaTank = possibleTank; + iter = lavaTanks.size(); + + /* + * IFluidTank newTank = ((IFluidHandler) + * newTankContainer).getTank(ForgeDirection.UNKNOWN, + * liquid); liquid = newTank.getFluid(); int + * capacity = newTank.getCapacity(); + */ + FluidTankInfo[] info = ((IFluidHandler) tankContainer).getTankInfo(ForgeDirection.DOWN); + liquid = info[0].fluid; + int capacity = info[0].capacity; + if (liquid != null) + { + fuelAmount = liquid.amount; + fuelGague = liquid.amount * 52 / capacity; + } + else + { + fuelAmount = 0; + fuelGague = 0; + } + } + } + iter++; + if (iter >= lavaTanks.size()) + foundTank = true; + } + // TConstruct.logger.info("Searching for tank, size: "+lavaTanks.size()); + } + } + } + + @SideOnly(Side.CLIENT) + public IIcon getFuelIcon () + { + IIcon defaultLava = Blocks.lava.getIcon(0, 0); + if (activeLavaTank == null) + return defaultLava; + + TileEntity tankContainer = worldObj.getTileEntity(activeLavaTank.x, activeLavaTank.y, activeLavaTank.z); + if (tankContainer instanceof IFluidHandler) + return ((IFluidHandler) tankContainer).getTankInfo(ForgeDirection.DOWN)[0].fluid.getFluid().getStillIcon(); + + return defaultLava; + } + + public FluidStack getResultFor (ItemStack stack) + { + return Smeltery.getSmelteryResult(stack); + } + + /* Inventory */ + /* + * public int getMaxStackStackSize (ItemStack stack) { FluidStack liquid = + * getResultFor(stack); if (liquid == null) return 0; return liquid.amount; + * } + */ + + @Override + public int getInventoryStackLimit () + { + return 1; + } + + @Override + public void markDirty () + { + updateTemperatures(); + updateEntity(); + super.markDirty(); + needsUpdate = true; + // worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); + // worldObj.markBlockForRenderUpdate(xCoord, yCoord, zCoord); + } + + /* + * @Override public void setInventorySlotContents (int slot, ItemStack + * itemstack) { inventory[slot] = itemstack != null ? + * itemstack.splitStack(1) : null; //May include unintended side effects. + * Possible fix for max stack size of 1? } + */ + + /* Multiblock */ + @Override + public void notifyChange (IServantLogic servant, int x, int y, int z) + { + checkValidPlacement(); + } + + public void checkValidPlacement () + { + switch (getRenderDirection()) + { + case 2: // +z + alignInitialPlacement(xCoord, yCoord, zCoord + 2); + break; + case 3: // -z + alignInitialPlacement(xCoord, yCoord, zCoord - 2); + break; + case 4: // +x + alignInitialPlacement(xCoord + 2, yCoord, zCoord); + break; + case 5: // -x + alignInitialPlacement(xCoord - 2, yCoord, zCoord); + break; + } + } + + public void alignInitialPlacement (int x, int y, int z) + { + Block northBlock = worldObj.getBlock(x, y, z + 1); + Block southBlock = worldObj.getBlock(x, y, z - 1); + Block eastBlock = worldObj.getBlock(x + 1, y, z); + Block westBlock = worldObj.getBlock(x - 1, y, z); + + if ((northBlock == null || worldObj.isAirBlock(x, y, z + 1)) && (southBlock == null || worldObj.isAirBlock(x, y, z - 1)) && (eastBlock == null || worldObj.isAirBlock(x + 1, y, z)) && (westBlock == null || worldObj.isAirBlock(x - 1, y, z))) + { + checkValidStructure(x, y, z); + } + + else if ((northBlock != null && !worldObj.isAirBlock(x, y, z + 1)) && (southBlock == null || worldObj.isAirBlock(x, y, z - 1)) && (eastBlock == null || worldObj.isAirBlock(x + 1, y, z)) && (westBlock == null || worldObj.isAirBlock(x - 1, y, z))) + { + checkValidStructure(x, y, z - 1); + } + + else if ((northBlock == null || worldObj.isAirBlock(x, y, z + 1)) && (southBlock != null && !worldObj.isAirBlock(x, y, z - 1)) && (eastBlock == null || worldObj.isAirBlock(x + 1, y, z)) && (westBlock == null || worldObj.isAirBlock(x - 1, y, z))) + { + checkValidStructure(x, y, z + 1); + } + + else if ((northBlock == null || worldObj.isAirBlock(x, y, z + 1)) && (southBlock == null || worldObj.isAirBlock(x, y, z - 1)) && (eastBlock != null && !worldObj.isAirBlock(x + 1, y, z)) && (westBlock == null || worldObj.isAirBlock(x - 1, y, z))) + { + checkValidStructure(x - 1, y, z); + } + + else if ((northBlock == null || worldObj.isAirBlock(x, y, z + 1)) && (southBlock == null || worldObj.isAirBlock(x, y, z - 1)) && (eastBlock == null || worldObj.isAirBlock(x + 1, y, z)) && (westBlock != null && !worldObj.isAirBlock(x - 1, y, z))) + { + checkValidStructure(x + 1, y, z); + } + + // Not valid, sorry + } + + public void checkValidStructure (int x, int y, int z) + { + int checkLayers = 0; + tempValidStructure = false; + if (checkSameLevel(x, y, z)) + { + checkLayers++; + checkLayers += recurseStructureUp(x, y + 1, z, 0); + checkLayers += recurseStructureDown(x, y - 1, z, 0); + } + + // maxLiquid = capacity * 20000; + + if (tempValidStructure != validStructure || checkLayers != this.layers) + { + if (tempValidStructure) + { + // try to derive temperature from fueltank + activeLavaTank = null; + for (CoordTuple tank : lavaTanks) + { + TileEntity tankContainer = worldObj.getTileEntity(tank.x, tank.y, tank.z); + if (!(tankContainer instanceof IFluidHandler)) + continue; + + FluidStack liquid = ((IFluidHandler) tankContainer).getTankInfo(ForgeDirection.DOWN)[0].fluid; + if (liquid == null) + continue; + if (!Smeltery.isSmelteryFuel(liquid.getFluid())) + continue; + + internalTemp = Smeltery.getFuelPower(liquid.getFluid()); + activeLavaTank = tank; + break; + } + + // no tank with fuel. we reserve the first found one + if (activeLavaTank == null) + activeLavaTank = lavaTanks.get(0); + + // update other stuff + adjustLayers(checkLayers, false); + worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); + validStructure = true; + } + else + { + internalTemp = 20; + validStructure = false; + } + } + } + + public boolean checkSameLevel (int x, int y, int z) + { + numBricks = 0; + lavaTanks.clear(); + Block block; + + // Check inside + for (int xPos = x - 1; xPos <= x + 1; xPos++) + { + for (int zPos = z - 1; zPos <= z + 1; zPos++) + { + block = worldObj.getBlock(xPos, y, zPos); + if (block != null && !worldObj.isAirBlock(xPos, y, zPos)) + return false; + } + } + + // Check outer layer + for (int xPos = x - 1; xPos <= x + 1; xPos++) + { + numBricks += checkBricks(xPos, y, z - 2); + numBricks += checkBricks(xPos, y, z + 2); + } + + for (int zPos = z - 1; zPos <= z + 1; zPos++) + { + numBricks += checkBricks(x - 2, y, zPos); + numBricks += checkBricks(x + 2, y, zPos); + } + + if (numBricks == 12 && lavaTanks.size() > 0) + return true; + else + return false; + } + + public int recurseStructureUp (int x, int y, int z, int count) + { + numBricks = 0; + // Check inside + for (int xPos = x - 1; xPos <= x + 1; xPos++) + { + for (int zPos = z - 1; zPos <= z + 1; zPos++) + { + Block block = worldObj.getBlock(xPos, y, zPos); + if (block != null && !worldObj.isAirBlock(xPos, y, zPos)) + return count; + } + } + + // Check outer layer + for (int xPos = x - 1; xPos <= x + 1; xPos++) + { + numBricks += checkBricks(xPos, y, z - 2); + numBricks += checkBricks(xPos, y, z + 2); + } + + for (int zPos = z - 1; zPos <= z + 1; zPos++) + { + numBricks += checkBricks(x - 2, y, zPos); + numBricks += checkBricks(x + 2, y, zPos); + } + + if (numBricks != 12) + return count; + + count++; + return recurseStructureUp(x, y + 1, z, count); + } + + public int recurseStructureDown (int x, int y, int z, int count) + { + numBricks = 0; + // Check inside + for (int xPos = x - 1; xPos <= x + 1; xPos++) + { + for (int zPos = z - 1; zPos <= z + 1; zPos++) + { + Block blockID = worldObj.getBlock(xPos, y, zPos); + if (blockID != null && !worldObj.isAirBlock(xPos, y, zPos)) + { + if (validBlockID(blockID)) + return validateBottom(x, y, z, count); + else + return count; + } + } + } + + // Check outer layer + for (int xPos = x - 1; xPos <= x + 1; xPos++) + { + numBricks += checkBricks(xPos, y, z - 2); + numBricks += checkBricks(xPos, y, z + 2); + } + + for (int zPos = z - 1; zPos <= z + 1; zPos++) + { + numBricks += checkBricks(x - 2, y, zPos); + numBricks += checkBricks(x + 2, y, zPos); + } + + if (numBricks != 12) + return count; + + count++; + return recurseStructureDown(x, y - 1, z, count); + } + + public int validateBottom (int x, int y, int z, int count) + { + int bottomBricks = 0; + for (int xPos = x - 1; xPos <= x + 1; xPos++) + { + for (int zPos = z - 1; zPos <= z + 1; zPos++) + { + if (validBlockID(worldObj.getBlock(xPos, y, zPos)) && (worldObj.getBlockMetadata(xPos, y, zPos) >= 2)) + bottomBricks++; + } + } + + if (bottomBricks == 9) + { + tempValidStructure = true; + centerPos = new CoordTuple(x, y + 1, z); + } + return count; + } + + /* + * Returns whether the brick is a lava tank or not. Increments bricks, sets + * them as part of the structure, and adds tanks to the list. + */ + int checkBricks (int x, int y, int z) + { + int tempBricks = 0; + Block blockID = worldObj.getBlock(x, y, z); + if (validBlockID(blockID) || validTankID(blockID)) + { + TileEntity te = worldObj.getTileEntity(x, y, z); + if (te == this) + { + tempBricks++; + } + else if (te instanceof MultiServantLogic) + { + MultiServantLogic servant = (MultiServantLogic) te; + if (servant.hasValidMaster()) + { + if (servant.verifyMaster(this, this.xCoord, this.yCoord, this.zCoord)) + tempBricks++; + } + else if (servant.setMaster(this.xCoord, this.yCoord, this.zCoord)) + { + tempBricks++; + } + + if (te instanceof LavaTankLogic) + { + lavaTanks.add(new CoordTuple(x, y, z)); + } + } + } + return tempBricks; + } + + boolean validBlockID (Block blockID) + { + return blockID == TinkerSmeltery.smeltery || blockID == TinkerSmeltery.smelteryNether; + } + + boolean validTankID (Block blockID) + { + return blockID == TinkerSmeltery.lavaTank || blockID == TinkerSmeltery.lavaTankNether; + } + + @Override + public int getCapacity () + { + return maxLiquid; + } + + public int getTotalLiquid () + { + return currentLiquid; + } + + @Override + public FluidStack drain (int maxDrain, boolean doDrain) + { + if (moltenMetal.size() == 0) + return null; + + FluidStack liquid = moltenMetal.get(0); + if (liquid != null) + { + if (liquid.amount - maxDrain <= 0) + { + FluidStack liq = liquid.copy(); + if (doDrain) + { + // liquid = null; + moltenMetal.remove(liquid); + worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); + currentLiquid = 0; + needsUpdate = true; + } + return liq; + } + else + { + if (doDrain && maxDrain > 0) + { + liquid.amount -= maxDrain; + worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); + currentLiquid -= maxDrain; + needsUpdate = true; + } + return new FluidStack(liquid.fluidID, maxDrain, liquid.tag); + } + } + else + { + return new FluidStack(0, 0); + } + } + + @Override + public int fill (FluidStack resource, boolean doFill) + { + if (resource != null && currentLiquid < maxLiquid)// resource.amount + + // currentLiquid < + // maxLiquid) + { + if (resource.amount + currentLiquid > maxLiquid) + resource.amount = maxLiquid - currentLiquid; + int amount = resource.amount; + + if (amount > 0 && doFill) + { + if (addMoltenMetal(resource, false)) + { + ArrayList alloys = Smeltery.mixMetals(moltenMetal); + for (int al = 0; al < alloys.size(); al++) + { + FluidStack liquid = (FluidStack) alloys.get(al); + addMoltenMetal(liquid, true); + } + } + needsUpdate = true; + worldObj.func_147479_m(xCoord, yCoord, zCoord); + } + return amount; + } + else + return 0; + } + + @Override + public FluidStack getFluid () + { + if (moltenMetal.size() == 0) + return null; + return moltenMetal.get(0); + } + + @Override + public int getFluidAmount () + { + return currentLiquid; + } + + @Override + public FluidTankInfo getInfo () + { + return new FluidTankInfo(this); + } + + public FluidTankInfo[] getMultiTankInfo () + { + FluidTankInfo[] info = new FluidTankInfo[moltenMetal.size() + 1]; + for (int i = 0; i < moltenMetal.size(); i++) + { + FluidStack fluid = moltenMetal.get(i); + info[i] = new FluidTankInfo(fluid.copy(), fluid.amount); + } + info[moltenMetal.size()] = new FluidTankInfo(null, maxLiquid - currentLiquid); + return info; + } + + /* NBT */ + + @Override + public void readFromNBT (NBTTagCompound tags) + { + layers = tags.getInteger("Layers"); + inventory = new ItemStack[layers * 9]; + super.readFromNBT(tags); + + // validStructure = tags.getBoolean("ValidStructure"); + internalTemp = tags.getInteger("InternalTemp"); + inUse = tags.getBoolean("InUse"); + + int[] center = tags.getIntArray("CenterPos"); + if (center.length > 2) + centerPos = new CoordTuple(center[0], center[1], center[2]); + else + centerPos = new CoordTuple(xCoord, yCoord, zCoord); + + direction = tags.getByte("Direction"); + useTime = tags.getInteger("UseTime"); + currentLiquid = tags.getInteger("CurrentLiquid"); + maxLiquid = tags.getInteger("MaxLiquid"); + meltingTemps = tags.getIntArray("MeltingTemps"); + activeTemps = tags.getIntArray("ActiveTemps"); + + NBTTagList liquidTag = tags.getTagList("Liquids", 10); + moltenMetal.clear(); + + for (int iter = 0; iter < liquidTag.tagCount(); iter++) + { + NBTTagCompound nbt = (NBTTagCompound) liquidTag.getCompoundTagAt(iter); + FluidStack fluid = FluidStack.loadFluidStackFromNBT(nbt); + if (fluid != null) + moltenMetal.add(fluid); + } + // adjustLayers(layers, true); + // checkValidPlacement(); + } + + @Override + public void writeToNBT (NBTTagCompound tags) + { + super.writeToNBT(tags); + + // tags.setBoolean("ValidStructure", validStructure); + tags.setInteger("InternalTemp", internalTemp); + tags.setBoolean("InUse", inUse); + + int[] center = new int[3];// { centerPos.x, centerPos.y, centerPos.z }; + if (centerPos == null) + center = new int[] { xCoord, yCoord, zCoord }; + else + center = new int[] { centerPos.x, centerPos.y, centerPos.z }; + tags.setIntArray("CenterPos", center); + + tags.setByte("Direction", direction); + tags.setInteger("UseTime", useTime); + tags.setInteger("CurrentLiquid", currentLiquid); + tags.setInteger("MaxLiquid", maxLiquid); + tags.setInteger("Layers", layers); + tags.setIntArray("MeltingTemps", meltingTemps); + tags.setIntArray("ActiveTemps", activeTemps); + + NBTTagList taglist = new NBTTagList(); + for (FluidStack liquid : moltenMetal) + { + NBTTagCompound nbt = new NBTTagCompound(); + liquid.writeToNBT(nbt); + taglist.appendTag(nbt); + } + + tags.setTag("Liquids", taglist); + } + + /* Packets */ + @Override + public Packet getDescriptionPacket () + { + NBTTagCompound tag = new NBTTagCompound(); + writeToNBT(tag); + return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 1, tag); + } + + @Override + public void onDataPacket (NetworkManager net, S35PacketUpdateTileEntity packet) + { + readFromNBT(packet.func_148857_g()); + markDirty(); + worldObj.func_147479_m(xCoord, yCoord, zCoord); + this.needsUpdate = true; + } + + @Override + public String getInventoryName () + { + return getDefaultName(); + } + + @Override + public boolean hasCustomInventoryName () + { + return true; + } + + @Override + public void closeInventory () + { + } + + @Override + public void openInventory () + { + } +} diff --git a/src/main/java/tconstruct/smeltery/model/SmelteryRender.java b/src/main/java/tconstruct/smeltery/model/SmelteryRender.java index bd5aa438c5b..a11af5fbb0d 100644 --- a/src/main/java/tconstruct/smeltery/model/SmelteryRender.java +++ b/src/main/java/tconstruct/smeltery/model/SmelteryRender.java @@ -44,7 +44,8 @@ public boolean renderSmeltery (IBlockAccess world, int x, int y, int z, Block bl SmelteryLogic logic = (SmelteryLogic) world.getTileEntity(x, y, z); if (logic.validStructure) { - int posX = logic.centerPos.x - 1, posY = logic.centerPos.y, posZ = logic.centerPos.z - 1; + //int posX = logic.centerPos.x - 1, posY = logic.centerPos.y, posZ = logic.centerPos.z - 1; + int posX = logic.minPos.x, posY = logic.minPos.y, posZ = logic.minPos.z; // todo: proper rendering //Melting if (logic.getSizeInventory() > 0) { diff --git a/src/main/java/tconstruct/util/config/PHConstruct.java b/src/main/java/tconstruct/util/config/PHConstruct.java index fc9367ed8f0..5720cf5ee92 100644 --- a/src/main/java/tconstruct/util/config/PHConstruct.java +++ b/src/main/java/tconstruct/util/config/PHConstruct.java @@ -350,7 +350,7 @@ public static void initProps (File location) // Experimental functionality public static boolean throwableSmeltery; public static boolean newSmeltery; - public static boolean newerSmeltery = true; + public static boolean oldSmeltery; public static boolean meltableHorses; }