Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

[Solved] [1.17.1] Is there are way to define a client only item state for client animation and other effects ?


Recommended Posts


I created a simple steel lighter item, which has a item property "open" with "1.0" or "0.0" to display two different models, see:


This works fine, but I want to change the state in the case the steel lighter is currently selected in the hotbar or not.

I tried the LivingEquipmentChangeEvent which offers exactly the needed functionality, see:


But it seems that the ItemStack from this event is different from the ItemStack which is used for the ItemProperties.register(...), even both should be client side only.

What I tried so far:

  • Using itemStack.getOrCreateTag().putBoolean(...) and itemStack.getOrCreateTag().getBoolean(...)
  • Using a hashmap with <itemStack, boolean>
  • Using a local variable (current version)

A debug of the hashmap with <itemStack, boolean> shows that the itemStack within the ItemProperties.register(...) is different from the itemStack in LivingEquipmentChangeEvent.

So I wonder if there is a alternative event / approach I could use in this case or any other client only item state which I could share between these two events.

Edited by Kaworru
Link to comment
Share on other sites

4 hours ago, diesieben07 said:

Check whether the LivingEntity you get is not null and if the ItemStack being rendered is == to LivingEntity#getMainHandItem.

Thanks. Works like a charm. 

Example for the record:

    new ResourceLocation(Constants.MOD_ID, "open"),
    (itemStack, clientLevel, livingEntity, id) -> {
      return (livingEntity == null || !itemStack.is(ModItems.STEEL_LIGHTER.get())
          || livingEntity.getMainHandItem().isEmpty()
          || itemStack != livingEntity.getMainHandItem()) ? 0.0F : 1.0F;


Link to comment
Share on other sites

  • Kaworru changed the title to [Solved] [1.17.1] Is there are way to define a client only item state for client animation and other effects ?

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.

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.


  • Recently Browsing

    No registered users viewing this page.

  • Posts

    • dude see me code, drawTexturedModalRect(X,Y,IMAGEOFFSETX,IMAGEOFFSETY,1920,1080,ZLEVEL) with drawTexturedModalRect the max size of the image is 1920x1080?, what method should i use
    • The code:   public class AncientFruitBlock extends CropsBlock { public static final IntegerProperty AGE = BlockStateProperties.AGE_0_5; public static final EnumProperty<DoubleBlockHalf> HALF = BlockStateProperties.DOUBLE_BLOCK_HALF; private static final VoxelShape[] SHAPE_BY_AGE = new VoxelShape[]{ Block.makeCuboidShape(0.0D, 0.0D, 0.0D, 16.0D, 6.0D, 16.0D), Block.makeCuboidShape(0.0D, 0.0D, 0.0D, 16.0D, 8.0D, 16.0D), Block.makeCuboidShape(0.0D, 0.0D, 0.0D, 16.0D, 10.0D, 16.0D), Block.makeCuboidShape(0.0D, 0.0D, 0.0D, 16.0D, 12.0D, 16.0D), Block.makeCuboidShape(0.0D, 0.0D, 0.0D, 16.0D, 14.0D, 16.0D), Block.makeCuboidShape(0.0D, 0.0D, 0.0D, 16.0D, 16.0D, 16.0D)}; public AncientFruitBlock(Properties builder) { super(builder); this.setDefaultState(this.stateContainer.getBaseState().with(HALF, DoubleBlockHalf.LOWER)); } public BlockState updatePostPlacement(BlockState stateIn, Direction facing, BlockState facingState, IWorld worldIn, BlockPos currentPos, BlockPos facingPos) { DoubleBlockHalf doubleblockhalf = stateIn.get(HALF); if (facing.getAxis() != Direction.Axis.Y || doubleblockhalf == DoubleBlockHalf.LOWER != (facing == Direction.UP) || facingState.isIn(this) && facingState.get(HALF) != doubleblockhalf) { return doubleblockhalf == DoubleBlockHalf.LOWER && facing == Direction.DOWN && !stateIn.isValidPosition(worldIn, currentPos) ? Blocks.AIR.getDefaultState() : super.updatePostPlacement(stateIn, facing, facingState, worldIn, currentPos, facingPos); } else { return Blocks.AIR.getDefaultState(); } } @Nullable public BlockState getStateForPlacement(BlockItemUseContext context) { BlockPos blockpos = context.getPos(); return blockpos.getY() < 255 && context.getWorld().getBlockState(blockpos.up()).isReplaceable(context) ? super.getStateForPlacement(context) : null; } public void onBlockPlacedBy(World worldIn, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) { worldIn.setBlockState(pos.up(), this.getDefaultState().with(HALF, DoubleBlockHalf.UPPER), 3); } public boolean isValidPosition(BlockState state, IWorldReader worldIn, BlockPos pos) { if (state.get(HALF) != DoubleBlockHalf.UPPER) { return super.isValidPosition(state, worldIn, pos); } else { BlockState blockstate = worldIn.getBlockState(pos.down()); if (state.getBlock() != this) return super.isValidPosition(state, worldIn, pos); return blockstate.isIn(this) && blockstate.get(HALF) == DoubleBlockHalf.LOWER; } } public void placeAt(IWorld worldIn, BlockPos pos, int flags) { worldIn.setBlockState(pos, this.getDefaultState().with(HALF, DoubleBlockHalf.LOWER), flags); worldIn.setBlockState(pos.up(), this.getDefaultState().with(HALF, DoubleBlockHalf.UPPER), flags); } public void onBlockHarvested(World worldIn, BlockPos pos, BlockState state, PlayerEntity player) { if (!worldIn.isRemote) { if (player.isCreative()) { removeBottomHalf(worldIn, pos, state, player); } else { spawnDrops(state, worldIn, pos, (TileEntity)null, player, player.getHeldItemMainhand()); } } super.onBlockHarvested(worldIn, pos, state, player); } public void harvestBlock(World worldIn, PlayerEntity player, BlockPos pos, BlockState state, @Nullable TileEntity te, ItemStack stack) { super.harvestBlock(worldIn, player, pos, Blocks.AIR.getDefaultState(), te, stack); } protected static void removeBottomHalf(World world, BlockPos pos, BlockState state, PlayerEntity player) { DoubleBlockHalf doubleblockhalf = state.get(HALF); if (doubleblockhalf == DoubleBlockHalf.UPPER) { BlockPos blockpos = pos.down(); BlockState blockstate = world.getBlockState(blockpos); if (blockstate.getBlock() == state.getBlock() && blockstate.get(HALF) == DoubleBlockHalf.LOWER) { world.setBlockState(blockpos, Blocks.AIR.getDefaultState(), 35); world.playEvent(player, 2001, blockpos, Block.getStateId(blockstate)); } } } protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) { builder.add(HALF); } @Override protected IItemProvider getSeedsItem() { return ItemInit.ANCIENT_SEED.get(); } @Override public int getMaxAge() { return 5; } @Override public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { return SHAPE_BY_AGE[state.get(this.getAgeProperty())]; } }  
    • Yes I have, however, when I put the code from the vanilla block into the block class, the game just throws me an error. Log Crash Report
    • Have you looked at the vanilla 2-tall blocks?
  • Topics

  • Who's Online (See full list)

  • Create New...

Important Information

By using this site, you agree to our Privacy Policy.