From 71b0c76861769c207980b86aff700dc3de2dba2a Mon Sep 17 00:00:00 2001 From: Owen <23108066+Owen1212055@users.noreply.github.com> Date: Sat, 21 Jun 2025 00:54:53 -0400 Subject: [PATCH] Adds support for vanilla negative explosions (#12705) Fixes #10460 --- .../0016-Moonrise-optimisation-patches.patch | 16 ++++++------ .../world/level/ServerExplosion.java.patch | 26 +++++-------------- .../block/state/BlockBehaviour.java.patch | 2 +- 3 files changed, 15 insertions(+), 29 deletions(-) diff --git a/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch b/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch index 09a9eba5749..b5e83ec741f 100644 --- a/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch +++ b/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch @@ -30766,7 +30766,7 @@ index c59f2c0634e3ebb11b8f6bc09020f951cb602f9b..0842fd6488c8b27d98c4344e1244996b ChunkAccess getChunk(int x, int z, ChunkStatus chunkStatus, boolean requireChunk); diff --git a/net/minecraft/world/level/ServerExplosion.java b/net/minecraft/world/level/ServerExplosion.java -index 8afaded394fcbf5d7ad4c51ea49642ce93cd5198..e5ccfb8cbfafed7bb0a1d888b5bc98a923e46e59 100644 +index 677780bf473f56a4083b984e1eb75b74f7716540..07e4025ca6c9c31905db2e6921138a0ded479dde 100644 --- a/net/minecraft/world/level/ServerExplosion.java +++ b/net/minecraft/world/level/ServerExplosion.java @@ -60,6 +60,249 @@ public class ServerExplosion implements Explosion { @@ -31019,7 +31019,7 @@ index 8afaded394fcbf5d7ad4c51ea49642ce93cd5198..e5ccfb8cbfafed7bb0a1d888b5bc98a9 public ServerExplosion( ServerLevel level, -@@ -131,63 +374,102 @@ public class ServerExplosion implements Explosion { +@@ -134,63 +377,102 @@ public class ServerExplosion implements Explosion { } private List calculateExplodedPositions() { @@ -31169,10 +31169,10 @@ index 8afaded394fcbf5d7ad4c51ea49642ce93cd5198..e5ccfb8cbfafed7bb0a1d888b5bc98a9 } private void hurtEntities() { -@@ -360,6 +642,14 @@ public class ServerExplosion implements Explosion { - return; - } - // CraftBukkit end +@@ -358,6 +640,14 @@ public class ServerExplosion implements Explosion { + } + + public void explode() { + // Paper start - collision optimisations + this.blockCache = new it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<>(); + this.chunkPosCache = new long[CHUNK_CACHE_WIDTH * CHUNK_CACHE_WIDTH]; @@ -31184,7 +31184,7 @@ index 8afaded394fcbf5d7ad4c51ea49642ce93cd5198..e5ccfb8cbfafed7bb0a1d888b5bc98a9 this.level.gameEvent(this.source, GameEvent.EXPLODE, this.center); List list = this.calculateExplodedPositions(); this.hurtEntities(); -@@ -373,6 +663,13 @@ public class ServerExplosion implements Explosion { +@@ -371,6 +661,13 @@ public class ServerExplosion implements Explosion { if (this.fire) { this.createFire(list); } @@ -31198,7 +31198,7 @@ index 8afaded394fcbf5d7ad4c51ea49642ce93cd5198..e5ccfb8cbfafed7bb0a1d888b5bc98a9 } private static void addOrAppendStack(List stackCollectors, ItemStack stack, BlockPos pos) { -@@ -461,12 +758,12 @@ public class ServerExplosion implements Explosion { +@@ -459,12 +756,12 @@ public class ServerExplosion implements Explosion { // Paper start - Optimize explosions private float getBlockDensity(Vec3 vec3d, Entity entity) { if (!this.level.paperConfig().environment.optimizeExplosions) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/ServerExplosion.java.patch b/paper-server/patches/sources/net/minecraft/world/level/ServerExplosion.java.patch index 215dbdad707..2ed4901cac6 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/ServerExplosion.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/ServerExplosion.java.patch @@ -27,18 +27,14 @@ public ServerExplosion( ServerLevel level, -@@ -60,12 +_,13 @@ - ) { - this.level = level; - this.source = source; -- this.radius = radius; -+ this.radius = (float) Math.max(radius, 0.0); // CraftBukkit - clamp bad values - this.center = center; - this.fire = fire; +@@ -66,6 +_,10 @@ this.blockInteraction = blockInteraction; this.damageSource = damageSource == null ? level.damageSources().explosion(this) : damageSource; this.damageCalculator = damageCalculator == null ? this.makeDamageCalculator(source) : damageCalculator; -+ this.yield = this.blockInteraction == Explosion.BlockInteraction.DESTROY_WITH_DECAY ? 1.0F / this.radius : 1.0F; // CraftBukkit ++ // Paper start - add yield ++ this.yield = this.blockInteraction == Explosion.BlockInteraction.DESTROY_WITH_DECAY ? 1.0F / this.radius : 1.0F; ++ this.yield = Double.isFinite(this.yield) ? this.yield : 0; // Paper - Don't allow infinite default yields ++ // Paper end - add yield } private ExplosionDamageCalculator makeDamageCalculator(@Nullable Entity entity) { @@ -201,7 +197,7 @@ this.level .getBlockState(blockPos) .onExplosionHit(this.level, blockPos, this, (itemStack, blockPos1) -> addOrAppendStack(list, itemStack, blockPos1)); -@@ -236,12 +_,21 @@ +@@ -236,7 +_,11 @@ private void createFire(List blocks) { for (BlockPos blockPos : blocks) { if (this.level.random.nextInt(3) == 0 && this.level.getBlockState(blockPos).isAir() && this.level.getBlockState(blockPos.below()).isSolidRender()) { @@ -214,16 +210,6 @@ } } } - - public void explode() { -+ // CraftBukkit start -+ if (this.radius < 0.1F) { -+ return; -+ } -+ // CraftBukkit end - this.level.gameEvent(this.source, GameEvent.EXPLODE, this.center); - List list = this.calculateExplodedPositions(); - this.hurtEntities(); @@ -338,4 +_,86 @@ } } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/state/BlockBehaviour.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/state/BlockBehaviour.java.patch index 2cb6e4913c6..4b4f6939c03 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/state/BlockBehaviour.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/state/BlockBehaviour.java.patch @@ -30,7 +30,7 @@ - builder.withParameter(LootContextParams.EXPLOSION_RADIUS, explosion.radius()); + // CraftBukkit start - add yield + if (explosion instanceof net.minecraft.world.level.ServerExplosion serverExplosion && serverExplosion.yield < 1.0F) { -+ builder.withParameter(LootContextParams.EXPLOSION_RADIUS, 1.0F / serverExplosion.yield); ++ builder.withParameter(LootContextParams.EXPLOSION_RADIUS, serverExplosion.yield == 0 ? 0 : 1.0F / serverExplosion.yield); + // CraftBukkit end }