Changes

25 bytes added ,  17:59, 11 March 2021
fix formatting
Line 1: Line 1: −
<div class="header">
+
Let's start with a basic example by extending SaplingBlock.First create a class that extends SaplingBlock.
  <h1>Saplings</h1>
+
 
  <p>How to create Saplings in Forge 1.16.4</p>
+
<code>public class ExampleSapling extends SaplingBlock{}</code>
</div>
+
 
Let's start with a basic example by extending SaplingBlock.First create a class that extends SaplingBlock.<br>
+
After that you can insert the constructor. It must call super with the Parameters :  
<code>public class ExampleSapling extends SaplingBlock{}</code> <br>
+
 
After that you can insert the constructor. It must call super with the Parameters : <br>
   
{| class="wikitable" border=1
 
{| class="wikitable" border=1
 
!Name !! Type !!Description  
 
!Name !! Type !!Description  
Line 13: Line 12:  
|  <code>properties</code>  ||  <code>net.minecraft.block.AbstractBlock.Properties</code>  ||  <code>The Block Properties of the Sapling</code>
 
|  <code>properties</code>  ||  <code>net.minecraft.block.AbstractBlock.Properties</code>  ||  <code>The Block Properties of the Sapling</code>
 
|-
 
|-
|}<br>
+
|}
That means we need to make a Tree for ourselves, but more on that in a bit.<br>
+
 
If you want to have the Sapling be placeable on your own Mods Block, you need to override <code>isValidGround</code> and make your own additions to the vanilla provided Blocks. I recommend making a <br><code>private static final List<Block> validBlocks = ImmutableList.of(Blocks block...)</code> to add Blocks to the List of possible Blocks.<br>
+
 
If you have that, your function could look like : <br>
+
That means we need to make a Tree for ourselves, but more on that in a bit.
<code>
+
If you want to have the Sapling be placeable on your own Mods Block, you need to override <code>isValidGround</code> and make your own additions to the vanilla provided Blocks. I recommend making a  
 +
<code>private static final List<Block> validBlocks = ImmutableList.of(Blocks block...)</code> to add Blocks to the List of possible Blocks.
 +
If you have that, your function could look like :
 +
<syntaxhighlight lang="java">
 
protected boolean isValidGround(@Nonnull BlockState state,@Nonnull IBlockReader worldIn,@Nonnull BlockPos pos) {
 
protected boolean isValidGround(@Nonnull BlockState state,@Nonnull IBlockReader worldIn,@Nonnull BlockPos pos) {
 
return validBlocks.stream().anyMatch(state::isIn) || super.isValidGround(state, worldIn, pos);
 
return validBlocks.stream().anyMatch(state::isIn) || super.isValidGround(state, worldIn, pos);
 
}
 
}
</code><br>
+
</syntaxhighlight>
Now onto making the Tree for your Sapling.<br>
+
 
Start by making a <code>class</code> that extends <code>Tree</code> : <br>
+
Now onto making the Tree for your Sapling.
<code>public class ExampleTree extends Tree </code> <br>
+
 
This <code>class</code> will only contain one <code>function</code> which is : <br>
+
Start by making a <code>class</code> that extends <code>Tree</code> :  
<code>protected ConfiguredFeature<BaseTreeFeatureConfig, ?> getTreeFeature(Random randomIn, boolean largeHive)</code><br>
+
 
As you can see, this function requires to return a ConfiguredFeature<BaseTreeFeatureConfig, ?>. This will be the Tree that is Placed in the World. <br>
+
<code>public class ExampleTree extends Tree </code>
The <code>ConfiguredFeature<BaseTreeFeatureConfig, ?><code> will look sth like this : <br>
+
This <code>class</code> will only contain one <code>function</code> which is :  
public static final ConfiguredFeature<BaseTreeFeatureConfig, ?> EXAMPLETREEFEATURE = <br>
+
<code>protected ConfiguredFeature<BaseTreeFeatureConfig, ?> getTreeFeature(Random randomIn, boolean largeHive)</code>
  Feature.TREE.withConfiguration(<br>
+
As you can see, this function requires to return a ConfiguredFeature<BaseTreeFeatureConfig, ?>. This will be the Tree that is Placed in the World.
             new BaseTreeFeatureConfig.Builder(<br>
+
The <code>ConfiguredFeature<BaseTreeFeatureConfig, ?></code> will look sth like this :
                     new SimpleBlockStateProvider(BlockInit.EXAMPLE_WOOD.get().getDefaultState()),<br>
+
<syntaxhighlight lang="java">
                     new SimpleBlockStateProvider(BlockInit.EXAMPLE_LEAVES.get().getDefaultState()),<br>
+
public static final ConfiguredFeature<BaseTreeFeatureConfig, ?> EXAMPLETREEFEATURE =  
                     new BlobFoliagePlacer(FeatureSpread.func_242252_a(2), FeatureSpread.func_242252_a(0), 3),<br>
+
  Feature.TREE.withConfiguration(
                     new StraightTrunkPlacer(4, 2, 0),<br>
+
             new BaseTreeFeatureConfig.Builder(
                     new TwoLayerFeature(1, 0, 1)<br>
+
                     new SimpleBlockStateProvider(BlockInit.EXAMPLE_WOOD.get().getDefaultState()),
             ).setIgnoreVines().build());<br>
+
                     new SimpleBlockStateProvider(BlockInit.EXAMPLE_LEAVES.get().getDefaultState()),
After we have our ExampleTree we need to register it. This is done via 2 functions : <br>
+
                     new BlobFoliagePlacer(FeatureSpread.func_242252_a(2), FeatureSpread.func_242252_a(0), 3),
<code>public static void registerTrees() {
+
                     new StraightTrunkPlacer(4, 2, 0),
 +
                     new TwoLayerFeature(1, 0, 1)
 +
             ).setIgnoreVines().build());
 +
</syntaxhighlight>
 +
After we have our ExampleTree we need to register it. This is done via 2 functions :
 +
<syntaxhighlight lang="java">
 +
public static void registerTrees() {
 
         register("example_tree", EXAMPLETREE);
 
         register("example_tree", EXAMPLETREE);
 
     }
 
     }
<code><br>
+
</syntaxhighlight>
 
and also the function <code>register</code> :  
 
and also the function <code>register</code> :  
<code>
+
<syntaxhighlight lang="java">
register(String key, ConfiguredFeature<FC, ?> configuredFeature){
+
public void register(String key, ConfiguredFeature<FC, ?> configuredFeature){
 
Registry.register(WorldGenRegistries.CONFIGURED_FEATURE, key, configuredFeature);
 
Registry.register(WorldGenRegistries.CONFIGURED_FEATURE, key, configuredFeature);
 
}
 
}
</code><br>
+
</syntaxhighlight >
 +
 
 
If you have everything setup, call registerTrees() in FMLCommonSetupEvent.<br>
 
If you have everything setup, call registerTrees() in FMLCommonSetupEvent.<br>
 
Back to the Sapling. Your constructor can now be completed by putting the Tree we just registered as the first super parameter and the Properties as the second parameter :  
 
Back to the Sapling. Your constructor can now be completed by putting the Tree we just registered as the first super parameter and the Properties as the second parameter :  
<code>
+
<syntaxhighlight lang="java">
 
public ExampleSapling() {
 
public ExampleSapling() {
 
         super(new ExampleTree(), AbstractBlock.Properties.create(Material.PLANTS).doesNotBlockMovement().tickRandomly().zeroHardnessAndResistance().sound(SoundType.PLANT));
 
         super(new ExampleTree(), AbstractBlock.Properties.create(Material.PLANTS).doesNotBlockMovement().tickRandomly().zeroHardnessAndResistance().sound(SoundType.PLANT));
 
     }
 
     }
</code><br>
+
</syntaxhighlight >
 
Also in your ExampleTree class, instead of null, the function now should return your TreeFeature : <br>
 
Also in your ExampleTree class, instead of null, the function now should return your TreeFeature : <br>
<code>
+
<syntaxhighlight lang="java">
 
protected ConfiguredFeature<BaseTreeFeatureConfig, ?> getTreeFeature(@Nonnull Random randomIn, boolean largeHive) {
 
protected ConfiguredFeature<BaseTreeFeatureConfig, ?> getTreeFeature(@Nonnull Random randomIn, boolean largeHive) {
 
         return EXAMPLETREEFEATURE;
 
         return EXAMPLETREEFEATURE;
 
     }
 
     }
</code><br>
+
</syntaxhighlight >
 
Now register the Sapling like any other Block and it should be able to be placed and grow with the correct Tree.
 
Now register the Sapling like any other Block and it should be able to be placed and grow with the correct Tree.