From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Yive <6853318+Yive@users.noreply.github.com> Date: Tue, 11 Jul 2023 13:27:01 -0700 Subject: [PATCH] Pluto: Check if the cactus can even survive being placed Original license: GPLv3 Original project: https://github.com/Yive/Pluto Results at 3,000 randomTickSpeed and 24,448 cacti: check-survival-before-growth - false & doTileDrop - true: 48mspt check-survival-before-growth - true & doTileDrop - true: 25mspt check-survival-before-growth - false & doTileDrop - false: 18mspt check-survival-before-growth - true & doTileDrop - false: 6mspt Setting the gamerule "doTileDrop" to false was to simulate a server that has chunk collectors. Note: This might increase the item output of a cacti farm, though in theory it should act the same as vanilla. diff --git a/net/minecraft/world/level/block/CactusBlock.java b/net/minecraft/world/level/block/CactusBlock.java index 0f8cfa5423cd1813c655237aa544dad2dc56ba4d..246193cc914f88cba2eb5959bd3fd8e56e7ebc61 100644 --- a/net/minecraft/world/level/block/CactusBlock.java +++ b/net/minecraft/world/level/block/CactusBlock.java @@ -52,25 +52,46 @@ 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 + final int x = pos.getX(); + final int z = pos.getZ(); + net.minecraft.world.level.chunk.LevelChunk chunk = level.getChunkIfLoaded(x >> 4, z >> 4); + if (chunk == null) return; + + final int y = pos.getY(); + if (chunk.getBlockState(x, y + 1, z).isAir()) { + // Pluto end - Decrease chunk/block lookups int i = 1; int ageValue = state.getValue(AGE); - while (level.getBlockState(pos.below(i)).is(this)) { + while (chunk.getBlockState(pos.below(i)).is(this)) { // Pluto - Decrease chunk/block lookups if (++i == level.paperConfig().maxGrowthHeight.cactus && ageValue == 15) { // Paper - Configurable cactus/bamboo/reed growth height return; } } - if (ageValue == 8 && this.canSurvive(this.defaultBlockState(), level, pos.above())) { + // Pluto start - Decrease chunk/block lookups + BlockPos blockPos = null; + if (ageValue == 8 && this.canSurvive(this.defaultBlockState(), level, blockPos = pos.above())) { + // Pluto end - Decrease chunk/block lookups double d = i >= level.paperConfig().maxGrowthHeight.cactus ? 0.25 : 0.1; // Paper - Configurable cactus/bamboo/reed growth height if (random.nextDouble() <= d) { org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, blockPos, Blocks.CACTUS_FLOWER.defaultBlockState(), 3); } } else if (ageValue == 15 && i < level.paperConfig().maxGrowthHeight.cactus) { // Paper - Configurable cactus/bamboo/reed growth height + // Pluto start - Check if the cactus can even survive being placed + if (org.dreeam.leaf.config.modules.opt.CheckSurvivalBeforeGrowth.cactusCheckSurvivalBeforeGrowth && !canSurvive(level, blockPos = pos.above())) { // Pluto - Decrease chunk/block lookups + 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_NONE); + return; + } + // Pluto end - Check if the cactus can even survive being placed // Paper start - if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, blockPos, this.defaultBlockState(), 3)) { + if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, blockPos == null ? blockPos = pos.above() : blockPos, this.defaultBlockState(), 3)) { // Pluto - Decrease chunk/block lookups return; } // Paper end @@ -115,6 +136,11 @@ 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