From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: JellySquid Date: Mon, 11 May 2020 22:56:27 +0200 Subject: [PATCH] lithium MixinLandPathNodeMaker Original code by JellySquid, licensed under GNU Lesser General Public License v3.0 you can find the original code on https://github.com/jellysquid3/lithium-fabric/tree/1.16.x/fabric (Yarn mappings) diff --git a/src/main/java/net/minecraft/server/PathfinderNormal.java b/src/main/java/net/minecraft/server/PathfinderNormal.java index ec55785af2b432b692d3a3bf4298ffb32489bf3b..4f59e4b31300009f5e7ef8767be6c89d7b449af0 100644 --- a/src/main/java/net/minecraft/server/PathfinderNormal.java +++ b/src/main/java/net/minecraft/server/PathfinderNormal.java @@ -10,6 +10,11 @@ import javax.annotation.Nullable; public class PathfinderNormal extends PathfinderAbstract { + // Yatopia start - this is not thread safe! + private static final it.unimi.dsi.fastutil.objects.Reference2ReferenceMap commonTypes = + new it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<>(); + // Yatopia end + protected float j; private final Long2ObjectMap k = new Long2ObjectOpenHashMap(); private final Object2BooleanMap l = new Object2BooleanOpenHashMap(); @@ -508,13 +513,44 @@ public class PathfinderNormal extends PathfinderAbstract { protected static PathType b(IBlockAccess iblockaccess, BlockPosition blockposition) { IBlockData iblockdata = iblockaccess.getTypeIfLoaded(blockposition); // Paper if (iblockdata == null) return PathType.BLOCKED; // Paper - Block block = iblockdata.getBlock(); - Material material = iblockdata.getMaterial(); + // Check early if the block is air as it will always be open regardless of other conditions + if(iblockdata.isAir())return PathType.OPEN; + + // Get the cached type for this block state + PathType type = commonTypes.get(iblockdata); + + // No result has been cached for this block state yet, so calculate and cache it + if (type == null) { + commonTypes.put(iblockdata, type = getPathType(iblockaccess, blockposition, iblockdata)); + } + // If the node type is open, it means that we were unable to determine a more specific type, so we need + // to check the fallback path. + if (type == PathType.OPEN) { + // This is only ever called in vanilla after all other possibilities are exhausted, but before fluid checks + // It should be safe to perform it last in actuality and take advantage of the cache for fluid types as well + // since fluids will always pass this check. + if (!iblockdata.a(iblockaccess, blockposition, PathMode.LAND)) { + return PathType.BLOCKED; + } - if (iblockdata.isAir()) { + // All checks succeed, this path node really is open! return PathType.OPEN; - } else if (!iblockdata.a((Tag) TagsBlock.TRAPDOORS) && !iblockdata.a(Blocks.LILY_PAD)) { - if (iblockdata.a(Blocks.CACTUS)) { + } + + // Return the cached value since we found an obstacle earlier + return type; + + } + + private static PathType getPathType(IBlockAccess iblockaccess, BlockPosition blockposition, + IBlockData iblockdata) { + Block block = iblockdata.getBlock(); + Material material = iblockdata.getMaterial(); + + if (!block.a(TagsBlock.TRAPDOORS) && block != Blocks.LILY_PAD) { + if (block == Blocks.FIRE) { + return PathType.DAMAGE_FIRE; + } else if (block == Blocks.CACTUS) { return PathType.DAMAGE_CACTUS; } else if (iblockdata.a(Blocks.SWEET_BERRY_BUSH)) { return PathType.DAMAGE_OTHER; @@ -540,7 +576,10 @@ public class PathfinderNormal extends PathfinderAbstract { } else { Fluid fluid = iblockdata.getFluid(); // Tuinity - remove another getType call - return fluid.a((Tag) TagsFluid.WATER) ? PathType.WATER : (fluid.a((Tag) TagsFluid.LAVA) ? PathType.LAVA : PathType.OPEN); + if(fluid.a(TagsFluid.WATER))return PathType.WATER; + if(fluid.a(TagsFluid.LAVA))return PathType.LAVA; + + return PathType.OPEN; } } else { return PathType.FENCE;