diff --git a/leaf-server/minecraft-patches/features/0160-Optimize-applyEffectsFromBlocks-and-checkInsideBlock.patch b/leaf-server/minecraft-patches/features/0160-Optimize-applyEffectsFromBlocks-and-checkInsideBlock.patch deleted file mode 100644 index 0ac1f020..00000000 --- a/leaf-server/minecraft-patches/features/0160-Optimize-applyEffectsFromBlocks-and-checkInsideBlock.patch +++ /dev/null @@ -1,246 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Taiyou06 -Date: Wed, 9 Apr 2025 18:46:23 +0200 -Subject: [PATCH] Optimize applyEffectsFromBlocks and checkInsideBlocks - - -diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 075fcbcde23b5bb7b27ff622e8d188c3a2583973..3a791927fa33be4346f28b55325a0340445731ae 100644 ---- a/net/minecraft/world/entity/Entity.java -+++ b/net/minecraft/world/entity/Entity.java -@@ -9,6 +9,8 @@ import com.mojang.logging.LogUtils; - import it.unimi.dsi.fastutil.floats.FloatArraySet; - import it.unimi.dsi.fastutil.floats.FloatArrays; - import it.unimi.dsi.fastutil.floats.FloatSet; -+import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; - import it.unimi.dsi.fastutil.longs.LongOpenHashSet; - import it.unimi.dsi.fastutil.longs.LongSet; - import it.unimi.dsi.fastutil.objects.Object2DoubleArrayMap; -@@ -832,7 +834,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - } - - protected AABB makeBoundingBox(Vec3 position) { -- return this.dimensions.makeBoundingBox(position); -+ if (this.lastDimensions == null || this.lastDimensions.width() != this.dimensions.width() || this.lastDimensions.height() != this.dimensions.height()) { -+ this.lastDimensions = this.dimensions; -+ this.cachedBoundingBox = this.dimensions.makeBoundingBox(Vec3.ZERO); -+ } -+ -+ return this.cachedBoundingBox.move(position); - } - - protected void reapplyPosition() { -@@ -1351,33 +1358,56 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - } - - public void applyEffectsFromBlocks(Vec3 oldPosition, Vec3 position) { -- if (this.isAffectedByBlocks()) { -- if (this.onGround()) { -- BlockPos onPosLegacy = this.getOnPosLegacy(); -+ if (!this.isAffectedByBlocks()) { -+ return; -+ } -+ -+ if (this.onGround()) { -+ BlockPos onPosLegacy = this.getOnPosLegacy(); -+ if (this.cachedSupportingBlockState == null || !this.isSupportedBy(onPosLegacy)) { - BlockState blockState = this.level().getBlockState(onPosLegacy); - blockState.getBlock().stepOn(this.level(), onPosLegacy, blockState, this); -+ this.cachedSupportingBlockState = blockState; -+ } else { -+ this.cachedSupportingBlockState.getBlock().stepOn(this.level(), onPosLegacy, this.cachedSupportingBlockState, this); - } -+ } - -+ if (oldPosition.distanceToSqr(position) > 1.0E-8) { - this.movementThisTick.add(new Entity.Movement(oldPosition, position)); -- List list = List.copyOf(this.movementThisTick); -- this.movementThisTick.clear(); -- this.checkInsideBlocks(list, this.blocksInside); -- boolean flag = Iterables.any(this.blocksInside, state -> state.is(BlockTags.FIRE) || state.is(Blocks.LAVA)); -- this.blocksInside.clear(); -- if (!flag && this.isAlive()) { -- if (this.remainingFireTicks <= 0) { -- this.setRemainingFireTicks(-this.getFireImmuneTicks()); -- } -+ } - -- if (this.wasOnFire && (this.isInPowderSnow || this.isInWaterRainOrBubble())) { -- this.playEntityOnFireExtinguishedSound(); -- } -+ if (this.movementThisTick.isEmpty()) { -+ return; -+ } -+ -+ this.checkInsideBlocks(this.movementThisTick, this.blocksInside); -+ -+ boolean inFireOrLava = false; -+ for (BlockState state : this.blocksInside) { -+ if (state.is(BlockTags.FIRE) || state.is(Blocks.LAVA)) { -+ inFireOrLava = true; -+ break; - } -+ } -+ -+ this.movementThisTick.clear(); - -- if (this.isOnFire() && (this.isInPowderSnow || this.isInWaterRainOrBubble())) { -+ if (!inFireOrLava && this.isAlive()) { -+ if (this.remainingFireTicks <= 0) { - this.setRemainingFireTicks(-this.getFireImmuneTicks()); - } -+ -+ if (this.wasOnFire && (this.isInPowderSnow || this.isInWaterRainOrBubble())) { -+ this.playEntityOnFireExtinguishedSound(); -+ } - } -+ -+ if (this.isOnFire() && (this.isInPowderSnow || this.isInWaterRainOrBubble())) { -+ this.setRemainingFireTicks(-this.getFireImmuneTicks()); -+ } -+ -+ this.blocksInside.clear(); - } - - public boolean isAffectedByBlocks() { -@@ -1706,50 +1736,109 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - public void recordMovementThroughBlocks(Vec3 oldPosition, Vec3 position) { - this.movementThisTick.add(new Entity.Movement(oldPosition, position)); - } -+ private final Int2ObjectMap blockStateCache = new Int2ObjectOpenHashMap<>(16); -+ private BlockPos lastBlockPos = BlockPos.ZERO; -+ private BlockState lastBlockState = null; - - private void checkInsideBlocks(List movements, Set blocksInside) { -- if (this.isAffectedByBlocks()) { -- LongSet set = this.visitedBlocks; -+ if (!this.isAffectedByBlocks()) { -+ return; -+ } -+ -+ this.visitedBlocks.clear(); -+ this.blockStateCache.clear(); -+ -+ for (Entity.Movement movement : movements) { -+ Vec3 fromPos = movement.from(); -+ Vec3 toPos = movement.to(); - -- for (Entity.Movement movement : movements) { -- Vec3 vec3 = movement.from(); -- Vec3 vec31 = movement.to(); -- AABB aabb = this.makeBoundingBox(vec31).deflate(1.0E-5F); -+ if (fromPos.distanceToSqr(toPos) < 1.0E-8) { -+ continue; -+ } -+ -+ AABB aabb = this.makeBoundingBox(toPos).deflate(1.0E-5F); -+ -+ int minX = Mth.floor(Math.min(fromPos.x, toPos.x) - aabb.getXsize()/2); -+ int maxX = Mth.ceil(Math.max(fromPos.x, toPos.x) + aabb.getXsize()/2); -+ int minY = Mth.floor(Math.min(fromPos.y, toPos.y) - aabb.getYsize()/2); -+ int maxY = Mth.ceil(Math.max(fromPos.y, toPos.y) + aabb.getYsize()/2); -+ int minZ = Mth.floor(Math.min(fromPos.z, toPos.z) - aabb.getZsize()/2); -+ int maxZ = Mth.ceil(Math.max(fromPos.z, toPos.z) + aabb.getZsize()/2); -+ -+ int minChunkX = minX >> 4; -+ int maxChunkX = maxX >> 4; -+ int minChunkZ = minZ >> 4; -+ int maxChunkZ = maxZ >> 4; - -- for (BlockPos blockPos : BlockGetter.boxTraverseBlocks(vec3, vec31, aabb)) { -- if (!this.isAlive()) { -- return; -+ BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos(); -+ -+ for (int chunkX = minChunkX; chunkX <= maxChunkX; chunkX++) { -+ for (int chunkZ = minChunkZ; chunkZ <= maxChunkZ; chunkZ++) { -+ if (!level().hasChunkAt(chunkX, chunkZ)) { -+ continue; - } - -- BlockState blockState = this.level().getBlockState(blockPos); -- if (!blockState.isAir() && set.add(blockPos.asLong())) { -- try { -- VoxelShape entityInsideCollisionShape = blockState.getEntityInsideCollisionShape(this.level(), blockPos); -- if (entityInsideCollisionShape != Shapes.block() -- && !this.collidedWithShapeMovingFrom(vec3, vec31, blockPos, entityInsideCollisionShape)) { -- continue; -- } -+ int xStart = Math.max(minX, chunkX << 4); -+ int xEnd = Math.min(maxX, (chunkX << 4) + 15); -+ int zStart = Math.max(minZ, chunkZ << 4); -+ int zEnd = Math.min(maxZ, (chunkZ << 4) + 15); - -- blockState.entityInside(this.level(), blockPos, this); -- this.onInsideBlock(blockState); -- } catch (Throwable var16) { -- CrashReport crashReport = CrashReport.forThrowable(var16, "Colliding entity with block"); -- CrashReportCategory crashReportCategory = crashReport.addCategory("Block being collided with"); -- CrashReportCategory.populateBlockDetails(crashReportCategory, this.level(), blockPos, blockState); -- CrashReportCategory crashReportCategory1 = crashReport.addCategory("Entity being checked for collision"); -- this.fillCrashReportCategory(crashReportCategory1); -- throw new ReportedException(crashReport); -- } -+ for (int x = xStart; x <= xEnd; x++) { -+ for (int z = zStart; z <= zEnd; z++) { -+ for (int y = minY; y <= maxY; y++) { -+ if (!this.isAlive()) { -+ return; -+ } -+ -+ mutablePos.set(x, y, z); -+ long posLong = mutablePos.asLong(); -+ -+ if (!this.visitedBlocks.add(posLong)) { -+ continue; -+ } - -- blocksInside.add(blockState); -+ BlockState blockState; -+ if (mutablePos.equals(this.lastBlockPos)) { -+ blockState = this.lastBlockState; -+ } else { -+ blockState = this.level().getBlockState(mutablePos); -+ this.lastBlockPos = mutablePos.immutable(); -+ this.lastBlockState = blockState; -+ } -+ -+ if (blockState.isAir()) { -+ continue; -+ } -+ -+ try { -+ VoxelShape entityInsideCollisionShape = blockState.getEntityInsideCollisionShape(this.level(), mutablePos); -+ if (entityInsideCollisionShape != Shapes.block() && -+ !this.collidedWithShapeMovingFrom(fromPos, toPos, mutablePos, entityInsideCollisionShape)) { -+ continue; -+ } -+ -+ blockState.entityInside(this.level(), mutablePos, this); -+ this.onInsideBlock(blockState); -+ blocksInside.add(blockState); -+ } catch (Throwable var16) { -+ CrashReport crashReport = CrashReport.forThrowable(var16, "Colliding entity with block"); -+ CrashReportCategory crashReportCategory = crashReport.addCategory("Block being collided with"); -+ CrashReportCategory.populateBlockDetails(crashReportCategory, this.level(), mutablePos, blockState); -+ CrashReportCategory crashReportCategory1 = crashReport.addCategory("Entity being checked for collision"); -+ this.fillCrashReportCategory(crashReportCategory1); -+ throw new ReportedException(crashReport); -+ } -+ } -+ } - } - } - } -- -- set.clear(); - } - } - -+ private EntityDimensions lastDimensions = null; -+ private AABB cachedBoundingBox = null; -+ - private boolean collidedWithShapeMovingFrom(Vec3 oldPosition, Vec3 position, BlockPos pos, VoxelShape shape) { - AABB aabb = this.makeBoundingBox(oldPosition); - Vec3 vec3 = position.subtract(oldPosition);