|
|
|
|
@@ -1,120 +1,185 @@
|
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
|
|
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
|
|
|
|
|
Date: Sun, 26 Nov 2023 16:10:26 +0800
|
|
|
|
|
From: MrHua269 <novau233@163.com>
|
|
|
|
|
Date: Sun, 16 Jun 2024 10:56:41 +0000
|
|
|
|
|
Subject: [PATCH] Pufferfish Reduce entity fluid lookups if no fluids
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff --git a/src/main/java/me/earthme/luminol/config/modules/optimizations/ReduceEntityFluidLookupConfig.java b/src/main/java/me/earthme/luminol/config/modules/optimizations/ReduceEntityFluidLookupConfig.java
|
|
|
|
|
new file mode 100644
|
|
|
|
|
index 0000000000000000000000000000000000000000..0523b3da3fb254bce1998bae6410c6323ccac2ef
|
|
|
|
|
--- /dev/null
|
|
|
|
|
+++ b/src/main/java/me/earthme/luminol/config/modules/optimizations/ReduceEntityFluidLookupConfig.java
|
|
|
|
|
@@ -0,0 +1,20 @@
|
|
|
|
|
+package me.earthme.luminol.config.modules.optimizations;
|
|
|
|
|
+
|
|
|
|
|
+import me.earthme.luminol.config.ConfigInfo;
|
|
|
|
|
+import me.earthme.luminol.config.EnumConfigCategory;
|
|
|
|
|
+import me.earthme.luminol.config.IConfigModule;
|
|
|
|
|
+
|
|
|
|
|
+public class ReduceEntityFluidLookupConfig implements IConfigModule {
|
|
|
|
|
+ @ConfigInfo(baseName = "enabled", comments = "See the optimization on Pufferfish")
|
|
|
|
|
+ public static boolean enabled = true;
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public EnumConfigCategory getCategory() {
|
|
|
|
|
+ return EnumConfigCategory.OPTIMIZATIONS;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public String getBaseName() {
|
|
|
|
|
+ return "reduce_entity_fluid_lookups_if_no_fluids";
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
|
|
|
|
index 94c9f407f526b2d43cf61725b414b113de03c67d..94bac805d032015587e88b4de3cf7064a534e736 100644
|
|
|
|
|
index 94c9f407f526b2d43cf61725b414b113de03c67d..46369f332765d5995d7d6884d9b0dd3151729160 100644
|
|
|
|
|
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
|
|
|
|
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
|
|
|
|
@@ -5317,16 +5317,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tag, double speed) {
|
|
|
|
|
- if (this.touchingUnloadedChunk()) {
|
|
|
|
|
+ if (false && this.touchingUnloadedChunk()) { // Pufferfish - cost of a lookup here is the same cost as below, so skip
|
|
|
|
|
@@ -5320,6 +5320,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
|
|
|
if (this.touchingUnloadedChunk()) {
|
|
|
|
|
return false;
|
|
|
|
|
} else {
|
|
|
|
|
AABB axisalignedbb = this.getBoundingBox().deflate(0.001D);
|
|
|
|
|
- int i = Mth.floor(axisalignedbb.minX);
|
|
|
|
|
- int j = Mth.ceil(axisalignedbb.maxX);
|
|
|
|
|
- int k = Mth.floor(axisalignedbb.minY);
|
|
|
|
|
- int l = Mth.ceil(axisalignedbb.maxY);
|
|
|
|
|
- int i1 = Mth.floor(axisalignedbb.minZ);
|
|
|
|
|
- int j1 = Mth.ceil(axisalignedbb.maxZ);
|
|
|
|
|
+ // Pufferfish start - rename
|
|
|
|
|
+ int minBlockX = Mth.floor(axisalignedbb.minX);
|
|
|
|
|
+ int maxBlockX = Mth.ceil(axisalignedbb.maxX);
|
|
|
|
|
+ int minBlockY = Mth.floor(axisalignedbb.minY);
|
|
|
|
|
+ int maxBlockY = Mth.ceil(axisalignedbb.maxY);
|
|
|
|
|
+ int minBlockZ = Mth.floor(axisalignedbb.minZ);
|
|
|
|
|
+ int maxBlockZ = Mth.ceil(axisalignedbb.maxZ);
|
|
|
|
|
+ // Pufferfish end
|
|
|
|
|
double d1 = 0.0D;
|
|
|
|
|
boolean flag = this.isPushedByFluid();
|
|
|
|
|
boolean flag1 = false;
|
|
|
|
|
@@ -5334,14 +5336,61 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
|
|
|
int k1 = 0;
|
|
|
|
|
BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos();
|
|
|
|
|
|
|
|
|
|
- for (int l1 = i; l1 < j; ++l1) {
|
|
|
|
|
- for (int i2 = k; i2 < l; ++i2) {
|
|
|
|
|
- for (int j2 = i1; j2 < j1; ++j2) {
|
|
|
|
|
- blockposition_mutableblockposition.set(l1, i2, j2);
|
|
|
|
|
- FluidState fluid = this.level().getFluidState(blockposition_mutableblockposition);
|
|
|
|
|
+ // Pufferfish start - based off CollisionUtil.getCollisionsForBlocksOrWorldBorder
|
|
|
|
|
+ final int minSection = io.papermc.paper.util.WorldUtil.getMinSection(this.level());
|
|
|
|
|
+ final int maxSection = io.papermc.paper.util.WorldUtil.getMaxSection(this.level());
|
|
|
|
|
+ final int minBlock = minSection << 4;
|
|
|
|
|
+ final int maxBlock = (maxSection << 4) | 15;
|
|
|
|
|
+
|
|
|
|
|
+ // special cases:
|
|
|
|
|
+ if (minBlockY > maxBlock || maxBlockY < minBlock) {
|
|
|
|
|
+ // no point in checking
|
|
|
|
|
+ return false;
|
|
|
|
|
+ //Luminol start - Configurable pufferfish optimization: Reduce entity fluid lookups if no fluids
|
|
|
|
|
+ if (me.earthme.luminol.config.modules.optimizations.ReduceEntityFluidLookupConfig.enabled){
|
|
|
|
|
+ return this.updateFluidHeightAndDoFluidPushingPufferfish$half(tag, speed);
|
|
|
|
|
+ }
|
|
|
|
|
+ //Luminol end
|
|
|
|
|
AABB axisalignedbb = this.getBoundingBox().deflate(0.001D);
|
|
|
|
|
int i = Mth.floor(axisalignedbb.minX);
|
|
|
|
|
int j = Mth.ceil(axisalignedbb.maxX);
|
|
|
|
|
@@ -5393,6 +5398,133 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
+ //Luminol start - Configurable pufferfish optimization: Reduce entity fluid lookups if no fluids
|
|
|
|
|
+ private boolean updateFluidHeightAndDoFluidPushingPufferfish$half(TagKey<Fluid> tag, double speed) {
|
|
|
|
|
+ AABB axisalignedbb = this.getBoundingBox().deflate(0.001D);
|
|
|
|
|
+ // Pufferfish start - rename
|
|
|
|
|
+ int minBlockX = Mth.floor(axisalignedbb.minX);
|
|
|
|
|
+ int maxBlockX = Mth.ceil(axisalignedbb.maxX);
|
|
|
|
|
+ int minBlockY = Mth.floor(axisalignedbb.minY);
|
|
|
|
|
+ int maxBlockY = Mth.ceil(axisalignedbb.maxY);
|
|
|
|
|
+ int minBlockZ = Mth.floor(axisalignedbb.minZ);
|
|
|
|
|
+ int maxBlockZ = Mth.ceil(axisalignedbb.maxZ);
|
|
|
|
|
+ // Pufferfish end
|
|
|
|
|
+ double d1 = 0.0D;
|
|
|
|
|
+ boolean flag = this.isPushedByFluid();
|
|
|
|
|
+ boolean flag1 = false;
|
|
|
|
|
+ Vec3 vec3d = Vec3.ZERO;
|
|
|
|
|
+ int k1 = 0;
|
|
|
|
|
+ BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos();
|
|
|
|
|
+
|
|
|
|
|
+ int minYIterate = Math.max(minBlock, minBlockY);
|
|
|
|
|
+ int maxYIterate = Math.min(maxBlock, maxBlockY);
|
|
|
|
|
+ // Pufferfish start - based off CollisionUtil.getCollisionsForBlocksOrWorldBorder
|
|
|
|
|
+ final int minSection = io.papermc.paper.util.WorldUtil.getMinSection(this.level());
|
|
|
|
|
+ final int maxSection = io.papermc.paper.util.WorldUtil.getMaxSection(this.level());
|
|
|
|
|
+ final int minBlock = minSection << 4;
|
|
|
|
|
+ final int maxBlock = (maxSection << 4) | 15;
|
|
|
|
|
+
|
|
|
|
|
+ int minChunkX = minBlockX >> 4;
|
|
|
|
|
+ int maxChunkX = maxBlockX >> 4;
|
|
|
|
|
+ // special cases:
|
|
|
|
|
+ if (minBlockY > maxBlock || maxBlockY < minBlock) {
|
|
|
|
|
+ // no point in checking
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ int minChunkZ = minBlockZ >> 4;
|
|
|
|
|
+ int maxChunkZ = maxBlockZ >> 4;
|
|
|
|
|
+ int minYIterate = Math.max(minBlock, minBlockY);
|
|
|
|
|
+ int maxYIterate = Math.min(maxBlock, maxBlockY);
|
|
|
|
|
+
|
|
|
|
|
+ for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) {
|
|
|
|
|
+ int minZ = currChunkZ == minChunkZ ? minBlockZ & 15 : 0; // coordinate in chunk
|
|
|
|
|
+ int maxZ = currChunkZ == maxChunkZ ? maxBlockZ & 15 : 16; // coordinate in chunk
|
|
|
|
|
+ int minChunkX = minBlockX >> 4;
|
|
|
|
|
+ int maxChunkX = maxBlockX >> 4;
|
|
|
|
|
+
|
|
|
|
|
+ for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) {
|
|
|
|
|
+ int minX = currChunkX == minChunkX ? minBlockX & 15 : 0; // coordinate in chunk
|
|
|
|
|
+ int maxX = currChunkX == maxChunkX ? maxBlockX & 15 : 16; // coordinate in chunk
|
|
|
|
|
+ int minChunkZ = minBlockZ >> 4;
|
|
|
|
|
+ int maxChunkZ = maxBlockZ >> 4;
|
|
|
|
|
+
|
|
|
|
|
+ net.minecraft.world.level.chunk.ChunkAccess chunk = this.level().getChunkIfLoadedImmediately(currChunkX, currChunkZ);
|
|
|
|
|
+ if (chunk == null) {
|
|
|
|
|
+ return false; // if we're touching an unloaded chunk then it's false
|
|
|
|
|
+ for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) {
|
|
|
|
|
+ int minZ = currChunkZ == minChunkZ ? minBlockZ & 15 : 0; // coordinate in chunk
|
|
|
|
|
+ int maxZ = currChunkZ == maxChunkZ ? maxBlockZ & 15 : 16; // coordinate in chunk
|
|
|
|
|
+
|
|
|
|
|
+ for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) {
|
|
|
|
|
+ int minX = currChunkX == minChunkX ? minBlockX & 15 : 0; // coordinate in chunk
|
|
|
|
|
+ int maxX = currChunkX == maxChunkX ? maxBlockX & 15 : 16; // coordinate in chunk
|
|
|
|
|
+
|
|
|
|
|
+ net.minecraft.world.level.chunk.ChunkAccess chunk = this.level().getChunkIfLoadedImmediately(currChunkX, currChunkZ);
|
|
|
|
|
+ if (chunk == null) {
|
|
|
|
|
+ return false; // if we're touching an unloaded chunk then it's false
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ net.minecraft.world.level.chunk.LevelChunkSection[] sections = chunk.getSections();
|
|
|
|
|
+
|
|
|
|
|
+ for (int currY = minYIterate; currY < maxYIterate; ++currY) {
|
|
|
|
|
+ net.minecraft.world.level.chunk.LevelChunkSection section = sections[(currY >> 4) - minSection];
|
|
|
|
|
+
|
|
|
|
|
+ if (section == null || section.hasOnlyAir() || section.fluidStateCount == 0) { // if no fluids, nothing in this section
|
|
|
|
|
+ // empty
|
|
|
|
|
+ // skip to next section
|
|
|
|
|
+ currY = (currY & ~(15)) + 15; // increment by 15: iterator loop increments by the extra one
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ net.minecraft.world.level.chunk.LevelChunkSection[] sections = chunk.getSections();
|
|
|
|
|
+ net.minecraft.world.level.chunk.PalettedContainer<BlockState> blocks = section.states;
|
|
|
|
|
+
|
|
|
|
|
+ for (int currY = minYIterate; currY < maxYIterate; ++currY) {
|
|
|
|
|
+ net.minecraft.world.level.chunk.LevelChunkSection section = sections[(currY >> 4) - minSection];
|
|
|
|
|
+ for (int currZ = minZ; currZ < maxZ; ++currZ) {
|
|
|
|
|
+ for (int currX = minX; currX < maxX; ++currX) {
|
|
|
|
|
+ FluidState fluid = blocks.get(currX & 15, currY & 15, currZ & 15).getFluidState();
|
|
|
|
|
+
|
|
|
|
|
+ if (section == null || section.hasOnlyAir() || section.fluidStateCount == 0) { // if no fluids, nothing in this section
|
|
|
|
|
+ // empty
|
|
|
|
|
+ // skip to next section
|
|
|
|
|
+ currY = (currY & ~(15)) + 15; // increment by 15: iterator loop increments by the extra one
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (fluid.is(tag)) {
|
|
|
|
|
+ blockposition_mutableblockposition.set((currChunkX << 4) + currX, currY, (currChunkZ << 4) + currZ);
|
|
|
|
|
+ double d2 = (double) ((float) currY + fluid.getHeight(this.level(), blockposition_mutableblockposition));
|
|
|
|
|
+
|
|
|
|
|
+ net.minecraft.world.level.chunk.PalettedContainer<BlockState> blocks = section.states;
|
|
|
|
|
+ if (d2 >= axisalignedbb.minY) {
|
|
|
|
|
+ flag1 = true;
|
|
|
|
|
+ d1 = Math.max(d2 - axisalignedbb.minY, d1);
|
|
|
|
|
+ if (flag) {
|
|
|
|
|
+ Vec3 vec3d1 = fluid.getFlow(this.level(), blockposition_mutableblockposition);
|
|
|
|
|
+
|
|
|
|
|
+ for (int currZ = minZ; currZ < maxZ; ++currZ) {
|
|
|
|
|
+ for (int currX = minX; currX < maxX; ++currX) {
|
|
|
|
|
+ FluidState fluid = blocks.get(currX & 15, currY & 15, currZ & 15).getFluidState();
|
|
|
|
|
|
|
|
|
|
if (fluid.is(tag)) {
|
|
|
|
|
- double d2 = (double) ((float) i2 + fluid.getHeight(this.level(), blockposition_mutableblockposition));
|
|
|
|
|
+ blockposition_mutableblockposition.set((currChunkX << 4) + currX, currY, (currChunkZ << 4) + currZ);
|
|
|
|
|
+ double d2 = (double) ((float) currY + fluid.getHeight(this.level(), blockposition_mutableblockposition));
|
|
|
|
|
|
|
|
|
|
if (d2 >= axisalignedbb.minY) {
|
|
|
|
|
flag1 = true;
|
|
|
|
|
@@ -5363,9 +5412,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
|
|
|
// CraftBukkit end
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
+ if (d1 < 0.4D) {
|
|
|
|
|
+ vec3d1 = vec3d1.scale(d1);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ vec3d = vec3d.add(vec3d1);
|
|
|
|
|
+ ++k1;
|
|
|
|
|
+ }
|
|
|
|
|
+ // CraftBukkit start - store last lava contact location
|
|
|
|
|
+ if (tag == FluidTags.LAVA) {
|
|
|
|
|
+ this.lastLavaContact = blockposition_mutableblockposition.immutable();
|
|
|
|
|
+ }
|
|
|
|
|
+ // CraftBukkit end
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
+ // Pufferfish end
|
|
|
|
|
|
|
|
|
|
if (vec3d.length() > 0.0D) {
|
|
|
|
|
if (k1 > 0) {
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ // Pufferfish end
|
|
|
|
|
+
|
|
|
|
|
+ if (vec3d.length() > 0.0D) {
|
|
|
|
|
+ if (k1 > 0) {
|
|
|
|
|
+ vec3d = vec3d.scale(1.0D / (double) k1);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!(this instanceof Player)) {
|
|
|
|
|
+ vec3d = vec3d.normalize();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Vec3 vec3d2 = this.getDeltaMovement();
|
|
|
|
|
+
|
|
|
|
|
+ vec3d = vec3d.scale(speed * 1.0D);
|
|
|
|
|
+ double d3 = 0.003D;
|
|
|
|
|
+
|
|
|
|
|
+ if (Math.abs(vec3d2.x) < 0.003D && Math.abs(vec3d2.z) < 0.003D && vec3d.length() < 0.0045000000000000005D) {
|
|
|
|
|
+ vec3d = vec3d.normalize().scale(0.0045000000000000005D);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ this.setDeltaMovement(this.getDeltaMovement().add(vec3d));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ this.fluidHeight.put(tag, d1);
|
|
|
|
|
+ return flag1;
|
|
|
|
|
+ }
|
|
|
|
|
+ //Luminol end
|
|
|
|
|
+
|
|
|
|
|
public boolean touchingUnloadedChunk() {
|
|
|
|
|
AABB axisalignedbb = this.getBoundingBox().inflate(1.0D);
|
|
|
|
|
int i = Mth.floor(axisalignedbb.minX);
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
|
|
|
|
|
index a2a5aef769ee8bb638a5a9f3da9812fa4a85dda5..7288261b8924d08e93abecb664e2273c624a325b 100644
|
|
|
|
|
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
|
|
|
|
|
|