Kalaskow Posted March 7, 2018 Share Posted March 7, 2018 Hi, i am trying to implement a Block with Inventory and GUI. When clicking it, the game crashes with "Slot 0 not in valid range - [0,0)". Now this sounds like the ItemStack is initialized with a size of 0. But i am initializing it with size 6. The GUI is opened, but after about half a second the crash occurs. Coding so far: abstract NodeTileEntity: Spoiler package com.kalaskow.kc.tile; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.ITickable; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.ItemStackHandler; public abstract class NodeTileEntity extends TileEntity implements ITickable { private ItemStackHandler itemStackHandler; @Override public void readFromNBT(NBTTagCompound compound) { super.readFromNBT(compound); if (compound.hasKey("items")) { getItemStackHandler().deserializeNBT((NBTTagCompound) compound.getTag("items")); } } @Override public NBTTagCompound writeToNBT(NBTTagCompound compound) { super.writeToNBT(compound); compound.setTag("items", getItemStackHandler().serializeNBT()); return compound; } public boolean canInteractWith(EntityPlayer playerIn) { // If we are too far away from this tile entity you cannot use it return !isInvalid() && playerIn.getDistanceSq(pos.add(0.5D, 0.5D, 0.5D)) <= 64D; } @Override public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newSate) { return false; } @Override public boolean hasCapability(Capability<?> capability, EnumFacing facing) { if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { return true; } return super.hasCapability(capability, facing); } @Override public <T> T getCapability(Capability<T> capability, EnumFacing facing) { if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { return CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.cast(getItemStackHandler()); } return super.getCapability(capability, facing); } public ItemStackHandler getItemStackHandler() { if (itemStackHandler == null) { itemStackHandler = new ItemStackHandler(getSIZE()) { @Override protected void onContentsChanged(int slot) { markDirty(); } }; } return itemStackHandler; } public abstract int getSIZE(); } CityCenterEntity: Spoiler package com.kalaskow.kc.tile; public class CityCenterEntity extends NodeTileEntity { public static final String ID = "city_center_entity"; @Override public int getSIZE() { return 6; } @Override public void update() { } } Abstract NodeContainer: Spoiler package com.kalaskow.kc.container; import com.kalaskow.kc.tile.NodeTileEntity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.Container; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.SlotItemHandler; import javax.annotation.Nullable; public abstract class NodeContainer extends Container { protected final int START_SLOTS_X = 8; protected final int START_NODE_INVENTORY_Y = 8; protected final int START_PLAYER_INVENTORY_Y = 84; protected final int START_PLAYER_HOTBAR_Y = 142; protected final int SLOT_DIMENS = 18; private char[][] inventory; protected NodeTileEntity te; public NodeContainer(IInventory playerInventory, NodeTileEntity te, char[][] inventory) { this.te = te; this.inventory = inventory; // This container references items out of our own inventory (the 9 slots we hold ourselves) // as well as the slots from the player inventory so that the user can transfer items between // both inventories. The two calls below make sure that slots are defined for both inventories. addOwnSlots(); addPlayerSlots(playerInventory); } public void addOwnSlots() { IItemHandler itemHandler = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); int slotIndex = 0; for (int row = 0; row < 4; row++) { for (int col = 0; col < 9; col++) { if (inventory[row][col] == 'X') { int x = START_SLOTS_X + col * SLOT_DIMENS; int y = START_NODE_INVENTORY_Y + row * SLOT_DIMENS; addSlotToContainer(new SlotItemHandler(itemHandler, slotIndex++, x, y)); } } } } @Override public boolean canInteractWith(EntityPlayer playerIn) { return te.canInteractWith(playerIn); } private void addPlayerSlots(IInventory playerInventory) { // Slots for the hotbar int slotID = 0; for (int col = 0; col < 9; col++) { int x = START_SLOTS_X + col * SLOT_DIMENS; this.addSlotToContainer(new Slot(playerInventory, slotID++, x, START_PLAYER_HOTBAR_Y)); } // Slots for the main inventory for (int row = 0; row < 3; row++) { for (int col = 0; col < 9; col++) { int x = START_SLOTS_X + col * SLOT_DIMENS; int y = START_PLAYER_INVENTORY_Y + row * SLOT_DIMENS; this.addSlotToContainer(new Slot(playerInventory, slotID++, x, y)); } } } @Nullable @Override public ItemStack transferStackInSlot(EntityPlayer playerIn, int index) { ItemStack itemstack = null; Slot slot = this.inventorySlots.get(index); if (slot != null && slot.getHasStack()) { ItemStack itemstack1 = slot.getStack(); itemstack = itemstack1.copy(); if (index < te.getSIZE()) { if (!this.mergeItemStack(itemstack1, te.getSIZE(), this.inventorySlots.size(), true)) { return null; } } else if (!this.mergeItemStack(itemstack1, 0, te.getSIZE(), false)) { return null; } if (itemstack1.isEmpty()) { slot.putStack(ItemStack.EMPTY); } else { slot.onSlotChanged(); } } return itemstack; } } CityCenterContainer: Spoiler package com.kalaskow.kc.container; import com.kalaskow.kc.tile.CityCenterEntity; import net.minecraft.inventory.IInventory; public class CityCenterContainer extends NodeContainer { private final static char[][] inventory = { {'X', 'X', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {'X', 'X', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {'X', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {'X', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, }; public CityCenterContainer(IInventory playerInventory, CityCenterEntity te) { super(playerInventory, te, inventory); } } Quote Link to comment Share on other sites More sharing options...
Draco18s Posted March 7, 2018 Share Posted March 7, 2018 (edited) 1 hour ago, Kalaskow said: @Override public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newSate) { return false; } This isn't related to your problem...but OH GOD WHY. You're essentially telling Minecraft that your TileEntity will never be invalid. Yes, even if you break your block and place a chest there, your TE is still valid. Good job. 1 hour ago, Kalaskow said: implements ITickable Why is your base TE class implementing ITickable when your subclass does fuckall with it? Leave this off and let the subclass implement it (or not). By making all of your TEs ticking you consume system resources to do nothing. Good job. As for your problem. Use the debugger. Why is your IItemStackhandler getting created with 0 size? The debugger can answer this for you. Edited March 7, 2018 by Draco18s Quote 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. Link to comment Share on other sites More sharing options...
Kalaskow Posted March 7, 2018 Author Share Posted March 7, 2018 4 minutes ago, Draco18s said: You're essentially telling Minecraft that your TileEntity will never be invalid. Yes, even if you break your block and place a chest there, your TE is still valid. Good job. Ok, ill fix that. 4 minutes ago, Draco18s said: Why is your base TE class implementing ITickable when your subclass does fuckall with it? Leave this off and let the subclass implement it (or not). By making all of your TEs ticking you consume system resources to do nothing. Good job. Because the Entities will be ticking at a later time. I've added it in advance. No worries. I wont let them do stuff every single tick. Quote Link to comment Share on other sites More sharing options...
Kalaskow Posted March 7, 2018 Author Share Posted March 7, 2018 I will be implementing stuff there anyways. There is no reason for me not to implement it already. The only CPU Power i am wasting is my own I wouldnt implement the Interface if i werent to use it. And i will. Quote Link to comment Share on other sites More sharing options...
Kalaskow Posted March 7, 2018 Author Share Posted March 7, 2018 Yes, but not in a state, where those tickable entities do nothing I'm in a very very early stage, as you can see Quote Link to comment Share on other sites More sharing options...
jabelar Posted March 7, 2018 Share Posted March 7, 2018 Back to the original problem, it says that the slot is not in valid range. I don't think that has anything to do with the size of the itemstack, I think you're trying to access a slot that doesn't "exist" based on the slot numbers. I usually find these errors have to do with some mismatch in how I add my own slots and then access them later. As mentioned, use standard debugging methods but I think focus should be on your slot numbering not the itemstack size. Quote Check out my tutorials here: http://jabelarminecraft.blogspot.com/ Link to comment Share on other sites More sharing options...
Kalaskow Posted March 8, 2018 Author Share Posted March 8, 2018 Fixed it, using https://shadowfacts.net/tutorials/forge-modding-112/tile-entities-inventory/ and the 'Common issues and recommendations' Topic. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.