CavePVP-Stuff/cSpigot-master/spigot-server-Patches/0064-Optimize-explosions.patch

163 lines
7.1 KiB
Diff
Raw Normal View History

2023-05-01 20:59:40 +02:00
From 90a3509dd9dc20ea3bcfd3c47128e6bdd75a46dd Mon Sep 17 00:00:00 2001
From: Byteflux <byte@byteflux.net>
Date: Sat, 13 Jun 2015 19:47:27 -0700
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/net/minecraft/server/Explosion.java b/src/main/java/net/minecraft/server/Explosion.java
index 364625859..4e5c7a512 100644
--- a/src/main/java/net/minecraft/server/Explosion.java
+++ b/src/main/java/net/minecraft/server/Explosion.java
@@ -131,7 +131,7 @@ public class Explosion {
d0 /= d8;
d1 /= d8;
d2 /= d8;
- double d9 = (double) this.world.a(vec3d, entity.boundingBox);
+ double d9 = this.getBlockDensity(vec3d, entity.boundingBox); // PaperSpigot - Optimize explosions
double d10 = (1.0D - d7) * d9;
// CraftBukkit start
@@ -274,4 +274,86 @@ public class Explosion {
public EntityLiving c() {
return this.source == null ? null : (this.source instanceof EntityTNTPrimed ? ((EntityTNTPrimed) this.source).getSource() : (this.source instanceof EntityLiving ? (EntityLiving) this.source : null));
}
+
+ // PaperSpigot start - Optimize explosions
+ private float getBlockDensity(Vec3D vec3d, AxisAlignedBB aabb) {
+ if (!this.world.paperSpigotConfig.optimizeExplosions) {
+ return this.world.a(vec3d, aabb);
+ }
+
+ CacheKey key = new CacheKey(this, aabb);
+ Float blockDensity = this.world.explosionDensityCache.get(key);
+ if (blockDensity == null) {
+ blockDensity = this.world.a(vec3d, aabb);
+ 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.a;
+ this.minY = aabb.b;
+ this.minZ = aabb.c;
+ this.maxX = aabb.d;
+ this.maxY = aabb.e;
+ this.maxZ = aabb.f;
+ }
+
+ @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;
+ }
+ }
+ // PaperSpigot end
}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 878214465..00f397723 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -735,6 +735,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
worldserver.timings.tracker.stopTiming(); // Spigot
this.methodProfiler.b();
this.methodProfiler.b();
+ worldserver.explosionDensityCache.clear(); // PaperSpigot - Optimize explosions
// } // CraftBukkit
// this.h[i][this.ticks % 100] = System.nanoTime() - j; // CraftBukkit
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 51ddb6c50..0c942aab1 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -14,6 +14,8 @@ import java.util.concurrent.Callable;
// PaperSpigot start
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.HashMap;
+import java.util.Map;
import net.minecraft.util.com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.bukkit.craftbukkit.CraftChunk;
// PaperSpigot end
@@ -136,6 +138,7 @@ public abstract class World implements IBlockAccess {
return lightingExecutor;
}
// Poweruser end
+ public final Map<Explosion.CacheKey, Float> explosionDensityCache = new HashMap<Explosion.CacheKey, Float>(); // PaperSpigot - Optimize explosions
public static long chunkToKey(int x, int z)
{
diff --git a/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java b/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java
index 91d4fc2da..ec27f7934 100644
--- a/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java
+++ b/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java
@@ -259,4 +259,10 @@ public class PaperSpigotWorldConfig
{
disableEndCredits = getBoolean( "game-mechanics.disable-end-credits", false );
}
+
+ public boolean optimizeExplosions;
+ private void optimizeExplosions()
+ {
+ optimizeExplosions = getBoolean( "optimize-explosions", false );
+ }
}
--
2.13.3