From bac7738314934b25d969bcfd350ef57213b2a571 Mon Sep 17 00:00:00 2001 From: granny Date: Thu, 9 Feb 2023 00:28:47 -0800 Subject: [PATCH] bonemealable sugarcane, cactus, and netherwart --- ...able-sugarcane-cactus-and-netherwart.patch | 163 ++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 patches/server/0309-bonemealable-sugarcane-cactus-and-netherwart.patch diff --git a/patches/server/0309-bonemealable-sugarcane-cactus-and-netherwart.patch b/patches/server/0309-bonemealable-sugarcane-cactus-and-netherwart.patch new file mode 100644 index 000000000..3093c77bf --- /dev/null +++ b/patches/server/0309-bonemealable-sugarcane-cactus-and-netherwart.patch @@ -0,0 +1,163 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: granny +Date: Thu, 9 Feb 2023 00:28:03 -0800 +Subject: [PATCH] bonemealable sugarcane, cactus, and netherwart + + +diff --git a/src/main/java/net/minecraft/world/level/block/CactusBlock.java b/src/main/java/net/minecraft/world/level/block/CactusBlock.java +index 2fd7e33a161bc89c91deca1f245d6dac0dcf1b46..44abdcc5b71c289601f412a20ee50ad4388a7a74 100644 +--- a/src/main/java/net/minecraft/world/level/block/CactusBlock.java ++++ b/src/main/java/net/minecraft/world/level/block/CactusBlock.java +@@ -23,7 +23,7 @@ import net.minecraft.world.phys.shapes.CollisionContext; + import net.minecraft.world.phys.shapes.VoxelShape; + import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit + +-public class CactusBlock extends Block { ++public class CactusBlock extends Block implements BonemealableBlock { // Purpur + + public static final IntegerProperty AGE = BlockStateProperties.AGE_15; + public static final int MAX_AGE = 15; +@@ -132,4 +132,34 @@ public class CactusBlock extends Block { + public boolean isPathfindable(BlockState state, BlockGetter world, BlockPos pos, PathComputationType type) { + return false; + } ++ ++ // Purpur start ++ @Override ++ public boolean isValidBonemealTarget(LevelReader world, BlockPos pos, BlockState state, boolean isClient) { ++ if (!((Level) world).purpurConfig.cactusAffectedByBonemeal || !world.isEmptyBlock(pos.above())) return false; ++ ++ int cactusHeight = 0; ++ while (world.getBlockState(pos.below(cactusHeight)).is(this)) { ++ cactusHeight++; ++ } ++ ++ return cactusHeight < ((Level) world).paperConfig().maxGrowthHeight.cactus; ++ } ++ ++ @Override ++ public boolean isBonemealSuccess(Level world, RandomSource random, BlockPos pos, BlockState state) { ++ return true; ++ } ++ ++ @Override ++ public void performBonemeal(ServerLevel world, RandomSource random, BlockPos pos, BlockState state) { ++ int cactusHeight = 0; ++ while (world.getBlockState(pos.below(cactusHeight)).is(this)) { ++ cactusHeight++; ++ } ++ for (int i = 0; i <= world.paperConfig().maxGrowthHeight.cactus - cactusHeight; i++) { ++ world.setBlockAndUpdate(pos.above(i), state.setValue(CactusBlock.AGE, 0)); ++ } ++ } ++ // Purpur end + } +diff --git a/src/main/java/net/minecraft/world/level/block/NetherWartBlock.java b/src/main/java/net/minecraft/world/level/block/NetherWartBlock.java +index 0e4026e9d39735b840f12e59f84469b9acc2fc77..bf4485b4cad324d5aace657ebf284c4d97197f53 100644 +--- a/src/main/java/net/minecraft/world/level/block/NetherWartBlock.java ++++ b/src/main/java/net/minecraft/world/level/block/NetherWartBlock.java +@@ -14,7 +14,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; + import net.minecraft.world.phys.shapes.CollisionContext; + import net.minecraft.world.phys.shapes.VoxelShape; + +-public class NetherWartBlock extends BushBlock { ++public class NetherWartBlock extends BushBlock implements BonemealableBlock { // Purpur + + public static final int MAX_AGE = 3; + public static final IntegerProperty AGE = BlockStateProperties.AGE_3; +@@ -70,5 +70,22 @@ public class NetherWartBlock extends BushBlock { + super.playerDestroy(world, player, pos, state, blockEntity, itemInHand); + } + } ++ ++ @Override ++ public boolean isValidBonemealTarget(net.minecraft.world.level.LevelReader world, BlockPos pos, BlockState state, boolean isClient) { ++ return ((net.minecraft.world.level.Level) world).purpurConfig.netherWartAffectedByBonemeal && state.getValue(NetherWartBlock.AGE) < 3; ++ } ++ ++ @Override ++ public boolean isBonemealSuccess(net.minecraft.world.level.Level world, RandomSource random, BlockPos pos, BlockState state) { ++ return true; ++ } ++ ++ @Override ++ public void performBonemeal(ServerLevel world, RandomSource random, BlockPos pos, BlockState state) { ++ int i = Math.min(3, state.getValue(NetherWartBlock.AGE) + 1); ++ state = state.setValue(NetherWartBlock.AGE, i); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, pos, state, 2); // CraftBukkit ++ } + // Purpur end + } +diff --git a/src/main/java/net/minecraft/world/level/block/SugarCaneBlock.java b/src/main/java/net/minecraft/world/level/block/SugarCaneBlock.java +index 6b400a4759c8c8612a3b5c96ca0d87ef9dc71435..992de1ab2c00a2545a857f1b5533926bc895f996 100644 +--- a/src/main/java/net/minecraft/world/level/block/SugarCaneBlock.java ++++ b/src/main/java/net/minecraft/world/level/block/SugarCaneBlock.java +@@ -19,7 +19,7 @@ import net.minecraft.world.level.material.FluidState; + import net.minecraft.world.phys.shapes.CollisionContext; + import net.minecraft.world.phys.shapes.VoxelShape; + +-public class SugarCaneBlock extends Block { ++public class SugarCaneBlock extends Block implements BonemealableBlock { // Purpur + + public static final IntegerProperty AGE = BlockStateProperties.AGE_15; + protected static final float AABB_OFFSET = 6.0F; +@@ -106,4 +106,34 @@ public class SugarCaneBlock extends Block { + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(SugarCaneBlock.AGE); + } ++ ++ // Purpur start ++ @Override ++ public boolean isValidBonemealTarget(LevelReader world, BlockPos pos, BlockState state, boolean isClient) { ++ if (!((net.minecraft.world.level.Level) world).purpurConfig.sugarCanAffectedByBonemeal || !world.isEmptyBlock(pos.above())) return false; ++ ++ int reedHeight = 0; ++ while (world.getBlockState(pos.below(reedHeight)).is(this)) { ++ reedHeight++; ++ } ++ ++ return reedHeight < ((net.minecraft.world.level.Level) world).paperConfig().maxGrowthHeight.reeds; ++ } ++ ++ @Override ++ public boolean isBonemealSuccess(net.minecraft.world.level.Level world, RandomSource random, BlockPos pos, BlockState state) { ++ return true; ++ } ++ ++ @Override ++ public void performBonemeal(ServerLevel world, RandomSource random, BlockPos pos, BlockState state) { ++ int reedHeight = 0; ++ while (world.getBlockState(pos.below(reedHeight)).is(this)) { ++ reedHeight++; ++ } ++ for (int i = 0; i <= world.paperConfig().maxGrowthHeight.reeds - reedHeight; i++) { ++ world.setBlockAndUpdate(pos.above(i), state.setValue(SugarCaneBlock.AGE, 0)); ++ } ++ } ++ // Purpur end + } +diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java +index 4cd080a0db99a5c36394bcf54526b96fe22a206a..c0c4742027217d5ae27843989ad18be93608496a 100644 +--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java ++++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java +@@ -806,8 +806,20 @@ public class PurpurWorldConfig { + } + + public boolean cactusBreaksFromSolidNeighbors = true; ++ public boolean cactusAffectedByBonemeal = false; + private void cactusSettings() { + cactusBreaksFromSolidNeighbors = getBoolean("blocks.cactus.breaks-from-solid-neighbors", cactusBreaksFromSolidNeighbors); ++ cactusAffectedByBonemeal = getBoolean("blocks.cactus.affected-by-bonemeal", cactusAffectedByBonemeal); ++ } ++ ++ public boolean sugarCanAffectedByBonemeal = false; ++ private void sugarCaneSettings() { ++ sugarCanAffectedByBonemeal = getBoolean("blocks.sugar_cane.affected-by-bonemeal", sugarCanAffectedByBonemeal); ++ } ++ ++ public boolean netherWartAffectedByBonemeal = false; ++ private void netherWartSettings() { ++ netherWartAffectedByBonemeal = getBoolean("blocks.nether_wart.affected-by-bonemeal", netherWartAffectedByBonemeal); + } + + public boolean campFireLitWhenPlaced = true;