From 1eddb87136392ba7941195f38c976c9b28cdf92f Mon Sep 17 00:00:00 2001 From: red_steel <> Date: Mon, 3 Oct 2022 17:04:31 -0300 Subject: [PATCH 1/5] add nms tree grower --- .../realisticbiomes/RBConfigManager.java | 3 + .../growth/NMSFeatureGrower.java | 231 ++++++++++++++++++ .../realisticbiomes/growth/RBFeatures.java | 119 +++++++++ 3 files changed, 353 insertions(+) create mode 100644 paper/src/main/java/com/untamedears/realisticbiomes/growth/NMSFeatureGrower.java create mode 100644 paper/src/main/java/com/untamedears/realisticbiomes/growth/RBFeatures.java diff --git a/paper/src/main/java/com/untamedears/realisticbiomes/RBConfigManager.java b/paper/src/main/java/com/untamedears/realisticbiomes/RBConfigManager.java index 20ce32aa..1e45cbe7 100644 --- a/paper/src/main/java/com/untamedears/realisticbiomes/RBConfigManager.java +++ b/paper/src/main/java/com/untamedears/realisticbiomes/RBConfigManager.java @@ -11,6 +11,7 @@ import com.untamedears.realisticbiomes.growth.HorizontalBlockSpreadGrower; import com.untamedears.realisticbiomes.growth.IArtificialGrower; import com.untamedears.realisticbiomes.growth.KelpGrower; +import com.untamedears.realisticbiomes.growth.NMSFeatureGrower; import com.untamedears.realisticbiomes.growth.SchematicGrower; import com.untamedears.realisticbiomes.growth.SeaPickleGrower; import com.untamedears.realisticbiomes.growth.StemGrower; @@ -306,6 +307,8 @@ private IArtificialGrower parseGrower(ConfigurationSection section, ItemStack it return new StemGrower(material, fruitConfig); case "tree": return new TreeGrower(material); + case "nmstree": + return new NMSFeatureGrower(material); case "horizontalspread": int maxAmount = section.getInt("max_amount"); int horRange = section.getInt("max_range"); diff --git a/paper/src/main/java/com/untamedears/realisticbiomes/growth/NMSFeatureGrower.java b/paper/src/main/java/com/untamedears/realisticbiomes/growth/NMSFeatureGrower.java new file mode 100644 index 00000000..0f031654 --- /dev/null +++ b/paper/src/main/java/com/untamedears/realisticbiomes/growth/NMSFeatureGrower.java @@ -0,0 +1,231 @@ +package com.untamedears.realisticbiomes.growth; + +import java.lang.reflect.Field; +import java.util.Iterator; +import java.util.List; +import java.util.OptionalInt; +import java.util.Random; + +import org.bukkit.Material; +import org.bukkit.TreeType; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.data.Ageable; +import org.bukkit.block.data.type.Sapling; +import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; +import org.bukkit.craftbukkit.v1_18_R2.block.CraftBlock; +import org.bukkit.craftbukkit.v1_18_R2.block.data.type.CraftSapling; + +import com.google.common.collect.ImmutableList; +import com.untamedears.realisticbiomes.PlantManager; +import com.untamedears.realisticbiomes.RealisticBiomes; +import com.untamedears.realisticbiomes.model.Plant; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.tags.BlockTags; +import net.minecraft.util.valueproviders.ConstantInt; +import net.minecraft.util.valueproviders.UniformInt; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.SaplingBlock; +import net.minecraft.world.level.block.grower.AbstractMegaTreeGrower; +import net.minecraft.world.level.block.grower.AbstractTreeGrower; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.HugeFungusConfiguration; +import net.minecraft.world.level.levelgen.feature.configurations.TreeConfiguration; +import net.minecraft.world.level.levelgen.feature.featuresize.ThreeLayersFeatureSize; +import net.minecraft.world.level.levelgen.feature.featuresize.TwoLayersFeatureSize; +import net.minecraft.world.level.levelgen.feature.foliageplacers.AcaciaFoliagePlacer; +import net.minecraft.world.level.levelgen.feature.foliageplacers.BlobFoliagePlacer; +import net.minecraft.world.level.levelgen.feature.foliageplacers.DarkOakFoliagePlacer; +import net.minecraft.world.level.levelgen.feature.foliageplacers.MegaJungleFoliagePlacer; +import net.minecraft.world.level.levelgen.feature.foliageplacers.MegaPineFoliagePlacer; +import net.minecraft.world.level.levelgen.feature.foliageplacers.SpruceFoliagePlacer; +import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider; +import net.minecraft.world.level.levelgen.feature.treedecorators.AlterGroundDecorator; +import net.minecraft.world.level.levelgen.feature.treedecorators.BeehiveDecorator; +import net.minecraft.world.level.levelgen.feature.treedecorators.LeaveVineDecorator; +import net.minecraft.world.level.levelgen.feature.treedecorators.TrunkVineDecorator; +import net.minecraft.world.level.levelgen.feature.trunkplacers.DarkOakTrunkPlacer; +import net.minecraft.world.level.levelgen.feature.trunkplacers.ForkingTrunkPlacer; +import net.minecraft.world.level.levelgen.feature.trunkplacers.GiantTrunkPlacer; +import net.minecraft.world.level.levelgen.feature.trunkplacers.MegaJungleTrunkPlacer; +import net.minecraft.world.level.levelgen.feature.trunkplacers.StraightTrunkPlacer; +import net.minecraft.data.worldgen.features.FeatureUtils; +import net.minecraft.data.worldgen.features.TreeFeatures; + +public class NMSFeatureGrower extends AgeableGrower { + + public NMSFeatureGrower(Material material) { + super(material, 1, 1); + } + + private boolean isMega; + + + + + @Override + public int getStage(Plant plant) { + Block block = plant.getLocation().getBlock(); + if (block.getType() != this.material) { + return -1; + } + return 0; + } + + @Override + public boolean setStage(Plant plant, int stage) { + if (stage < 1) { + return true; + } + Block block = plant.getLocation().getBlock(); + // Re-Read the block data to make sure it is up to date + if (!(block.getBlockData() instanceof Sapling)) { + return true; + } + + + //Sapling sapling = + //(Sapling) block.getBlockData(); + //sapling.setStage(3); + //plant.getLocation().getWorld().setBlockData(plant.getLocation(), sapling); + CraftBlock cBlock = (CraftBlock) block; + BlockPos pos = cBlock.getPosition(); + ServerLevel spWorld = cBlock.getCraftWorld().getHandle(); + BlockState spBlock = cBlock.getNMS(); + //TODO basically copy AbstractTressGrower.growTree + this.growTreeFeature(spWorld, spWorld.getChunkSource().getGenerator(), pos, spBlock, new Random()); + return true; + } + + public boolean growTreeFeature( + ServerLevel world, + ChunkGenerator chunkGenerator, + BlockPos pos, + BlockState state, + Random random) { + isMega = false; + if(placeMegaTree(world, chunkGenerator, pos, state, random)) {return true;}; + if(isMega) return false; + ConfiguredFeature feature; + ConfiguredFeature featureSmall; + switch(state.getBukkitMaterial()) { + case JUNGLE_SAPLING: + feature = TreeFeatures.JUNGLE_TREE_NO_VINE.value(); + featureSmall = RBFeatures.SHORT_JUNGLE.value(); + break; + case SPRUCE_SAPLING: + feature = TreeFeatures.SPRUCE.value(); + featureSmall = RBFeatures.SHORT_SPRUCE.value(); + break; + case OAK_SAPLING: + feature = this.hasFlowers(world, pos) ? TreeFeatures.OAK_BEES_005.value() : TreeFeatures.OAK.value(); + featureSmall = this.hasFlowers(world, pos) ? RBFeatures.SHORT_OAK_BEES.value() : RBFeatures.SHORT_OAK.value(); + break; + case BIRCH_SAPLING: + feature = this.hasFlowers(world, pos) ? TreeFeatures.BIRCH_BEES_005.value() : TreeFeatures.BIRCH.value(); + featureSmall = this.hasFlowers(world, pos) ? RBFeatures.SHORT_BIRCH_BEES.value() : RBFeatures.SHORT_BIRCH.value(); + break; + case ACACIA_SAPLING: + feature = TreeFeatures.ACACIA.value(); + featureSmall = RBFeatures.SHORT_ACACIA.value(); + break; + case DARK_OAK_SAPLING: + default: + return false; + } + world.setBlock(pos, Blocks.AIR.defaultBlockState(), 4); + if (feature.place(world, chunkGenerator, random, pos)) { + return true; + } else if(featureSmall.place(world, chunkGenerator, random, pos)) { + return true; + } else { + world.setBlock(pos, state, 4); + return false; + } + } + + private boolean placeMegaTree(ServerLevel world, ChunkGenerator chunkGenerator, BlockPos pos, BlockState state, Random random) { + ConfiguredFeature feature; + ConfiguredFeature featureSmall; + switch(state.getBukkitMaterial()) { + case JUNGLE_SAPLING: + feature = TreeFeatures.MEGA_JUNGLE_TREE.value(); + featureSmall = RBFeatures.SHORT_MEGA_JUNGLE.value(); + break; + case SPRUCE_SAPLING: + feature = TreeFeatures.MEGA_SPRUCE.value(); + featureSmall = RBFeatures.SHORT_MEGA_SPRUCE.value(); + break; + case DARK_OAK_SAPLING: + feature = TreeFeatures.DARK_OAK.value(); + featureSmall = RBFeatures.SHORT_DARK_OAK.value(); + break; + default: + return false; + } + for (int i = 0; i >= -1; --i) { + for (int j = 0; j >= -1; --j) { + if (AbstractMegaTreeGrower.isTwoByTwoSapling(state, world, pos, i, j)) { + isMega = true; + BlockState air = Blocks.AIR.defaultBlockState(); + world.setBlock(pos.offset(i, 0, j), air, 4); + world.setBlock(pos.offset(i + 1, 0, j), air, 4); + world.setBlock(pos.offset(i, 0, j + 1), air, 4); + world.setBlock(pos.offset(i + 1, 0, j + 1), air, 4); + if (feature.place(world, chunkGenerator, random, pos.offset(i, 0, j))) { + return true; + } else if(featureSmall.place(world, chunkGenerator, random, pos.offset(i, 0, j))){ + return true; + } else { + world.setBlock(pos.offset(i, 0, j), state, 4); + world.setBlock(pos.offset(i + 1, 0, j), state, 4); + world.setBlock(pos.offset(i, 0, j + 1), state, 4); + world.setBlock(pos.offset(i + 1, 0, j + 1), state, 4); + return false ; + } + } + } + } + return false; + } + + private boolean hasFlowers(LevelAccessor world, BlockPos pos) { + Iterator iterator = BlockPos.MutableBlockPos.betweenClosed(pos.below().north(2).west(2), pos.above().south(2).east(2)).iterator(); + + BlockPos blockposition1; + + do { + if (!iterator.hasNext()) { + return false; + } + + blockposition1 = (BlockPos) iterator.next(); + } while (!world.getBlockState(blockposition1).is(BlockTags.FLOWERS)); + + return true; + } + + + + + @Override + public boolean deleteOnFullGrowth() { + return true; + } + + + //this class will be the one growing the trees for us + //private class InternalNMSTreeGrower extends AbstractTreeGrower { + //turns out there's not rly any need for this class + //most of what was here has been moved to RBFeatures + + + +} diff --git a/paper/src/main/java/com/untamedears/realisticbiomes/growth/RBFeatures.java b/paper/src/main/java/com/untamedears/realisticbiomes/growth/RBFeatures.java new file mode 100644 index 00000000..b29a5ea8 --- /dev/null +++ b/paper/src/main/java/com/untamedears/realisticbiomes/growth/RBFeatures.java @@ -0,0 +1,119 @@ +package com.untamedears.realisticbiomes.growth; + +import java.util.List; +import java.util.OptionalInt; +import java.util.Random; + +import com.google.common.collect.ImmutableList; + +import net.minecraft.core.Holder; +import net.minecraft.data.worldgen.features.FeatureUtils; +import net.minecraft.util.valueproviders.ConstantInt; +import net.minecraft.util.valueproviders.UniformInt; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.configurations.TreeConfiguration; +import net.minecraft.world.level.levelgen.feature.featuresize.ThreeLayersFeatureSize; +import net.minecraft.world.level.levelgen.feature.featuresize.TwoLayersFeatureSize; +import net.minecraft.world.level.levelgen.feature.foliageplacers.AcaciaFoliagePlacer; +import net.minecraft.world.level.levelgen.feature.foliageplacers.BlobFoliagePlacer; +import net.minecraft.world.level.levelgen.feature.foliageplacers.DarkOakFoliagePlacer; +import net.minecraft.world.level.levelgen.feature.foliageplacers.MegaJungleFoliagePlacer; +import net.minecraft.world.level.levelgen.feature.foliageplacers.MegaPineFoliagePlacer; +import net.minecraft.world.level.levelgen.feature.foliageplacers.SpruceFoliagePlacer; +import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider; +import net.minecraft.world.level.levelgen.feature.treedecorators.AlterGroundDecorator; +import net.minecraft.world.level.levelgen.feature.treedecorators.BeehiveDecorator; +import net.minecraft.world.level.levelgen.feature.treedecorators.LeaveVineDecorator; +import net.minecraft.world.level.levelgen.feature.treedecorators.TrunkVineDecorator; +import net.minecraft.world.level.levelgen.feature.trunkplacers.DarkOakTrunkPlacer; +import net.minecraft.world.level.levelgen.feature.trunkplacers.ForkingTrunkPlacer; +import net.minecraft.world.level.levelgen.feature.trunkplacers.GiantTrunkPlacer; +import net.minecraft.world.level.levelgen.feature.trunkplacers.MegaJungleTrunkPlacer; +import net.minecraft.world.level.levelgen.feature.trunkplacers.StraightTrunkPlacer; + +//manage NMS Configured features for RB +public class RBFeatures { + + //mega in this case means 2x2 + protected Holder> treeMatcher(Random random, boolean bees, boolean megatree, boolean shortTree) { + // TODO Auto-generated method stub + return null; + } + private static TreeConfiguration.TreeConfigurationBuilder createStraightBlobTree( + net.minecraft.world.level.block.Block log, net.minecraft.world.level.block.Block leaves, + int baseHeight, int radius) { + return new TreeConfiguration.TreeConfigurationBuilder(BlockStateProvider.simple(log), new StraightTrunkPlacer(baseHeight, 0, 0), BlockStateProvider.simple(leaves), new BlobFoliagePlacer(ConstantInt.of(radius), ConstantInt.of(0), 3), new TwoLayersFeatureSize(1, 0, 1)); + } + //tree features: + + //beehive with 5% chance of generating + private static final BeehiveDecorator BEEHIVE_005 = new BeehiveDecorator(0.05F); + //Short oak tree feature, short meaning the tree will grow at the smallest size vanilla does + public static final Holder> SHORT_OAK = + FeatureUtils.register("short_oak", Feature.TREE, createStraightBlobTree + (Blocks.OAK_LOG, Blocks.OAK_LEAVES, 4, 2).build()); + //Short birch tree feature + public static final Holder> SHORT_BIRCH = + FeatureUtils.register("short_birch", Feature.TREE, createStraightBlobTree + (Blocks.BIRCH_LOG, Blocks.BIRCH_LEAVES, 5, 2).build()); + //Short oak tree with bees feature, the chance for a beehive is vanilla's 5%, but might be worth adding an adjust to config.yaml maybe ? + public static final Holder> SHORT_OAK_BEES = + FeatureUtils.register("short_oak_bees", Feature.TREE, createStraightBlobTree + (Blocks.OAK_LOG, Blocks.OAK_LEAVES, 4, 2).decorators(List.of(BEEHIVE_005)).build()); + //Short birch tree with bees feature + public static final Holder> SHORT_BIRCH_BEES = + FeatureUtils.register("short_birch_bees", Feature.TREE, createStraightBlobTree + (Blocks.BIRCH_LOG, Blocks.BIRCH_LEAVES, 5, 2).decorators(List.of(BEEHIVE_005)).build()); + //short jungle tree feature + public static final Holder> SHORT_JUNGLE = + FeatureUtils.register("short_jungle", Feature.TREE, createStraightBlobTree + (Blocks.JUNGLE_LOG, Blocks.JUNGLE_LEAVES, 4, 2).build()); + //short spruce, this one is a fair bit longer lmao + //might also be worth adding options to configure type of grower for each tree instead of hard coding ? + //idk, I am also lazy and don't wanna wrap my head around how the config parser woks + public static final Holder> SHORT_SPRUCE = + FeatureUtils.register( + "short_spruce", Feature.TREE, ( + new TreeConfiguration.TreeConfigurationBuilder(BlockStateProvider.simple(Blocks.SPRUCE_LOG), + new StraightTrunkPlacer(5, 0, 0), BlockStateProvider.simple(Blocks.SPRUCE_LEAVES), + new SpruceFoliagePlacer(UniformInt.of(2, 3), UniformInt.of(0, 2), UniformInt.of(1, 2)), + new TwoLayersFeatureSize(2, 0, 2))).ignoreVines().build()); + //short acacia + public static final Holder> SHORT_ACACIA = + FeatureUtils.register( + "short_acacia", Feature.TREE, ( + new TreeConfiguration.TreeConfigurationBuilder(BlockStateProvider.simple(Blocks.ACACIA_LOG), + new ForkingTrunkPlacer(5, 0 ,0), BlockStateProvider.simple(Blocks.ACACIA_LEAVES), + new AcaciaFoliagePlacer(ConstantInt.of(2), ConstantInt.of(0)), + new TwoLayersFeatureSize(1, 0, 2))).ignoreVines().build()); + //short 2x2 jungle tree + public static final Holder> SHORT_MEGA_JUNGLE = + FeatureUtils.register( + "short_mega_jungle_tree", Feature.TREE, ( + new TreeConfiguration.TreeConfigurationBuilder(BlockStateProvider.simple(Blocks.JUNGLE_LOG), + new MegaJungleTrunkPlacer(10, 2, 19), BlockStateProvider.simple(Blocks.JUNGLE_LEAVES), + new MegaJungleFoliagePlacer(ConstantInt.of(2), ConstantInt.of(0), 2), + new TwoLayersFeatureSize(1, 1, 2))). + decorators(ImmutableList.of(TrunkVineDecorator.INSTANCE, LeaveVineDecorator.INSTANCE)).build()); + //short 2x2 spruce tree + //should 2x2 pine tree also be included ? + public static final Holder> SHORT_MEGA_SPRUCE = + FeatureUtils.register( + "short_mega_spruce", Feature.TREE, ( + new TreeConfiguration.TreeConfigurationBuilder(BlockStateProvider.simple(Blocks.SPRUCE_LOG), + new GiantTrunkPlacer(13, 2, 14), BlockStateProvider.simple(Blocks.SPRUCE_LEAVES), + new MegaPineFoliagePlacer(ConstantInt.of(0), ConstantInt.of(0), UniformInt.of(13, 17)), + new TwoLayersFeatureSize(1, 1, 2))) + .decorators(ImmutableList.of(new AlterGroundDecorator(BlockStateProvider.simple(Blocks.PODZOL)))).build()); + //short 2x2 ofc because that's the only way it grows in vanilla dark oak tree + public static final Holder> SHORT_DARK_OAK = + FeatureUtils.register( + "short_dark_oak", Feature.TREE, ( + new TreeConfiguration.TreeConfigurationBuilder(BlockStateProvider.simple(Blocks.DARK_OAK_LOG), + new DarkOakTrunkPlacer(6, 0, 0), BlockStateProvider.simple(Blocks.DARK_OAK_LEAVES), + new DarkOakFoliagePlacer(ConstantInt.of(0), ConstantInt.of(0)), + new ThreeLayersFeatureSize(1, 1, 0, 1, 2, OptionalInt.empty()))).ignoreVines().build()); + +} From 6bd613836838d8d779aaba3218adf4b2a6c0f7c7 Mon Sep 17 00:00:00 2001 From: red_steel <> Date: Mon, 3 Oct 2022 18:52:17 -0300 Subject: [PATCH 2/5] streamline comments and imports, fix mega jungle and mega spruce --- .../growth/NMSFeatureGrower.java | 77 ++++--------------- .../realisticbiomes/growth/RBFeatures.java | 13 +--- 2 files changed, 19 insertions(+), 71 deletions(-) diff --git a/paper/src/main/java/com/untamedears/realisticbiomes/growth/NMSFeatureGrower.java b/paper/src/main/java/com/untamedears/realisticbiomes/growth/NMSFeatureGrower.java index 0f031654..4e43307b 100644 --- a/paper/src/main/java/com/untamedears/realisticbiomes/growth/NMSFeatureGrower.java +++ b/paper/src/main/java/com/untamedears/realisticbiomes/growth/NMSFeatureGrower.java @@ -1,63 +1,25 @@ package com.untamedears.realisticbiomes.growth; -import java.lang.reflect.Field; import java.util.Iterator; -import java.util.List; -import java.util.OptionalInt; import java.util.Random; import org.bukkit.Material; -import org.bukkit.TreeType; import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.block.data.Ageable; import org.bukkit.block.data.type.Sapling; -import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; import org.bukkit.craftbukkit.v1_18_R2.block.CraftBlock; -import org.bukkit.craftbukkit.v1_18_R2.block.data.type.CraftSapling; -import com.google.common.collect.ImmutableList; -import com.untamedears.realisticbiomes.PlantManager; -import com.untamedears.realisticbiomes.RealisticBiomes; import com.untamedears.realisticbiomes.model.Plant; import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; +import net.minecraft.data.worldgen.features.TreeFeatures; import net.minecraft.server.level.ServerLevel; import net.minecraft.tags.BlockTags; -import net.minecraft.util.valueproviders.ConstantInt; -import net.minecraft.util.valueproviders.UniformInt; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.SaplingBlock; import net.minecraft.world.level.block.grower.AbstractMegaTreeGrower; -import net.minecraft.world.level.block.grower.AbstractTreeGrower; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; -import net.minecraft.world.level.levelgen.feature.Feature; -import net.minecraft.world.level.levelgen.feature.HugeFungusConfiguration; -import net.minecraft.world.level.levelgen.feature.configurations.TreeConfiguration; -import net.minecraft.world.level.levelgen.feature.featuresize.ThreeLayersFeatureSize; -import net.minecraft.world.level.levelgen.feature.featuresize.TwoLayersFeatureSize; -import net.minecraft.world.level.levelgen.feature.foliageplacers.AcaciaFoliagePlacer; -import net.minecraft.world.level.levelgen.feature.foliageplacers.BlobFoliagePlacer; -import net.minecraft.world.level.levelgen.feature.foliageplacers.DarkOakFoliagePlacer; -import net.minecraft.world.level.levelgen.feature.foliageplacers.MegaJungleFoliagePlacer; -import net.minecraft.world.level.levelgen.feature.foliageplacers.MegaPineFoliagePlacer; -import net.minecraft.world.level.levelgen.feature.foliageplacers.SpruceFoliagePlacer; -import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider; -import net.minecraft.world.level.levelgen.feature.treedecorators.AlterGroundDecorator; -import net.minecraft.world.level.levelgen.feature.treedecorators.BeehiveDecorator; -import net.minecraft.world.level.levelgen.feature.treedecorators.LeaveVineDecorator; -import net.minecraft.world.level.levelgen.feature.treedecorators.TrunkVineDecorator; -import net.minecraft.world.level.levelgen.feature.trunkplacers.DarkOakTrunkPlacer; -import net.minecraft.world.level.levelgen.feature.trunkplacers.ForkingTrunkPlacer; -import net.minecraft.world.level.levelgen.feature.trunkplacers.GiantTrunkPlacer; -import net.minecraft.world.level.levelgen.feature.trunkplacers.MegaJungleTrunkPlacer; -import net.minecraft.world.level.levelgen.feature.trunkplacers.StraightTrunkPlacer; -import net.minecraft.data.worldgen.features.FeatureUtils; -import net.minecraft.data.worldgen.features.TreeFeatures; public class NMSFeatureGrower extends AgeableGrower { @@ -91,15 +53,11 @@ public boolean setStage(Plant plant, int stage) { } - //Sapling sapling = - //(Sapling) block.getBlockData(); - //sapling.setStage(3); - //plant.getLocation().getWorld().setBlockData(plant.getLocation(), sapling); CraftBlock cBlock = (CraftBlock) block; BlockPos pos = cBlock.getPosition(); ServerLevel spWorld = cBlock.getCraftWorld().getHandle(); BlockState spBlock = cBlock.getNMS(); - //TODO basically copy AbstractTressGrower.growTree + this.growTreeFeature(spWorld, spWorld.getChunkSource().getGenerator(), pos, spBlock, new Random()); return true; } @@ -112,9 +70,10 @@ public boolean growTreeFeature( Random random) { isMega = false; if(placeMegaTree(world, chunkGenerator, pos, state, random)) {return true;}; - if(isMega) return false; + if(isMega) return false; // fail tree growth here if it's a mega tree and it hasn't returned true above ConfiguredFeature feature; ConfiguredFeature featureSmall; + //feature holds the default Minecraft tree and featureSmall holds a version with randomHeight set to 0 so that it will grow at minimum height switch(state.getBukkitMaterial()) { case JUNGLE_SAPLING: feature = TreeFeatures.JUNGLE_TREE_NO_VINE.value(); @@ -136,17 +95,17 @@ public boolean growTreeFeature( feature = TreeFeatures.ACACIA.value(); featureSmall = RBFeatures.SHORT_ACACIA.value(); break; - case DARK_OAK_SAPLING: - default: + case DARK_OAK_SAPLING: //completly unecessary only left this in for the sake of completion tbh + default: return false; } world.setBlock(pos, Blocks.AIR.defaultBlockState(), 4); - if (feature.place(world, chunkGenerator, random, pos)) { + if (feature.place(world, chunkGenerator, random, pos)) { //attempt to place the normal tree feature return true; - } else if(featureSmall.place(world, chunkGenerator, random, pos)) { + } else if(featureSmall.place(world, chunkGenerator, random, pos)) { //attempt to place the small/short version if the normal fails return true; } else { - world.setBlock(pos, state, 4); + world.setBlock(pos, state, 4); //replace the sappling if both fail return false; } } @@ -154,6 +113,7 @@ public boolean growTreeFeature( private boolean placeMegaTree(ServerLevel world, ChunkGenerator chunkGenerator, BlockPos pos, BlockState state, Random random) { ConfiguredFeature feature; ConfiguredFeature featureSmall; + //feature holds the default minecraft tree and featuresmall holds a version with randomHeight set to 0 so that it will grow at minimum height switch(state.getBukkitMaterial()) { case JUNGLE_SAPLING: feature = TreeFeatures.MEGA_JUNGLE_TREE.value(); @@ -173,18 +133,18 @@ private boolean placeMegaTree(ServerLevel world, ChunkGenerator chunkGenerator, for (int i = 0; i >= -1; --i) { for (int j = 0; j >= -1; --j) { if (AbstractMegaTreeGrower.isTwoByTwoSapling(state, world, pos, i, j)) { - isMega = true; + isMega = true; //set ismega so that function above can know when a tree is 2x2 and has failed growth (admitedly this is probs not the best solution) BlockState air = Blocks.AIR.defaultBlockState(); - world.setBlock(pos.offset(i, 0, j), air, 4); + world.setBlock(pos.offset(i, 0, j), air, 4); //remove saplings world.setBlock(pos.offset(i + 1, 0, j), air, 4); world.setBlock(pos.offset(i, 0, j + 1), air, 4); world.setBlock(pos.offset(i + 1, 0, j + 1), air, 4); if (feature.place(world, chunkGenerator, random, pos.offset(i, 0, j))) { return true; - } else if(featureSmall.place(world, chunkGenerator, random, pos.offset(i, 0, j))){ + } else if(featureSmall.place(world, chunkGenerator, random, pos.offset(i, 0, j))){ //try placing short tree if normal tree fails return true; } else { - world.setBlock(pos.offset(i, 0, j), state, 4); + world.setBlock(pos.offset(i, 0, j), state, 4); //replace saplings if both fail world.setBlock(pos.offset(i + 1, 0, j), state, 4); world.setBlock(pos.offset(i, 0, j + 1), state, 4); world.setBlock(pos.offset(i + 1, 0, j + 1), state, 4); @@ -196,7 +156,7 @@ private boolean placeMegaTree(ServerLevel world, ChunkGenerator chunkGenerator, return false; } - private boolean hasFlowers(LevelAccessor world, BlockPos pos) { + private boolean hasFlowers(LevelAccessor world, BlockPos pos) { //straight up pulled from nms code Iterator iterator = BlockPos.MutableBlockPos.betweenClosed(pos.below().north(2).west(2), pos.above().south(2).east(2)).iterator(); BlockPos blockposition1; @@ -219,13 +179,6 @@ private boolean hasFlowers(LevelAccessor world, BlockPos pos) { public boolean deleteOnFullGrowth() { return true; } - - - //this class will be the one growing the trees for us - //private class InternalNMSTreeGrower extends AbstractTreeGrower { - //turns out there's not rly any need for this class - //most of what was here has been moved to RBFeatures - } diff --git a/paper/src/main/java/com/untamedears/realisticbiomes/growth/RBFeatures.java b/paper/src/main/java/com/untamedears/realisticbiomes/growth/RBFeatures.java index b29a5ea8..89a0f968 100644 --- a/paper/src/main/java/com/untamedears/realisticbiomes/growth/RBFeatures.java +++ b/paper/src/main/java/com/untamedears/realisticbiomes/growth/RBFeatures.java @@ -2,7 +2,6 @@ import java.util.List; import java.util.OptionalInt; -import java.util.Random; import com.google.common.collect.ImmutableList; @@ -36,11 +35,7 @@ //manage NMS Configured features for RB public class RBFeatures { - //mega in this case means 2x2 - protected Holder> treeMatcher(Random random, boolean bees, boolean megatree, boolean shortTree) { - // TODO Auto-generated method stub - return null; - } + private static TreeConfiguration.TreeConfigurationBuilder createStraightBlobTree( net.minecraft.world.level.block.Block log, net.minecraft.world.level.block.Block leaves, int baseHeight, int radius) { @@ -93,7 +88,7 @@ private static TreeConfiguration.TreeConfigurationBuilder createStraightBlobTree FeatureUtils.register( "short_mega_jungle_tree", Feature.TREE, ( new TreeConfiguration.TreeConfigurationBuilder(BlockStateProvider.simple(Blocks.JUNGLE_LOG), - new MegaJungleTrunkPlacer(10, 2, 19), BlockStateProvider.simple(Blocks.JUNGLE_LEAVES), + new MegaJungleTrunkPlacer(10, 0, 0), BlockStateProvider.simple(Blocks.JUNGLE_LEAVES), new MegaJungleFoliagePlacer(ConstantInt.of(2), ConstantInt.of(0), 2), new TwoLayersFeatureSize(1, 1, 2))). decorators(ImmutableList.of(TrunkVineDecorator.INSTANCE, LeaveVineDecorator.INSTANCE)).build()); @@ -103,11 +98,11 @@ private static TreeConfiguration.TreeConfigurationBuilder createStraightBlobTree FeatureUtils.register( "short_mega_spruce", Feature.TREE, ( new TreeConfiguration.TreeConfigurationBuilder(BlockStateProvider.simple(Blocks.SPRUCE_LOG), - new GiantTrunkPlacer(13, 2, 14), BlockStateProvider.simple(Blocks.SPRUCE_LEAVES), + new GiantTrunkPlacer(13, 0, 0), BlockStateProvider.simple(Blocks.SPRUCE_LEAVES), new MegaPineFoliagePlacer(ConstantInt.of(0), ConstantInt.of(0), UniformInt.of(13, 17)), new TwoLayersFeatureSize(1, 1, 2))) .decorators(ImmutableList.of(new AlterGroundDecorator(BlockStateProvider.simple(Blocks.PODZOL)))).build()); - //short 2x2 ofc because that's the only way it grows in vanilla dark oak tree + //short 2x2 ofc because that's the only way it grows (normally) dark oak tree public static final Holder> SHORT_DARK_OAK = FeatureUtils.register( "short_dark_oak", Feature.TREE, ( From bb7bfe0f921fe822f9f1e21a9b11fb358234d85d Mon Sep 17 00:00:00 2001 From: red_steel <> Date: Tue, 4 Oct 2022 03:59:03 -0300 Subject: [PATCH 3/5] add azalea to nms feature grower --- .../growth/NMSFeatureGrower.java | 4 ++++ .../realisticbiomes/growth/RBFeatures.java | 19 ++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/paper/src/main/java/com/untamedears/realisticbiomes/growth/NMSFeatureGrower.java b/paper/src/main/java/com/untamedears/realisticbiomes/growth/NMSFeatureGrower.java index 4e43307b..b0dea63a 100644 --- a/paper/src/main/java/com/untamedears/realisticbiomes/growth/NMSFeatureGrower.java +++ b/paper/src/main/java/com/untamedears/realisticbiomes/growth/NMSFeatureGrower.java @@ -95,6 +95,10 @@ public boolean growTreeFeature( feature = TreeFeatures.ACACIA.value(); featureSmall = RBFeatures.SHORT_ACACIA.value(); break; + case FLOWERING_AZALEA: + feature = TreeFeatures.AZALEA_TREE.value(); + featureSmall = RBFeatures.SHORT_AZALEA_TREE.value(); + break; case DARK_OAK_SAPLING: //completly unecessary only left this in for the sake of completion tbh default: return false; diff --git a/paper/src/main/java/com/untamedears/realisticbiomes/growth/RBFeatures.java b/paper/src/main/java/com/untamedears/realisticbiomes/growth/RBFeatures.java index 89a0f968..ce034b4e 100644 --- a/paper/src/main/java/com/untamedears/realisticbiomes/growth/RBFeatures.java +++ b/paper/src/main/java/com/untamedears/realisticbiomes/growth/RBFeatures.java @@ -7,9 +7,11 @@ import net.minecraft.core.Holder; import net.minecraft.data.worldgen.features.FeatureUtils; +import net.minecraft.util.random.SimpleWeightedRandomList; import net.minecraft.util.valueproviders.ConstantInt; import net.minecraft.util.valueproviders.UniformInt; import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.configurations.TreeConfiguration; @@ -20,12 +22,15 @@ import net.minecraft.world.level.levelgen.feature.foliageplacers.DarkOakFoliagePlacer; import net.minecraft.world.level.levelgen.feature.foliageplacers.MegaJungleFoliagePlacer; import net.minecraft.world.level.levelgen.feature.foliageplacers.MegaPineFoliagePlacer; +import net.minecraft.world.level.levelgen.feature.foliageplacers.RandomSpreadFoliagePlacer; import net.minecraft.world.level.levelgen.feature.foliageplacers.SpruceFoliagePlacer; import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider; +import net.minecraft.world.level.levelgen.feature.stateproviders.WeightedStateProvider; import net.minecraft.world.level.levelgen.feature.treedecorators.AlterGroundDecorator; import net.minecraft.world.level.levelgen.feature.treedecorators.BeehiveDecorator; import net.minecraft.world.level.levelgen.feature.treedecorators.LeaveVineDecorator; import net.minecraft.world.level.levelgen.feature.treedecorators.TrunkVineDecorator; +import net.minecraft.world.level.levelgen.feature.trunkplacers.BendingTrunkPlacer; import net.minecraft.world.level.levelgen.feature.trunkplacers.DarkOakTrunkPlacer; import net.minecraft.world.level.levelgen.feature.trunkplacers.ForkingTrunkPlacer; import net.minecraft.world.level.levelgen.feature.trunkplacers.GiantTrunkPlacer; @@ -99,7 +104,7 @@ private static TreeConfiguration.TreeConfigurationBuilder createStraightBlobTree "short_mega_spruce", Feature.TREE, ( new TreeConfiguration.TreeConfigurationBuilder(BlockStateProvider.simple(Blocks.SPRUCE_LOG), new GiantTrunkPlacer(13, 0, 0), BlockStateProvider.simple(Blocks.SPRUCE_LEAVES), - new MegaPineFoliagePlacer(ConstantInt.of(0), ConstantInt.of(0), UniformInt.of(13, 17)), + new MegaPineFoliagePlacer(ConstantInt.of(0), ConstantInt.of(0), UniformInt.of(13, 17)), //oh maybe this uniformint is why sometimes it still fails to grow with height restriction even with the other things new TwoLayersFeatureSize(1, 1, 2))) .decorators(ImmutableList.of(new AlterGroundDecorator(BlockStateProvider.simple(Blocks.PODZOL)))).build()); //short 2x2 ofc because that's the only way it grows (normally) dark oak tree @@ -110,5 +115,17 @@ private static TreeConfiguration.TreeConfigurationBuilder createStraightBlobTree new DarkOakTrunkPlacer(6, 0, 0), BlockStateProvider.simple(Blocks.DARK_OAK_LEAVES), new DarkOakFoliagePlacer(ConstantInt.of(0), ConstantInt.of(0)), new ThreeLayersFeatureSize(1, 1, 0, 1, 2, OptionalInt.empty()))).ignoreVines().build()); + //azalea + public static final Holder> SHORT_AZALEA_TREE = + FeatureUtils.register( + "short_azalea_tree", Feature.TREE, ( + new TreeConfiguration.TreeConfigurationBuilder(BlockStateProvider.simple(Blocks.OAK_LOG), + new BendingTrunkPlacer(4, 0, 0, 3, UniformInt.of(1, 2)), + new WeightedStateProvider(SimpleWeightedRandomList.builder() + .add(Blocks.AZALEA_LEAVES.defaultBlockState(), 3).add(Blocks.FLOWERING_AZALEA_LEAVES.defaultBlockState(), 1)), + new RandomSpreadFoliagePlacer(ConstantInt.of(3), ConstantInt.of(0), ConstantInt.of(2), 50), + new TwoLayersFeatureSize(1, 0, 1))).dirt(BlockStateProvider.simple(Blocks.ROOTED_DIRT)).forceDirt().build()); + } + From 8bbfa0e40b0c9ce038d46328d4768ad179fc347b Mon Sep 17 00:00:00 2001 From: rosacarmesin Date: Wed, 4 Jan 2023 23:21:40 -0300 Subject: [PATCH 4/5] add paper/run to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 10a748a9..fc4c4dbf 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ dependency-reduced-pom.xml .gradle build libs/ +paper/run From 1c7c1365accd20c87495053b169acec92d694be2 Mon Sep 17 00:00:00 2001 From: rosacarmesin Date: Wed, 4 Jan 2023 23:30:01 -0300 Subject: [PATCH 5/5] the tinniest change, to fix azalea --- .../untamedears/realisticbiomes/growth/NMSFeatureGrower.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paper/src/main/java/com/untamedears/realisticbiomes/growth/NMSFeatureGrower.java b/paper/src/main/java/com/untamedears/realisticbiomes/growth/NMSFeatureGrower.java index b0dea63a..d266f92e 100644 --- a/paper/src/main/java/com/untamedears/realisticbiomes/growth/NMSFeatureGrower.java +++ b/paper/src/main/java/com/untamedears/realisticbiomes/growth/NMSFeatureGrower.java @@ -48,7 +48,7 @@ public boolean setStage(Plant plant, int stage) { } Block block = plant.getLocation().getBlock(); // Re-Read the block data to make sure it is up to date - if (!(block.getBlockData() instanceof Sapling)) { + if (!(block.getBlockData() instanceof Sapling||block.getBlockData().getMaterial() == Material.FLOWERING_AZALEA)) { return true; }