From ddd72659e366acc950e262be4fddc635c9228a46 Mon Sep 17 00:00:00 2001 From: granny Date: Sun, 12 Jan 2025 17:11:23 -0800 Subject: [PATCH] bonemealable sugarcane, cactus, and netherwart --- ...able-sugarcane-cactus-and-netherwart.patch | 163 ------------------ .../world/level/block/CactusBlock.java.patch | 44 +++++ .../level/block/NetherWartBlock.java.patch | 30 +++- .../level/block/SugarCaneBlock.java.patch | 46 +++++ .../purpurmc/purpur/PurpurWorldConfig.java | 12 ++ 5 files changed, 131 insertions(+), 164 deletions(-) delete mode 100644 patches/server/0272-bonemealable-sugarcane-cactus-and-netherwart.patch create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/SugarCaneBlock.java.patch diff --git a/patches/server/0272-bonemealable-sugarcane-cactus-and-netherwart.patch b/patches/server/0272-bonemealable-sugarcane-cactus-and-netherwart.patch deleted file mode 100644 index 20d6139d9..000000000 --- a/patches/server/0272-bonemealable-sugarcane-cactus-and-netherwart.patch +++ /dev/null @@ -1,163 +0,0 @@ -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/net/minecraft/world/level/block/CactusBlock.java b/net/minecraft/world/level/block/CactusBlock.java -index bbfd8f5d404d0add94f0d8ac89a2964692b37e44..9f163ed07f8e6a5370c4c355b4e910f7a49b6bcd 100644 ---- a/net/minecraft/world/level/block/CactusBlock.java -+++ b/net/minecraft/world/level/block/CactusBlock.java -@@ -24,7 +24,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 MapCodec CODEC = simpleCodec(CactusBlock::new); - public static final IntegerProperty AGE = BlockStateProperties.AGE_15; -@@ -135,4 +135,34 @@ public class CactusBlock extends Block { - protected boolean isPathfindable(BlockState state, PathComputationType type) { - return false; - } -+ -+ // Purpur start -+ @Override -+ public boolean isValidBonemealTarget(final LevelReader world, final BlockPos pos, final BlockState state) { -+ 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/net/minecraft/world/level/block/NetherWartBlock.java b/net/minecraft/world/level/block/NetherWartBlock.java -index b571bca4375ca7caf9b75dbf84009cb0604b66ad..264692baa4a20b66910d8ff379fa72acb99e27f8 100644 ---- a/net/minecraft/world/level/block/NetherWartBlock.java -+++ b/net/minecraft/world/level/block/NetherWartBlock.java -@@ -16,7 +16,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 MapCodec CODEC = simpleCodec(NetherWartBlock::new); - public static final int MAX_AGE = 3; -@@ -78,5 +78,22 @@ public class NetherWartBlock extends BushBlock { - super.playerDestroy(world, player, pos, state, blockEntity, itemInHand, includeDrops, dropExp); - } - } -+ -+ @Override -+ public boolean isValidBonemealTarget(final net.minecraft.world.level.LevelReader world, final BlockPos pos, final BlockState state) { -+ 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/net/minecraft/world/level/block/SugarCaneBlock.java b/net/minecraft/world/level/block/SugarCaneBlock.java -index 547ea09ed84595286c97c128b3b96f6d387ae25f..d0f8a13f27132257ece6dadf736c2dc6b1e5720e 100644 ---- a/net/minecraft/world/level/block/SugarCaneBlock.java -+++ b/net/minecraft/world/level/block/SugarCaneBlock.java -@@ -20,7 +20,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 MapCodec CODEC = simpleCodec(SugarCaneBlock::new); - public static final IntegerProperty AGE = BlockStateProperties.AGE_15; -@@ -113,4 +113,34 @@ public class SugarCaneBlock extends Block { - protected void createBlockStateDefinition(StateDefinition.Builder builder) { - builder.add(SugarCaneBlock.AGE); - } -+ -+ // Purpur start -+ @Override -+ public boolean isValidBonemealTarget(final LevelReader world, final BlockPos pos, final BlockState state) { -+ 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 7c468d3002a0b6fca37ae5a731c5f0456af35744..280fae97ec04fea5ffe00189880a5de09c69dbc3 100644 ---- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -@@ -877,8 +877,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; diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/CactusBlock.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/CactusBlock.java.patch index 5e4254c1c..64fecea91 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/CactusBlock.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/CactusBlock.java.patch @@ -1,5 +1,14 @@ --- a/net/minecraft/world/level/block/CactusBlock.java +++ b/net/minecraft/world/level/block/CactusBlock.java +@@ -21,7 +_,7 @@ + import net.minecraft.world.phys.shapes.CollisionContext; + import net.minecraft.world.phys.shapes.VoxelShape; + +-public class CactusBlock extends Block { ++public class CactusBlock extends Block implements BonemealableBlock { // Purpur - bonemealable cactus + public static final MapCodec CODEC = simpleCodec(CactusBlock::new); + public static final IntegerProperty AGE = BlockStateProperties.AGE_15; + public static final int MAX_AGE = 15; @@ -104,7 +_,7 @@ protected boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) { for (Direction direction : Direction.Plane.HORIZONTAL) { @@ -9,3 +18,38 @@ return false; } } +@@ -128,4 +_,34 @@ + protected boolean isPathfindable(BlockState state, PathComputationType pathComputationType) { + return false; + } ++ ++ // Purpur start - bonemealable cactus ++ @Override ++ public boolean isValidBonemealTarget(final LevelReader world, final BlockPos pos, final BlockState state) { ++ 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 - bonemealable cactus + } diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/NetherWartBlock.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/NetherWartBlock.java.patch index 39c1ccf96..95b1bb2c1 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/NetherWartBlock.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/NetherWartBlock.java.patch @@ -1,6 +1,15 @@ --- a/net/minecraft/world/level/block/NetherWartBlock.java +++ b/net/minecraft/world/level/block/NetherWartBlock.java -@@ -70,4 +_,15 @@ +@@ -16,7 +_,7 @@ + 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 - bonemealable netherwart + public static final MapCodec CODEC = simpleCodec(NetherWartBlock::new); + public static final int MAX_AGE = 3; + public static final IntegerProperty AGE = BlockStateProperties.AGE_3; +@@ -70,4 +_,34 @@ protected void createBlockStateDefinition(StateDefinition.Builder builder) { builder.add(AGE); } @@ -15,4 +24,23 @@ + } + } + // Purpur end - Ability for hoe to replant nether warts ++ ++ // Purpur start - bonemealable netherwart ++ @Override ++ public boolean isValidBonemealTarget(final net.minecraft.world.level.LevelReader world, final BlockPos pos, final BlockState state) { ++ 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 - bonemealable netherwart } diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/SugarCaneBlock.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/SugarCaneBlock.java.patch new file mode 100644 index 000000000..b39dc02a3 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/SugarCaneBlock.java.patch @@ -0,0 +1,46 @@ +--- a/net/minecraft/world/level/block/SugarCaneBlock.java ++++ b/net/minecraft/world/level/block/SugarCaneBlock.java +@@ -19,7 +_,7 @@ + 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 - bonemealable sugarcane + public static final MapCodec CODEC = simpleCodec(SugarCaneBlock::new); + public static final IntegerProperty AGE = BlockStateProperties.AGE_15; + protected static final float AABB_OFFSET = 6.0F; +@@ -113,4 +_,34 @@ + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(AGE); + } ++ ++ // Purpur start - bonemealable sugarcane ++ @Override ++ public boolean isValidBonemealTarget(final LevelReader world, final BlockPos pos, final BlockState state) { ++ 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 - bonemealable sugarcane + } diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java index 61fe9baa6..43677e583 100644 --- a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java +++ b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java @@ -876,8 +876,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;