Jump to content

[1.12] setBlockState state.CycleProperty without resetting block NBT data (or update blockState/model based on NBT data)


Recommended Posts

Posted

I'm trying to make a block I've made change its model when I put something into its inventory. Right now, the only way I can tell how to change block states at all is with world.setBlockState(pos, state.cycleProperty(MODE, 3); (at least that's the code I'm using for it), but doing that resets the NBT and clears out the inventory. I've tried shuffling around the tile.markDirty(); commands and the setBlockUpdate ones but nothing's managed to save the inventory and the state. What should I be doing instead?

 

The code being used, in case I'm just doing something drastically wrong with what I currently have:

Spoiler

package space.bbkr.aura.block;

import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.world.IBlockAccess;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.world.World;
import net.minecraft.block.state.IBlockState;
import net.minecraft.block.properties.PropertyDirection;
import net.minecraft.block.properties.PropertyInteger;
import net.minecraft.util.Rotation;
import net.minecraft.util.Mirror;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.CapabilityItemHandler;
import space.bbkr.aura.Aura;
import space.bbkr.aura.tileentity.TileEntitySmelter;

import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;


public class BlockSmelter extends BlockMachine<TileEntitySmelter> {
    private static final PropertyDirection FACING = PropertyDirection.create("f");
    public static final PropertyInteger MODE = PropertyInteger.create("m", 0, 1);

    public BlockSmelter() {
        super(Material.ROCK, "aura_smelter");
    }

    @Override
    public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ) {
        if (!world.isRemote) {
            TileEntitySmelter tile = getTileEntity(world, pos);
            ItemStack heldItem = player.getHeldItem(hand);
            IItemHandler itemHandler = tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, side);
          	//note: I've tried putting world.setBlockUpdate here, with no success
            if (!player.isSneaking()) {
                //note: I've tried putting world.setBlockUpdate here, with no success
                if (heldItem.isEmpty()) {
                    player.setHeldItem(hand, itemHandler.extractItem(0, 64, false));
                    world.setBlockState(pos, state.cycleProperty(MODE), 3);
                    //note: I've tried putting tile.markDirty here and in the corresponding spot in else, with no success
                } else {
                    player.setHeldItem(hand, itemHandler.insertItem(0, heldItem, false));
                    world.setBlockState(pos, state.cycleProperty(MODE), 3);
                }
                tile.markDirty();
                //note: I've tried putting world.setBlockUpdate here, with no succes
            } else {
                ItemStack stack = itemHandler.getStackInSlot(0);
                if (!stack.isEmpty()) {
                    String localized = Aura.proxy.localize(stack.getUnlocalizedName() + ".name");
                    player.sendMessage(new TextComponentString(stack.getCount() + "x" + localized));
                } else {
                    player.sendMessage(new TextComponentString("empty"));
                }
            }
        }
        return true;
    }

    @Override
    public void breakBlock(World world, BlockPos pos, IBlockState state) {
        TileEntitySmelter tile = getTileEntity(world, pos);
        IItemHandler itemHandler = tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, EnumFacing.NORTH);
        ItemStack stack = itemHandler.getStackInSlot(0);
        if (!stack.isEmpty()) {
            EntityItem item = new EntityItem(world, pos.getX(), pos.getY(), pos.getZ(), stack);
            world.spawnEntity(item);
        }
        super.breakBlock(world, pos, state);
    }

    @Override
    public Class<TileEntitySmelter> getTileEntityClass() {
        return TileEntitySmelter.class;
    }

    @Nullable
    @Override
    public TileEntitySmelter createTileEntity(World world, IBlockState state) {
        return new TileEntitySmelter();
    }

    @Override
    public IBlockState getStateForPlacement(World w, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer, EnumHand hand) {
        return getDefaultState().withProperty(FACING, EnumFacing.getDirectionFromEntityLiving(pos, placer)).withProperty(MODE, 0);
    }

    @Override
    public void onBlockPlacedBy(World w, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack) {
        w.setBlockState(pos, state.withProperty(FACING, EnumFacing.getDirectionFromEntityLiving(pos, placer)), 2);
    }

    @Override public IBlockState getStateFromMeta(int meta) {
        return getDefaultState().withProperty(MODE, meta % 2).withProperty(FACING, EnumFacing.VALUES[(meta / 2) % 6]);
    }

    @Override public int getMetaFromState(IBlockState state) {
        return state.getValue(MODE) + (2 * state.getValue(FACING).getIndex());
    }

    @Override public IBlockState withRotation(IBlockState state, Rotation rot) {
        return state.withProperty(FACING, rot.rotate(state.getValue(FACING)));
    }

    @Override public IBlockState withMirror(IBlockState state, Mirror mir) {
        return state.withRotation(mir.toRotation(state.getValue(FACING)));
    }

    @Override protected BlockStateContainer createBlockState() {
        return new BlockStateContainer(this, FACING, MODE);
    }
}

and the tileentity:


package space.bbkr.aura.tileentity;

import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.ItemStackHandler;

import javax.annotation.Nullable;

public class TileEntitySmelter extends TileEntity {

    private ItemStackHandler inventory = new ItemStackHandler(1);

    @Override
    public NBTTagCompound writeToNBT(NBTTagCompound compound) {
        compound.setTag("inventory", inventory.serializeNBT());
        return super.writeToNBT(compound);
    }

    @Override
    public void readFromNBT(NBTTagCompound compound) {
        inventory.deserializeNBT(compound.getCompoundTag("inventory"));
        super.readFromNBT(compound);
    }

    @Override
    public boolean hasCapability(Capability<?> capability, @Nullable EnumFacing facing) {
        return capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY|| super.hasCapability(capability, facing);
    }

    @Nullable
    @Override
    public <T> T getCapability (Capability<T> capability, @Nullable EnumFacing facing) {
        return capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY ? (T)inventory : super.getCapability(capability, facing);
    }

}

 

 

Posted

Override TileEntity#shouldRefresh to return true only when the Block changes. This will allow the TileEntity to remain intact when the state changes but the Block is still the same.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Posted

Worked. Thank you! For others with the problem, here's the code I used, grabbed from this Minecraft Forum post:

public class TileEntitySmelter extends TileEntity {
	//...

	@Override
   	public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newState) {
		return (oldState.getBlock() != newState.getBlock());
    }
  
}

 

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.