Posted March 15, 20169 yr I'm trying to make a tile entity that when one presses a button on it, it will make an item. Whenever I try to take the item or click it for that matter, it disappears. Also, I've been reading on how the "server" in Minecraft should handle everything to prevent hacking. I'm not sure if I'm doing that right and I was hoping for some help on resolving this issue with the items disappearing and just being sure that hacking won't happen with my mod. Thanks to anyone that helps. Block Class: package com.littlepup.xcom.blocks.engineering_block; import com.littlepup.xcom.XcomMain; import com.littlepup.xcom.packets.XcomGuiHandler; import net.minecraft.block.Block; import net.minecraft.block.BlockContainer; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockPos; import net.minecraft.util.EnumFacing; import net.minecraft.world.World; public class BlockEngineeringPanel extends BlockContainer { public BlockEngineeringPanel(Material materialIn) { super(materialIn); this.setBlockUnbreakable(); this.setCreativeTab(XcomMain.xcomTab); this.setUnlocalizedName("engineering_block"); } @Override public TileEntity createNewTileEntity(World world, int meta) { return new TileEntityEngineerPanel(); } @Override public int getRenderType() { return 3; } @Override public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumFacing side, float hitX, float hitY, float hitZ) { if(!world.isRemote) { player.openGui(XcomMain.instance, XcomGuiHandler.engineerPanelGui, world, pos.getX(), pos.getY(), pos.getZ()); } return true; } } TileEntity Class package com.littlepup.xcom.blocks.engineering_block; import java.util.List; import com.google.common.collect.Lists; import com.littlepup.xcom.blocks.control_block.TileEntityControlPanel; import com.littlepup.xcom.blocks.research_block.TileEntityResearchPanel; import com.littlepup.xcom.items.ItemAlienMaterials; import com.littlepup.xcom.items.ItemAlienSpecies; import com.littlepup.xcom.items.ItemAlienTrophy; import com.littlepup.xcom.projects.EngineeringProject; import com.littlepup.xcom.projects.ResearchProject; import com.littlepup.xcom.projects.XcomEngineeringProjects; import com.littlepup.xcom.utilities.Utilities; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.Container; import net.minecraft.inventory.IInventory; 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.server.gui.IUpdatePlayerListBox; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockPos; import net.minecraft.util.ChatComponentText; import net.minecraft.util.IChatComponent; import net.minecraft.world.IInteractionObject; public class TileEntityEngineerPanel extends TileEntity implements IInventory, IUpdatePlayerListBox, IInteractionObject { public TileEntityEngineerPanel() { this.storedMaterials = new ItemStack[this.getSizeInventory()]; } public TileEntityControlPanel associatedBase; public ItemStack[] storedMaterials; private ItemStack[] usingMaterials = {null, null, null, null, null, null}; boolean isManufacturing = false; EngineeringProject currentProject; List allProjects = XcomEngineeringProjects.getEngineeringProjects(); List availibleProjects; long timeNeeded; int amount = 1; int assocX = -1; int assocY = -1; int assocZ = -1; public void setControlBlock(BlockPos pos) { this.assocX = pos.getX(); this.assocY = pos.getY(); this.assocZ = pos.getZ(); System.out.println("The associated block position is " + assocX + ", " + assocY + ", " + assocZ); this.worldObj.markBlockForUpdate(this.getPos()); this.markDirty(); } @Override public void update() { if(this.isManufacturing()) { EngineeringProject eProj = this.currentProject; if(eProj.timeCost == 0) { this.endManufacturing(eProj); } else if(this.timeNeeded <= 0) { this.endManufacturing(eProj); } else { this.timeNeeded--; } } } public void startManufacturing(EngineeringProject project) { ItemStack[] needed = project.getMaterialsNeeded(); if(needed != null) { for(int l = 0; l < needed.length; l++) { int i1 = ((l + (needed.length * this.amount)) % (needed.length * this.amount)); int used = needed[i1].stackSize * this.amount - this.getStackInSlot(l).stackSize; if(used > 1) { ItemStack stack = new ItemStack(needed[i1].getItem(), used, needed[i1].getMetadata()); this.setInventorySlotContents(l, stack); } else { if(needed[i1].getItem() instanceof ItemAlienMaterials || needed[i1].getItem() instanceof ItemAlienTrophy) { used -= 64; } else { used--; } this.setInventorySlotContents(l, null); } } } else { System.out.println("No materials were needed."); } if(project.timeCost == 0) { ItemStack[] output = project.getOutput(); if(output != null) { for(int l = 0; l < output.length * this.amount; l++) { int i1 = (l + output.length) % output.length; System.out.println("The value of the i1 variable is " + i1); ItemStack stack; if(output[i1].getHasSubtypes()) { stack = new ItemStack(output[i1].getItem(), 1, output[i1].getMetadata()); } else { stack = new ItemStack(output[i1].getItem(), 1, 0); } this.setInventorySlotContents(l + 6, stack); System.out.println("The tile entity slot " + l + " has a/an " + this.getStackInSlot(l + 6).getItem().getUnlocalizedName()); } } else { System.out.println("The project output is null."); } } else { this.currentProject = project; this.timeNeeded = project.timeCost; this.isManufacturing = true; this.worldObj.markBlockForUpdate(this.getPos()); this.markDirty(); } } public void cancelManufacturing(EngineeringProject project) { this.associatedBase.cash += project.getMoneyCost() * this.amount; for(int l = 0; l < 6; l++) { this.setInventorySlotContents(l, this.usingMaterials[l]); } this.isManufacturing = false; this.currentProject = null; } public void endManufacturing(EngineeringProject project) { int cashRefund = Utilities.roundDoubles(currentProject.getMoneyCost() * this.associatedBase.numberWorkshops * 0.10); this.associatedBase.cash += cashRefund; EngineeringProject eProj = this.currentProject; for(int l = 0; l < eProj.getOutput().length * amount; l++) { this.setInventorySlotContents(l + 6, eProj.getOutput()[(eProj.getOutput().length + l) % eProj.getOutput().length]); } this.currentProject = null; this.isManufacturing = false; } public int getRoomNeeded(EngineeringProject project) { ItemStack[] stack = project.getOutput(); int slotsNeeded = 0; for(int i2 = 0; i2 < stack.length; i2++) { int maxSize; if(stack[i2].getItem() instanceof ItemAlienMaterials || stack[i2].getItem() instanceof ItemAlienSpecies) { maxSize = 64; } else { maxSize = 1; } slotsNeeded += Math.ceil(amount/maxSize); } return slotsNeeded; } public List getAvailibleProjects() { System.out.println("The associatedBasePos coordinates are " + assocX + ", " + assocY + ", " + assocZ); this.associatedBase = (TileEntityControlPanel) this.worldObj.getTileEntity(new BlockPos(this.assocX, this.assocY, this.assocZ)); BlockPos rPanelL = new BlockPos(this.associatedBase.rPanelPosX, this.associatedBase.rPanelPosY, this.associatedBase.rPanelPosZ); List researched = ((TileEntityResearchPanel)(this.worldObj.getTileEntity(rPanelL))).researchedProjects; List projects = Lists.newArrayList(); for(int i1 = 0; i1 < allProjects.size(); i1++) { ResearchProject needed = ((EngineeringProject) allProjects.get(i1)).getResearchNeeded(); if(needed == null) { projects.add(allProjects.get(i1)); } else { if(researched.contains(needed)) { projects.add(allProjects.get(i1)); } } } return projects; } public boolean isManufacturing() { return this.isManufacturing; } @Override public String getName() { return ""; } @Override public boolean hasCustomName() { return false; } @Override public int getSizeInventory() { return 12; } @Override public ItemStack getStackInSlot(int index) { ItemStack[] stack = this.storedMaterials; if(index >= stack.length) { index -= 36; } return this.storedMaterials[index]; } @Override public ItemStack decrStackSize(int index, int count) { if(this.getStackInSlot(index) != null) { ItemStack stack; if(this.getStackInSlot(index).stackSize <= count) { stack = this.getStackInSlot(index); this.setInventorySlotContents(index, null); this.markDirty(); return stack; } else { stack = this.getStackInSlot(index).splitStack(count); if(this.getStackInSlot(index).stackSize <= 0) { this.setInventorySlotContents(index, null); } else { this.setInventorySlotContents(index, this.getStackInSlot(index)); } this.markDirty(); return stack; } } else { return null; } } @Override public ItemStack getStackInSlotOnClosing(int index) { ItemStack stack = this.getStackInSlot(index); this.setInventorySlotContents(index, null); return stack; } @Override public void setInventorySlotContents(int index, ItemStack stack) { if(index < 0 || index > this.getSizeInventory()) { return; } if (stack != null && stack.stackSize > this.getInventoryStackLimit()) stack.stackSize = this.getInventoryStackLimit(); if (stack != null && stack.stackSize == 0) stack = null; this.storedMaterials[index] = stack; this.worldObj.markBlockForUpdate(this.getPos()); this.markDirty(); } @Override public int getInventoryStackLimit() { return 64; } @Override public boolean isUseableByPlayer(EntityPlayer player) { return Utilities.getDistance(player.getPosition(), this.getPos()) < 8.0D; } @Override public void openInventory(EntityPlayer player) {} @Override public void closeInventory(EntityPlayer player) {} @Override public boolean isItemValidForSlot(int index, ItemStack stack) { return true; } @Override public int getField(int id) { return 0; } @Override public void setField(int id, int value) {} @Override public int getFieldCount() { return 0; } @Override public void clear() { for(int i = 0; i < this.getSizeInventory(); i++) { this.setInventorySlotContents(i, null); } } @Override public Container createContainer(InventoryPlayer pInventory, EntityPlayer player) { if(!this.worldObj.isRemote) { return new ContainerEngineerPanel(this.worldObj, player, this); } return null; } @Override public String getGuiID() { return "xcom:engineer_panel"; } @Override public void writeToNBT(NBTTagCompound nbtParent) { System.out.println("The writeToNBT is being called."); super.writeToNBT(nbtParent); nbtParent.setInteger("associatedX", this.assocX); nbtParent.setInteger("associatedY", this.assocY); nbtParent.setInteger("associatedZ", this.assocZ); System.out.println("The tile entity's nbt associated BlockPos is being set to " + this.assocX + ", " + this.assocY + ", " + this.assocZ); NBTTagList tag_list = new NBTTagList(); for(int l = 0; l < this.storedMaterials.length; ++l) { if(this.storedMaterials[l] != null) { NBTTagCompound item = new NBTTagCompound(); item.setInteger("slot", l); this.storedMaterials[l].writeToNBT(item); tag_list.appendTag(item); } else { System.out.println("The storedMaterial at " + l + " is null."); } } nbtParent.setTag("stored", tag_list); for(int l = 0; l < nbtParent.getTagList("stored", 10).tagCount(); l++) { NBTTagList list = nbtParent.getTagList("stored", 10); NBTTagCompound nbt = list.getCompoundTagAt(l); System.out.println("The item " + ItemStack.loadItemStackFromNBT(nbt).getItem().getUnlocalizedName() + " in slot " + l); } if(this.worldObj != null) { if(this.worldObj.isRemote) { System.out.println("This was all for a client tile entity."); } else { System.out.println("This was all for a server tile entity."); } } } @Override public void readFromNBT(NBTTagCompound nbtParent) { super.readFromNBT(nbtParent); this.assocX = nbtParent.getInteger("associatedX"); this.assocY = nbtParent.getInteger("associatedY"); this.assocZ = nbtParent.getInteger("associatedZ"); this.storedMaterials = new ItemStack[this.getSizeInventory()]; NBTTagList nbtList = (NBTTagList) nbtParent.getTag("stored"); if(nbtList != null) { System.out.println("The are " + nbtList.tagCount() + " tags in the list."); for(int i1 = 0; i1 < nbtList.tagCount(); ++i1) { NBTTagCompound compound = nbtList.getCompoundTagAt(i1); int i2 = compound.getInteger("slot"); System.out.println("The slot number is " + i2); if(i2 >= 0 && i2 < this.storedMaterials.length) { this.storedMaterials[i1] = ItemStack.loadItemStackFromNBT(compound); System.out.println("The itemstack is being loaded at slot" + i1); } } } else { System.out.println("The nbtList variable in readFromNBT is null."); } if(this.worldObj != null) { if(this.worldObj.isRemote) { System.out.println("This was all for a client tile entity."); } else { System.out.println("This was all for a server tile entity."); } } } @Override public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity packet) { this.readFromNBT(packet.getNbtCompound()); System.out.println("The onDataPacket method is done."); } @Override public Packet getDescriptionPacket() { NBTTagCompound nbt = new NBTTagCompound(); this.writeToNBT(nbt); int meta = this.getBlockMetadata(); System.out.println("The getDescriptionPacket method is almost done."); return new S35PacketUpdateTileEntity(this.getPos(), meta, nbt); } @Override public IChatComponent getDisplayName() { return new ChatComponentText("Engineering"); } } Gui Class: package com.littlepup.xcom.blocks.engineering_block; import java.util.List; import com.littlepup.xcom.projects.EngineeringProject; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.Slot; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.MathHelper; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @SideOnly(Side.CLIENT) public class GuiEngineerPanel extends GuiContainer { public GuiEngineerPanel(World world, EntityPlayer player, TileEntity tileEntity) { super(new ContainerEngineerPanel(world, player, tileEntity)); this.ePanel = (TileEntityEngineerPanel) tileEntity; this.availibleProjects = this.ePanel.getAvailibleProjects(); System.out.println("The amount of availible projects is " + availibleProjects.size()); for(int l = 0; l < availibleProjects.size(); l++) { String title = ((EngineeringProject)this.availibleProjects.get(l)).getDescription()[0]; System.out.println("The availible projects are " + l + " " + title); } } private final ResourceLocation engineeringGui = new ResourceLocation("xcom:textures/gui/engineer_panel.png"); TileEntityEngineerPanel ePanel; int currentProjectID = 0; List availibleProjects; @Override public void actionPerformed(GuiButton button) { switch(button.id) { case 0: this.ePanel.startManufacturing((EngineeringProject)(availibleProjects.get(currentProjectID))); if(this.ePanel.getWorld().isRemote) { System.out.println("This is a client world."); } else { System.out.println("This is a server world."); } this.ePanel.markDirty(); System.out.println("The project " + ((EngineeringProject)(availibleProjects.get(currentProjectID))).getDescription()[0] + " has been decided on."); break; case 1: this.ePanel.cancelManufacturing((EngineeringProject)(availibleProjects.get(currentProjectID))); System.out.println("The project " + ((EngineeringProject)(availibleProjects.get(currentProjectID))).getDescription()[0] + "has been canceled."); break; case 2: this.ePanel.amount--; System.out.println("The new amount is " + this.ePanel.amount); break; case 3: this.ePanel.amount++; System.out.println("The new amount is " + this.ePanel.amount); break; case 4: this.currentProjectID--; System.out.println("The new project ID is " + this.currentProjectID); break; case 5: this.currentProjectID++; System.out.println("The new project ID is " + this.currentProjectID); break; } } @Override protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) { GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); this.mc.getTextureManager().bindTexture(engineeringGui); int k = (this.width - this.xSize) / 2; int l = (this.height - this.ySize) / 2; this.drawTexturedModalRect(k, l, 0, 0, this.xSize, this.ySize); } private void drawTimeRemaining(long ticks) { if(ticks != 0) { int days = MathHelper.floor_double(ticks / 24000); int min = MathHelper.floor_double((ticks - days * 24000)/1200); int sec = MathHelper.floor_double((ticks - (days * 24000 + min * 1200))/20); this.fontRendererObj.drawString("D: " + days, 130, 20, 80000); this.fontRendererObj.drawString("M: " + min, 130, 30, 80000); this.fontRendererObj.drawString("S: " + sec, 130, 40, 80000); } } @Override public void initGui() { super.initGui(); this.buttonList.add(new GuiButton(0, this.guiLeft + 45, this.guiTop + 15, 36, 12, "BEGIN")); this.buttonList.add(new GuiButton(1, this.guiLeft + 45, this.guiTop + 27, 36, 12, "CANCEL")); this.buttonList.add(new GuiButton(2, this.guiLeft + 45, this.guiTop + 39, 12, 12, "-")); this.buttonList.add(new GuiButton(3, this.guiLeft + 69, this.guiTop + 39, 12, 12, "+")); this.buttonList.add(new GuiButton(4, this.guiLeft + 85, this.guiTop + 58, 9, 12, "<")); this.buttonList.add(new GuiButton(5, this.guiLeft + 118, this.guiTop + 58, 9, 12, ">")); } @Override public void updateScreen() { super.updateScreen(); if(this.ePanel.isManufacturing()) { this.drawTimeRemaining(this.ePanel.currentProject.timeCost); } else { ((GuiButton)this.buttonList.get(1)).enabled = false; if(this.currentProjectID == 0) { ((GuiButton)(this.buttonList.get(4))).enabled = false; } else if(this.currentProjectID == this.availibleProjects.size() - 1) { ((GuiButton)(this.buttonList.get(5))).enabled = false; } else { ((GuiButton)(this.buttonList.get(4))).enabled = true; ((GuiButton)(this.buttonList.get(5))).enabled = true; } if(this.ePanel.amount == 1) { ((GuiButton)(this.buttonList.get(2))).enabled = false; } else if(this.ePanel.getRoomNeeded((EngineeringProject) this.availibleProjects.get(currentProjectID)) > 6) { ((GuiButton)(this.buttonList.get(3))).enabled = false; } else { ((GuiButton)(this.buttonList.get(2))).enabled = true; ((GuiButton)(this.buttonList.get(3))).enabled = true; } } } } Container Class: package com.littlepup.xcom.blocks.engineering_block; import com.littlepup.xcom.utilities.Utilities; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.Container; import net.minecraft.inventory.ICrafting; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; public class ContainerEngineerPanel extends Container { public ContainerEngineerPanel(World world, EntityPlayer player, TileEntity tileEntity) { this.ePanel = (TileEntityEngineerPanel) tileEntity; this.playerInv = player.inventory; this.panelInv = (IInventory) tileEntity; this.addSlots(); } IInventory playerInv; IInventory panelInv; TileEntityEngineerPanel ePanel; @Override public void addCraftingToCrafters(ICrafting crafting) { super.addCraftingToCrafters(crafting); crafting.func_175173_a(this, this.ePanel); } private void addSlots() { /*Slots 0-35 are the player's inventory * Note: since the engineer panel and player's inventory are * seperate, the slots can have the same ID if needed. * Slots 36-41 are the engineer panel's input * Slots 42-49 are the engineer panel's output */ //Player's non-hotbar inventory for(int x = 0; x < 9; ++x) { for(int y = 0; y < 3; ++y) { this.addSlotToContainer(new Slot(playerInv, x * 3 + y, 8 + x * 18, 84 + y * 18)); } } //Player's hotbar inventory for(int x = 0; x < 9; ++x) { this.addSlotToContainer(new Slot(playerInv, x + 27, 8 + x * 18, 142)); } //Engineer panel block's input inventory for(int x = 0; x < 2; ++x) { for(int y = 0; y < 3; ++y) { this.addSlotToContainer(new Slot(panelInv, x * 3 + y + 36, 9 + x * 18, 16 + y * 18)); } } //Engineer panel block's output inventory for(int x = 0; x < 2; ++x) { for(int y = 0; y < 3; ++y) { this.addSlotToContainer(new Slot(panelInv, x * 3 + y + 42, 133 + x * 18, 16 + y * 18)); } } } @Override public boolean canInteractWith(EntityPlayer player) { return Utilities.getDistance(player.getPosition(), ePanel.getPos()) < 8.0D; } @Override public ItemStack transferStackInSlot(EntityPlayer player, int slotID) { System.out.println("The transferStackInSlot is being called in the container."); ItemStack stack1 = null; Slot slot = this.getSlot(slotID); IInventory inventory = slot.inventory; if(slot != null && slot.getHasStack()) { ItemStack stack2 = slot.getStack(); stack1 = stack2.copy(); //The slot is in the tile entity if(slotID >= 36) { System.out.println("The slot is thought to be in the tile entity."); if(!this.mergeItemStack(stack1, 36, 50, false)) { System.out.println("The slot's itemstack cannot be merged."); return null; } } else if(!this.mergeItemStack(stack1, 36, 50, false)) { System.out.println("The slot's itemstack cannot be merged."); return null; } if(stack1.stackSize == 0) { System.out.println("The stack size is thought to be zero."); this.putStackInSlot(slotID, null); } else { slot.onSlotChanged(); } } return stack1; } }
March 15, 20169 yr In your Gui class there are 2 outputs created if you click button one. Is there any Server output in the Log ? If no (and it should be so) then every thing only happens at the client. And if you click on an Item in a Gui and it disappear this is because the Server never had this Item. So you need to use packet handling if something like click at this button to start the progress should happen. (Mouse clicks are only client) catch(Exception e) { } Yay, Pokémon exception handling, gotta catch 'em all (and then do nothing with 'em).
March 15, 20169 yr Author Is there any Server output in the Log ? There hasn't been any now that you mention it. you need to use packet handling if something like click at this button to start the progress should happen I've been trying to use the writeToNBT and readFromNBT methods from the TileEntity class. Is that wrong? Should I be using the custom forge packets or something like that? Thanks for the help.
March 15, 20169 yr you will need to use IMessage and IMessageHandler to send information between the server and client, although you can still use the nbt methods of the class to create and read your message contents. Current Project: Armerger Planned mods: Light Drafter | Ore Swords Looking for help getting a mod off the ground? Coding | Textures
March 16, 20169 yr Author Okay, I'll look into using the IMessage and IMessageHandler. Thanks for the help.
March 18, 20169 yr Hi This tutorial project has a working example of synchronising gui and containers between client and server, which you might find useful https://github.com/TheGreyGhost/MinecraftByExample/blob/master/src/main/java/minecraftbyexample/mbe31_inventory_furnace/Notes.txt also an example of messages https://github.com/TheGreyGhost/MinecraftByExample/blob/master/src/main/java/minecraftbyexample/mbe60_network_messages/Notes.txt -TGG
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.