aboutsummaryrefslogtreecommitdiffhomepage
path: root/Spigot-Server-Patches-Unmapped/0033-Optimize-explosions.patch
diff options
context:
space:
mode:
Diffstat (limited to 'Spigot-Server-Patches-Unmapped/0033-Optimize-explosions.patch')
-rw-r--r--Spigot-Server-Patches-Unmapped/0033-Optimize-explosions.patch148
1 files changed, 148 insertions, 0 deletions
diff --git a/Spigot-Server-Patches-Unmapped/0033-Optimize-explosions.patch b/Spigot-Server-Patches-Unmapped/0033-Optimize-explosions.patch
new file mode 100644
index 0000000000..78ab387974
--- /dev/null
+++ b/Spigot-Server-Patches-Unmapped/0033-Optimize-explosions.patch
@@ -0,0 +1,148 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Byteflux <[email protected]>
+Date: Wed, 2 Mar 2016 11:59:48 -0600
+Subject: [PATCH] Optimize explosions
+
+The process of determining an entity's exposure from explosions can be
+expensive when there are hundreds or more entities in range.
+
+This patch adds a per-tick cache that is used for storing and retrieving
+an entity's exposure during an explosion.
+
+diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+index e6e18f309dc09ea9416ea37dcc697ddc2b571a96..4881b03d470646843bad1bc343eb6a6ab9072d8e 100644
+--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
++++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+@@ -155,4 +155,10 @@ public class PaperWorldConfig {
+ disableEndCredits = getBoolean("game-mechanics.disable-end-credits", false);
+ log("End credits disabled: " + disableEndCredits);
+ }
++
++ public boolean optimizeExplosions;
++ private void optimizeExplosions() {
++ optimizeExplosions = getBoolean("optimize-explosions", false);
++ log("Optimize explosions: " + optimizeExplosions);
++ }
+ }
+diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
+index add4f149fd31d1420d825b646b3e088808e5896b..06071e15851d5d27f1c9a0d60a764a6214e0ba0f 100644
+--- a/src/main/java/net/minecraft/server/MinecraftServer.java
++++ b/src/main/java/net/minecraft/server/MinecraftServer.java
+@@ -1326,6 +1326,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
+
+ this.methodProfiler.exit();
+ this.methodProfiler.exit();
++ worldserver.explosionDensityCache.clear(); // Paper - Optimize explosions
+ }
+
+ this.methodProfiler.exitEnter("connection");
+diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java
+index 7786a06ba09aacaa70c346e85a9eeed9f2ffec6e..6a7af2c0c3c294b10c6ddbf98babb0f30d7d5f56 100644
+--- a/src/main/java/net/minecraft/world/level/Explosion.java
++++ b/src/main/java/net/minecraft/world/level/Explosion.java
+@@ -201,7 +201,7 @@ public class Explosion {
+ d8 /= d11;
+ d9 /= d11;
+ d10 /= d11;
+- double d12 = (double) a(vec3d, entity);
++ double d12 = this.getBlockDensity(vec3d, entity); // Paper - Optimize explosions
+ double d13 = (1.0D - d7) * d12;
+
+ // CraftBukkit start
+@@ -420,4 +420,84 @@ public class Explosion {
+
+ private Effect() {}
+ }
++ // Paper start - Optimize explosions
++ private float getBlockDensity(Vec3D vec3d, Entity entity) {
++ if (!this.world.paperConfig.optimizeExplosions) {
++ return a(vec3d, entity);
++ }
++ CacheKey key = new CacheKey(this, entity.getBoundingBox());
++ Float blockDensity = this.world.explosionDensityCache.get(key);
++ if (blockDensity == null) {
++ blockDensity = a(vec3d, entity);
++ this.world.explosionDensityCache.put(key, blockDensity);
++ }
++
++ return blockDensity;
++ }
++
++ static class CacheKey {
++ private final World world;
++ private final double posX, posY, posZ;
++ private final double minX, minY, minZ;
++ private final double maxX, maxY, maxZ;
++
++ public CacheKey(Explosion explosion, AxisAlignedBB aabb) {
++ this.world = explosion.world;
++ this.posX = explosion.posX;
++ this.posY = explosion.posY;
++ this.posZ = explosion.posZ;
++ this.minX = aabb.minX;
++ this.minY = aabb.minY;
++ this.minZ = aabb.minZ;
++ this.maxX = aabb.maxX;
++ this.maxY = aabb.maxY;
++ this.maxZ = aabb.maxZ;
++ }
++
++ @Override
++ public boolean equals(Object o) {
++ if (this == o) return true;
++ if (o == null || getClass() != o.getClass()) return false;
++
++ CacheKey cacheKey = (CacheKey) o;
++
++ if (Double.compare(cacheKey.posX, posX) != 0) return false;
++ if (Double.compare(cacheKey.posY, posY) != 0) return false;
++ if (Double.compare(cacheKey.posZ, posZ) != 0) return false;
++ if (Double.compare(cacheKey.minX, minX) != 0) return false;
++ if (Double.compare(cacheKey.minY, minY) != 0) return false;
++ if (Double.compare(cacheKey.minZ, minZ) != 0) return false;
++ if (Double.compare(cacheKey.maxX, maxX) != 0) return false;
++ if (Double.compare(cacheKey.maxY, maxY) != 0) return false;
++ if (Double.compare(cacheKey.maxZ, maxZ) != 0) return false;
++ return world.equals(cacheKey.world);
++ }
++
++ @Override
++ public int hashCode() {
++ int result;
++ long temp;
++ result = world.hashCode();
++ temp = Double.doubleToLongBits(posX);
++ result = 31 * result + (int) (temp ^ (temp >>> 32));
++ temp = Double.doubleToLongBits(posY);
++ result = 31 * result + (int) (temp ^ (temp >>> 32));
++ temp = Double.doubleToLongBits(posZ);
++ result = 31 * result + (int) (temp ^ (temp >>> 32));
++ temp = Double.doubleToLongBits(minX);
++ result = 31 * result + (int) (temp ^ (temp >>> 32));
++ temp = Double.doubleToLongBits(minY);
++ result = 31 * result + (int) (temp ^ (temp >>> 32));
++ temp = Double.doubleToLongBits(minZ);
++ result = 31 * result + (int) (temp ^ (temp >>> 32));
++ temp = Double.doubleToLongBits(maxX);
++ result = 31 * result + (int) (temp ^ (temp >>> 32));
++ temp = Double.doubleToLongBits(maxY);
++ result = 31 * result + (int) (temp ^ (temp >>> 32));
++ temp = Double.doubleToLongBits(maxZ);
++ result = 31 * result + (int) (temp ^ (temp >>> 32));
++ return result;
++ }
++ }
++ // Paper end
+ }
+diff --git a/src/main/java/net/minecraft/world/level/World.java b/src/main/java/net/minecraft/world/level/World.java
+index 87e37c38825ad20fc11f41ea2a4512753266d2b4..06455fb3916e347c075c6aa84977dca7e25760c2 100644
+--- a/src/main/java/net/minecraft/world/level/World.java
++++ b/src/main/java/net/minecraft/world/level/World.java
+@@ -136,6 +136,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
+ private org.spigotmc.TickLimiter entityLimiter;
+ private org.spigotmc.TickLimiter tileLimiter;
+ private int tileTickPosition;
++ public final Map<Explosion.CacheKey, Float> explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions
+
+ public CraftWorld getWorld() {
+ return this.world;