Posted February 6, 201510 yr Hi guys. I made a custom block like the chestblock. Now it can work normally when it just been used as a chest.But when I overrode the onNeighborBlockChange and updateTick function I met a problem. The items I stored in the block disappeared after I gave it power. There is only one line code in updateTick: public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) { if (!worldIn.isRemote) { TileEntity tileentity = worldIn.getTileEntity(pos); } } There won't be any problems if I don't use worldIn.getTileEntity(pos), but I have to get Items from my block. So could anyone tell me why the items were missing? The code of my block imitates that of dispenser's. I don't exactly know which code should I post here, can anyone give me some hints? Some methods in my tileentity public class TileEntityPlanter extends TileEntityLockable implements IInventory { private ItemStack[] stacks = new ItemStack[9]; @Override public Container createContainer(InventoryPlayer playerInventory, EntityPlayer playerIn) { return new ContainerPlanter(playerInventory, this); } @Override public void readFromNBT(NBTTagCompound compound) { super.readFromNBT(compound); NBTTagList nbttaglist = compound.getTagList("Items", 10); this.stacks = new ItemStack[this.getSizeInventory()]; for (int i = 0; i < nbttaglist.tagCount(); ++i) { NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(i); int j = nbttagcompound1.getByte("Slot") & 255; if (j >= 0 && j < this.stacks.length) { this.stacks[j] = ItemStack.loadItemStackFromNBT(nbttagcompound1); } } } @Override public void writeToNBT(NBTTagCompound compound) { super.writeToNBT(compound); NBTTagList nbttaglist = new NBTTagList(); for (int i = 0; i < this.stacks.length; ++i) { if (this.stacks[i] != null) { NBTTagCompound nbttagcompound1 = new NBTTagCompound(); nbttagcompound1.setByte("Slot", (byte)i); this.stacks[i].writeToNBT(nbttagcompound1); nbttaglist.appendTag(nbttagcompound1); } } compound.setTag("Items", nbttaglist); } @Override public ItemStack getStackInSlot(int index) { return this.stacks[index]; } @Override public ItemStack decrStackSize(int index, int count) { if (this.stacks[index] != null) { ItemStack itemstack; if (this.stacks[index].stackSize <= count) { itemstack = this.stacks[index]; this.stacks[index] = null; this.markDirty(); return itemstack; } else { itemstack = this.stacks[index].splitStack(count); if (this.stacks[index].stackSize == 0) { this.stacks[index] = null; } this.markDirty(); return itemstack; } } else { return null; } } @Override public ItemStack getStackInSlotOnClosing(int index) { if (this.stacks[index] != null) { ItemStack itemstack = this.stacks[index]; this.stacks[index] = null; return itemstack; } else { return null; } } @Override public void setInventorySlotContents(int index, ItemStack stack) { this.stacks[index] = stack; if (stack != null && stack.stackSize > this.getInventoryStackLimit()) { stack.stackSize = this.getInventoryStackLimit(); } this.markDirty(); } public void clear() { for (int i = 0; i < this.stacks.length; ++i) { this.stacks[i] = null; } }
February 7, 201510 yr When you just remove the worldIn.getTileEntity(pos), does everything works fine? Like saving & loading the chest inventory, etc. + Post your full block class, including the updateTick method. I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP) II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.
February 7, 201510 yr Author to Abastro: Yes, if I remove worldIn.getTileEntity(pos) everything works fine. I think I've found something. My block's onNeighborBlockChange method copied from BlockDispenser's.It is public void onNeighborBlockChange(World worldIn, BlockPos pos, IBlockState state, Block neighborBlock) { boolean flag = worldIn.isBlockPowered(pos) || worldIn.isBlockPowered(pos.up()); boolean flag1 = ((Boolean)state.getValue(TRIGGERED)).booleanValue(); if (flag && !flag1) { worldIn.scheduleUpdate(pos, this, this.tickRate(worldIn)); worldIn.setBlockState(pos, state.withProperty(TRIGGERED, Boolean.valueOf(true))); } else if (!flag && flag1) { worldIn.setBlockState(pos, state.withProperty(TRIGGERED, Boolean.valueOf(false))); } } When the power is on, this code updates block's state. If I remove worldIn.setBlockState, I can get the items in my block successfully by TileEntity tileentity = worldIn.getTileEntity(pos) and they won't go missing. So I think this issue has something to do with state. Can anyone explain this? And how can I solve this problem without removing worldIn.setBlockState()?
February 7, 201510 yr Author + Post your full block class, including the updateTick method. public class BlockPlanter extends BlockContainer { public static final PropertyBool TRIGGERED = PropertyBool.create("triggered"); public BlockPlanter() { super(Material.rock); setHardness(4); setStepSound(Block.soundTypeStone); setUnlocalizedName("Planter"); setCreativeTab(CreativeTabs.tabTools); setHarvestLevel("pickaxe", 3); setDefaultState(this.blockState.getBaseState().withProperty(TRIGGERED, Boolean.valueOf(false))); } protected BlockState createBlockState() { return new BlockState(this, new IProperty[]{TRIGGERED}); } public int tickRate(World worldIn) { return 3; } public void onNeighborBlockChange(World worldIn, BlockPos pos, IBlockState state, Block neighborBlock) { boolean flag = worldIn.isBlockPowered(pos) || worldIn.isBlockPowered(pos.up()); boolean flag1 = ((Boolean)state.getValue(TRIGGERED)).booleanValue(); if (flag && !flag1) { worldIn.scheduleUpdate(pos, this, this.tickRate(worldIn)); worldIn.setBlockState(pos, state.withProperty(TRIGGERED, Boolean.valueOf(true))); } else if (!flag && flag1) { worldIn.setBlockState(pos, state.withProperty(TRIGGERED, Boolean.valueOf(false))); } } public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) { if (!worldIn.isRemote) { TileEntity tileentity = worldIn.getTileEntity(pos); } } public TileEntity createNewTileEntity(World worldIn, int meta) { return new TileEntityPlanter(); } public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumFacing side, float hitX, float hitY, float hitZ) { if (worldIn.isRemote) { return true; } else { TileEntity tileentity = worldIn.getTileEntity(pos); if (tileentity instanceof TileEntityPlanter) { playerIn.displayGUIChest((TileEntityPlanter)tileentity); } return true; } } public void breakBlock(World worldIn, BlockPos pos, IBlockState state) { TileEntity tileentity = worldIn.getTileEntity(pos); if (tileentity instanceof TileEntityPlanter) { InventoryHelper.dropInventoryItems(worldIn, pos, (TileEntityPlanter)tileentity); worldIn.updateComparatorOutputLevel(pos, this); } super.breakBlock(worldIn, pos, state); } @Override public int getRenderType() { return 3; } public IBlockState getStateFromMeta(int meta) { return this.getDefaultState().withProperty(TRIGGERED, Boolean.valueOf(meta == 1)); } public int getMetaFromState(IBlockState state) { int i = 0; if (((Boolean)state.getValue(TRIGGERED)).booleanValue()) { i = 1; } return i; } }
February 7, 201510 yr The TileEntity would be refreshed and reloaded on the metadata change, so I suspect that the data would not be synced with original. But if your tileentity saves & loads well, then I don't know.. I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP) II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.
February 8, 201510 yr 1. Put @Override over EVERY method you override. Simple right? 2. If that doesn't fix it then add something similar to super.onNeighborBlockChange(World worldIn, BlockPos pos, IBlockState state, Block neighborBlock) to every method you've overridden.
February 8, 201510 yr 1. Put @Override over EVERY method you override. Simple right? 2. If that doesn't fix it then add something similar to super.onNeighborBlockChange(World worldIn, BlockPos pos, IBlockState state, Block neighborBlock) to every method you've overridden. What? it would not change anything.. It already OVERRIDES the method, and it makes the symptom. About the problem, try putting breakpoints on readNBT, and see if it calls the method on state change. I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP) II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.
February 8, 201510 yr Author What? it would not change anything.. It already OVERRIDES the method, and it makes the symptom. About the problem, try putting breakpoints on readNBT, and see if it calls the method on state change. I add some debug codes in TileEntityPlanter.readFromNBT public void readFromNBT(NBTTagCompound compound) { System.out.println("uniqeT debug here : read from nbt"); super.readFromNBT(compound); NBTTagList nbttaglist = compound.getTagList("Items", 10); this.stacks = new ItemStack[this.getSizeInventory()]; for (int i = 0; i < nbttaglist.tagCount(); ++i) { NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(i); int j = nbttagcompound1.getByte("Slot") & 255; if (j >= 0 && j < this.stacks.length) { this.stacks[j] = ItemStack.loadItemStackFromNBT(nbttagcompound1); System.out.println("frouniqeT debug here : stacks length="+stacks.length); } } } But nothing printed in console when I turn the switch on or off. It seems like this method is not called when the block state changes.
February 9, 201510 yr Author Override shouldRefresh in your TileEntity. It allows you to specify when a new TE is created. Oh,you are right, TiltEntity.shouldRefresh returns !isVanilla || (oldState.getBlock() != newSate.getBlock()), and isVanilla = getClass().getName().startsWith("net.minecraft.tileentity"). Surprisingly simple. Thanks a lot!.
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.