diff --git a/README.md b/README.md index 9a5f39b4..7667b812 100644 --- a/README.md +++ b/README.md @@ -113,6 +113,7 @@ If these excellent projects hadn't appeared, Leaf wouldn't have become great. • Matter
Luminol
Nitori
+ • Moonrise

diff --git a/patches/server/0064-Moonrise-Avoid-streams-for-block-retrieval-in-Entity.patch b/patches/server/0064-Moonrise-Avoid-streams-for-block-retrieval-in-Entity.patch new file mode 100644 index 00000000..2246545a --- /dev/null +++ b/patches/server/0064-Moonrise-Avoid-streams-for-block-retrieval-in-Entity.patch @@ -0,0 +1,118 @@ +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 + +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 085925162f5099609c9b82ca0103d8dd5d2cb22d..1ca8c17df3f0bf6cca8831145c3282834f20a6b5 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,90 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + // Paper end - detailed watchdog information + } + ++ // Leaf start - Optimize check nearby fire or lava on entity move ++ private boolean nearByBlockStateNoneMatch(java.util.List into, Predicate predicate) { ++ if (into.isEmpty()) return true; ++ ++ for (BlockState iblockdata : into) { ++ if (predicate.test(iblockdata)) { ++ return false; ++ } ++ } ++ ++ return true; ++ } ++ // Leaf end - Optimize check nearby fire or lava on entity move ++ ++ // 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(); ++ ++ if (!((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel) world).moonrise$areChunksLoaded(minChunkX, minChunkZ, maxChunkX, maxChunkZ)) { ++ return true; ++ } ++ ++ 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.LevelChunkSection[] sections = chunkSource.getChunk(currChunkX, currChunkZ, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, false).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); + }