mirror of
https://github.com/Samsuik/Sakura.git
synced 2026-01-04 15:31:43 +00:00
The player velocity was not being talied correctly, and velocity was not sent when explosion effects were disabled in fps settings.
286 lines
15 KiB
Diff
286 lines
15 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Samsuik <kfian294ma4@gmail.com>
|
|
Date: Mon, 22 Apr 2024 23:01:26 +0100
|
|
Subject: [PATCH] Replace explosion density cache
|
|
|
|
|
|
diff --git a/src/main/java/me/samsuik/sakura/explosion/density/BlockDensityCache.java b/src/main/java/me/samsuik/sakura/explosion/density/BlockDensityCache.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..35454e122e87892099226ba8fd8d444664be9037
|
|
--- /dev/null
|
|
+++ b/src/main/java/me/samsuik/sakura/explosion/density/BlockDensityCache.java
|
|
@@ -0,0 +1,62 @@
|
|
+package me.samsuik.sakura.explosion.density;
|
|
+
|
|
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
|
+import net.minecraft.util.Mth;
|
|
+import net.minecraft.world.entity.Entity;
|
|
+import net.minecraft.world.phys.Vec3;
|
|
+
|
|
+/**
|
|
+ * This is a replacement for papers explosion density cache to be more lenient and efficient.
|
|
+ */
|
|
+public final class BlockDensityCache {
|
|
+ public static final float UNKNOWN_DENSITY = -1.0f;
|
|
+
|
|
+ private final Int2ObjectOpenHashMap<DensityData> densityDataMap = new Int2ObjectOpenHashMap<>();
|
|
+ private DensityData data;
|
|
+ private int key;
|
|
+ private boolean knownSource;
|
|
+
|
|
+ public float getDensity(Vec3 explosion, Entity entity) {
|
|
+ int key = getKey(explosion, entity);
|
|
+ DensityData data = this.densityDataMap.get(key);
|
|
+
|
|
+ if (data != null && data.hasPosition(explosion, entity.getBoundingBox())) {
|
|
+ return data.density();
|
|
+ } else {
|
|
+ this.knownSource = data != null && data.complete() && data.isExplosionPosition(explosion);
|
|
+ this.data = data;
|
|
+ this.key = key;
|
|
+ return UNKNOWN_DENSITY;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public float getKnownDensity(Vec3 point) {
|
|
+ if (this.knownSource && this.data.isKnownPosition(point)) {
|
|
+ return this.data.density();
|
|
+ } else {
|
|
+ return UNKNOWN_DENSITY;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public void putDensity(Vec3 explosion, Entity entity, float density) {
|
|
+ if (this.data == null || !this.data.complete()) {
|
|
+ this.densityDataMap.put(this.key, new DensityData(explosion, entity, density));
|
|
+ } else if (this.data.density() == density) {
|
|
+ this.data.expand(explosion, entity);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public void invalidate() {
|
|
+ this.densityDataMap.clear();
|
|
+ }
|
|
+
|
|
+ private static int getKey(Vec3 explosion, Entity entity) {
|
|
+ int key = Mth.floor(explosion.x());
|
|
+ key = 31 * key + Mth.floor(explosion.y());
|
|
+ key = 31 * key + Mth.floor(explosion.z());
|
|
+ key = 31 * key + entity.getBlockX();
|
|
+ key = 31 * key + entity.getBlockY();
|
|
+ key = 31 * key + entity.getBlockZ();
|
|
+ return key;
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/me/samsuik/sakura/explosion/density/DensityData.java b/src/main/java/me/samsuik/sakura/explosion/density/DensityData.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..d7e24638f07f243502004970ab4ce646cbe1e436
|
|
--- /dev/null
|
|
+++ b/src/main/java/me/samsuik/sakura/explosion/density/DensityData.java
|
|
@@ -0,0 +1,47 @@
|
|
+package me.samsuik.sakura.explosion.density;
|
|
+
|
|
+import net.minecraft.world.entity.Entity;
|
|
+import net.minecraft.world.phys.AABB;
|
|
+import net.minecraft.world.phys.Vec3;
|
|
+
|
|
+public final class DensityData {
|
|
+ private AABB source;
|
|
+ private AABB known;
|
|
+ private AABB entity;
|
|
+ private final float density;
|
|
+ private final boolean complete;
|
|
+
|
|
+ public DensityData(Vec3 explosion, Entity entity, float density) {
|
|
+ this.source = new AABB(explosion, explosion);
|
|
+ this.known = new AABB(entity.position(), entity.position());
|
|
+ this.entity = entity.getBoundingBox();
|
|
+ this.density = density;
|
|
+ this.complete = Math.abs(density - 0.5f) == 0.5f;
|
|
+ }
|
|
+
|
|
+ public float density() {
|
|
+ return this.density;
|
|
+ }
|
|
+
|
|
+ public boolean complete() {
|
|
+ return this.complete;
|
|
+ }
|
|
+
|
|
+ public boolean hasPosition(Vec3 explosion, AABB entity) {
|
|
+ return this.isExplosionPosition(explosion) && this.entity.isAABBInBounds(entity);
|
|
+ }
|
|
+
|
|
+ public boolean isKnownPosition(Vec3 point) {
|
|
+ return this.entity.isVec3InBounds(point);
|
|
+ }
|
|
+
|
|
+ public boolean isExplosionPosition(Vec3 explosion) {
|
|
+ return this.source.isVec3InBounds(explosion);
|
|
+ }
|
|
+
|
|
+ public void expand(Vec3 explosion, Entity entity) {
|
|
+ this.source = this.source.expand(explosion);
|
|
+ this.known = this.known.expand(entity.position());
|
|
+ this.entity = this.entity.minmax(entity.getBoundingBox());
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
index 61b24eac8f17d5a433817ae2ebb3baf2599af210..3f3a7035a07efce5b8438abf989312b6df137ec8 100644
|
|
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
@@ -1891,6 +1891,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
|
worldserver.explosionDensityCache.clear(); // Paper - Optimize explosions
|
|
worldserver.localConfig().expire(currentTick); // Sakura - add local config
|
|
worldserver.mergeHandler.expire(currentTick); // Sakura - merge cannon entities
|
|
+ worldserver.densityCache.invalidate(); // Sakura - explosion density cache
|
|
}
|
|
this.isIteratingOverLevels = false; // Paper - Throw exception on world create while being ticked
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
|
index d036cdcc17b8429c986946a020cb34cd6ced322e..b45ad0125cd5c116126e8ffb893585970ea3b960 100644
|
|
--- a/src/main/java/net/minecraft/world/level/Level.java
|
|
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
|
@@ -842,6 +842,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
|
}
|
|
// Paper end - optimise random ticking
|
|
public final me.samsuik.sakura.entity.merge.EntityMergeHandler mergeHandler = new me.samsuik.sakura.entity.merge.EntityMergeHandler(); // Sakura - merge cannon entities
|
|
+ public final me.samsuik.sakura.explosion.density.BlockDensityCache densityCache = new me.samsuik.sakura.explosion.density.BlockDensityCache(); // Sakura - explosion density cache
|
|
|
|
protected Level(WritableLevelData worlddatamutable, ResourceKey<Level> resourcekey, RegistryAccess iregistrycustom, Holder<DimensionType> holder, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function<org.spigotmc.SpigotWorldConfig, io.papermc.paper.configuration.WorldConfiguration> paperWorldConfigCreator, java.util.function.Supplier<me.samsuik.sakura.configuration.WorldConfiguration> sakuraWorldConfigCreator, java.util.concurrent.Executor executor) { // Sakura - sakura configuration files // Paper - create paper world config & Anti-Xray
|
|
// Paper start - getblock optimisations - cache world height/sections
|
|
diff --git a/src/main/java/net/minecraft/world/level/ServerExplosion.java b/src/main/java/net/minecraft/world/level/ServerExplosion.java
|
|
index a7f64335001c7beb7f4474c9cda3c6988725f69a..c4d167ea4390c6605c99d5868d778e0b3f01f97c 100644
|
|
--- a/src/main/java/net/minecraft/world/level/ServerExplosion.java
|
|
+++ b/src/main/java/net/minecraft/world/level/ServerExplosion.java
|
|
@@ -297,7 +297,12 @@ public class ServerExplosion implements Explosion {
|
|
Math.fma(dz, diffZ, offZ)
|
|
);
|
|
|
|
- if (!this.clipsAnything(from, source, context, blockCache, blockPos)) {
|
|
+ // Sakura start - replace density cache
|
|
+ final float density = this.level.densityCache.getKnownDensity(from);
|
|
+ if (density != me.samsuik.sakura.explosion.density.BlockDensityCache.UNKNOWN_DENSITY) {
|
|
+ missedRays += (int) density;
|
|
+ } else if (!this.clipsAnything(from, source, context, blockCache, blockPos)) {
|
|
+ // Sakura end - replace density cache
|
|
++missedRays;
|
|
}
|
|
}
|
|
@@ -377,7 +382,16 @@ public class ServerExplosion implements Explosion {
|
|
double d10 = Mth.lerp(d7, axisalignedbb.minZ, axisalignedbb.maxZ);
|
|
Vec3 vec3d1 = new Vec3(d8 + d3, d9, d10 + d4);
|
|
|
|
- if (entity.level().clip(new ClipContext(vec3d1, pos, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, entity)).getType() == HitResult.Type.MISS) {
|
|
+ // Sakura start - replace density cache
|
|
+ final net.minecraft.world.phys.HitResult.Type hitResult;
|
|
+ final float density = entity.level().densityCache.getKnownDensity(vec3d1);
|
|
+ if (density != me.samsuik.sakura.explosion.density.BlockDensityCache.UNKNOWN_DENSITY) {
|
|
+ hitResult = density != 0.0f ? net.minecraft.world.phys.HitResult.Type.MISS : net.minecraft.world.phys.HitResult.Type.BLOCK;
|
|
+ } else {
|
|
+ hitResult = entity.level().clip(new ClipContext(vec3d1, pos, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, entity)).getType();
|
|
+ }
|
|
+ if (hitResult == HitResult.Type.MISS) {
|
|
+ // Sakura end - replace density cache
|
|
++i;
|
|
}
|
|
|
|
@@ -694,6 +708,12 @@ public class ServerExplosion implements Explosion {
|
|
return;
|
|
}
|
|
// CraftBukkit end
|
|
+ // Sakura start - explosion density cache
|
|
+ if (!positions.isEmpty() && !this.level.paperConfig().environment.optimizeExplosions) {
|
|
+ this.level.densityCache.invalidate();
|
|
+ }
|
|
+ // Sakura end - explosion density cache
|
|
+
|
|
Iterator iterator = positions.iterator();
|
|
|
|
while (iterator.hasNext()) {
|
|
@@ -867,14 +887,12 @@ public class ServerExplosion implements Explosion {
|
|
|
|
// Paper start - Optimize explosions
|
|
private float getBlockDensity(Vec3 vec3d, Entity entity) {
|
|
- if (!this.level.paperConfig().environment.optimizeExplosions) {
|
|
- return this.getSeenFraction(vec3d, entity, this.directMappedBlockCache, this.mutablePos); // Paper - collision optimisations
|
|
- }
|
|
- CacheKey key = new CacheKey(this, entity.getBoundingBox());
|
|
- Float blockDensity = this.level.explosionDensityCache.get(key);
|
|
- if (blockDensity == null) {
|
|
+ // Sakura start - replace density cache
|
|
+ float blockDensity = this.level.densityCache.getDensity(vec3d, entity);
|
|
+ if (blockDensity == me.samsuik.sakura.explosion.density.BlockDensityCache.UNKNOWN_DENSITY) {
|
|
blockDensity = this.getSeenFraction(vec3d, entity, this.directMappedBlockCache, this.mutablePos); // Paper - collision optimisations
|
|
- this.level.explosionDensityCache.put(key, blockDensity);
|
|
+ this.level.densityCache.putDensity(vec3d, entity, blockDensity);
|
|
+ // Sakura end - replace density cache
|
|
}
|
|
|
|
return blockDensity;
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/BasePressurePlateBlock.java b/src/main/java/net/minecraft/world/level/block/BasePressurePlateBlock.java
|
|
index c2eb63de04fc48bd2cc1aad8d9cba272c0829c80..0d9f944a3777ac3a0f569832468c5c97b0fdf488 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/BasePressurePlateBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/BasePressurePlateBlock.java
|
|
@@ -109,6 +109,11 @@ public abstract class BasePressurePlateBlock extends Block {
|
|
if (output != j) {
|
|
BlockState iblockdata1 = this.setSignalForState(state, j);
|
|
|
|
+ // Sakura start - explosion density cache
|
|
+ if (!world.paperConfig().environment.optimizeExplosions) {
|
|
+ world.densityCache.invalidate();
|
|
+ }
|
|
+ // Sakura end - explosion density cache
|
|
world.setBlock(pos, iblockdata1, 2);
|
|
this.updateNeighbours(world, pos);
|
|
world.setBlocksDirty(pos, state, iblockdata1);
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java b/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java
|
|
index c2589f42c467ca672417c24076313da51bb2dcbb..5ae5ef6edf3a6e2b8be9ce11ca46c7714accc4f3 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java
|
|
@@ -175,6 +175,11 @@ public class TripWireHookBlock extends Block {
|
|
blockposition1 = pos.relative(enumdirection, j);
|
|
Direction enumdirection1 = enumdirection.getOpposite();
|
|
|
|
+ // Sakura start - explosion density cache
|
|
+ if (!world.paperConfig().environment.optimizeExplosions) {
|
|
+ world.densityCache.invalidate();
|
|
+ }
|
|
+ // Sakura end - explosion density cache
|
|
world.setBlock(blockposition1, (BlockState) iblockdata3.setValue(TripWireHookBlock.FACING, enumdirection1), 3);
|
|
TripWireHookBlock.notifyNeighbors(block, world, blockposition1, enumdirection1);
|
|
TripWireHookBlock.emitState(world, blockposition1, flag4, flag5, flag2, flag3);
|
|
diff --git a/src/main/java/net/minecraft/world/phys/AABB.java b/src/main/java/net/minecraft/world/phys/AABB.java
|
|
index 6cf6d4ec7b9e43c7b2b4c0e2fb080964ff588130..a867ec0347038c7246af3f3377eceda17e695ec3 100644
|
|
--- a/src/main/java/net/minecraft/world/phys/AABB.java
|
|
+++ b/src/main/java/net/minecraft/world/phys/AABB.java
|
|
@@ -551,4 +551,28 @@ public class AABB {
|
|
public static AABB ofSize(Vec3 center, double dx, double dy, double dz) {
|
|
return new AABB(center.x - dx / 2.0, center.y - dy / 2.0, center.z - dz / 2.0, center.x + dx / 2.0, center.y + dy / 2.0, center.z + dz / 2.0);
|
|
}
|
|
+
|
|
+ // Sakura start - explosion density cache
|
|
+ public final boolean isAABBInBounds(AABB bb) {
|
|
+ return this.minX <= bb.minX && this.maxX >= bb.maxX
|
|
+ && this.minY <= bb.minY && this.maxY >= bb.maxY
|
|
+ && this.minZ <= bb.minZ && this.maxZ >= bb.maxZ;
|
|
+ }
|
|
+
|
|
+ public final boolean isVec3InBounds(Vec3 p) {
|
|
+ return this.minX <= p.x && this.maxX >= p.x
|
|
+ && this.minY <= p.y && this.maxY >= p.y
|
|
+ && this.minZ <= p.z && this.maxZ >= p.z;
|
|
+ }
|
|
+
|
|
+ public final AABB expand(Vec3 pos) {
|
|
+ double minX = Math.min(this.minX, pos.x);
|
|
+ double minY = Math.min(this.minY, pos.y);
|
|
+ double minZ = Math.min(this.minZ, pos.z);
|
|
+ double maxX = Math.max(this.maxX, pos.x);
|
|
+ double maxY = Math.max(this.maxY, pos.y);
|
|
+ double maxZ = Math.max(this.maxZ, pos.z);
|
|
+ return new AABB(minX, minY, minZ, maxX, maxY, maxZ);
|
|
+ }
|
|
+ // Sakura end - explosion density cache
|
|
}
|