diff options
Diffstat (limited to 'Spigot-Server-Patches-Unmapped/0033-Optimize-explosions.patch')
-rw-r--r-- | Spigot-Server-Patches-Unmapped/0033-Optimize-explosions.patch | 148 |
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; |