diff --git a/leaf-server/minecraft-patches/features/0170-Pluto-Check-if-the-cactus-can-even-survive-being-pla.patch b/leaf-server/minecraft-patches/features/0170-Pluto-Check-if-the-cactus-can-even-survive-being-pla.patch new file mode 100644 index 00000000..a985202f --- /dev/null +++ b/leaf-server/minecraft-patches/features/0170-Pluto-Check-if-the-cactus-can-even-survive-being-pla.patch @@ -0,0 +1,70 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Taiyou06 +Date: Thu, 8 May 2025 21:24:48 +0200 +Subject: [PATCH] Pluto: Check if the cactus can even survive being placed + + +diff --git a/net/minecraft/world/level/block/CactusBlock.java b/net/minecraft/world/level/block/CactusBlock.java +index 079b4c95cf81119ca99daeb159aefca389afed74..8fe29455d7ae44f43c663718d38ea2d8cf639797 100644 +--- a/net/minecraft/world/level/block/CactusBlock.java ++++ b/net/minecraft/world/level/block/CactusBlock.java +@@ -49,10 +49,15 @@ public class CactusBlock extends Block implements BonemealableBlock { // Purpur + @Override + protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + BlockPos blockPos = pos.above(); +- if (level.isEmptyBlock(blockPos)) { ++ // Pluto start - Decrease chunk/block lookups ++ net.minecraft.world.level.chunk.LevelChunk chunk = level.getChunkIfLoaded(blockPos); ++ if (chunk == null) return; ++ ++ if (chunk.getBlockState(blockPos).isAir()) { ++ // Pluto end - Decrease chunk/block lookups + int i = 1; + +- while (level.getBlockState(pos.below(i)).is(this)) { ++ while (chunk.getBlockState(pos.below(i)).is(this)) { // Pluto - Decrease chunk/block lookups + i++; + } + +@@ -61,11 +66,28 @@ public class CactusBlock extends Block implements BonemealableBlock { // Purpur + + int modifier = level.spigotConfig.cactusModifier; // Spigot - SPIGOT-7159: Better modifier resolution + if (ageValue >= 15 || (modifier != 100 && random.nextFloat() < (modifier / (100.0f * 16)))) { // Spigot - SPIGOT-7159: Better modifier ++ // Pluto start - Check if the cactus can even survive being placed ++ if (org.dreeam.leaf.config.modules.opt.CheckSurvivalBeforeGrowth.cactusCheckSurvivalBeforeGrowth && !canSurvive(level, blockPos)) { ++ level.levelEvent(LevelEvent.PARTICLES_DESTROY_BLOCK, blockPos, Block.getId(state)); ++ // We're going to fake the block breaking to match vanilla standards. ++ for (net.minecraft.world.item.ItemStack drop : Block.getDrops(state, level, pos, null)) { // Use base cactus since we don't place a block ++ Block.popResource(level, blockPos, drop); ++ } ++ level.setBlock(pos, state.setValue(CactusBlock.AGE, 0), Block.UPDATE_CLIENTS | Block.UPDATE_KNOWN_SHAPE); ++ return; ++ } ++ // Pluto end - Check if the cactus can even survive being placed + org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, blockPos, this.defaultBlockState()); // CraftBukkit + BlockState blockState = state.setValue(AGE, Integer.valueOf(0)); + level.setBlock(pos, blockState, 4); + level.neighborChanged(blockState, blockPos, this, null, false); + } else if (modifier == 100 || random.nextFloat() < (modifier / (100.0f * 16))) { // Spigot - SPIGOT-7159: Better modifier resolution ++ // Pluto start - Check if the cactus can even survive being placed ++ if (org.dreeam.leaf.config.modules.opt.CheckSurvivalBeforeGrowth.cactusCheckSurvivalBeforeGrowth) { ++ level.setBlock(pos, state.setValue(CactusBlock.AGE, ageValue + 1), Block.UPDATE_CLIENTS | Block.UPDATE_KNOWN_SHAPE); ++ return; ++ } ++ // Pluto end - Check if the cactus can even survive being placed + level.setBlock(pos, state.setValue(AGE, Integer.valueOf(ageValue + 1)), 4); + } + } +@@ -102,6 +124,12 @@ public class CactusBlock extends Block implements BonemealableBlock { // Purpur + + @Override + protected boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) { ++ // Pluto start - Check if the cactus can even survive being placed ++ return canSurvive(level, pos); ++ } ++ ++ protected boolean canSurvive(LevelReader level, BlockPos pos) { ++ // Pluto end - Check if the cactus can even survive being placed + for (Direction direction : Direction.Plane.HORIZONTAL) { + BlockState blockState = level.getBlockState(pos.relative(direction)); + if ((level.getWorldBorder().world.purpurConfig.cactusBreaksFromSolidNeighbors && blockState.isSolid()) || level.getFluidState(pos.relative(direction)).is(FluidTags.LAVA)) { // Purpur - Cactus breaks from solid neighbors config diff --git a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/CheckSurvivalBeforeGrowth.java b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/CheckSurvivalBeforeGrowth.java new file mode 100644 index 00000000..0058b1b8 --- /dev/null +++ b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/CheckSurvivalBeforeGrowth.java @@ -0,0 +1,22 @@ +package org.dreeam.leaf.config.modules.opt; + +import org.dreeam.leaf.config.ConfigModules; +import org.dreeam.leaf.config.EnumConfigCategory; + +public class CheckSurvivalBeforeGrowth extends ConfigModules { + + public String getBasePath() { + return EnumConfigCategory.PERF.getBaseKeyName() + ".check-survival-before-growth"; + } + + public static boolean cactusCheckSurvivalBeforeGrowth = false; + + @Override + public void onLoaded() { + cactusCheckSurvivalBeforeGrowth = config.getBoolean(getBasePath() + ".cactus-check-survival", cactusCheckSurvivalBeforeGrowth, + config.pickStringRegionBased(""" + Check if a cactus can survive before growing.""", + """ + 在仙人掌生长前检查其是否能够存活。""")); + } +}