Jump to content

1.16.4 Custom Tree Feature


jonaskohl

Recommended Posts

I'm trying to add a custom tree to my mod. I'm using the following method to register the tree:

//// == ElderTree.java == ////
public class ElderTree extends Tree {
    @Nullable
    @Override
    protected ConfiguredFeature<BaseTreeFeatureConfig, ?> getTreeFeature(Random randomIn, boolean largeHive) {
        return (ConfiguredFeature<BaseTreeFeatureConfig, ?>) ModFeatures.ELDER_TREE.get();
    }
}

//// == ModFeatures.java == ////
// [...]
public static final Lazy<ConfiguredFeature<? extends IFeatureConfig, ?>> ELDER_TREE = register("elder_tree", () ->
        Feature.TREE.withConfiguration(Configs.ELDER_TREE_CONFIG)
                    .withPlacement(Features.Placements.HEIGHTMAP_PLACEMENT)
                    .withPlacement(Placements.ELDER_TREE_PLACEMENT)
);
// [...]
public static final class Configs {
    public static final BaseTreeFeatureConfig ELDER_TREE_CONFIG;
	// [...]
    static {
      ELDER_TREE_CONFIG = new BaseTreeFeatureConfig.Builder(
        new SimpleBlockStateProvider(ModBlocks.ELDER_LOG.get().getDefaultState()),
        new SimpleBlockStateProvider(ModBlocks.ELDER_LEAVES.get().getDefaultState()),
        //                                       Radius             | Offset    | Height
        new BlobFoliagePlacer(FeatureSpread.create(2), FeatureSpread.create(0), 3),
        //                      Base height | Height Rand A | Height Rand B
        new StraightTrunkPlacer(4, 2, 0),
        new TwoLayerFeature(1, 0, 1)
      )
        .setIgnoreVines()
        .build();
    }
	// [...]
}

But whenever I try to grow a sapling or generate a new world, Minecraft crashes with the following exception:

[13:25:21] [Server thread/FATAL] [minecraft/ThreadTaskExecutor]: Error executing task on Server
java.lang.ClassCastException: net.minecraft.world.gen.feature.DecoratedFeatureConfig cannot be cast to net.minecraft.world.gen.feature.BaseTreeFeatureConfig
	at net.minecraft.block.trees.Tree.attemptGrowTree(Tree.java:28) ~[forge:?] {re:classloading}
	at team.mixxit.allotment.blocks.ModSapling.placeTree(ModSapling.java:50) ~[?:?] {re:classloading}
	at team.mixxit.allotment.blocks.ModSapling.grow(ModSapling.java:71) ~[?:?] {re:classloading}
	at net.minecraft.item.BoneMealItem.applyBonemeal(BoneMealItem.java:73) ~[forge:?] {re:classloading}
	at net.minecraft.item.BoneMealItem.onItemUse(BoneMealItem.java:36) ~[forge:?] {re:classloading}
	at net.minecraftforge.common.ForgeHooks.onPlaceItemIntoWorld(ForgeHooks.java:613) ~[forge:?] {re:classloading}
	at net.minecraft.item.ItemStack.onItemUse(ItemStack.java:191) ~[forge:?] {re:classloading}
	at net.minecraft.server.management.PlayerInteractionManager.func_219441_a(PlayerInteractionManager.java:359) ~[forge:?] {re:classloading}
	at net.minecraft.network.play.ServerPlayNetHandler.processTryUseItemOnBlock(ServerPlayNetHandler.java:986) ~[forge:?] {re:classloading}
	at net.minecraft.network.play.client.CPlayerTryUseItemOnBlockPacket.processPacket(CPlayerTryUseItemOnBlockPacket.java:45) ~[forge:?] {re:classloading}
	at net.minecraft.network.play.client.CPlayerTryUseItemOnBlockPacket.processPacket(CPlayerTryUseItemOnBlockPacket.java:12) ~[forge:?] {re:classloading}
	at net.minecraft.network.PacketThreadUtil.lambda$checkThreadAndEnqueue$0(PacketThreadUtil.java:19) ~[forge:?] {re:classloading}
	at net.minecraft.util.concurrent.TickDelayedTask.run(TickDelayedTask.java:20) ~[forge:?] {re:classloading}
	at net.minecraft.util.concurrent.ThreadTaskExecutor.run(ThreadTaskExecutor.java:139) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.util.concurrent.RecursiveEventLoop.run(RecursiveEventLoop.java:22) ~[forge:?] {re:classloading}
	at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:758) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:159) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.util.concurrent.ThreadTaskExecutor.driveOne(ThreadTaskExecutor.java:109) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.server.MinecraftServer.driveOneInternal(MinecraftServer.java:741) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.server.MinecraftServer.driveOne(MinecraftServer.java:735) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.util.concurrent.ThreadTaskExecutor.driveUntil(ThreadTaskExecutor.java:122) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.server.MinecraftServer.runScheduledTasks(MinecraftServer.java:721) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.server.MinecraftServer.func_240802_v_(MinecraftServer.java:667) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.server.MinecraftServer.lambda$startServer$0(MinecraftServer.java:233) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at java.lang.Thread.run(Thread.java:748) [?:1.8.0_241] {}

It seems that ConfiguredFeature#withPlacement(ConfiguredPlacement<?>) is the culprit, as it adds a DecoratedFeatureConfig to the feature. What is the proper way to add a placement rule to a tree?

Link to comment
Share on other sites

  • 7 months later...
Guest
This topic is now closed to further replies.


×
×
  • Create New...

Important Information

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