Posted September 16, 20169 yr I have an item that is supposed to place a specific block when used. These blocks should be changing their texture based on whether the block above them is the same kind as itself. It seems I'm not doing this right, and I'm wondering if someone would be willing to help me out with this. I'm somewhat new to block states and how to use them correctly. [spoiler=Item] package com.trekkiecub.oddsandends.items; import java.util.List; import com.trekkiecub.oddsandends.blocks.Block_Chain; import com.trekkiecub.oddsandends.init.BlockInit; import net.minecraft.block.Block; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.ActionResult; import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; public class Item_Chain extends Item { @Override public EnumActionResult onItemUse(ItemStack stack, EntityPlayer playerIn, World worldIn, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { if (worldIn.getBlockState(pos).getBlock() == BlockInit.chain) { Block_Chain chain = (Block_Chain)worldIn.getBlockState(pos).getBlock(); BlockPos nextChain = chain.canAddSegment(worldIn, pos); if (nextChain != null) { worldIn.setBlockState(nextChain, BlockInit.chain.getDefaultState()); stack.stackSize--; } } if (facing != null && facing == EnumFacing.DOWN) { if (playerIn.canPlayerEdit(pos, facing, stack)) { worldIn.setBlockState(pos.down(), BlockInit.chain.getDefaultState()); stack.stackSize--; } } return EnumActionResult.PASS; } @Override public ActionResult<ItemStack> onItemRightClick(ItemStack itemStackIn, World worldIn, EntityPlayer playerIn, EnumHand hand) { return new ActionResult(EnumActionResult.PASS, itemStackIn); } } [spoiler=Block] package com.trekkiecub.oddsandends.blocks; import java.util.Random; import com.trekkiecub.oddsandends.init.BlockInit; import com.trekkiecub.oddsandends.init.ItemInit; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.block.properties.IProperty; import net.minecraft.block.properties.PropertyBool; import net.minecraft.block.properties.PropertyEnum; import net.minecraft.block.state.BlockStateContainer; import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumFacing; import net.minecraft.util.IStringSerializable; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; public class Block_Chain extends Block { public static final PropertyBool MID = PropertyBool.create("mid"); public Block_Chain(Material materialIn) { super(materialIn); this.setDefaultState(this.blockState.getBaseState().withProperty(MID, Boolean.valueOf(false))); } @Override public boolean isOpaqueCube(IBlockState state) { return false; } @Override public boolean isFullCube(IBlockState state) { return false; } @SideOnly(Side.CLIENT) public BlockRenderLayer getBlockLayer() { return BlockRenderLayer.CUTOUT; } @Override public void neighborChanged(IBlockState state, World worldIn, BlockPos pos, Block blockIn) { if (!this.canBlockStay(worldIn, pos)) { worldIn.destroyBlock(pos, true); } } @Override public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) { return state.withProperty(MID, isBottom((World) worldIn, pos)); } public boolean isBottom(World worldIn, BlockPos pos) { if (worldIn.getBlockState(pos.down()).getBlock() instanceof Block_Chain) { return false; } else { return true; } } @Override public boolean canSilkHarvest() { return false; } @Override public Item getItemDropped(IBlockState state, Random rand, int fortune) { boolean mid = state.getValue(MID); return (mid ? Items.APPLE : ItemInit.chain); } public boolean canBlockStay(World world, BlockPos pos) { if (world.getBlockState(pos.up()).getBlock() == BlockInit.chain) { return true; } else if (world.getBlockState(pos.up()).isSideSolid(world, pos, EnumFacing.DOWN)) { return true; } else { return false; } } public BlockPos canAddSegment(World worldIn, BlockPos pos) { if (worldIn.getBlockState(pos.down()).getBlock() == Blocks.AIR) { if (pos.down().getY() > 0) { return pos.down(); } else { return null; } } else if (worldIn.getBlockState(pos.down()).getBlock() instanceof Block_Chain) { return canAddSegment(worldIn, pos.down()); } else { return null; } } @Override protected BlockStateContainer createBlockState() { return new BlockStateContainer(this, new IProperty[] {MID}); } @Override public int getMetaFromState(IBlockState state) { return 0; } }
September 16, 20169 yr Show where you registered the block, and was there an error in the log? VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator.
September 16, 20169 yr Why does it seem that you're not doing it right? You haven't told us what happens versus what you expected. You haven't told us what you saw happening as you stepped through in the debugger. What's "not right"? The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.
September 17, 20169 yr Author Sorry about that. What should be happening is a chain block should change how it renders based on whether the block above it is a chain block as well. So far, that's not working, and every chain block placed keeps its default block state and doesn't change when a new chain block is added.
September 17, 20169 yr Hi Perhaps your blockstates json is not correct. You could check your getActualState by putting a breakpoint in there or alternatively System.out.println("state:" + actualState); @Override public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) { actualState = state.withProperty(MID, isBottom((World) worldIn, pos)); return actualState }
September 17, 20169 yr You might want MID to be !isBottom The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.
September 28, 20168 yr Author getActualState is running, but it appears the MID property is not being set or accessed correctly and I'm not sure what I'm doing wrong. It doesn't matter whether I use the isBottom function as-is or negate it.
September 28, 20168 yr Did you step through its execution? Did you see what was returned by isBottom? Did you step into withProperty to see what happened there? If all those things went well, then post your blockstates json file. The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.
September 30, 20168 yr Author I'm not sure how to step into the withProperty function of IBlockState in Eclipse (the option is grayed out, not sure what I'm supposed to do to fix this). isBottom() is returning the correct values. When I change the default value for the MID property, the block has the correct model and drops the correct item for the blockstate. It seems the problem is one where the block's state isn't changing when I add a new block below it. I thought the getActualState() function was supposed to let me do that, but it looks like I might need to do more to the block class. Does anyone know what I'm doing wrong?
September 30, 20168 yr I'm not sure how to step into the withProperty function of IBlockState in Eclipse... You need to be running in debug mode. What did you try to do, and where did you set your breakpoint(s)? How much experience do you have with debugger tools? the block's state isn't changing when I add a new block below it Then you want to step through the neighbor change. The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.
October 5, 20168 yr Author I actually have little experience with debugger tools. Most coding I've done in college has been through a text editor and a console, and when I do use an IDE, I use it for error detection and code consistency. What I usually do is I use text output to determine and isolate a problem. I've been looking at the code for the vanilla BlockPane, and it looks like my code should work. The only difference between BlockPane and Block_Chain was that getActualState was overriden in Block_Chain. Removing the override did not change the outcome. I'm doing some debugging now and it looks like BlockRendererDispatcher's renderBlock() is throwing an exception when it tries to set the state to the value returned from getActualBlockState(). This exception is caught and nothing happens afterward. I'm not sure what's causing this, but it looks like the code was designed to smother the exception rather than help figure out what's going wrong.
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.