From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Thu, 5 Sep 2024 16:23:04 -0700 Subject: [PATCH] Moonrise: Avoid streams for block retrieval in Entity#move Original license: GPLv3 Original project: https://github.com/Tuinity/Moonrise https://github.com/Tuinity/Moonrise/commit/f9c99d1e32614666913bc614d019dd86e2a0b2e5 This is Dreeam's tiny modified version, should be around 1~2+ times faster. Avoid streams for retrieving blocks diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java index db0133b8e5e4e26d3f5ca48f87d6d49f8cff0532..08a3714c530fb375ee729e91965c65efb9e6e3d2 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -1337,9 +1337,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } } // Gale end - skip negligible planar movement multiplication - if (this.level().getBlockStatesIfLoaded(this.getBoundingBox().deflate(1.0E-6D)).noneMatch((iblockdata2) -> { - return iblockdata2.is(BlockTags.FIRE) || iblockdata2.is(Blocks.LAVA); - })) { + if (noLavaAndFireNearEntityByRange(this.getBoundingBox().deflate(1.0E-6D))) { // Moonrise - Avoid streams for block retrieval in Entity#move if (this.remainingFireTicks <= 0) { this.setRemainingFireTicks(-this.getFireImmuneTicks()); } @@ -1363,6 +1361,78 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess // Paper end - detailed watchdog information } + // Moonrise start - Avoid streams for block retrieval in Entity#move + private boolean noLavaAndFireNearEntityByRange(final AABB boundingBox) { + final int minBlockX = Mth.floor(boundingBox.minX); + final int minBlockY = Mth.floor(boundingBox.minY); + final int minBlockZ = Mth.floor(boundingBox.minZ); + + final int maxBlockX = Mth.floor(boundingBox.maxX); + final int maxBlockY = Mth.floor(boundingBox.maxY); + final int maxBlockZ = Mth.floor(boundingBox.maxZ); + + final int minChunkX = minBlockX >> 4; + final int minChunkY = minBlockY >> 4; + final int minChunkZ = minBlockZ >> 4; + + final int maxChunkX = maxBlockX >> 4; + final int maxChunkY = maxBlockY >> 4; + final int maxChunkZ = maxBlockZ >> 4; + + final Level world = this.level(); + + final int minSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(world); + final net.minecraft.world.level.chunk.ChunkSource chunkSource = world.getChunkSource(); + + for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) { + for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) { + final net.minecraft.world.level.chunk.ChunkAccess chunk = chunkSource.getChunk(currChunkX, currChunkZ, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, false); + + if (chunk == null) { + continue; + } + + final net.minecraft.world.level.chunk.LevelChunkSection[] sections = chunk.getSections(); + + for (int currChunkY = minChunkY; currChunkY <= maxChunkY; ++currChunkY) { + final int sectionIdx = currChunkY - minSection; + if (sectionIdx < 0 || sectionIdx >= sections.length) { + continue; + } + final net.minecraft.world.level.chunk.LevelChunkSection section = sections[sectionIdx]; + if (section.hasOnlyAir()) { + // empty + continue; + } + + final net.minecraft.world.level.chunk.PalettedContainer blocks = section.states; + + final int minXIterate = currChunkX == minChunkX ? (minBlockX & 15) : 0; + final int maxXIterate = currChunkX == maxChunkX ? (maxBlockX & 15) : 15; + final int minZIterate = currChunkZ == minChunkZ ? (minBlockZ & 15) : 0; + final int maxZIterate = currChunkZ == maxChunkZ ? (maxBlockZ & 15) : 15; + final int minYIterate = currChunkY == minChunkY ? (minBlockY & 15) : 0; + final int maxYIterate = currChunkY == maxChunkY ? (maxBlockY & 15) : 15; + + for (int currY = minYIterate; currY <= maxYIterate; ++currY) { + for (int currZ = minZIterate; currZ <= maxZIterate; ++currZ) { + for (int currX = minXIterate; currX <= maxXIterate; ++currX) { + final BlockState blockState = blocks.get((currX) | (currZ << 4) | ((currY) << 8)); + + if (blockState.is(Blocks.LAVA) || blockState.is(BlockTags.FIRE)) { + return false; + } + } + } + } + } + } + } + + return true; + } + // Moonrise end - Avoid streams for block retrieval in Entity#move + private boolean isStateClimbable(BlockState state) { return state.is(BlockTags.CLIMBABLE) || state.is(Blocks.POWDER_SNOW); }