Jump to content

[1.8] Tile entity deletes itself on block state change [SOLVED, NEW PROBLEM]


TheRedMezek

Recommended Posts

I wish I didn't have to ask about block states and my mod again, but...oh well. I'm making a furnace-like block, which is functional except that whenever it has a fuel item in the fuel slot and a cookable item in the cooking slot, rather than starting to cook it closes the GUI and when I open it again the items have vanished. I assume this means that the tile entity is deleting itself, but it isn't producing any errors so I don't really know. Here's the code:

 

Block (ignore the commented-out parts)

 

public class CookingBrazier extends BlockContainer {

    private String name = "cookingbrazier";

    private boolean isBurning;

    private static boolean keepInventory;

    public static final PropertyBool ISBURNING = PropertyBool.create("active");

 

    public boolean isOpaqueCube(){

        return false;

    }

    public boolean isFullCube()

    {

        return false;

    }

 

    @SideOnly(Side.CLIENT)

    public void randomDisplayTick(World worldIn, BlockPos pos, IBlockState state, Random rand)

    {

        if(isBurning) {

            double d0 = (double) pos.getX() + 0.5D;

            double d1 = (double) pos.getY() + 0.4D;

            double d2 = (double) pos.getZ() + 0.5D;

 

            worldIn.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, d0, d1, d2, 0.0D, 0.0D, 0.0D, new int[0]);

        }

    }

 

    @Override

    public int getRenderType() {

        return 3;

    }

 

    public String getName(){

        return name;

    }

 

    public void setBlockBoundsBasedOnState(IBlockAccess worldIn, BlockPos pos) {

        setBlockBounds(0.1F, 0.0F, 0.1F, 0.9F, 1F, 0.9F);

    }

 

    public CookingBrazier(boolean isBurning){

        super(Material.rock);

        this.isBurning = false;

        this.setDefaultState(this.blockState.getBaseState());//.withProperty(ISBURNING, Boolean.valueOf(false)));

        this.setCreativeTab(CreativeTabs.tabDecorations);

        this.setUnlocalizedName("braziermod" + "_" + name);

        this.setHardness(0.8f);

        this.setLightLevel(.96f);

        GameRegistry.registerBlock(this, name);

    }

 

    public TileEntity createNewTileEntity(World worldIn, int meta)

    {

        return new TileEntityCookingBrazier();

    }

 

    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 TileEntityCookingBrazier)

            {

                playerIn.displayGUIChest((TileEntityCookingBrazier)tileentity);

            }

 

            return true;

        }

    }

 

    public void breakBlock(World worldIn, BlockPos pos, IBlockState state)

    {

        if (!keepInventory)

        {

            TileEntity tileentity = worldIn.getTileEntity(pos);

 

            if (tileentity instanceof TileEntityFurnace)

            {

                InventoryHelper.dropInventoryItems(worldIn, pos, (TileEntityFurnace)tileentity);

                worldIn.updateComparatorOutputLevel(pos, this);

            }

        }

 

        super.breakBlock(worldIn, pos, state);

    }

 

    public void setIsburning(boolean active){

        isBurning = active;

    }

 

    public static void setState(boolean active, World worldIn, BlockPos pos){

        TileEntity tileentity = worldIn.getTileEntity(pos);

 

        if(active){

            //worldIn.setBlockState(pos, );

            worldIn.setBlockState(pos, BrazierMod.cookingbrazier.getDefaultState().withProperty(ISBURNING, Boolean.valueOf(true)));

        }else{

            worldIn.setBlockState(pos, BrazierMod.cookingbrazier.getDefaultState().withProperty(ISBURNING, Boolean.valueOf(false)));

            //worldIn.setBlockState(pos, BrazierMod.cookingbrazier.getDefaultState().withProperty(ISBURNING, Boolean.valueOf(false)));

        }

 

        if (tileentity != null)

        {

            tileentity.validate();

            worldIn.setTileEntity(pos, tileentity);

        }

    }

 

    //public IBlockState onBlockPlaced(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer)

    //{

        //return this.getDefaultState().withProperty(ISBURNING, Boolean.valueOf(false));

    //}

 

    protected BlockState createBlockState()

    {

        return new BlockState(this, new IProperty[] {ISBURNING});

    }

 

    public IBlockState getStateFromMeta(int meta)

    {

        return this.getDefaultState().withProperty(ISBURNING, Boolean.valueOf(isBurning));

    }

 

    public int getMetaFromState(IBlockState state)

    {

        return 0;

    }

 

    //public void onBlockAdded(World worldIn, BlockPos pos, IBlockState state)

    //{

        //worldIn.setBlockState(pos, BrazierMod.cookingbrazier.getDefaultState().withProperty(ISBURNING, Boolean.valueOf(false)));

    //}

 

    //public void onBlockPlacedBy(World worldIn, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack)

    //{

        //worldIn.setBlockState(pos, BrazierMod.cookingbrazier.getDefaultState().withProperty(ISBURNING, Boolean.valueOf(false)));

    //}

}

 

 

Tile entity

 

public class TileEntityCookingBrazier extends TileEntityLockable implements IUpdatePlayerListBox, ISidedInventory

{

    private static final int[] slotsTop = new int[] {0};

    private static final int[] slotsBottom = new int[] {2, 1};

    private static final int[] slotsSides = new int[] {1};

    /** The ItemStacks that hold the items currently being used in the furnace */

    private ItemStack[] furnaceItemStacks = new ItemStack[3];

    /** The number of ticks that the furnace will keep burning */

    private int furnaceBurnTime;

    /** The number of ticks that a fresh copy of the currently-burning item would keep the furnace burning for */

    private int currentItemBurnTime;

    private int cookTime;

    private int totalCookTime;

    private String furnaceCustomName;

    private static final String __OBFID = "CL_00000357";

 

    /**

    * Returns the number of slots in the inventory.

    */

    public int getSizeInventory()

    {

        return this.furnaceItemStacks.length;

    }

 

    /**

    * Returns the stack in slot i

    */

    public ItemStack getStackInSlot(int index)

    {

        return this.furnaceItemStacks[index];

    }

 

    /**

    * Removes from an inventory slot (first arg) up to a specified number (second arg) of items and returns them in a

    * new stack.

    */

    public ItemStack decrStackSize(int index, int count)

    {

        if (this.furnaceItemStacks[index] != null)

        {

            ItemStack itemstack;

 

            if (this.furnaceItemStacks[index].stackSize <= count)

            {

                itemstack = this.furnaceItemStacks[index];

                this.furnaceItemStacks[index] = null;

                return itemstack;

            }

            else

            {

                itemstack = this.furnaceItemStacks[index].splitStack(count);

 

                if (this.furnaceItemStacks[index].stackSize == 0)

                {

                    this.furnaceItemStacks[index] = null;

                }

 

                return itemstack;

            }

        }

        else

        {

            return null;

        }

    }

 

    /**

    * When some containers are closed they call this on each slot, then drop whatever it returns as an EntityItem -

    * like when you close a workbench GUI.

    */

    public ItemStack getStackInSlotOnClosing(int index)

    {

        if (this.furnaceItemStacks[index] != null)

        {

            ItemStack itemstack = this.furnaceItemStacks[index];

            this.furnaceItemStacks[index] = null;

            return itemstack;

        }

        else

        {

            return null;

        }

    }

 

    /**

    * Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections).

    */

    public void setInventorySlotContents(int index, ItemStack stack)

    {

        boolean flag = stack != null && stack.isItemEqual(this.furnaceItemStacks[index]) && ItemStack.areItemStackTagsEqual(stack, this.furnaceItemStacks[index]);

        this.furnaceItemStacks[index] = stack;

 

        if (stack != null && stack.stackSize > this.getInventoryStackLimit())

        {

            stack.stackSize = this.getInventoryStackLimit();

        }

 

        if (index == 0 && !flag)

        {

            this.totalCookTime = this.func_174904_a(stack);

            this.cookTime = 0;

            this.markDirty();

        }

    }

 

    /**

    * Gets the name of this command sender (usually username, but possibly "Rcon")

    */

    public String getName()

    {

        return this.hasCustomName() ? this.furnaceCustomName : "Cooking Brazier";

    }

 

    /**

    * Returns true if this thing is named

    */

    public boolean hasCustomName()

    {

        return this.furnaceCustomName != null && this.furnaceCustomName.length() > 0;

    }

 

    public void setCustomInventoryName(String p_145951_1_)

    {

        this.furnaceCustomName = p_145951_1_;

    }

 

    public void readFromNBT(NBTTagCompound compound)

    {

        super.readFromNBT(compound);

        NBTTagList nbttaglist = compound.getTagList("Items", 10);

        this.furnaceItemStacks = new ItemStack[this.getSizeInventory()];

 

        for (int i = 0; i < nbttaglist.tagCount(); ++i)

        {

            NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(i);

            byte b0 = nbttagcompound1.getByte("Slot");

 

            if (b0 >= 0 && b0 < this.furnaceItemStacks.length)

            {

                this.furnaceItemStacks[b0] = ItemStack.loadItemStackFromNBT(nbttagcompound1);

            }

        }

 

        this.furnaceBurnTime = compound.getShort("BurnTime");

        this.cookTime = compound.getShort("CookTime");

        this.totalCookTime = compound.getShort("CookTimeTotal");

        this.currentItemBurnTime = getItemBurnTime(this.furnaceItemStacks[1]);

 

        if (compound.hasKey("CustomName", 8))

        {

            this.furnaceCustomName = compound.getString("CustomName");

        }

    }

 

    public void writeToNBT(NBTTagCompound compound)

    {

        super.writeToNBT(compound);

        compound.setShort("BurnTime", (short)this.furnaceBurnTime);

        compound.setShort("CookTime", (short)this.cookTime);

        compound.setShort("CookTimeTotal", (short)this.totalCookTime);

        NBTTagList nbttaglist = new NBTTagList();

 

        for (int i = 0; i < this.furnaceItemStacks.length; ++i)

        {

            if (this.furnaceItemStacks != null)

            {

                NBTTagCompound nbttagcompound1 = new NBTTagCompound();

                nbttagcompound1.setByte("Slot", (byte)i);

                this.furnaceItemStacks.writeToNBT(nbttagcompound1);

                nbttaglist.appendTag(nbttagcompound1);

            }

        }

 

        compound.setTag("Items", nbttaglist);

 

        if (this.hasCustomName())

        {

            compound.setString("CustomName", this.furnaceCustomName);

        }

    }

 

    /**

    * Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended. *Isn't

    * this more of a set than a get?*

    */

    public int getInventoryStackLimit()

    {

        return 64;

    }

 

    /**

    * Furnace isBurning

    */

    public boolean isBurning()

    {

        return this.furnaceBurnTime > 0;

    }

 

    @SideOnly(Side.CLIENT)

    public static boolean isBurning(IInventory p_174903_0_)

    {

        return p_174903_0_.getField(0) > 0;

    }

 

    /**

    * Updates the JList with a new model.

    */

    public void update()

    {

        boolean flag = this.isBurning();

        boolean flag1 = false;

 

 

        if (this.isBurning())

        {

            --this.furnaceBurnTime;

        }

 

        if (!this.worldObj.isRemote)

        {

            if (!this.isBurning() && (this.furnaceItemStacks[1] == null || this.furnaceItemStacks[0] == null))

            {

                if (!this.isBurning() && this.cookTime > 0)

                {

                    this.cookTime = MathHelper.clamp_int(this.cookTime - 2, 0, this.totalCookTime);

                }

            }

            else

            {

                if (!this.isBurning() && this.canSmelt())

                {

                    this.currentItemBurnTime = this.furnaceBurnTime = getItemBurnTime(this.furnaceItemStacks[1]);

 

                    if (this.isBurning())

                    {

                        flag1 = true;

 

                        if (this.furnaceItemStacks[1] != null)

                        {

                            --this.furnaceItemStacks[1].stackSize;

 

                            if (this.furnaceItemStacks[1].stackSize == 0)

                            {

                                this.furnaceItemStacks[1] = furnaceItemStacks[1].getItem().getContainerItem(furnaceItemStacks[1]);

                            }

                        }

                    }

                }

 

                if (this.isBurning() && this.canSmelt())

                {

                    ++this.cookTime;

 

                    if (this.cookTime == this.totalCookTime)

                    {

                        this.cookTime = 0;

                        this.totalCookTime = this.func_174904_a(this.furnaceItemStacks[0]);

                        this.smeltItem();

                        flag1 = true;

                    }

                }

                else

                {

                    this.cookTime = 0;

                }

            }

 

            if (flag != this.isBurning())

            {

                flag1 = true;

                CookingBrazier.setState(this.isBurning(), this.worldObj, this.pos);

                IBlockState iblockstate = this.worldObj.getBlockState(this.getPos());

                iblockstate = iblockstate.withProperty(CookingBrazier.ISBURNING, Boolean.valueOf(this.isBurning()));

                this.worldObj.setBlockState(this.pos, iblockstate, 2);

            }

 

        }

 

        if (flag1)

        {

            this.markDirty();

        }

    }

 

    public int func_174904_a(ItemStack p_174904_1_)

    {

        return 200;

    }

 

    /**

    * Returns true if the furnace can smelt an item, i.e. has a source item, destination stack isn't full, etc.

    */

    private boolean canSmelt()

    {

        if (this.furnaceItemStacks[0] == null)

        {

            return false;

        }

        else

        {

            ItemStack itemstack = FurnaceRecipes.instance().getSmeltingResult(this.furnaceItemStacks[0]);

            if (itemstack == null) return false;

            if (this.furnaceItemStacks[2] == null) return true;

            if (!this.furnaceItemStacks[2].isItemEqual(itemstack)) return false;

            int result = furnaceItemStacks[2].stackSize + itemstack.stackSize;

            return result <= getInventoryStackLimit() && result <= this.furnaceItemStacks[2].getMaxStackSize(); //Forge BugFix: Make it respect stack sizes properly.

        }

    }

 

    /**

    * Turn one item from the furnace source stack into the appropriate smelted item in the furnace result stack

    */

    public void smeltItem()

    {

        if (this.canSmelt())

        {

            ItemStack itemstack = FurnaceRecipes.instance().getSmeltingResult(this.furnaceItemStacks[0]);

 

            if (this.furnaceItemStacks[2] == null)

            {

                this.furnaceItemStacks[2] = itemstack.copy();

            }

            else if (this.furnaceItemStacks[2].getItem() == itemstack.getItem())

            {

                this.furnaceItemStacks[2].stackSize += itemstack.stackSize; // Forge BugFix: Results may have multiple items

            }

 

            if (this.furnaceItemStacks[0].getItem() == Item.getItemFromBlock(Blocks.sponge) && this.furnaceItemStacks[0].getMetadata() == 1 && this.furnaceItemStacks[1] != null && this.furnaceItemStacks[1].getItem() == Items.bucket)

            {

                this.furnaceItemStacks[1] = new ItemStack(Items.water_bucket);

            }

 

            --this.furnaceItemStacks[0].stackSize;

 

            if (this.furnaceItemStacks[0].stackSize <= 0)

            {

                this.furnaceItemStacks[0] = null;

            }

        }

    }

 

    /**

    * Returns the number of ticks that the supplied fuel item will keep the furnace burning, or 0 if the item isn't

    * fuel

    */

    public static int getItemBurnTime(ItemStack p_145952_0_)

    {

        if (p_145952_0_ == null)

        {

            return 0;

        }

        else

        {

            Item item = p_145952_0_.getItem();

 

            if (item instanceof ItemBlock && Block.getBlockFromItem(item) != Blocks.air)

            {

                Block block = Block.getBlockFromItem(item);

 

                if (block == Blocks.wooden_slab)

                {

                    return 150;

                }

 

                if (block.getMaterial() == Material.wood)

                {

                    return 300;

                }

 

                if (block == Blocks.coal_block)

                {

                    return 16000;

                }

            }

 

            if (item instanceof ItemTool && ((ItemTool)item).getToolMaterialName().equals("WOOD")) return 200;

            if (item instanceof ItemSword && ((ItemSword)item).getToolMaterialName().equals("WOOD")) return 200;

            if (item instanceof ItemHoe && ((ItemHoe)item).getMaterialName().equals("WOOD")) return 200;

            if (item == Items.stick) return 100;

            if (item == Items.coal) return 1600;

            if (item == Items.lava_bucket) return 20000;

            if (item == Item.getItemFromBlock(Blocks.sapling)) return 100;

            if (item == Items.blaze_rod) return 2400;

            return net.minecraftforge.fml.common.registry.GameRegistry.getFuelValue(p_145952_0_);

        }

    }

 

    public static boolean isItemFuel(ItemStack p_145954_0_)

    {

        /**

        * Returns the number of ticks that the supplied fuel item will keep the furnace burning, or 0 if the item isn't

        * fuel

        */

        return getItemBurnTime(p_145954_0_) > 0;

    }

 

    /**

    * Do not make give this method the name canInteractWith because it clashes with Container

    */

    public boolean isUseableByPlayer(EntityPlayer player)

    {

        return this.worldObj.getTileEntity(this.pos) != this ? false : player.getDistanceSq((double)this.pos.getX() + 0.5D, (double)this.pos.getY() + 0.5D, (double)this.pos.getZ() + 0.5D) <= 64.0D;

    }

 

    public void openInventory(EntityPlayer player) {}

 

    public void closeInventory(EntityPlayer player) {}

 

    /**

    * Returns true if automation is allowed to insert the given stack (ignoring stack size) into the given slot.

    */

    public boolean isItemValidForSlot(int index, ItemStack stack)

    {

        return index == 2 ? false : (index != 1 ? true : isItemFuel(stack) || SlotFurnaceFuel.isBucket(stack));

    }

 

    public int[] getSlotsForFace(EnumFacing side)

    {

        return side == EnumFacing.DOWN ? slotsBottom : (side == EnumFacing.UP ? slotsTop : slotsSides);

    }

 

    /**

    * Returns true if automation can insert the given item in the given slot from the given side. Args: slot, item,

    * side

    */

    public boolean canInsertItem(int index, ItemStack itemStackIn, EnumFacing direction)

    {

        return this.isItemValidForSlot(index, itemStackIn);

    }

 

    /**

    * Returns true if automation can extract the given item in the given slot from the given side. Args: slot, item,

    * side

    */

    public boolean canExtractItem(int index, ItemStack stack, EnumFacing direction)

    {

        if (direction == EnumFacing.DOWN && index == 1)

        {

            Item item = stack.getItem();

 

            if (item != Items.water_bucket && item != Items.bucket)

            {

                return false;

            }

        }

 

        return true;

    }

 

    public String getGuiID()

    {

        return "minecraft:furnace";

    }

 

    public Container createContainer(InventoryPlayer playerInventory, EntityPlayer playerIn)

    {

        return new ContainerCookingBrazier(playerInventory, this);

    }

 

    public int getField(int id)

    {

        switch (id)

        {

            case 0:

                return this.furnaceBurnTime;

            case 1:

                return this.currentItemBurnTime;

            case 2:

                return this.cookTime;

            case 3:

                return this.totalCookTime;

            default:

                return 0;

        }

    }

 

    public void setField(int id, int value)

    {

        switch (id)

        {

            case 0:

                this.furnaceBurnTime = value;

                break;

            case 1:

                this.currentItemBurnTime = value;

                break;

            case 2:

                this.cookTime = value;

                break;

            case 3:

                this.totalCookTime = value;

        }

    }

 

    public int getFieldCount()

    {

        return 4;

    }

 

    public void clear()

    {

        for (int i = 0; i < this.furnaceItemStacks.length; ++i)

        {

            this.furnaceItemStacks = null;

        }

    }

}

 

Link to comment
Share on other sites

Non-vanilla TEs are always replaced when their BlockState changes. Override shouldRefresh in your TE to correct that.

 

Makes me wonder why Forge doesn't patch that.  Unless this behavior is the patch, in which case, I question someone's sanity.

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

Non-vanilla TEs are always replaced when their BlockState changes. Override shouldRefresh in your TE to correct that.

I added this to the tile entity:

 

public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newSate)

    {

        return false;

    }

 

And now it cooks things like a furnace, but the block model doesn't change with the state like it's supposed to. Here's the blockstates json in case you need that:

 

{

  "variants": {

    "active=false": { "model": "braziermod:raisedbrazier" },

    "active=true": { "model": "braziermod:bigbrazier" }

  }

}

 

Both models work just fine, as I have tested by switching the false and true above.

Link to comment
Share on other sites

Oops.

 

public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newSate)

    {

        return (oldState.getBlock() != newSate.getBlock());

    }

 

Also, I noticed an error in the launcher output, although it could be caused by some other mod I have installed:

 

[08:48:04] [Thread-10/ERROR]: Error in class 'LibraryLWJGLOpenAL'

[08:48:04] [Thread-10/ERROR]: Source '60ea8f7f-d987-4d46-904b-2690630d242c' not found in method 'play'

[08:48:04] [Thread-10/ERROR]: Error in class 'LibraryLWJGLOpenAL'

[08:48:04] [Thread-10/ERROR]: Source '60ea8f7f-d987-4d46-904b-2690630d242c' not found in method 'play'

Link to comment
Share on other sites

Makes me wonder why Forge doesn't patch that.  Unless this behavior is the patch, in which case, I question someone's sanity.

The vanilla behavior is: Always replace on metadata / BlockState change. Forge gives you the possibility to change it.

 

Yes, fine, but why does forge supply the default that it does? e.g. inconsistent with prior behavior.

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

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.