Posted December 29, 201311 yr Hi all, i've recently tried to make my first GUI for minecraf 1.6.4 but i've been having severe trouble after about 8 hours of searching the internet it still isn't working, there have been several bugs mixed together i think incuding a desync between player and server caused by calling player.openGUI not FMLNetworkHandler.openGui, some weird slot index errors and some other just weird errors, the current errors that i need help fixing are as follows: - my shift click code is weird, ghost items used to appear, stacks didn't decrement, but now i just get a StackOverflow error in the console that looks like this: 2013-12-29 11:28:47 [iNFO] [sTDOUT] at net.minecraft.inventory.Container.retrySlotClick(Container.java:520) 2013-12-29 11:28:47 [iNFO] [sTDOUT] at net.minecraft.inventory.Container.slotClick(Container.java:291) 2013-12-29 11:28:47 [iNFO] [sTDOUT] at net.minecraft.inventory.Container.retrySlotClick(Container.java:520) 2013-12-29 11:28:47 [iNFO] [sTDOUT] at net.minecraft.inventory.Container.slotClick(Container.java:291) 2013-12-29 11:28:47 [iNFO] [sTDOUT] at net.minecraft.inventory.Container.retrySlotClick(Container.java:520) 2013-12-29 11:28:47 [iNFO] [sTDOUT] at net.minecraft.inventory.Container.slotClick(Container.java:291) 2013-12-29 11:28:47 [iNFO] [sTDOUT] at net.minecraft.inventory.Container.retrySlotClick(Container.java:520) - when you double-click an item the stack size is weird (e.g if i fill my inv with single stacks of stone and double click sometimes it will give me a 29 stack but hen i do it again a 31 and when i do it again the correct size of 36) - sometimes you can't pick up items in your inventory - sometimes left click will act as right click in the GUI slots Here is the important parts of my load class (NOTE: the spoiler/code button in the post editor isn't working(or i'm doign it wrong)): Mod(modid = "EndoEnergy", name = "Endo-Energy", version = "Alpha 0.1.0") @NetworkMod(clientSideRequired = true,serverSideRequired = true) public class EndoEnergy { @Instance(value = "EndoEnergy") public static EndoEnergy instance; public EndoEnergy() { // rendering stuff CommonProxy proxy2 = new CommonProxy(); proxy2.registerRenderers(); ClientRegistry.bindTileEntitySpecialRenderer( endernoobs.mods.endoEnergy.entity.TileEntityWire.class, new TileEntityWireRenderer()); ClientRegistry.bindTileEntitySpecialRenderer( endernoobs.mods.endoEnergy.entity.TileEntityBatteryRack.class, new TileEntityWireRenderer()); GameRegistry.registerTileEntity(TileEntityWire.class, "TileEntityWire"); GameRegistry.registerTileEntity(TileEntityStorageWire.class, "TileEntityStorageWire"); GameRegistry.registerBlock(BlockBatteryRack, "BlockBatteryRack"); NetworkRegistry.instance().registerGuiHandler(this, new GuiHandler()); MinecraftForge.EVENT_BUS.register(BlockBatteryRack); } } Here is BlockBatteryRack: public class BlockBatteryRack extends BlockContainer{ @Override public TileEntity createNewTileEntity(World world) { //says:int metadata, no 'new' return new TileEntityBatteryRack(5); } public BlockBatteryRack(int id, Material material) { super(id, material); this.setBlockBounds(0F, 0F, 0F, 1F, 1F, 1F); } public boolean shouldSideBeRendered(IBlockAccess iblockaccess, int i, int j, int k, int l) { return false; } public boolean isOpaqueCube() { return false; } @Override public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int metadata, float what, float these, float are) { TileEntity tileEntity = world.getBlockTileEntity(x, y, z); if (tileEntity == null || player.isSneaking()) { return false; } FMLNetworkHandler.openGui(player, EndoEnergy.instance, 0, world, x,y,z); return true; } public int idDropped(int par1, Random random, int zero) { return EndoEnergy.ItemBatteryRack.itemID; } @Override public void breakBlock(World world, int x, int y, int z, int par5, int par6) { dropItems(world, x, y, z); world.removeBlockTileEntity(x, y, z); super.breakBlock(world, x, y, z, par5, par6); } private void dropItems(World world, int x, int y, int z){ Random rand = new Random(); TileEntity tileEntity = world.getBlockTileEntity(x, y, z); if (!(tileEntity instanceof IInventory)) { return; } IInventory inventory = (IInventory) tileEntity; for (int i = 0; i < inventory.getSizeInventory(); i++) { ItemStack item = inventory.getStackInSlot(i); if (item != null && item.stackSize > 0) { float rx = rand.nextFloat() * 0.8F + 0.1F; float ry = rand.nextFloat() * 0.8F + 0.1F; float rz = rand.nextFloat() * 0.8F + 0.1F; EntityItem entityItem = new EntityItem(world, x + rx, y + ry, z + rz, new ItemStack(item.itemID, item.stackSize, item.getItemDamage())); if (item.hasTagCompound()) { entityItem.getEntityItem().setTagCompound((NBTTagCompound) item.getTagCompound().copy()); } float factor = 0.05F; entityItem.motionX = rand.nextGaussian() * factor; entityItem.motionY = rand.nextGaussian() * factor + 0.2F; entityItem.motionZ = rand.nextGaussian() * factor; world.spawnEntityInWorld(entityItem); item.stackSize = 0; } } } } Here is TileEntityBatteryRack: public class TileEntityBatteryRack extends TileEntityStorageWire implements IInventory{ public ItemStack[] inv; public TileEntityBatteryRack(int i) { super(i); inv = new ItemStack[2]; } public TileEntityBatteryRack() { super(); } @Override public int getSizeInventory() { if (inv != null) { return inv.length; } else { return 0; } } @Override public ItemStack getStackInSlot(int slot) { //slot = slot - 36; return inv[slot]; } @Override public ItemStack decrStackSize(int slot, int amt) { //slot = slot - 36; ItemStack stack = getStackInSlot(slot); if (stack != null) { if (stack.stackSize <= amt) { setInventorySlotContents(slot, null); } else { ItemStack newstack = stack.splitStack(stack.stackSize - amt); setInventorySlotContents(slot, newstack); } } return stack; } @Override public ItemStack getStackInSlotOnClosing(int slot) { //slot = slot - 36; ItemStack stack = getStackInSlot(slot); if (stack != null) { setInventorySlotContents(slot, null); } return stack; } @Override public void setInventorySlotContents(int slot, ItemStack stack) { inv[slot] = stack; //if (stack != null && stack.stackSize > getInventoryStackLimit()) { // stack.stackSize = getInventoryStackLimit(); //} } @Override public String getInvName() { return "Battery Rack"; } @Override public boolean isInvNameLocalized() { // TODO Auto-generated method stub return false; } @Override public int getInventoryStackLimit() { return 1; } @Override public boolean isUseableByPlayer(EntityPlayer player) { return worldObj.getBlockTileEntity(xCoord, yCoord, zCoord) == this && player.getDistanceSq(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5) < 64; } @Override public void openChest() { } @Override public void closeChest() {} @Override public boolean isItemValidForSlot(int i, ItemStack itemstack) { // TODO Auto-generated method stub return false; } @Override public void readFromNBT(NBTTagCompound tagCompound) { super.readFromNBT(tagCompound); NBTTagList tagList = tagCompound.getTagList("Inventory"); for (int i = 0; i < tagList.tagCount(); i++) { NBTTagCompound tag = (NBTTagCompound) tagList.tagAt(i); byte slot = tag.getByte("Slot"); if (slot >= 0 && slot < inv.length) { inv[slot] = ItemStack.loadItemStackFromNBT(tag); } } } @Override public void writeToNBT(NBTTagCompound tagCompound) { super.writeToNBT(tagCompound); NBTTagList itemList = new NBTTagList(); if (inv != null) { for (int i = 0; i < inv.length; i++) { ItemStack stack = inv; if (stack != null) { NBTTagCompound tag = new NBTTagCompound(); tag.setByte("Slot", (byte) i); stack.writeToNBT(tag); itemList.appendTag(tag); } } tagCompound.setTag("Inventory", itemList); } } } Here is ContainerBatteryRack: public class ContainerBatteryRack extends Container{ private TileEntityBatteryRack tileEntity; private float lastEnergyStored; public ContainerBatteryRack (InventoryPlayer inventoryPlayer, TileEntityBatteryRack te){ tileEntity = te; addSlotToContainer(new Slot(tileEntity, 0,44,53)); addSlotToContainer(new Slot(tileEntity, 1,116,53)); bindPlayerInventory(inventoryPlayer); } @Override public boolean canInteractWith(EntityPlayer player) { return true;//tileEntity.isUseableByPlayer(player); } /** * Called to transfer a stack from one inventory to the other eg. when shift * clicking. */ @Override public ItemStack transferStackInSlot(EntityPlayer player, int index){ ItemStack stack = null; Slot slot = (Slot) this.inventorySlots.get(index); if(slot!=null&&slot.getHasStack()){ ItemStack slotstack = slot.getStack(); stack = slotstack.copy(); System.out.println(slotstack + " is in " + index); } else { return null; } System.out.println(index); int slotid = index; if (index > 1 && index < 29) { slotid = index + 7; } else if (index > 28 && index < 38) { slotid = index - 29; } if (index == 36 || index == 37) { slotid = index - 36; //tileEntity.decrStackSize(slotid, 1); } else { //slotid -= 2; //this.inventorySlots.set(index, ((Slot) this.inventorySlots.get(index)).decrStackSize(1)); //player.inventory.decrStackSize(index, 1); } return stack;//stack; } @Override public boolean mergeItemStack(ItemStack stack, int start, int end, boolean reverse){ return super.mergeItemStack(stack,start,end,reverse); } /** * Does the same as mergeItemStack with the same args, except does not * actually merge— just returns the number of items that can be merged * (usually either stack.stackSize or 0, but can be in between) * @param stack * @param start * @param end * @param reverse * @return */ int dryMerge(ItemStack stack, int start, int end, boolean reverse){ boolean flag1 = false; int i = start; if(reverse){ i = end-1; } int quantity = stack.stackSize; Slot slot; ItemStack slotstack; if(stack.isStackable()){ while(stack.stackSize>0&&(!reverse&&i<end||reverse&&i>=start)){ slot = this.getSlot(i); slotstack = slot.getStack(); if(slotstack!=null&&slotstack.itemID==stack.itemID&&(!stack.getHasSubtypes()||stack.getItemDamage()==slotstack.getItemDamage())&&ItemStack.areItemStackTagsEqual(stack,slotstack)){ int l = slotstack.stackSize+stack.stackSize; if(l<=stack.getMaxStackSize()){ quantity -= slotstack.stackSize; }else if(slotstack.stackSize<stack.getMaxStackSize()){ quantity -= (stack.getMaxStackSize() - slotstack.stackSize); } } if(reverse) --i; else ++i; } } if(stack.stackSize>0){ if(reverse){ i = end-1; }else{ i = start; } while(!reverse&&i<end||reverse&&i>=start){ slot = (Slot) this.inventorySlots.get(i); slotstack = slot.getStack(); if(slotstack==null){ quantity = 0; break; } if(reverse){ --i; }else{ ++i; } } } return stack.stackSize-quantity; } @Override public void addCraftingToCrafters(ICrafting par1ICrafting) { super.addCraftingToCrafters(par1ICrafting); par1ICrafting.sendProgressBarUpdate(this, 0, (int) this.tileEntity.energyStored); } @Override public void detectAndSendChanges() { super.detectAndSendChanges(); for (int i = 0; i < this.crafters.size(); ++i) { ICrafting icrafting = (ICrafting)this.crafters.get(i); if (this.lastEnergyStored != this.tileEntity.energyStored) { icrafting.sendProgressBarUpdate(this, 0, (int) this.tileEntity.energyStored); } } this.lastEnergyStored= this.tileEntity.energyStored; } @SideOnly(Side.CLIENT) public void updateProgressBar(int par1, int par2) { if (par1 == 0) { this.tileEntity.energyStored = par2; } } protected void bindPlayerInventory(InventoryPlayer inventoryPlayer) { for (int i = 0; i < 3; i++) { for (int j = 0; j < 9; j++) { addSlotToContainer(new Slot(inventoryPlayer, j + i * 9 + 9,8 + j * 18, 84 + i * 18)); } } for (int i = 0; i < 9; i++) { addSlotToContainer(new Slot(inventoryPlayer, i, 8 + i * 18, 142)); } } } Here is GuiBatteryRack: public class GuiBatteryRack extends GuiContainer{ private TileEntityBatteryRack rack; public GuiBatteryRack (InventoryPlayer inventoryPlayer, TileEntityBatteryRack tileEntity) { super(new ContainerBatteryRack(inventoryPlayer, tileEntity)); this.rack = tileEntity; } @Override protected void drawGuiContainerForegroundLayer(int param1, int param2) { String s = this.rack.isInvNameLocalized() ? this.rack.getInvName() : "Battery Rack"; //draw text and stuff here //the parameters for drawString are: string, x, y, color this.fontRenderer.drawString(s, this.xSize / 2 - this.fontRenderer.getStringWidth(s) / 2, 6, 4210752); //draws "Inventory" or your regional equivalent fontRenderer.drawString(StatCollector.translateToLocal("container.inventory"), 8, ySize - 96 + 2, 4210752); } @Override protected void drawGuiContainerBackgroundLayer(float par1, int par2,int par3) { //draw your Gui here, only thing you need to change is the path float bar = this.rack.energyStored; int k = (this.width - this.xSize) / 2; int l = (this.height - this.ySize) / 2; GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); this.mc.renderEngine.bindTexture((new ResourceLocation("endoenergy", "textures/gui/GuiBatteryRack.png"))); int x = (width - xSize) / 2; int y = (height - ySize) / 2; this.drawTexturedModalRect(x, y, 0, 0, xSize, ySize); this.drawTexturedModalRect(x+40, y+19, 0, 179, (int) (bar/EndoEnergy.BatteryRackCapacity*96), 12); } } Thanks in advance, Redstonedude, head programmer of the endernoobs modding team
December 29, 201311 yr Author i tried making mergeitemstack return false and making drymerge return 0 but that didn't change anything
December 29, 201311 yr Author making mergeitemstack return true isn't doing anything either - i think the errors in transferstackinslot
December 29, 201311 yr Author I just tested and making transferStackInSlot return null stops crash on shiftclick but i can't pick up items with regular click
December 29, 201311 yr Author edit: sometimes you can pick items up, it has a weird offset on slot( 1.g click in what should be slot 0 and you pick up the itemstack in slot 29), double click still duplicates/deletes items sometimes, rightclick and leftclick still sometimes switch what they do and serveral other weird things
December 30, 201311 yr Author could someone atleast post working code for me to compare mine against? (I would need working, tested 1.6.4 forge 9.11.1.953 (i think that's the right number, might have got some decima points the wrong way around)), also since 1.7 forge is out (so i've heard) would you recommend that i update ASAP and fix all errors first or get a stable beta version of my mod before i update?
December 30, 201311 yr Ok, here's a container I have https://github.com/Draco18s/Artifacts/blob/master/draco18s/artifacts/block/BlockPedestal.java https://github.com/Draco18s/Artifacts/blob/master/draco18s/artifacts/entity/TileEntityDisplayPedestal.java https://github.com/Draco18s/Artifacts/blob/master/draco18s/artifacts/client/GuiContPedestal.java https://github.com/Draco18s/Artifacts/blob/master/draco18s/artifacts/inventory/ContainerPedestal.java I think that's everything except the custom slot (it is just set to allow only certain item types) Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable. If you think this is the case, JUST REPORT ME. Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice. Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked. DO NOT PM ME WITH PROBLEMS. No help will be given.
December 30, 201311 yr Author Thanks for the code but still no luck, i've tried copying off the forge forums, ive tried copying that code you pasted, i've tried copying youtube tutorials and i've tried tweaking the code from all of the above for hours, still no luck however i did override 'public ItemStack slotClick(int slot, int button, int flag, EntityPlayer player)' and put some debug in it before passing it to super and found out that it's getting the correct slot that you click on with the correct itemStack but when you try it in the GUI you're actually picking up the stack two to the right and one above, after lots of editing i think it's taking one above because it is somehow creating the 'slot indexes' for the hotbar wrong(when you click slot 0 the method gives you the number slot 29 and when you feed that back into this.inventorySlots you still manage to get the same itemStack0 and the 2 to the right is caused by there being 2 slots in the tileEntity part of the GUI (i think as it has 2 slots). Also if it helps the slotClick method is only being called client side
January 2, 201411 yr Author anyone know? please, this is really important for my mod without working GUIs the mod can't do much
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.