Jump to content

[1.14.4/1.15.2] [Solved] Custom Leaf Help


killerjdog51

Recommended Posts

Hello, I'm trying to make a custom leaf block in my mod (for both 1.14 and 1.15 [and probably 1.16 now that that's out]) and have run into two problems. The first issue is the farthest leaves despawn, so to fix that I tried creating my own leaf class and extending the LeavesBlock class as shown, but upon loading the game I get this error: 

 

Cannot set property IntegerProperty{name=distance, clazz=class java.lang.Integer, values=[1, 2, 3, 4, 5, 6, 7]} as it does not exist in Block{null}

 

package killerjdog51.biomeEnhancementsMod.blocks;

import java.util.Random;

import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.LeavesBlock;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.state.IntegerProperty;
import net.minecraft.state.StateContainer;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tags.BlockTags;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorld;
import net.minecraft.world.World;

public class PalmLeavesBlock extends LeavesBlock {
	   public static final IntegerProperty DISTANCE = IntegerProperty.create("distance", 1, 11);

	   public PalmLeavesBlock(Block.Properties properties) {
	      super(properties);
	      this.setDefaultState(this.stateContainer.getBaseState().with(DISTANCE, Integer.valueOf(11)).with(PERSISTENT, Boolean.valueOf(false)));
	   }

	   @Override
	   public boolean ticksRandomly(BlockState state) {
	      return state.get(DISTANCE) == 11 && !state.get(PERSISTENT);
	   }

	   @Override
	   public void randomTick(BlockState state, World worldIn, BlockPos pos, Random random) {
	      if (!state.get(PERSISTENT) && state.get(DISTANCE) == 11) {
	         spawnDrops(state, worldIn, pos);
	         worldIn.removeBlock(pos, false);
	      }

	   }

	   @Override
	   public void tick(BlockState state, World worldIn, BlockPos pos, Random random) {
	      worldIn.setBlockState(pos, updateDistance(state, worldIn, pos), 3);
	   }

	   @Override
	   public BlockState updatePostPlacement(BlockState stateIn, Direction facing, BlockState facingState, IWorld worldIn, BlockPos currentPos, BlockPos facingPos) {
	      int i = getDistance(facingState) + 1;
	      if (i != 1 || stateIn.get(DISTANCE) != i) {
	         worldIn.getPendingBlockTicks().scheduleTick(currentPos, this, 1);
	      }

	      return stateIn;
	   }

	   private static BlockState updateDistance(BlockState p_208493_0_, IWorld p_208493_1_, BlockPos p_208493_2_) {
	      int i = 11;

	      try (BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.retain()) {
	         for(Direction direction : Direction.values()) {
	            blockpos$pooledmutableblockpos.setPos(p_208493_2_).move(direction);
	            i = Math.min(i, getDistance(p_208493_1_.getBlockState(blockpos$pooledmutableblockpos)) + 1);
	            if (i == 1) {
	               break;
	            }
	         }
	      }

	      return p_208493_0_.with(DISTANCE, Integer.valueOf(i));
	   }

	   private static int getDistance(BlockState neighbor) {
	      if (BlockTags.LOGS.contains(neighbor.getBlock())) {
	         return 0;
	      } else {
	         return neighbor.getBlock() instanceof PalmLeavesBlock ? neighbor.get(DISTANCE) : 11;
	      }
	   }

	   @Override
	   protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) {
	      builder.add(DISTANCE, PERSISTENT);
	   }

	   @Override
	   public BlockState getStateForPlacement(BlockItemUseContext context) {
	      return updateDistance(this.getDefaultState().with(PERSISTENT, Boolean.valueOf(true)), context.getWorld(), context.getPos());
	   }
	}

 

So far the best solution I could think of was just to copy the entire LeavesBlock class and replace the necessary values since it appears that there's some sort of conflict between my distance property and LeavesBlock's distance property (I tried changing all the values to newdistance and that didn't work). I want to try avoiding this if possible and just find a solution that involves extending the LeavesBlock class and overriding the necessary functions to increase the distance. 

The second issue is that my leaves are all grayed out. I saw that in 1.12.2 people created a color manager class for this, I was wondering if that was still the case in 1.14/1.15?

 

Thanks for the feedback, I'll really appreciate it. 

Edited by killerjdog51
Link to comment
Share on other sites

6 minutes ago, killerjdog51 said:

The second issue is that my leaves are all grayed out. I saw that in 1.12.2 people created a color manager class for this, I was wondering if that was still the case in 1.14/1.15?

You need to register an IBlockColor instance on (and only on) the client thread.

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

5 hours ago, killerjdog51 said:

Cannot set property IntegerProperty{name=distance, clazz=class java.lang.Integer, values=[1, 2, 3, 4, 5, 6, 7]} as it does not exist in Block{null}

I think the problem is that the superclass LeavesBlock tries to set the default state for DISTANCE in its constructor, which unfortunately does not exist anymore due to the fact that you have overriden fillStateContainer.

To fix this, change the string name of your DISTANCE variable, like so:

public static final IntegerProperty DISTANCE = IntegerProperty.create("distance2", 1, 11);

and also change fillStateContainer to the following:

@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) {
	builder.add(DISTANCE);
  	super.fillStateContainer(builder);
}

Hopefully that will work.

Edited by vemerion
Link to comment
Share on other sites

9 hours ago, Draco18s said:

You need to register an IBlockColor instance on (and only on) the client thread.

public class BlockColorHandler
{
  	@OnlyIn(Dist.CLIENT)
	@SubscribeEvent
	public void registerBlockColourHandlers(final ColorHandlerEvent.Block event)
	{
		// Use the colour of the biome or the default colour
		final IBlockColor grassColourHandler = (state, blockAccess, pos, tintIndex) -> {
			
			if (blockAccess != null && pos != null)
			{
				return BiomeColors.getFoliageColor(blockAccess, pos);
			}

			return GrassColors.get(0.5D, 1.0D);
		};

		event.getBlockColors().register(grassColourHandler, ModBlocks.BAOBAB_LEAVES, ModBlocks.MANGROVE_LEAVES, ModBlocks.PALM_LEAVES);
	}
  	@OnlyIn(Dist.CLIENT)
	@SubscribeEvent
	public void registerItemColourHandlers(final ColorHandlerEvent.Item event)
	{
		// Use the Block's colour handler for an ItemBlock
		final IItemColor itemBlockColourHandler = (stack, tintIndex) -> {
			BlockState iblockstate = ((BlockItem) stack.getItem()).getBlock().getDefaultState();
			return event.getBlockColors().getColor(iblockstate, null, null, tintIndex);
		};

		event.getItemColors().register(itemBlockColourHandler, ModBlocks.BAOBAB_LEAVES, ModBlocks.MANGROVE_LEAVES, ModBlocks.PALM_LEAVES);
	}
}
MinecraftForge.EVENT_BUS.register(new BlockColorHandler());

So here are my events, but they never get called.

 

Initially i used:

Minecraft.GetInstance().getBlockColors().register();

like in the Coloring Textures section in the Forge Documentation, but that results in a nullPointerException error

Link to comment
Share on other sites

7 minutes ago, ChampionAsh5357 said:

Are they never called or do you just not see the result because you never set the tint index on your models?

I set up a breakpoint at the beginning of each event, since neither of the breakpoints were triggered I'm guessing the events just aren't called. 

Link to comment
Share on other sites

15 minutes ago, ChampionAsh5357 said:

Completely missed this, needs to be the mod event bus.

Thank you, that solved it! I had no idea that the color handler events were moved to the mod event bus since in 1.12 and 1.13 they were in the Forge event bus. 

Now to tackle Vemerion's suggestion

Link to comment
Share on other sites

6 hours ago, vemerion said:

I think the problem is that the superclass LeavesBlock tries to set the default state for DISTANCE in its constructor, which unfortunately does not exist anymore due to the fact that you have overriden fillStateContainer.

To fix this, change the string name of your DISTANCE variable, like so:


public static final IntegerProperty DISTANCE = IntegerProperty.create("distance2", 1, 11);

and also change fillStateContainer to the following:


@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) {
	builder.add(DISTANCE);
  	super.fillStateContainer(builder);
}

Hopefully that will work.

Thank you, this worked as well! Now none of the leaves despawn from the tree.

  • Like 1
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.



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.