Jump to content

items in my custom chest disappeared after worldIn.getTileEntity(pos)


uniqueT

Recommended Posts

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;
        }
}

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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()?

 

Link to comment
Share on other sites

+ 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;
    }

}

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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!.

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.