B0undarybreaker Posted September 2, 2017 Posted September 2, 2017 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); } } Quote
Choonster Posted September 2, 2017 Posted September 2, 2017 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. Quote 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.
B0undarybreaker Posted September 2, 2017 Author Posted September 2, 2017 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()); } } Quote
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.