From 8e023eacfdd1e21704c90386c3874ccfff9ed841 Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Thu, 10 Nov 2022 00:31:14 -0600 Subject: [PATCH 01/17] Fixed flight pathing, merged with some 1.7.10 code. --- .../npcs/ai/pathfinder/FlyPathFinder.java | 328 +++++++++++------- .../npcs/entity/EntityNPCInterface.java | 2 +- 2 files changed, 212 insertions(+), 118 deletions(-) diff --git a/src/main/java/noppes/npcs/ai/pathfinder/FlyPathFinder.java b/src/main/java/noppes/npcs/ai/pathfinder/FlyPathFinder.java index 121d2d5c6..16f268c64 100644 --- a/src/main/java/noppes/npcs/ai/pathfinder/FlyPathFinder.java +++ b/src/main/java/noppes/npcs/ai/pathfinder/FlyPathFinder.java @@ -8,6 +8,7 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.init.Blocks; import net.minecraft.pathfinding.PathFinder; +import net.minecraft.pathfinding.PathPoint; import net.minecraft.util.MathHelper; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.IntHashMap; @@ -33,11 +34,22 @@ public class FlyPathFinder extends PathFinder private Entity theEntity; private final Map mapPathPriority = Maps.newEnumMap(PathNodeType.class); + + private boolean isPathingInWater; + private boolean isMovementBlockAllowed; + private boolean isWoodenDoorAllowed; + private boolean canEntityDrown; + public FlyPathFinder(IBlockAccess _worldMap, boolean doorsAllowed, boolean closedDoors, boolean canPathWater, boolean canDrown, Entity entityIn) { super(_worldMap,doorsAllowed,closedDoors,canPathWater,canDrown); this.theEntity = entityIn; this.worldMap = _worldMap; + + this.isWoodenDoorAllowed = doorsAllowed; + this.isMovementBlockAllowed = closedDoors; + this.isPathingInWater = canPathWater; + this.canEntityDrown = canDrown; } /** @@ -66,7 +78,8 @@ public class FlyPathFinder extends PathFinder this.pointMap.clearMap(); NPCPathPoint pathpoint = this.getStart(); NPCPathPoint pathpoint1 = this.getPathPointToCoords(entityIn, x, y, z); - NPCPath pathentity = addToPath(entityIn, pathpoint, pathpoint1, distance); + NPCPathPoint pathPoint2 = new NPCPathPoint((int)Math.ceil(entityIn.width),(int)Math.ceil(entityIn.height),(int)Math.ceil(entityIn.width)); + NPCPath pathentity = addToPath(entityIn, pathpoint, pathpoint1, pathPoint2, distance); return pathentity; } @@ -107,93 +120,78 @@ public class FlyPathFinder extends PathFinder if (this.getPathPriority(pathnodetype) >= 0.0F) { - return openPoint(blockpos.getX(), blockpos.getY(), blockpos.getZ(), 0); + return openPoint(blockpos.getX(), blockpos.getY(), blockpos.getZ()); } } } - return openPoint(blockpos1.getX(), i, blockpos1.getZ(), 0); + return openPoint(blockpos1.getX(), i, blockpos1.getZ()); } public NPCPathPoint getPathPointToCoords(Entity entityIn, double x, double y, double z) { - return openPoint(MathHelper.floor_double(x), MathHelper.floor_double(y), MathHelper.floor_double(z), 0); + return openPoint(MathHelper.floor_double(x), MathHelper.floor_double(y), MathHelper.floor_double(z)); } - /** - * Adds a path from start to end and returns the whole path (args: unused, start, end, unused, maxDistance) - */ - private NPCPath addToPath(Entity entityIn, NPCPathPoint pathFrom, NPCPathPoint pathTo, float maxDistance) + private NPCPath addToPath(Entity p_75861_1_, NPCPathPoint p_75861_2_, NPCPathPoint p_75861_3_, NPCPathPoint p_75861_4_, float p_75861_5_) { - pathFrom.totalPathDistance = 0.0F; - pathFrom.distanceToNext = pathFrom.distanceManhattan(pathTo); - pathFrom.distanceToTarget = pathFrom.distanceToNext; + p_75861_2_.totalPathDistance = 0.0F; + p_75861_2_.distanceToNext = p_75861_2_.distanceToSquared(p_75861_3_); + p_75861_2_.distanceToTarget = p_75861_2_.distanceToNext; this.path.clearPath(); - this.path.addPoint(pathFrom); - NPCPathPoint pathpoint = pathFrom; - int i = 0; + this.path.addPoint(p_75861_2_); + NPCPathPoint pathpoint3 = p_75861_2_; while (!this.path.isPathEmpty()) { - ++i; + NPCPathPoint pathpoint4 = this.path.dequeue(); - if (i >= 200) + if (pathpoint4.equals(p_75861_3_)) { - break; + return this.createEntityPath(p_75861_2_, p_75861_3_); } - NPCPathPoint pathpoint1 = this.path.dequeue(); - - if (pathpoint1.equals(pathTo)) + if (pathpoint4.distanceToSquared(p_75861_3_) < pathpoint3.distanceToSquared(p_75861_3_)) { - pathpoint = pathTo; - break; + pathpoint3 = pathpoint4; } - if (pathpoint1.distanceManhattan(pathTo) < pathpoint.distanceManhattan(pathTo)) + pathpoint4.isFirst = true; + int i = this.findPathOptions(p_75861_1_, pathpoint4, p_75861_4_, p_75861_3_, p_75861_5_); + + for (int j = 0; j < i; ++j) { - pathpoint = pathpoint1; - } + NPCPathPoint pathpoint5 = this.pathOptions[j]; + float f1 = pathpoint4.totalPathDistance + pathpoint4.distanceToSquared(pathpoint5); - pathpoint1.isFirst = true; - int j = this.findPathOptions(this.pathOptions, entityIn, pathpoint1, pathTo, maxDistance); - - for (int k = 0; k < j; ++k) - { - NPCPathPoint pathpoint2 = this.pathOptions[k]; - float f = pathpoint1.distanceManhattan(pathpoint2); - pathpoint2.distanceFromOrigin = pathpoint1.distanceFromOrigin + f; - pathpoint2.cost = f + pathpoint2.costMalus; - float f1 = pathpoint1.totalPathDistance + pathpoint2.cost; - - if (pathpoint2.distanceFromOrigin < maxDistance && (!pathpoint2.isAssigned() || f1 < pathpoint2.totalPathDistance)) + if (!pathpoint5.isAssigned() || f1 < pathpoint5.totalPathDistance) { - pathpoint2.previous = pathpoint1; - pathpoint2.totalPathDistance = f1; - pathpoint2.distanceToNext = pathpoint2.distanceManhattan(pathTo) + pathpoint2.costMalus; + pathpoint5.previous = pathpoint4; + pathpoint5.totalPathDistance = f1; + pathpoint5.distanceToNext = pathpoint5.distanceToSquared(p_75861_3_); - if (pathpoint2.isAssigned()) + if (pathpoint5.isAssigned()) { - this.path.changeDistance(pathpoint2, pathpoint2.totalPathDistance + pathpoint2.distanceToNext); + this.path.changeDistance(pathpoint5, pathpoint5.totalPathDistance + pathpoint5.distanceToNext); } else { - pathpoint2.distanceToTarget = pathpoint2.totalPathDistance + pathpoint2.distanceToNext; - this.path.addPoint(pathpoint2); + pathpoint5.distanceToTarget = pathpoint5.totalPathDistance + pathpoint5.distanceToNext; + this.path.addPoint(pathpoint5); } } } } - if (pathpoint == pathFrom) + if (pathpoint3 == p_75861_2_) { return null; } else { - return this.createEntityPath(pathFrom, pathpoint); + return this.createEntityPath(p_75861_2_, pathpoint3); } } @@ -201,56 +199,62 @@ public class FlyPathFinder extends PathFinder * populates pathOptions with available points and returns the number of options found (args: unused1, currentPoint, * unused2, targetPoint, maxDistance) */ - public int findPathOptions(NPCPathPoint[] pathOptions, Entity entityIn, NPCPathPoint currentPoint, NPCPathPoint targetPoint, float maxDistance) + private int findPathOptions(Entity p_75860_1_, NPCPathPoint p_75860_2_, NPCPathPoint p_75860_3_, NPCPathPoint targetPoint, float maxDistance) { int i = 0; - NPCPathPoint pathpoint = this.openPoint(currentPoint.xCoord, currentPoint.yCoord, currentPoint.zCoord + 1); - NPCPathPoint pathpoint1 = this.openPoint(currentPoint.xCoord - 1, currentPoint.yCoord, currentPoint.zCoord); - NPCPathPoint pathpoint2 = this.openPoint(currentPoint.xCoord + 1, currentPoint.yCoord, currentPoint.zCoord); - NPCPathPoint pathpoint3 = this.openPoint(currentPoint.xCoord, currentPoint.yCoord, currentPoint.zCoord - 1); - NPCPathPoint pathpoint4 = this.openPoint(currentPoint.xCoord, currentPoint.yCoord + 1, currentPoint.zCoord); - NPCPathPoint pathpoint5 = this.openPoint(currentPoint.xCoord, currentPoint.yCoord - 1, currentPoint.zCoord); + byte b0 = 0; - if (pathpoint != null && !pathpoint.isFirst && pathpoint.distanceTo(targetPoint) < maxDistance) + /*if (this.getVerticalOffset(p_75860_1_, p_75860_2_.xCoord, p_75860_2_.yCoord + 1, p_75860_2_.zCoord, p_75860_3_) == 1) { + b0 = 1; + }*/ + + NPCPathPoint pathpoint0 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord, p_75860_2_.yCoord, p_75860_2_.zCoord + 1, p_75860_3_, b0); + NPCPathPoint pathpoint1 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord - 1, p_75860_2_.yCoord, p_75860_2_.zCoord, p_75860_3_, b0); + NPCPathPoint pathpoint2 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord + 1, p_75860_2_.yCoord, p_75860_2_.zCoord, p_75860_3_, b0); + NPCPathPoint pathpoint3 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord, p_75860_2_.yCoord, p_75860_2_.zCoord - 1, p_75860_3_, b0); + NPCPathPoint pathpoint4 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord, p_75860_2_.yCoord + 1, p_75860_2_.zCoord, p_75860_3_, b0); + NPCPathPoint pathpoint5 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord, p_75860_2_.yCoord - 1, p_75860_2_.zCoord, p_75860_3_, b0); + + if (pathpoint0 != null && !pathpoint0.isFirst && pathpoint0.distanceTo(targetPoint) < maxDistance) { - pathOptions[i++] = pathpoint; + this.pathOptions[i++] = pathpoint0; } if (pathpoint1 != null && !pathpoint1.isFirst && pathpoint1.distanceTo(targetPoint) < maxDistance) { - pathOptions[i++] = pathpoint1; + this.pathOptions[i++] = pathpoint1; } if (pathpoint2 != null && !pathpoint2.isFirst && pathpoint2.distanceTo(targetPoint) < maxDistance) { - pathOptions[i++] = pathpoint2; + this.pathOptions[i++] = pathpoint2; } if (pathpoint3 != null && !pathpoint3.isFirst && pathpoint3.distanceTo(targetPoint) < maxDistance) { - pathOptions[i++] = pathpoint3; + this.pathOptions[i++] = pathpoint3; } if (pathpoint4 != null && !pathpoint4.isFirst && pathpoint4.distanceTo(targetPoint) < maxDistance) { - pathOptions[i++] = pathpoint4; + this.pathOptions[i++] = pathpoint4; } if (pathpoint5 != null && !pathpoint5.isFirst && pathpoint5.distanceTo(targetPoint) < maxDistance) { - pathOptions[i++] = pathpoint5; + this.pathOptions[i++] = pathpoint5; } - boolean flag = pathpoint3 != null && pathpoint3.costMalus != 0.0F; - boolean flag1 = pathpoint != null && pathpoint.costMalus != 0.0F; - boolean flag2 = pathpoint2 != null && pathpoint2.costMalus != 0.0F; - boolean flag3 = pathpoint1 != null && pathpoint1.costMalus != 0.0F; - boolean flag4 = pathpoint4 != null && pathpoint4.costMalus != 0.0F; - boolean flag5 = pathpoint5 != null && pathpoint5.costMalus != 0.0F; + boolean flag = pathpoint3 != null;// && pathpoint3.costMalus != 0.0F; + boolean flag1 = pathpoint0 != null;// && pathpoint0.costMalus != 0.0F; + boolean flag2 = pathpoint2 != null;// && pathpoint2.costMalus != 0.0F; + boolean flag3 = pathpoint1 != null;// && pathpoint1.costMalus != 0.0F; + boolean flag4 = pathpoint4 != null;// && pathpoint4.costMalus != 0.0F; + boolean flag5 = pathpoint5 != null;// && pathpoint5.costMalus != 0.0F; if (flag && flag3) { - NPCPathPoint pathpoint6 = this.openPoint(currentPoint.xCoord - 1, currentPoint.yCoord, currentPoint.zCoord - 1); + NPCPathPoint pathpoint6 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord - 1, p_75860_2_.yCoord, p_75860_2_.zCoord - 1, p_75860_3_, b0); if (pathpoint6 != null && !pathpoint6.isFirst && pathpoint6.distanceTo(targetPoint) < maxDistance) { @@ -260,141 +264,231 @@ public class FlyPathFinder extends PathFinder if (flag && flag2) { - NPCPathPoint pathpoint7 = this.openPoint(currentPoint.xCoord + 1, currentPoint.yCoord, currentPoint.zCoord - 1); + NPCPathPoint pathpoint6 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord + 1, p_75860_2_.yCoord, p_75860_2_.zCoord - 1, p_75860_3_, b0); - if (pathpoint7 != null && !pathpoint7.isFirst && pathpoint7.distanceTo(targetPoint) < maxDistance) + if (pathpoint6 != null && !pathpoint6.isFirst && pathpoint6.distanceTo(targetPoint) < maxDistance) { - pathOptions[i++] = pathpoint7; + pathOptions[i++] = pathpoint6; } } if (flag1 && flag3) { - NPCPathPoint pathpoint8 = this.openPoint(currentPoint.xCoord - 1, currentPoint.yCoord, currentPoint.zCoord + 1); + NPCPathPoint pathpoint6 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord - 1, p_75860_2_.yCoord, p_75860_2_.zCoord + 1, p_75860_3_, b0); - if (pathpoint8 != null && !pathpoint8.isFirst && pathpoint8.distanceTo(targetPoint) < maxDistance) + if (pathpoint6 != null && !pathpoint6.isFirst && pathpoint6.distanceTo(targetPoint) < maxDistance) { - pathOptions[i++] = pathpoint8; + pathOptions[i++] = pathpoint6; } } if (flag1 && flag2) { - NPCPathPoint pathpoint9 = this.openPoint(currentPoint.xCoord + 1, currentPoint.yCoord, currentPoint.zCoord + 1); + NPCPathPoint pathpoint6 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord + 1, p_75860_2_.yCoord, p_75860_2_.zCoord + 1, p_75860_3_, b0); - if (pathpoint9 != null && !pathpoint9.isFirst && pathpoint9.distanceTo(targetPoint) < maxDistance) + if (pathpoint6 != null && !pathpoint6.isFirst && pathpoint6.distanceTo(targetPoint) < maxDistance) { - pathOptions[i++] = pathpoint9; + pathOptions[i++] = pathpoint6; } } if (flag && flag4) { - NPCPathPoint pathpoint10 = this.openPoint(currentPoint.xCoord, currentPoint.yCoord + 1, currentPoint.zCoord - 1); + NPCPathPoint pathpoint6 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord, p_75860_2_.yCoord + 1, p_75860_2_.zCoord - 1, p_75860_3_, b0); - if (pathpoint10 != null && !pathpoint10.isFirst && pathpoint10.distanceTo(targetPoint) < maxDistance) + if (pathpoint6 != null && !pathpoint6.isFirst && pathpoint6.distanceTo(targetPoint) < maxDistance) { - pathOptions[i++] = pathpoint10; + pathOptions[i++] = pathpoint6; } } if (flag1 && flag4) { - NPCPathPoint pathpoint11 = this.openPoint(currentPoint.xCoord, currentPoint.yCoord + 1, currentPoint.zCoord + 1); + NPCPathPoint pathpoint6 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord, p_75860_2_.yCoord + 1, p_75860_2_.zCoord + 1, p_75860_3_, b0); - if (pathpoint11 != null && !pathpoint11.isFirst && pathpoint11.distanceTo(targetPoint) < maxDistance) + if (pathpoint6 != null && !pathpoint6.isFirst && pathpoint6.distanceTo(targetPoint) < maxDistance) { - pathOptions[i++] = pathpoint11; + pathOptions[i++] = pathpoint6; } } if (flag2 && flag4) { - NPCPathPoint pathpoint12 = this.openPoint(currentPoint.xCoord + 1, currentPoint.yCoord + 1, currentPoint.zCoord); + NPCPathPoint pathpoint6 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord + 1, p_75860_2_.yCoord + 1, p_75860_2_.zCoord, p_75860_3_, b0); - if (pathpoint12 != null && !pathpoint12.isFirst && pathpoint12.distanceTo(targetPoint) < maxDistance) + if (pathpoint6 != null && !pathpoint6.isFirst && pathpoint6.distanceTo(targetPoint) < maxDistance) { - pathOptions[i++] = pathpoint12; + pathOptions[i++] = pathpoint6; } } if (flag3 && flag4) { - NPCPathPoint pathpoint13 = this.openPoint(currentPoint.xCoord - 1, currentPoint.yCoord + 1, currentPoint.zCoord); + NPCPathPoint pathpoint6 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord - 1, p_75860_2_.yCoord + 1, p_75860_2_.zCoord, p_75860_3_, b0); - if (pathpoint13 != null && !pathpoint13.isFirst && pathpoint13.distanceTo(targetPoint) < maxDistance) + if (pathpoint6 != null && !pathpoint6.isFirst && pathpoint6.distanceTo(targetPoint) < maxDistance) { - pathOptions[i++] = pathpoint13; + pathOptions[i++] = pathpoint6; } } if (flag && flag5) { - NPCPathPoint pathpoint14 = this.openPoint(currentPoint.xCoord, currentPoint.yCoord - 1, currentPoint.zCoord - 1); + NPCPathPoint pathpoint6 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord, p_75860_2_.yCoord - 1, p_75860_2_.zCoord - 1, p_75860_3_, b0); - if (pathpoint14 != null && !pathpoint14.isFirst && pathpoint14.distanceTo(targetPoint) < maxDistance) + if (pathpoint6 != null && !pathpoint6.isFirst && pathpoint6.distanceTo(targetPoint) < maxDistance) { - pathOptions[i++] = pathpoint14; + pathOptions[i++] = pathpoint6; } } if (flag1 && flag5) { - NPCPathPoint pathpoint15 = this.openPoint(currentPoint.xCoord, currentPoint.yCoord - 1, currentPoint.zCoord + 1); + NPCPathPoint pathpoint6 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord, p_75860_2_.yCoord - 1, p_75860_2_.zCoord + 1, p_75860_3_, b0); - if (pathpoint15 != null && !pathpoint15.isFirst && pathpoint15.distanceTo(targetPoint) < maxDistance) + if (pathpoint6 != null && !pathpoint6.isFirst && pathpoint6.distanceTo(targetPoint) < maxDistance) { - pathOptions[i++] = pathpoint15; + pathOptions[i++] = pathpoint6; } } if (flag2 && flag5) { - NPCPathPoint pathpoint16 = this.openPoint(currentPoint.xCoord + 1, currentPoint.yCoord - 1, currentPoint.zCoord); + NPCPathPoint pathpoint6 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord + 1, p_75860_2_.yCoord - 1, p_75860_2_.zCoord, p_75860_3_, b0); - if (pathpoint16 != null && !pathpoint16.isFirst && pathpoint16.distanceTo(targetPoint) < maxDistance) + if (pathpoint6 != null && !pathpoint6.isFirst && pathpoint6.distanceTo(targetPoint) < maxDistance) { - pathOptions[i++] = pathpoint16; + pathOptions[i++] = pathpoint6; } } if (flag3 && flag5) { - NPCPathPoint pathpoint17 = this.openPoint(currentPoint.xCoord - 1, currentPoint.yCoord - 1, currentPoint.zCoord); + NPCPathPoint pathpoint6 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord - 1, p_75860_2_.yCoord - 1, p_75860_2_.zCoord, p_75860_3_, b0); - if (pathpoint17 != null && !pathpoint17.isFirst && pathpoint17.distanceTo(targetPoint) < maxDistance) + if (pathpoint6 != null && !pathpoint6.isFirst && pathpoint6.distanceTo(targetPoint) < maxDistance) { - pathOptions[i++] = pathpoint17; + pathOptions[i++] = pathpoint6; } } return i; } - @Nullable - protected NPCPathPoint openPoint(int x, int y, int z) + private NPCPathPoint getSafePoint(Entity p_75858_1_, int p_75858_2_, int p_75858_3_, int p_75858_4_, NPCPathPoint p_75858_5_, int p_75858_6_) { - NPCPathPoint pathpoint = null; - BlockPos blockPos = new BlockPos(x, y, z); - PathNodeType pathnodetype = this.getPathNodeType((EntityLiving) this.theEntity, blockPos); - float f = getPathPriority(pathnodetype); + NPCPathPoint pathpoint1 = null; + int i1 = this.getVerticalOffset(p_75858_1_, p_75858_2_, p_75858_3_, p_75858_4_, p_75858_5_); - if (f >= 0.0F) + if (i1 == 2) { - pathpoint = this.openPoint(x, y, z, 0); - pathpoint.nodeType = pathnodetype; - pathpoint.costMalus = Math.max(pathpoint.costMalus, f); - - if (pathnodetype == PathNodeType.WALKABLE) - { - ++pathpoint.costMalus; - } + return this.openPoint(p_75858_2_, p_75858_3_, p_75858_4_); } + else + { + if (i1 == 1) + { + pathpoint1 = this.openPoint(p_75858_2_, p_75858_3_, p_75858_4_); + } - return pathnodetype != PathNodeType.OPEN && pathnodetype != PathNodeType.WALKABLE ? pathpoint : pathpoint; + if (pathpoint1 == null && p_75858_6_ > 0 && i1 != -3 && i1 != -4 && this.getVerticalOffset(p_75858_1_, p_75858_2_, p_75858_3_ + p_75858_6_, p_75858_4_, p_75858_5_) == 1) + { + pathpoint1 = this.openPoint(p_75858_2_, p_75858_3_ + p_75858_6_, p_75858_4_); + p_75858_3_ += p_75858_6_; + } + + if (pathpoint1 != null) + { + int j1 = 0; + int k1 = 0; + + while (p_75858_3_ > 0) + { + k1 = this.getVerticalOffset(p_75858_1_, p_75858_2_, p_75858_3_ - 1, p_75858_4_, p_75858_5_); + + if (this.isPathingInWater && k1 == -1) + { + return null; + } + + if (k1 != 1) + { + break; + } + + if (j1++ >= p_75858_1_.getMaxSafePointTries()) + { + return null; + } + + --p_75858_3_; + + if (p_75858_3_ > 0) + { + pathpoint1 = this.openPoint(p_75858_2_, p_75858_3_, p_75858_4_); + } + } + + if (k1 == -2) + { + return null; + } + } + + return pathpoint1; + } } - protected NPCPathPoint openPoint(int x, int y, int z, int b) + public int getVerticalOffset(Entity entity, int x, int y, int z, PathPoint pathEndpoint) + { + return getVerticalOffset(entity, x, y, z, pathEndpoint, this.isPathingInWater, this.isMovementBlockAllowed, this.isWoodenDoorAllowed); + } + + private int getVerticalOffset(Entity entity, int x, int y, int z, PathPoint pathEndpoint, boolean isPathingInWater, boolean isMovementBlockAllowed, boolean isWoodenDoorAllowed) + { + PathNodeType pathnodetype = this.getPathNodeType((EntityLiving) entity, new BlockPos(x,y,z)); + + switch (pathnodetype) { + case BLOCKED: + return 0; + case OPEN: + return 2; + case WALKABLE: + return 1; + case TRAPDOOR: + return -4; + case FENCE: + return -3; + case LAVA: + return -2; + case WATER: + return -1; + case RAIL: + return 2; + case DANGER_FIRE: + return -1; + case DAMAGE_FIRE: + return -2; + case DANGER_CACTUS: + return -1; + case DAMAGE_CACTUS: + return -2; + case DANGER_OTHER: + return -1; + case DAMAGE_OTHER: + return -2; + case DOOR_OPEN: + return 1; + case DOOR_WOOD_CLOSED: + return 0; + case DOOR_IRON_CLOSED: + return 0; + } + + return 1; + } + + protected NPCPathPoint openPoint(int x, int y, int z) { int i = NPCPathPoint.makeHash(x, y, z); NPCPathPoint pathpoint = this.pointMap.lookup(i); diff --git a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java index 121d9f607..9aa74cd08 100644 --- a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java +++ b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java @@ -220,7 +220,7 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti public int getMaxSafePointTries() { - return 10; + return 3; } @Override From 554bcac4d30a476bece37e8ffc776abc592b5f64 Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Thu, 10 Nov 2022 00:47:40 -0600 Subject: [PATCH 02/17] Fixed flying pathfinding not being able to go above/below walls in the air --- src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java b/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java index bf1f4079a..17c1d196e 100644 --- a/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java +++ b/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java @@ -453,6 +453,7 @@ public class PathNavigateFlying extends PathNavigate { d0 *= d3; d1 *= d3; entityXSize += 2; + entityYSize += 2; entityZSize += 2; if (!this.isSafeToStandAt(l, (int)vec31.yCoord, i1, entityXSize, entityYSize, entityZSize, vec31, d0, d1)) @@ -462,6 +463,7 @@ public class PathNavigateFlying extends PathNavigate { else { entityXSize -= 2; + entityYSize -= 2; entityZSize -= 2; double d4 = 1.0D / Math.abs(d0); double d5 = 1.0D / Math.abs(d1); From 83db114a0dd7c7c02da62139d53e0f4c22fbc1d9 Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Thu, 10 Nov 2022 01:18:25 -0600 Subject: [PATCH 03/17] Decreased max safe point tries for flight pathing, and added limit to pathfinding while loop. --- src/main/java/noppes/npcs/entity/EntityNPCInterface.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java index 9aa74cd08..8111b2c05 100644 --- a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java +++ b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java @@ -220,7 +220,7 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti public int getMaxSafePointTries() { - return 3; + return canFly() ? 2 : super.getMaxSafePointTries(); } @Override From 081c47b0aae00462f798031a19ec67a84baf2bd0 Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Thu, 10 Nov 2022 03:26:32 -0600 Subject: [PATCH 04/17] Path optimizations --- .../npcs/ai/pathfinder/FlyPathFinder.java | 30 +++++++++++++------ .../npcs/entity/EntityNPCInterface.java | 2 +- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/main/java/noppes/npcs/ai/pathfinder/FlyPathFinder.java b/src/main/java/noppes/npcs/ai/pathfinder/FlyPathFinder.java index 16f268c64..12caf03cb 100644 --- a/src/main/java/noppes/npcs/ai/pathfinder/FlyPathFinder.java +++ b/src/main/java/noppes/npcs/ai/pathfinder/FlyPathFinder.java @@ -144,8 +144,15 @@ public class FlyPathFinder extends PathFinder this.path.addPoint(p_75861_2_); NPCPathPoint pathpoint3 = p_75861_2_; + int x = 0; while (!this.path.isPathEmpty()) { + x++; + + if (x >= 200) { + break; + } + NPCPathPoint pathpoint4 = this.path.dequeue(); if (pathpoint4.equals(p_75861_3_)) @@ -245,12 +252,12 @@ public class FlyPathFinder extends PathFinder this.pathOptions[i++] = pathpoint5; } - boolean flag = pathpoint3 != null;// && pathpoint3.costMalus != 0.0F; - boolean flag1 = pathpoint0 != null;// && pathpoint0.costMalus != 0.0F; - boolean flag2 = pathpoint2 != null;// && pathpoint2.costMalus != 0.0F; - boolean flag3 = pathpoint1 != null;// && pathpoint1.costMalus != 0.0F; - boolean flag4 = pathpoint4 != null;// && pathpoint4.costMalus != 0.0F; - boolean flag5 = pathpoint5 != null;// && pathpoint5.costMalus != 0.0F; + boolean flag = pathpoint3 != null && pathpoint3.costMalus != 1 && pathpoint3.costMalus != 2; + boolean flag1 = pathpoint0 != null && pathpoint0.costMalus != 1 && pathpoint0.costMalus != 2; + boolean flag2 = pathpoint2 != null && pathpoint2.costMalus != 1 && pathpoint2.costMalus != 2; + boolean flag3 = pathpoint1 != null && pathpoint1.costMalus != 1 && pathpoint1.costMalus != 2; + boolean flag4 = pathpoint4 != null && pathpoint4.costMalus != 1 && pathpoint4.costMalus != 2; + boolean flag5 = pathpoint5 != null && pathpoint5.costMalus != 1 && pathpoint5.costMalus != 2; if (flag && flag3) { @@ -382,18 +389,23 @@ public class FlyPathFinder extends PathFinder if (i1 == 2) { - return this.openPoint(p_75858_2_, p_75858_3_, p_75858_4_); + pathpoint1 = this.openPoint(p_75858_2_, p_75858_3_, p_75858_4_); + pathpoint1.costMalus = i1; + return pathpoint1; } else { if (i1 == 1) { pathpoint1 = this.openPoint(p_75858_2_, p_75858_3_, p_75858_4_); + pathpoint1.costMalus = i1; } - if (pathpoint1 == null && p_75858_6_ > 0 && i1 != -3 && i1 != -4 && this.getVerticalOffset(p_75858_1_, p_75858_2_, p_75858_3_ + p_75858_6_, p_75858_4_, p_75858_5_) == 1) + int vertOffset2 = this.getVerticalOffset(p_75858_1_, p_75858_2_, p_75858_3_ + p_75858_6_, p_75858_4_, p_75858_5_); + if (pathpoint1 == null && p_75858_6_ > 0 && i1 != -3 && i1 != -4 && vertOffset2 == 1) { pathpoint1 = this.openPoint(p_75858_2_, p_75858_3_ + p_75858_6_, p_75858_4_); + pathpoint1.costMalus = vertOffset2; p_75858_3_ += p_75858_6_; } @@ -426,6 +438,7 @@ public class FlyPathFinder extends PathFinder if (p_75858_3_ > 0) { pathpoint1 = this.openPoint(p_75858_2_, p_75858_3_, p_75858_4_); + pathpoint1.costMalus = k1; } } @@ -434,7 +447,6 @@ public class FlyPathFinder extends PathFinder return null; } } - return pathpoint1; } } diff --git a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java index 8111b2c05..9aa74cd08 100644 --- a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java +++ b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java @@ -220,7 +220,7 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti public int getMaxSafePointTries() { - return canFly() ? 2 : super.getMaxSafePointTries(); + return 3; } @Override From 2c1a5d330aa293e7d92cfe31e31a322656a6fad4 Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Thu, 10 Nov 2022 17:38:37 -0600 Subject: [PATCH 05/17] Improved pathfinding, and made NPCs able to traverse through lava/fire sources and water if immune to fire or able to breathe in water respectively. --- .../npcs/ai/pathfinder/FlyPathFinder.java | 110 ++++++++++-------- .../npcs/entity/EntityNPCInterface.java | 10 ++ 2 files changed, 74 insertions(+), 46 deletions(-) diff --git a/src/main/java/noppes/npcs/ai/pathfinder/FlyPathFinder.java b/src/main/java/noppes/npcs/ai/pathfinder/FlyPathFinder.java index 12caf03cb..7a7462321 100644 --- a/src/main/java/noppes/npcs/ai/pathfinder/FlyPathFinder.java +++ b/src/main/java/noppes/npcs/ai/pathfinder/FlyPathFinder.java @@ -40,6 +40,9 @@ public class FlyPathFinder extends PathFinder private boolean isWoodenDoorAllowed; private boolean canEntityDrown; + private int drowningType; + private boolean immuneToFire; + public FlyPathFinder(IBlockAccess _worldMap, boolean doorsAllowed, boolean closedDoors, boolean canPathWater, boolean canDrown, Entity entityIn) { super(_worldMap,doorsAllowed,closedDoors,canPathWater,canDrown); @@ -76,6 +79,10 @@ public class FlyPathFinder extends PathFinder { this.path.clearPath(); this.pointMap.clearMap(); + + this.drowningType = ((EntityNPCInterface)theEntity).stats.drowningType; + this.immuneToFire = ((EntityNPCInterface)theEntity).stats.immuneToFire; + NPCPathPoint pathpoint = this.getStart(); NPCPathPoint pathpoint1 = this.getPathPointToCoords(entityIn, x, y, z); NPCPathPoint pathPoint2 = new NPCPathPoint((int)Math.ceil(entityIn.width),(int)Math.ceil(entityIn.height),(int)Math.ceil(entityIn.width)); @@ -206,21 +213,22 @@ public class FlyPathFinder extends PathFinder * populates pathOptions with available points and returns the number of options found (args: unused1, currentPoint, * unused2, targetPoint, maxDistance) */ - private int findPathOptions(Entity p_75860_1_, NPCPathPoint p_75860_2_, NPCPathPoint p_75860_3_, NPCPathPoint targetPoint, float maxDistance) + private int findPathOptions(Entity entity, NPCPathPoint currentPoint, NPCPathPoint p_75860_3_, NPCPathPoint targetPoint, float maxDistance) { int i = 0; byte b0 = 0; - /*if (this.getVerticalOffset(p_75860_1_, p_75860_2_.xCoord, p_75860_2_.yCoord + 1, p_75860_2_.zCoord, p_75860_3_) == 1) { + if (this.getVerticalOffset(entity, currentPoint.xCoord, currentPoint.yCoord + 1, currentPoint.zCoord, p_75860_3_) == 1) + { b0 = 1; - }*/ + } - NPCPathPoint pathpoint0 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord, p_75860_2_.yCoord, p_75860_2_.zCoord + 1, p_75860_3_, b0); - NPCPathPoint pathpoint1 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord - 1, p_75860_2_.yCoord, p_75860_2_.zCoord, p_75860_3_, b0); - NPCPathPoint pathpoint2 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord + 1, p_75860_2_.yCoord, p_75860_2_.zCoord, p_75860_3_, b0); - NPCPathPoint pathpoint3 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord, p_75860_2_.yCoord, p_75860_2_.zCoord - 1, p_75860_3_, b0); - NPCPathPoint pathpoint4 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord, p_75860_2_.yCoord + 1, p_75860_2_.zCoord, p_75860_3_, b0); - NPCPathPoint pathpoint5 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord, p_75860_2_.yCoord - 1, p_75860_2_.zCoord, p_75860_3_, b0); + NPCPathPoint pathpoint0 = this.getSafePoint(entity, currentPoint.xCoord, currentPoint.yCoord, currentPoint.zCoord + 1, p_75860_3_, b0); + NPCPathPoint pathpoint1 = this.getSafePoint(entity, currentPoint.xCoord - 1, currentPoint.yCoord, currentPoint.zCoord, p_75860_3_, b0); + NPCPathPoint pathpoint2 = this.getSafePoint(entity, currentPoint.xCoord + 1, currentPoint.yCoord, currentPoint.zCoord, p_75860_3_, b0); + NPCPathPoint pathpoint3 = this.getSafePoint(entity, currentPoint.xCoord, currentPoint.yCoord, currentPoint.zCoord - 1, p_75860_3_, b0); + NPCPathPoint pathpoint4 = this.getSafePoint(entity, currentPoint.xCoord, currentPoint.yCoord + 1, currentPoint.zCoord, p_75860_3_, b0); + NPCPathPoint pathpoint5 = this.getSafePoint(entity, currentPoint.xCoord, currentPoint.yCoord - 1, currentPoint.zCoord, p_75860_3_, b0); if (pathpoint0 != null && !pathpoint0.isFirst && pathpoint0.distanceTo(targetPoint) < maxDistance) { @@ -261,7 +269,7 @@ public class FlyPathFinder extends PathFinder if (flag && flag3) { - NPCPathPoint pathpoint6 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord - 1, p_75860_2_.yCoord, p_75860_2_.zCoord - 1, p_75860_3_, b0); + NPCPathPoint pathpoint6 = this.getSafePoint(entity, currentPoint.xCoord - 1, currentPoint.yCoord, currentPoint.zCoord - 1, p_75860_3_, b0); if (pathpoint6 != null && !pathpoint6.isFirst && pathpoint6.distanceTo(targetPoint) < maxDistance) { @@ -271,7 +279,7 @@ public class FlyPathFinder extends PathFinder if (flag && flag2) { - NPCPathPoint pathpoint6 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord + 1, p_75860_2_.yCoord, p_75860_2_.zCoord - 1, p_75860_3_, b0); + NPCPathPoint pathpoint6 = this.getSafePoint(entity, currentPoint.xCoord + 1, currentPoint.yCoord, currentPoint.zCoord - 1, p_75860_3_, b0); if (pathpoint6 != null && !pathpoint6.isFirst && pathpoint6.distanceTo(targetPoint) < maxDistance) { @@ -281,7 +289,7 @@ public class FlyPathFinder extends PathFinder if (flag1 && flag3) { - NPCPathPoint pathpoint6 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord - 1, p_75860_2_.yCoord, p_75860_2_.zCoord + 1, p_75860_3_, b0); + NPCPathPoint pathpoint6 = this.getSafePoint(entity, currentPoint.xCoord - 1, currentPoint.yCoord, currentPoint.zCoord + 1, p_75860_3_, b0); if (pathpoint6 != null && !pathpoint6.isFirst && pathpoint6.distanceTo(targetPoint) < maxDistance) { @@ -291,7 +299,7 @@ public class FlyPathFinder extends PathFinder if (flag1 && flag2) { - NPCPathPoint pathpoint6 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord + 1, p_75860_2_.yCoord, p_75860_2_.zCoord + 1, p_75860_3_, b0); + NPCPathPoint pathpoint6 = this.getSafePoint(entity, currentPoint.xCoord + 1, currentPoint.yCoord, currentPoint.zCoord + 1, p_75860_3_, b0); if (pathpoint6 != null && !pathpoint6.isFirst && pathpoint6.distanceTo(targetPoint) < maxDistance) { @@ -301,7 +309,7 @@ public class FlyPathFinder extends PathFinder if (flag && flag4) { - NPCPathPoint pathpoint6 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord, p_75860_2_.yCoord + 1, p_75860_2_.zCoord - 1, p_75860_3_, b0); + NPCPathPoint pathpoint6 = this.getSafePoint(entity, currentPoint.xCoord, currentPoint.yCoord + 1, currentPoint.zCoord - 1, p_75860_3_, b0); if (pathpoint6 != null && !pathpoint6.isFirst && pathpoint6.distanceTo(targetPoint) < maxDistance) { @@ -311,7 +319,7 @@ public class FlyPathFinder extends PathFinder if (flag1 && flag4) { - NPCPathPoint pathpoint6 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord, p_75860_2_.yCoord + 1, p_75860_2_.zCoord + 1, p_75860_3_, b0); + NPCPathPoint pathpoint6 = this.getSafePoint(entity, currentPoint.xCoord, currentPoint.yCoord + 1, currentPoint.zCoord + 1, p_75860_3_, b0); if (pathpoint6 != null && !pathpoint6.isFirst && pathpoint6.distanceTo(targetPoint) < maxDistance) { @@ -321,7 +329,7 @@ public class FlyPathFinder extends PathFinder if (flag2 && flag4) { - NPCPathPoint pathpoint6 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord + 1, p_75860_2_.yCoord + 1, p_75860_2_.zCoord, p_75860_3_, b0); + NPCPathPoint pathpoint6 = this.getSafePoint(entity, currentPoint.xCoord + 1, currentPoint.yCoord + 1, currentPoint.zCoord, p_75860_3_, b0); if (pathpoint6 != null && !pathpoint6.isFirst && pathpoint6.distanceTo(targetPoint) < maxDistance) { @@ -331,7 +339,7 @@ public class FlyPathFinder extends PathFinder if (flag3 && flag4) { - NPCPathPoint pathpoint6 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord - 1, p_75860_2_.yCoord + 1, p_75860_2_.zCoord, p_75860_3_, b0); + NPCPathPoint pathpoint6 = this.getSafePoint(entity, currentPoint.xCoord - 1, currentPoint.yCoord + 1, currentPoint.zCoord, p_75860_3_, b0); if (pathpoint6 != null && !pathpoint6.isFirst && pathpoint6.distanceTo(targetPoint) < maxDistance) { @@ -341,7 +349,7 @@ public class FlyPathFinder extends PathFinder if (flag && flag5) { - NPCPathPoint pathpoint6 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord, p_75860_2_.yCoord - 1, p_75860_2_.zCoord - 1, p_75860_3_, b0); + NPCPathPoint pathpoint6 = this.getSafePoint(entity, currentPoint.xCoord, currentPoint.yCoord - 1, currentPoint.zCoord - 1, p_75860_3_, b0); if (pathpoint6 != null && !pathpoint6.isFirst && pathpoint6.distanceTo(targetPoint) < maxDistance) { @@ -351,7 +359,7 @@ public class FlyPathFinder extends PathFinder if (flag1 && flag5) { - NPCPathPoint pathpoint6 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord, p_75860_2_.yCoord - 1, p_75860_2_.zCoord + 1, p_75860_3_, b0); + NPCPathPoint pathpoint6 = this.getSafePoint(entity, currentPoint.xCoord, currentPoint.yCoord - 1, currentPoint.zCoord + 1, p_75860_3_, b0); if (pathpoint6 != null && !pathpoint6.isFirst && pathpoint6.distanceTo(targetPoint) < maxDistance) { @@ -361,7 +369,7 @@ public class FlyPathFinder extends PathFinder if (flag2 && flag5) { - NPCPathPoint pathpoint6 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord + 1, p_75860_2_.yCoord - 1, p_75860_2_.zCoord, p_75860_3_, b0); + NPCPathPoint pathpoint6 = this.getSafePoint(entity, currentPoint.xCoord + 1, currentPoint.yCoord - 1, currentPoint.zCoord, p_75860_3_, b0); if (pathpoint6 != null && !pathpoint6.isFirst && pathpoint6.distanceTo(targetPoint) < maxDistance) { @@ -371,7 +379,7 @@ public class FlyPathFinder extends PathFinder if (flag3 && flag5) { - NPCPathPoint pathpoint6 = this.getSafePoint(p_75860_1_, p_75860_2_.xCoord - 1, p_75860_2_.yCoord - 1, p_75860_2_.zCoord, p_75860_3_, b0); + NPCPathPoint pathpoint6 = this.getSafePoint(entity, currentPoint.xCoord - 1, currentPoint.yCoord - 1, currentPoint.zCoord, p_75860_3_, b0); if (pathpoint6 != null && !pathpoint6.isFirst && pathpoint6.distanceTo(targetPoint) < maxDistance) { @@ -382,31 +390,36 @@ public class FlyPathFinder extends PathFinder return i; } - private NPCPathPoint getSafePoint(Entity p_75858_1_, int p_75858_2_, int p_75858_3_, int p_75858_4_, NPCPathPoint p_75858_5_, int p_75858_6_) + private NPCPathPoint getSafePoint(Entity entity, int x, int y, int z, NPCPathPoint p_75858_5_, int p_75858_6_) { NPCPathPoint pathpoint1 = null; - int i1 = this.getVerticalOffset(p_75858_1_, p_75858_2_, p_75858_3_, p_75858_4_, p_75858_5_); + PathNodeType pathNodeType1 = this.getPathNodeType(entity,x,y,z); + int i1 = this.nodeTypeToOffset(pathNodeType1); if (i1 == 2) { - pathpoint1 = this.openPoint(p_75858_2_, p_75858_3_, p_75858_4_); + pathpoint1 = this.openPoint(x, y, z); pathpoint1.costMalus = i1; + pathpoint1.nodeType = pathNodeType1; return pathpoint1; } else { if (i1 == 1) { - pathpoint1 = this.openPoint(p_75858_2_, p_75858_3_, p_75858_4_); + pathpoint1 = this.openPoint(x, y, z); pathpoint1.costMalus = i1; + pathpoint1.nodeType = pathNodeType1; } - int vertOffset2 = this.getVerticalOffset(p_75858_1_, p_75858_2_, p_75858_3_ + p_75858_6_, p_75858_4_, p_75858_5_); + PathNodeType pathNodeType2 = this.getPathNodeType(entity, x,y + p_75858_6_, z); + int vertOffset2 = this.nodeTypeToOffset(pathNodeType2); if (pathpoint1 == null && p_75858_6_ > 0 && i1 != -3 && i1 != -4 && vertOffset2 == 1) { - pathpoint1 = this.openPoint(p_75858_2_, p_75858_3_ + p_75858_6_, p_75858_4_); + pathpoint1 = this.openPoint(x, y + p_75858_6_, z); pathpoint1.costMalus = vertOffset2; - p_75858_3_ += p_75858_6_; + pathpoint1.nodeType = pathNodeType2; + y += p_75858_6_; } if (pathpoint1 != null) @@ -414,9 +427,10 @@ public class FlyPathFinder extends PathFinder int j1 = 0; int k1 = 0; - while (p_75858_3_ > 0) + while (y > 0) { - k1 = this.getVerticalOffset(p_75858_1_, p_75858_2_, p_75858_3_ - 1, p_75858_4_, p_75858_5_); + PathNodeType pathNodeType3 = this.getPathNodeType(entity,x, y - 1, z); + k1 = this.nodeTypeToOffset(pathNodeType3); if (this.isPathingInWater && k1 == -1) { @@ -428,17 +442,18 @@ public class FlyPathFinder extends PathFinder break; } - if (j1++ >= p_75858_1_.getMaxSafePointTries()) + if (j1++ >= entity.getMaxSafePointTries()) { return null; } - --p_75858_3_; + --y; - if (p_75858_3_ > 0) + if (y > 0) { - pathpoint1 = this.openPoint(p_75858_2_, p_75858_3_, p_75858_4_); + pathpoint1 = this.openPoint(x, y, z); pathpoint1.costMalus = k1; + pathpoint1.nodeType = pathNodeType3; } } @@ -451,16 +466,13 @@ public class FlyPathFinder extends PathFinder } } - public int getVerticalOffset(Entity entity, int x, int y, int z, PathPoint pathEndpoint) + private PathNodeType getPathNodeType(Entity entity, int x, int y, int z) { - return getVerticalOffset(entity, x, y, z, pathEndpoint, this.isPathingInWater, this.isMovementBlockAllowed, this.isWoodenDoorAllowed); + return this.getPathNodeType((EntityLiving) entity, new BlockPos(x,y,z)); } - private int getVerticalOffset(Entity entity, int x, int y, int z, PathPoint pathEndpoint, boolean isPathingInWater, boolean isMovementBlockAllowed, boolean isWoodenDoorAllowed) - { - PathNodeType pathnodetype = this.getPathNodeType((EntityLiving) entity, new BlockPos(x,y,z)); - - switch (pathnodetype) { + public int nodeTypeToOffset(PathNodeType nodeType) { + switch (nodeType) { case BLOCKED: return 0; case OPEN: @@ -514,6 +526,12 @@ public class FlyPathFinder extends PathFinder return pathpoint; } + public NPCPathPoint getPointFromHash(int x, int y, int z) + { + int i = NPCPathPoint.makeHash(x, y, z); + return this.pointMap.lookup(i); + } + /** * Returns a new FlyPathEntity for a given start and end point */ @@ -682,7 +700,7 @@ public class FlyPathFinder extends PathFinder { type = PathNodeType.DANGER_CACTUS; } - else if (block == Blocks.fire) + else if (block == Blocks.fire && !immuneToFire) { type = PathNodeType.DANGER_FIRE; } @@ -703,13 +721,13 @@ public class FlyPathFinder extends PathFinder if (material == Material.air) { - return PathNodeType.OPEN; + return drowningType == 2 ? PathNodeType.WATER : PathNodeType.OPEN; } else if (block != Blocks.trapdoor && block != Blocks.waterlily) { if (block == Blocks.fire) { - return PathNodeType.DAMAGE_FIRE; + return immuneToFire ? PathNodeType.OPEN : PathNodeType.DAMAGE_FIRE; } else if (block == Blocks.cactus) { @@ -735,11 +753,11 @@ public class FlyPathFinder extends PathFinder { if (material == Material.water) { - return PathNodeType.WATER; + return drowningType == 1 ? PathNodeType.WATER : PathNodeType.OPEN; } else if (material == Material.lava) { - return PathNodeType.LAVA; + return immuneToFire ? PathNodeType.OPEN : PathNodeType.LAVA; } else { diff --git a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java index 9aa74cd08..140cdf5fa 100644 --- a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java +++ b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java @@ -1620,6 +1620,16 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti this.isImmuneToFire = immuneToFire; stats.immuneToFire = immuneToFire; } + + public boolean handleLavaMovement() + { + return !stats.immuneToFire && super.handleLavaMovement(); + } + + public boolean handleWaterMovement() + { + return stats.drowningType == 1 && super.handleWaterMovement(); + } public void setAvoidWater(boolean avoidWater) { this.getNavigator().setAvoidsWater(avoidWater); From a69468322eaf32b117c19f2afd2602988d2e3a65 Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Thu, 10 Nov 2022 20:19:36 -0600 Subject: [PATCH 06/17] Added new isDirectPathBetweenPoints function with severely increased performance. --- .../ai/pathfinder/PathNavigateFlying.java | 155 +----------------- 1 file changed, 5 insertions(+), 150 deletions(-) diff --git a/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java b/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java index 17c1d196e..000679411 100644 --- a/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java +++ b/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java @@ -6,11 +6,13 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.ai.attributes.IAttributeInstance; +import net.minecraft.init.Blocks; import net.minecraft.pathfinding.PathEntity; import net.minecraft.pathfinding.PathFinder; import net.minecraft.pathfinding.PathNavigate; import net.minecraft.pathfinding.PathPoint; import net.minecraft.util.MathHelper; +import net.minecraft.util.MovingObjectPosition; import net.minecraft.util.Vec3; import net.minecraft.util.math.BlockPos; import net.minecraft.world.ChunkCache; @@ -435,159 +437,12 @@ public class PathNavigateFlying extends PathNavigate { * Returns true when an entity of specified size could safely walk in a straight line between the two points. Args: * pos1, pos2, entityXSize, entityYSize, entityZSize */ - private boolean isDirectPathBetweenPoints(Vec3 vec31, Vec3 vec32, int entityXSize, int entityYSize, int entityZSize) + private boolean isDirectPathBetweenPoints(Vec3 pos1, Vec3 pos2, int entityXSize, int entityYSize, int entityZSize) { - int l = MathHelper.floor_double(vec31.xCoord); - int i1 = MathHelper.floor_double(vec31.zCoord); - double d0 = vec32.xCoord - vec31.xCoord; - double d1 = vec32.zCoord - vec31.zCoord; - double d2 = d0 * d0 + d1 * d1; - - if (d2 < 1.0E-8D) - { - return false; - } - else - { - double d3 = 1.0D / Math.sqrt(d2); - d0 *= d3; - d1 *= d3; - entityXSize += 2; - entityYSize += 2; - entityZSize += 2; - - if (!this.isSafeToStandAt(l, (int)vec31.yCoord, i1, entityXSize, entityYSize, entityZSize, vec31, d0, d1)) - { - return false; - } - else - { - entityXSize -= 2; - entityYSize -= 2; - entityZSize -= 2; - double d4 = 1.0D / Math.abs(d0); - double d5 = 1.0D / Math.abs(d1); - double d6 = (double)(l * 1) - vec31.xCoord; - double d7 = (double)(i1 * 1) - vec31.zCoord; - - if (d0 >= 0.0D) - { - ++d6; - } - - if (d1 >= 0.0D) - { - ++d7; - } - - d6 /= d0; - d7 /= d1; - int j1 = d0 < 0.0D ? -1 : 1; - int k1 = d1 < 0.0D ? -1 : 1; - int l1 = MathHelper.floor_double(vec32.xCoord); - int i2 = MathHelper.floor_double(vec32.zCoord); - int j2 = l1 - l; - int k2 = i2 - i1; - - do - { - if (j2 * j1 <= 0 && k2 * k1 <= 0) - { - return true; - } - - if (d6 < d7) - { - d6 += d4; - l += j1; - j2 = l1 - l; - } - else - { - d7 += d5; - i1 += k1; - k2 = i2 - i1; - } - } - while (this.isSafeToStandAt(l, (int)vec31.yCoord, i1, entityXSize, entityYSize, entityZSize, vec31, d0, d1)); - - return false; - } - } + MovingObjectPosition var6 = this.worldObj.func_147447_a(pos1, Vec3.createVectorHelper(pos2.xCoord, pos2.yCoord + (double)this.theEntity.height * 0.5D, pos2.zCoord), false, true, false); + return var6 == null || var6.typeOfHit == MovingObjectPosition.MovingObjectType.MISS; } - private boolean isSafeToStandAt(int p_75483_1_, int p_75483_2_, int p_75483_3_, int p_75483_4_, int p_75483_5_, int p_75483_6_, Vec3 p_75483_7_, double p_75483_8_, double p_75483_10_) - { - int k1 = p_75483_1_ - p_75483_4_ / 2; - int l1 = p_75483_3_ - p_75483_6_ / 2; - - if (!this.isPositionClear(k1, p_75483_2_, l1, p_75483_4_, p_75483_5_, p_75483_6_, p_75483_7_, p_75483_8_, p_75483_10_)) - { - return false; - } - else - { - for (int i2 = k1; i2 < k1 + p_75483_4_; ++i2) - { - for (int j2 = l1; j2 < l1 + p_75483_6_; ++j2) - { - double d2 = (double)i2 + 0.5D - p_75483_7_.xCoord; - double d3 = (double)j2 + 0.5D - p_75483_7_.zCoord; - - if (d2 * p_75483_8_ + d3 * p_75483_10_ >= 0.0D) - { - Block block = this.worldObj.getBlock(i2, p_75483_2_ - 1, j2); - Material material = block.getMaterial(); - - if (material == Material.water && !this.theEntity.isInWater()) - { - return false; - } - - if (material == Material.lava) - { - return false; - } - } - } - } - - return true; - } - } - - private boolean isPositionClear(int x, int y, int z, int entityXSize, int entityYSize, int entityZSize, Vec3 p_75483_7_, double p_75483_8_, double p_75483_10_) - { - return pathFinder.getPathNodeType(this.theEntity.worldObj, x, y, z, (EntityLiving) this.theEntity, entityXSize, entityYSize, entityZSize, ((EntityCustomNpc)this.theEntity).ai.doorInteract == 0, ((EntityCustomNpc)this.theEntity).ai.doorInteract == 1).getPriority() == 0; - } - - /*private boolean isPositionClear(int p_75496_1_, int p_75496_2_, int p_75496_3_, int p_75496_4_, int p_75496_5_, int p_75496_6_, Vec3 p_75496_7_, double p_75496_8_, double p_75496_10_) - { - for (int k1 = p_75496_1_; k1 < p_75496_1_ + p_75496_4_; ++k1) - { - for (int l1 = p_75496_2_; l1 < p_75496_2_ + p_75496_5_; ++l1) - { - for (int i2 = p_75496_3_; i2 < p_75496_3_ + p_75496_6_; ++i2) - { - double d2 = (double)k1 + 0.5D - p_75496_7_.xCoord; - double d3 = (double)i2 + 0.5D - p_75496_7_.zCoord; - - if (d2 * p_75496_8_ + d3 * p_75496_10_ >= 0.0D) - { - Block block = this.worldObj.getBlock(k1, l1, i2); - - if (!block.getBlocksMovement(this.worldObj, k1, l1, i2)) - { - return false; - } - } - } - } - } - - return true; - }*/ - protected void checkForStuck(Vec3 positionVec3) { if (this.totalTicks - this.ticksAtLastPos > 100) From 3f58ef029cf32dca7c82fb4612ca44586b997da7 Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Fri, 11 Nov 2022 02:17:54 -0600 Subject: [PATCH 07/17] Improved isDirectPathBetweenPoints detection in flight pathing, still need to optimize. --- .../ai/pathfinder/PathNavigateFlying.java | 44 +++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java b/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java index 000679411..5294dbb80 100644 --- a/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java +++ b/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java @@ -437,10 +437,48 @@ public class PathNavigateFlying extends PathNavigate { * Returns true when an entity of specified size could safely walk in a straight line between the two points. Args: * pos1, pos2, entityXSize, entityYSize, entityZSize */ - private boolean isDirectPathBetweenPoints(Vec3 pos1, Vec3 pos2, int entityXSize, int entityYSize, int entityZSize) + private boolean isDirectPathBetweenPoints(Vec3 startPos, Vec3 endPos, int entityXSize, int entityYSize, int entityZSize) { - MovingObjectPosition var6 = this.worldObj.func_147447_a(pos1, Vec3.createVectorHelper(pos2.xCoord, pos2.yCoord + (double)this.theEntity.height * 0.5D, pos2.zCoord), false, true, false); - return var6 == null || var6.typeOfHit == MovingObjectPosition.MovingObjectType.MISS; + Vec3 pos1 = Vec3.createVectorHelper(startPos.xCoord,startPos.yCoord + (double)this.theEntity.height * 0.1D, startPos.zCoord); + MovingObjectPosition var1 = this.worldObj.func_147447_a(pos1, Vec3.createVectorHelper(endPos.xCoord, endPos.yCoord + (double)this.theEntity.height, endPos.zCoord), false, false, false); + + Vec3 pos2 = Vec3.createVectorHelper(startPos.xCoord,startPos.yCoord + (double)this.theEntity.height, startPos.zCoord); + MovingObjectPosition var2 = this.worldObj.func_147447_a(pos2, Vec3.createVectorHelper(endPos.xCoord, endPos.yCoord + (double)this.theEntity.height * 0.1D, endPos.zCoord), false, false, false); + + Vec3 pos3 = Vec3.createVectorHelper(startPos.xCoord,startPos.yCoord + (double)this.theEntity.height * 0.1D, startPos.zCoord); + MovingObjectPosition var3 = this.worldObj.func_147447_a(pos3, Vec3.createVectorHelper(endPos.xCoord, endPos.yCoord + + (double)this.theEntity.height * 0.1D, endPos.zCoord), false, false, false); + + Vec3 pos4 = Vec3.createVectorHelper(startPos.xCoord,startPos.yCoord + (double)this.theEntity.height, startPos.zCoord); + MovingObjectPosition var4 = this.worldObj.func_147447_a(pos4, Vec3.createVectorHelper(endPos.xCoord, endPos.yCoord + (double)this.theEntity.height, endPos.zCoord), false, false, false); + + Vec3 pos5 = Vec3.createVectorHelper(startPos.xCoord,startPos.yCoord, startPos.zCoord); + MovingObjectPosition var5 = this.worldObj.func_147447_a(pos5, Vec3.createVectorHelper(endPos.xCoord, endPos.yCoord, endPos.zCoord), false, false, false); + + Vec3 pos6 = Vec3.createVectorHelper(startPos.xCoord - this.theEntity.width,startPos.yCoord + (double)this.theEntity.height * 0.1D, startPos.zCoord); + Vec3 pos7 = Vec3.createVectorHelper(endPos.xCoord + this.theEntity.width,endPos.yCoord + (double)this.theEntity.height, endPos.zCoord); + MovingObjectPosition var6 = this.worldObj.func_147447_a(pos6, pos7, false, false, false); + + Vec3 pos8 = Vec3.createVectorHelper(startPos.xCoord - this.theEntity.width,startPos.yCoord + (double)this.theEntity.height, startPos.zCoord); + Vec3 pos9 = Vec3.createVectorHelper(endPos.xCoord + this.theEntity.width,endPos.yCoord + (double)this.theEntity.height * 0.1D, endPos.zCoord); + MovingObjectPosition var7 = this.worldObj.func_147447_a(pos8, pos9, false, false, false); + + Vec3 pos10 = Vec3.createVectorHelper(startPos.xCoord,startPos.yCoord + (double)this.theEntity.height * 0.1D, startPos.zCoord - this.theEntity.width); + Vec3 pos11 = Vec3.createVectorHelper(endPos.xCoord,endPos.yCoord + (double)this.theEntity.height, endPos.zCoord + this.theEntity.width); + MovingObjectPosition var8 = this.worldObj.func_147447_a(pos10, pos11, false, false, false); + + Vec3 pos12 = Vec3.createVectorHelper(startPos.xCoord,startPos.yCoord + (double)this.theEntity.height, startPos.zCoord - this.theEntity.width); + Vec3 pos13 = Vec3.createVectorHelper(endPos.xCoord,endPos.yCoord + (double)this.theEntity.height * 0.1D, endPos.zCoord + this.theEntity.width); + MovingObjectPosition var9 = this.worldObj.func_147447_a(pos12, pos13, false, false, false); + + return (var1 == null || var1.typeOfHit == MovingObjectPosition.MovingObjectType.MISS) + && (var2 == null || var2.typeOfHit == MovingObjectPosition.MovingObjectType.MISS) + && (var3 == null || var3.typeOfHit == MovingObjectPosition.MovingObjectType.MISS) + && (var4 == null || var4.typeOfHit == MovingObjectPosition.MovingObjectType.MISS) + && (var5 == null || var5.typeOfHit == MovingObjectPosition.MovingObjectType.MISS) + && (var6 == null || var6.typeOfHit == MovingObjectPosition.MovingObjectType.MISS) + && (var7 == null || var7.typeOfHit == MovingObjectPosition.MovingObjectType.MISS) + && (var8 == null || var8.typeOfHit == MovingObjectPosition.MovingObjectType.MISS) + && (var9 == null || var9.typeOfHit == MovingObjectPosition.MovingObjectType.MISS); } protected void checkForStuck(Vec3 positionVec3) From c3a029890220d54025d359b1f8c32793b87d9be7 Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Fri, 11 Nov 2022 03:16:56 -0600 Subject: [PATCH 08/17] Improved performance of isDirectPathBetweenPoints. --- .../ai/pathfinder/PathNavigateFlying.java | 81 +++++++++++-------- 1 file changed, 49 insertions(+), 32 deletions(-) diff --git a/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java b/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java index 5294dbb80..56847d22b 100644 --- a/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java +++ b/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java @@ -439,46 +439,63 @@ public class PathNavigateFlying extends PathNavigate { */ private boolean isDirectPathBetweenPoints(Vec3 startPos, Vec3 endPos, int entityXSize, int entityYSize, int entityZSize) { - Vec3 pos1 = Vec3.createVectorHelper(startPos.xCoord,startPos.yCoord + (double)this.theEntity.height * 0.1D, startPos.zCoord); - MovingObjectPosition var1 = this.worldObj.func_147447_a(pos1, Vec3.createVectorHelper(endPos.xCoord, endPos.yCoord + (double)this.theEntity.height, endPos.zCoord), false, false, false); + Vec3 pos17 = Vec3.createVectorHelper(startPos.xCoord,startPos.yCoord, startPos.zCoord); + Vec3 pos18 = Vec3.createVectorHelper(endPos.xCoord,endPos.yCoord, endPos.zCoord); + MovingObjectPosition var10 = this.worldObj.func_147447_a(pos17, pos18, false, false, false); + if (!(var10 == null || var10.typeOfHit == MovingObjectPosition.MovingObjectType.MISS)) + return false; - Vec3 pos2 = Vec3.createVectorHelper(startPos.xCoord,startPos.yCoord + (double)this.theEntity.height, startPos.zCoord); - MovingObjectPosition var2 = this.worldObj.func_147447_a(pos2, Vec3.createVectorHelper(endPos.xCoord, endPos.yCoord + (double)this.theEntity.height * 0.1D, endPos.zCoord), false, false, false); + if (this.theEntity.motionY >= 0) { + Vec3 pos1 = Vec3.createVectorHelper(startPos.xCoord + this.theEntity.width, startPos.yCoord + (double) this.theEntity.height * 0.1D, startPos.zCoord); + Vec3 pos2 = Vec3.createVectorHelper(endPos.xCoord - this.theEntity.width, endPos.yCoord + (double) this.theEntity.height, endPos.zCoord); + MovingObjectPosition var2 = this.worldObj.func_147447_a(pos1, pos2, false, false, false); + if (!(var2 == null || var2.typeOfHit == MovingObjectPosition.MovingObjectType.MISS)) + return false; - Vec3 pos3 = Vec3.createVectorHelper(startPos.xCoord,startPos.yCoord + (double)this.theEntity.height * 0.1D, startPos.zCoord); - MovingObjectPosition var3 = this.worldObj.func_147447_a(pos3, Vec3.createVectorHelper(endPos.xCoord, endPos.yCoord + + (double)this.theEntity.height * 0.1D, endPos.zCoord), false, false, false); + Vec3 pos5 = Vec3.createVectorHelper(startPos.xCoord - this.theEntity.width, startPos.yCoord + (double) this.theEntity.height * 0.1D, startPos.zCoord); + Vec3 pos6 = Vec3.createVectorHelper(endPos.xCoord + this.theEntity.width, endPos.yCoord + (double) this.theEntity.height, endPos.zCoord); + MovingObjectPosition var4 = this.worldObj.func_147447_a(pos5, pos6, false, false, false); + if (!(var4 == null || var4.typeOfHit == MovingObjectPosition.MovingObjectType.MISS)) + return false; - Vec3 pos4 = Vec3.createVectorHelper(startPos.xCoord,startPos.yCoord + (double)this.theEntity.height, startPos.zCoord); - MovingObjectPosition var4 = this.worldObj.func_147447_a(pos4, Vec3.createVectorHelper(endPos.xCoord, endPos.yCoord + (double)this.theEntity.height, endPos.zCoord), false, false, false); + Vec3 pos9 = Vec3.createVectorHelper(startPos.xCoord, startPos.yCoord + (double) this.theEntity.height * 0.1D, startPos.zCoord + this.theEntity.width); + Vec3 pos10 = Vec3.createVectorHelper(endPos.xCoord, endPos.yCoord + (double) this.theEntity.height, endPos.zCoord - this.theEntity.width); + MovingObjectPosition var6 = this.worldObj.func_147447_a(pos9, pos10, false, false, false); + if (!(var6 == null || var6.typeOfHit == MovingObjectPosition.MovingObjectType.MISS)) + return false; - Vec3 pos5 = Vec3.createVectorHelper(startPos.xCoord,startPos.yCoord, startPos.zCoord); - MovingObjectPosition var5 = this.worldObj.func_147447_a(pos5, Vec3.createVectorHelper(endPos.xCoord, endPos.yCoord, endPos.zCoord), false, false, false); + Vec3 pos13 = Vec3.createVectorHelper(startPos.xCoord, startPos.yCoord + (double) this.theEntity.height * 0.1D, startPos.zCoord - this.theEntity.width); + Vec3 pos14 = Vec3.createVectorHelper(endPos.xCoord, endPos.yCoord + (double) this.theEntity.height, endPos.zCoord + this.theEntity.width); + MovingObjectPosition var8 = this.worldObj.func_147447_a(pos14, pos13, false, false, false); + if (!(var8 == null || var8.typeOfHit == MovingObjectPosition.MovingObjectType.MISS)) + return false; + } else { + Vec3 pos3 = Vec3.createVectorHelper(startPos.xCoord + this.theEntity.width, startPos.yCoord + (double) this.theEntity.height, startPos.zCoord); + Vec3 pos4 = Vec3.createVectorHelper(endPos.xCoord - this.theEntity.width, endPos.yCoord + (double) this.theEntity.height * 0.1D, endPos.zCoord); + MovingObjectPosition var3 = this.worldObj.func_147447_a(pos3, pos4, false, false, false); + if (!(var3 == null || var3.typeOfHit == MovingObjectPosition.MovingObjectType.MISS)) + return false; - Vec3 pos6 = Vec3.createVectorHelper(startPos.xCoord - this.theEntity.width,startPos.yCoord + (double)this.theEntity.height * 0.1D, startPos.zCoord); - Vec3 pos7 = Vec3.createVectorHelper(endPos.xCoord + this.theEntity.width,endPos.yCoord + (double)this.theEntity.height, endPos.zCoord); - MovingObjectPosition var6 = this.worldObj.func_147447_a(pos6, pos7, false, false, false); + Vec3 pos7 = Vec3.createVectorHelper(startPos.xCoord - this.theEntity.width, startPos.yCoord + (double) this.theEntity.height, startPos.zCoord); + Vec3 pos8 = Vec3.createVectorHelper(endPos.xCoord + this.theEntity.width, endPos.yCoord + (double) this.theEntity.height * 0.1D, endPos.zCoord); + MovingObjectPosition var5 = this.worldObj.func_147447_a(pos7, pos8, false, false, false); + if (!(var5 == null || var5.typeOfHit == MovingObjectPosition.MovingObjectType.MISS)) + return false; - Vec3 pos8 = Vec3.createVectorHelper(startPos.xCoord - this.theEntity.width,startPos.yCoord + (double)this.theEntity.height, startPos.zCoord); - Vec3 pos9 = Vec3.createVectorHelper(endPos.xCoord + this.theEntity.width,endPos.yCoord + (double)this.theEntity.height * 0.1D, endPos.zCoord); - MovingObjectPosition var7 = this.worldObj.func_147447_a(pos8, pos9, false, false, false); + Vec3 pos11 = Vec3.createVectorHelper(startPos.xCoord, startPos.yCoord + (double) this.theEntity.height, startPos.zCoord + this.theEntity.width); + Vec3 pos12 = Vec3.createVectorHelper(endPos.xCoord, endPos.yCoord + (double) this.theEntity.height * 0.1D, endPos.zCoord - this.theEntity.width); + MovingObjectPosition var7 = this.worldObj.func_147447_a(pos11, pos12, false, false, false); + if (!(var7 == null || var7.typeOfHit == MovingObjectPosition.MovingObjectType.MISS)) + return false; - Vec3 pos10 = Vec3.createVectorHelper(startPos.xCoord,startPos.yCoord + (double)this.theEntity.height * 0.1D, startPos.zCoord - this.theEntity.width); - Vec3 pos11 = Vec3.createVectorHelper(endPos.xCoord,endPos.yCoord + (double)this.theEntity.height, endPos.zCoord + this.theEntity.width); - MovingObjectPosition var8 = this.worldObj.func_147447_a(pos10, pos11, false, false, false); + Vec3 pos15 = Vec3.createVectorHelper(startPos.xCoord, startPos.yCoord + (double) this.theEntity.height, startPos.zCoord - this.theEntity.width); + Vec3 pos16 = Vec3.createVectorHelper(endPos.xCoord, endPos.yCoord + (double) this.theEntity.height * 0.1D, endPos.zCoord + this.theEntity.width); + MovingObjectPosition var9 = this.worldObj.func_147447_a(pos15, pos16, false, false, false); + if (!(var9 == null || var9.typeOfHit == MovingObjectPosition.MovingObjectType.MISS)) + return false; + } - Vec3 pos12 = Vec3.createVectorHelper(startPos.xCoord,startPos.yCoord + (double)this.theEntity.height, startPos.zCoord - this.theEntity.width); - Vec3 pos13 = Vec3.createVectorHelper(endPos.xCoord,endPos.yCoord + (double)this.theEntity.height * 0.1D, endPos.zCoord + this.theEntity.width); - MovingObjectPosition var9 = this.worldObj.func_147447_a(pos12, pos13, false, false, false); - - return (var1 == null || var1.typeOfHit == MovingObjectPosition.MovingObjectType.MISS) - && (var2 == null || var2.typeOfHit == MovingObjectPosition.MovingObjectType.MISS) - && (var3 == null || var3.typeOfHit == MovingObjectPosition.MovingObjectType.MISS) - && (var4 == null || var4.typeOfHit == MovingObjectPosition.MovingObjectType.MISS) - && (var5 == null || var5.typeOfHit == MovingObjectPosition.MovingObjectType.MISS) - && (var6 == null || var6.typeOfHit == MovingObjectPosition.MovingObjectType.MISS) - && (var7 == null || var7.typeOfHit == MovingObjectPosition.MovingObjectType.MISS) - && (var8 == null || var8.typeOfHit == MovingObjectPosition.MovingObjectType.MISS) - && (var9 == null || var9.typeOfHit == MovingObjectPosition.MovingObjectType.MISS); + return true; } protected void checkForStuck(Vec3 positionVec3) From 7425e935f1d86f6a330eb7a600cf8cc65821cb2f Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Fri, 11 Nov 2022 16:57:06 -0600 Subject: [PATCH 09/17] EntityNPCInterface: -Fixed flying NPCs not returning to mid-air start y positions. --- .../npcs/entity/EntityNPCInterface.java | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java index 140cdf5fa..1a7f6a60f 100644 --- a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java +++ b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java @@ -1335,15 +1335,19 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti int j = getStartPos()[1]; int k = getStartPos()[2]; double yy = 0; - for (int ii = j; ii >= 0; ii--) { - Block block = worldObj.getBlock(i, ii, k); - if (block == null) - continue; - AxisAlignedBB bb = block.getCollisionBoundingBoxFromPool(worldObj, i, ii, k); - if (bb == null) - continue; - yy = bb.maxY; - break; + if (!this.canFly()) { + for (int ii = j; ii >= 0; ii--) { + Block block = worldObj.getBlock(i, ii, k); + if (block == null) + continue; + AxisAlignedBB bb = block.getCollisionBoundingBoxFromPool(worldObj, i, ii, k); + if (bb == null) + continue; + yy = bb.maxY; + break; + } + } else { + yy = j; } if (yy <= 0) setDead(); From aa4b1dd9fbb43d9cca6b8e47f07a3a38b950b1c3 Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Sat, 12 Nov 2022 12:09:22 -0600 Subject: [PATCH 10/17] PathNavigateFlying: -Significantly improved flight performance using an LRUHashMap. --- .../ai/pathfinder/PathNavigateFlying.java | 402 +++++++++++++++--- 1 file changed, 338 insertions(+), 64 deletions(-) diff --git a/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java b/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java index 56847d22b..740e3f92a 100644 --- a/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java +++ b/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java @@ -1,14 +1,12 @@ package noppes.npcs.ai.pathfinder; import net.minecraft.block.Block; -import net.minecraft.block.material.Material; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.ai.attributes.IAttributeInstance; import net.minecraft.init.Blocks; import net.minecraft.pathfinding.PathEntity; -import net.minecraft.pathfinding.PathFinder; import net.minecraft.pathfinding.PathNavigate; import net.minecraft.pathfinding.PathPoint; import net.minecraft.util.MathHelper; @@ -17,12 +15,15 @@ import net.minecraft.util.Vec3; import net.minecraft.util.math.BlockPos; import net.minecraft.world.ChunkCache; import net.minecraft.world.World; -import noppes.npcs.entity.EntityCustomNpc; import noppes.npcs.entity.EntityNPCInterface; +import noppes.npcs.util.LRUHashMap; import javax.annotation.Nullable; +import java.util.Map; public class PathNavigateFlying extends PathNavigate { + private static final Map pathClearCache = new LRUHashMap<>(5000); + private EntityNPCInterface theEntity; private World worldObj; /** The PathEntity being followed. */ @@ -330,16 +331,7 @@ public class PathNavigateFlying extends PathNavigate { k = MathHelper.floor_double(this.theEntity.width + 1.0F); int l = MathHelper.floor_double(this.theEntity.height + 1.0F); - int i1 = k; - - for (int j1 = i - 1; j1 >= this.currentPath.getCurrentPathIndex(); --j1) - { - if (this.isDirectPathBetweenPoints(vec3, this.currentPath.getVectorFromIndex(this.theEntity, j1), k, l, i1)) - { - this.currentPath.setCurrentPathIndex(j1); - break; - } - } + this.trimPath(vec3,i,k,l); this.checkForStuck(vec3); } @@ -366,20 +358,25 @@ public class PathNavigateFlying extends PathNavigate { } int k = MathHelper.ceiling_double_int(this.theEntity.width); - // Adjust Size HERE int l = MathHelper.ceiling_double_int(this.theEntity.height + 1.0F); - int i1 = k; + this.trimPath(vec3,i,k,l); - for (int j1 = i - 1; j1 >= this.currentPath.getCurrentPathIndex(); --j1) + this.checkForStuck(vec3); + } + + public void trimPath(Vec3 position, int pathLength, int width, int height) { + for (int j1 = pathLength - 1; j1 >= this.currentPath.getCurrentPathIndex(); --j1) { - if (this.isDirectPathBetweenPoints(vec3, this.currentPath.getVectorFromIndex(this.theEntity, j1), k, l, i1)) + Vec3 pathPoint = this.currentPath.getVectorFromIndex(this.theEntity, j1); + if (position.distanceTo(pathPoint) > 6) + continue; + + if (this.isDirectPathBetweenPoints(position, pathPoint, width, height)) { this.currentPath.setCurrentPathIndex(j1); break; } } - - this.checkForStuck(vec3); } @@ -437,65 +434,342 @@ public class PathNavigateFlying extends PathNavigate { * Returns true when an entity of specified size could safely walk in a straight line between the two points. Args: * pos1, pos2, entityXSize, entityYSize, entityZSize */ - private boolean isDirectPathBetweenPoints(Vec3 startPos, Vec3 endPos, int entityXSize, int entityYSize, int entityZSize) + private boolean isDirectPathBetweenPoints(Vec3 startPos, Vec3 endPos, int width, int height) { Vec3 pos17 = Vec3.createVectorHelper(startPos.xCoord,startPos.yCoord, startPos.zCoord); Vec3 pos18 = Vec3.createVectorHelper(endPos.xCoord,endPos.yCoord, endPos.zCoord); - MovingObjectPosition var10 = this.worldObj.func_147447_a(pos17, pos18, false, false, false); - if (!(var10 == null || var10.typeOfHit == MovingObjectPosition.MovingObjectType.MISS)) + if (this.rayTraceBlocks(pos17, pos18, false, false, false, width, height)) return false; - if (this.theEntity.motionY >= 0) { - Vec3 pos1 = Vec3.createVectorHelper(startPos.xCoord + this.theEntity.width, startPos.yCoord + (double) this.theEntity.height * 0.1D, startPos.zCoord); - Vec3 pos2 = Vec3.createVectorHelper(endPos.xCoord - this.theEntity.width, endPos.yCoord + (double) this.theEntity.height, endPos.zCoord); - MovingObjectPosition var2 = this.worldObj.func_147447_a(pos1, pos2, false, false, false); - if (!(var2 == null || var2.typeOfHit == MovingObjectPosition.MovingObjectType.MISS)) - return false; + return true; + } - Vec3 pos5 = Vec3.createVectorHelper(startPos.xCoord - this.theEntity.width, startPos.yCoord + (double) this.theEntity.height * 0.1D, startPos.zCoord); - Vec3 pos6 = Vec3.createVectorHelper(endPos.xCoord + this.theEntity.width, endPos.yCoord + (double) this.theEntity.height, endPos.zCoord); - MovingObjectPosition var4 = this.worldObj.func_147447_a(pos5, pos6, false, false, false); - if (!(var4 == null || var4.typeOfHit == MovingObjectPosition.MovingObjectType.MISS)) - return false; + public boolean rayTraceBlocks(Vec3 p_147447_1_, Vec3 p_147447_2_, boolean p_147447_3_, boolean p_147447_4_, boolean p_147447_5_, int width, int height) + { + if (!Double.isNaN(p_147447_1_.xCoord) && !Double.isNaN(p_147447_1_.yCoord) && !Double.isNaN(p_147447_1_.zCoord)) + { + if (!Double.isNaN(p_147447_2_.xCoord) && !Double.isNaN(p_147447_2_.yCoord) && !Double.isNaN(p_147447_2_.zCoord)) + { + int i = MathHelper.floor_double(p_147447_2_.xCoord); + int j = MathHelper.floor_double(p_147447_2_.yCoord); + int k = MathHelper.floor_double(p_147447_2_.zCoord); + int l = MathHelper.floor_double(p_147447_1_.xCoord); + int i1 = MathHelper.floor_double(p_147447_1_.yCoord); + int j1 = MathHelper.floor_double(p_147447_1_.zCoord); + Block block = this.worldObj.getBlock(l, i1, j1); + int k1 = this.worldObj.getBlockMetadata(l, i1, j1); - Vec3 pos9 = Vec3.createVectorHelper(startPos.xCoord, startPos.yCoord + (double) this.theEntity.height * 0.1D, startPos.zCoord + this.theEntity.width); - Vec3 pos10 = Vec3.createVectorHelper(endPos.xCoord, endPos.yCoord + (double) this.theEntity.height, endPos.zCoord - this.theEntity.width); - MovingObjectPosition var6 = this.worldObj.func_147447_a(pos9, pos10, false, false, false); - if (!(var6 == null || var6.typeOfHit == MovingObjectPosition.MovingObjectType.MISS)) - return false; + if ((!p_147447_4_ || block.getCollisionBoundingBoxFromPool(this.worldObj, l, i1, j1) != null) && block.canCollideCheck(k1, p_147447_3_)) + { + MovingObjectPosition movingobjectposition = block.collisionRayTrace(this.worldObj, l, i1, j1, p_147447_1_, p_147447_2_); - Vec3 pos13 = Vec3.createVectorHelper(startPos.xCoord, startPos.yCoord + (double) this.theEntity.height * 0.1D, startPos.zCoord - this.theEntity.width); - Vec3 pos14 = Vec3.createVectorHelper(endPos.xCoord, endPos.yCoord + (double) this.theEntity.height, endPos.zCoord + this.theEntity.width); - MovingObjectPosition var8 = this.worldObj.func_147447_a(pos14, pos13, false, false, false); - if (!(var8 == null || var8.typeOfHit == MovingObjectPosition.MovingObjectType.MISS)) - return false; - } else { - Vec3 pos3 = Vec3.createVectorHelper(startPos.xCoord + this.theEntity.width, startPos.yCoord + (double) this.theEntity.height, startPos.zCoord); - Vec3 pos4 = Vec3.createVectorHelper(endPos.xCoord - this.theEntity.width, endPos.yCoord + (double) this.theEntity.height * 0.1D, endPos.zCoord); - MovingObjectPosition var3 = this.worldObj.func_147447_a(pos3, pos4, false, false, false); - if (!(var3 == null || var3.typeOfHit == MovingObjectPosition.MovingObjectType.MISS)) - return false; + if (movingobjectposition != null && movingobjectposition.typeOfHit != MovingObjectPosition.MovingObjectType.MISS) + { + return true; + } + } - Vec3 pos7 = Vec3.createVectorHelper(startPos.xCoord - this.theEntity.width, startPos.yCoord + (double) this.theEntity.height, startPos.zCoord); - Vec3 pos8 = Vec3.createVectorHelper(endPos.xCoord + this.theEntity.width, endPos.yCoord + (double) this.theEntity.height * 0.1D, endPos.zCoord); - MovingObjectPosition var5 = this.worldObj.func_147447_a(pos7, pos8, false, false, false); - if (!(var5 == null || var5.typeOfHit == MovingObjectPosition.MovingObjectType.MISS)) - return false; + MovingObjectPosition movingobjectposition2 = null; + k1 = 200; - Vec3 pos11 = Vec3.createVectorHelper(startPos.xCoord, startPos.yCoord + (double) this.theEntity.height, startPos.zCoord + this.theEntity.width); - Vec3 pos12 = Vec3.createVectorHelper(endPos.xCoord, endPos.yCoord + (double) this.theEntity.height * 0.1D, endPos.zCoord - this.theEntity.width); - MovingObjectPosition var7 = this.worldObj.func_147447_a(pos11, pos12, false, false, false); - if (!(var7 == null || var7.typeOfHit == MovingObjectPosition.MovingObjectType.MISS)) - return false; + while (k1-- >= 0) + { + if (Double.isNaN(p_147447_1_.xCoord) || Double.isNaN(p_147447_1_.yCoord) || Double.isNaN(p_147447_1_.zCoord)) + { + return false; + } - Vec3 pos15 = Vec3.createVectorHelper(startPos.xCoord, startPos.yCoord + (double) this.theEntity.height, startPos.zCoord - this.theEntity.width); - Vec3 pos16 = Vec3.createVectorHelper(endPos.xCoord, endPos.yCoord + (double) this.theEntity.height * 0.1D, endPos.zCoord + this.theEntity.width); - MovingObjectPosition var9 = this.worldObj.func_147447_a(pos15, pos16, false, false, false); - if (!(var9 == null || var9.typeOfHit == MovingObjectPosition.MovingObjectType.MISS)) + if (l == i && i1 == j && j1 == k) + { + if (p_147447_5_) { + return movingobjectposition2 != null && movingobjectposition2.typeOfHit != MovingObjectPosition.MovingObjectType.MISS; + } + return false; + } + + boolean flag6 = true; + boolean flag3 = true; + boolean flag4 = true; + double d0 = 999.0D; + double d1 = 999.0D; + double d2 = 999.0D; + + if (i > l) + { + d0 = (double)l + 1.0D; + } + else if (i < l) + { + d0 = (double)l + 0.0D; + } + else + { + flag6 = false; + } + + if (j > i1) + { + d1 = (double)i1 + 1.0D; + } + else if (j < i1) + { + d1 = (double)i1 + 0.0D; + } + else + { + flag3 = false; + } + + if (k > j1) + { + d2 = (double)j1 + 1.0D; + } + else if (k < j1) + { + d2 = (double)j1 + 0.0D; + } + else + { + flag4 = false; + } + + double d3 = 999.0D; + double d4 = 999.0D; + double d5 = 999.0D; + double d6 = p_147447_2_.xCoord - p_147447_1_.xCoord; + double d7 = p_147447_2_.yCoord - p_147447_1_.yCoord; + double d8 = p_147447_2_.zCoord - p_147447_1_.zCoord; + + if (flag6) + { + d3 = (d0 - p_147447_1_.xCoord) / d6; + } + + if (flag3) + { + d4 = (d1 - p_147447_1_.yCoord) / d7; + } + + if (flag4) + { + d5 = (d2 - p_147447_1_.zCoord) / d8; + } + + boolean flag5 = false; + byte b0; + + if (d3 < d4 && d3 < d5) + { + if (i > l) + { + b0 = 4; + } + else + { + b0 = 5; + } + + p_147447_1_.xCoord = d0; + p_147447_1_.yCoord += d7 * d3; + p_147447_1_.zCoord += d8 * d3; + } + else if (d4 < d5) + { + if (j > i1) + { + b0 = 0; + } + else + { + b0 = 1; + } + + p_147447_1_.xCoord += d6 * d4; + p_147447_1_.yCoord = d1; + p_147447_1_.zCoord += d8 * d4; + } + else + { + if (k > j1) + { + b0 = 2; + } + else + { + b0 = 3; + } + + p_147447_1_.xCoord += d6 * d5; + p_147447_1_.yCoord += d7 * d5; + p_147447_1_.zCoord = d2; + } + + Vec3 vec32 = Vec3.createVectorHelper(p_147447_1_.xCoord, p_147447_1_.yCoord, p_147447_1_.zCoord); + l = (int)(vec32.xCoord = (double)MathHelper.floor_double(p_147447_1_.xCoord)); + + if (b0 == 5) + { + --l; + ++vec32.xCoord; + } + + i1 = (int)(vec32.yCoord = (double)MathHelper.floor_double(p_147447_1_.yCoord)); + + if (b0 == 1) + { + --i1; + ++vec32.yCoord; + } + + j1 = (int)(vec32.zCoord = (double)MathHelper.floor_double(p_147447_1_.zCoord)); + + if (b0 == 3) + { + --j1; + ++vec32.zCoord; + } + + boolean value = false; + for (int x = 1 - width; x < width; x++) { + if (value) { + break; + } + for (int y = 0; y <= height; y++) { + if (value) { + break; + } + for (int z = 1 - width; z < width; z++) { + l += x; + i1 += y; + j1 += z; + + CacheKey key = new CacheKey(this.theEntity, Vec3.createVectorHelper(l,i1,j1)); + Boolean hashCollides = PathNavigateFlying.pathClearCache.get(key); + if (hashCollides != null && hashCollides) { + value = true; + l -= x; + i1 -= y; + j1 -= z; + break; + } + + Block block2 = this.worldObj.getBlock(l, i1, j1); + int meta2 = this.worldObj.getBlockMetadata(l, i1, j1); + + if (block2 != Blocks.air && (!p_147447_4_ || block2.getCollisionBoundingBoxFromPool(this.worldObj, l, i1, j1) != null) + && block2.canCollideCheck(meta2, p_147447_3_)) { + if (!block2.getBlocksMovement(this.worldObj, l, i1, j1)) { + value = true; + l -= x; + i1 -= y; + j1 -= z; + break; + } + MovingObjectPosition movingobjectposition = block2.collisionRayTrace(this.worldObj, l, i1, j1, p_147447_1_, p_147447_2_); + + if (movingobjectposition != null && movingobjectposition.typeOfHit != MovingObjectPosition.MovingObjectType.MISS) { + value = true; + l -= x; + i1 -= y; + j1 -= z; + break; + } else { + movingobjectposition2 = new MovingObjectPosition(l, i1, j1, b0, p_147447_1_, false); + } + } + + l -= x; + i1 -= y; + j1 -= z; + } + } + } + + for (int x = 1 - width; x < width; x++) { + for (int y = 0; y <= height; y++) { + for (int z = 1 - width; z < width; z++) { + l += x; + i1 += y; + j1 += z; + CacheKey key = new CacheKey(this.theEntity, Vec3.createVectorHelper(l,i1,j1)); + + if (value) { + PathNavigateFlying.pathClearCache.put(key, true); + } else { + PathNavigateFlying.pathClearCache.put(key, false); + } + + l -= x; + i1 -= y; + j1 -= z; + } + } + } + + if (value) { + return true; + } + } + + if (p_147447_5_) { + return movingobjectposition2 != null && movingobjectposition2.typeOfHit != MovingObjectPosition.MovingObjectType.MISS; + } return false; + } + else + { + return false; + } + } + else + { + return false; + } + } + + static class CacheKey { + private final World world; + private final double posX, posY, posZ; + + public CacheKey(Entity entity, Vec3 vec3) { + this.world = entity.worldObj; + this.posX = vec3.xCoord; + this.posY = vec3.yCoord; + this.posZ = vec3.zCoord; } - return true; + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + CacheKey cacheKey = (CacheKey) o; + + if (Double.compare(cacheKey.posX, posX) != 0) + return false; + if (Double.compare(cacheKey.posY, posY) != 0) + return false; + if (Double.compare(cacheKey.posZ, posZ) != 0) + return false; + + return world.equals(cacheKey.world); + } + + @Override + public int hashCode() { + int result; + long temp; + result = world.hashCode(); + temp = Double.doubleToLongBits(posX); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(posY); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(posZ); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + return result; + } } protected void checkForStuck(Vec3 positionVec3) From d86f571df64f255d214abbbe5c4c8df7d645e118 Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Sat, 12 Nov 2022 15:53:20 -0600 Subject: [PATCH 11/17] PathNavigateFlying: -Fixed pathfinder running into lava & water when it shouldn't. FlyPathFinder: -Simplified nodeTypeToOffset switch statement, removed unused function, and made air always return an open path node type. EntityNPCInterface: -Fixed "In Air" drowning type. Breathes underwater now. EntityNPCFlying: -Fixed NPCs still using flight movement when not being able to breathe. ICustomNpc: -Added canBreathe() function --- .../npcs/ai/pathfinder/FlyPathFinder.java | 42 ++++++------------- .../ai/pathfinder/PathNavigateFlying.java | 11 +++-- .../noppes/npcs/entity/EntityNPCFlying.java | 2 +- .../npcs/entity/EntityNPCInterface.java | 29 +++++++++++-- .../npcs/scripted/entity/ScriptNpc.java | 4 ++ .../interfaces/entity/ICustomNpc.java | 2 + 6 files changed, 53 insertions(+), 37 deletions(-) diff --git a/src/main/java/noppes/npcs/ai/pathfinder/FlyPathFinder.java b/src/main/java/noppes/npcs/ai/pathfinder/FlyPathFinder.java index 7a7462321..46d94f044 100644 --- a/src/main/java/noppes/npcs/ai/pathfinder/FlyPathFinder.java +++ b/src/main/java/noppes/npcs/ai/pathfinder/FlyPathFinder.java @@ -473,40 +473,30 @@ public class FlyPathFinder extends PathFinder public int nodeTypeToOffset(PathNodeType nodeType) { switch (nodeType) { - case BLOCKED: - return 0; - case OPEN: - return 2; - case WALKABLE: - return 1; case TRAPDOOR: return -4; case FENCE: return -3; case LAVA: - return -2; - case WATER: - return -1; - case RAIL: - return 2; - case DANGER_FIRE: - return -1; case DAMAGE_FIRE: - return -2; - case DANGER_CACTUS: - return -1; case DAMAGE_CACTUS: - return -2; - case DANGER_OTHER: - return -1; case DAMAGE_OTHER: return -2; - case DOOR_OPEN: - return 1; + case WATER: + case DANGER_FIRE: + case DANGER_CACTUS: + case DANGER_OTHER: + return -1; + case BLOCKED: case DOOR_WOOD_CLOSED: - return 0; case DOOR_IRON_CLOSED: return 0; + case WALKABLE: + case DOOR_OPEN: + return 1; + case OPEN: + case RAIL: + return 2; } return 1; @@ -526,12 +516,6 @@ public class FlyPathFinder extends PathFinder return pathpoint; } - public NPCPathPoint getPointFromHash(int x, int y, int z) - { - int i = NPCPathPoint.makeHash(x, y, z); - return this.pointMap.lookup(i); - } - /** * Returns a new FlyPathEntity for a given start and end point */ @@ -721,7 +705,7 @@ public class FlyPathFinder extends PathFinder if (material == Material.air) { - return drowningType == 2 ? PathNodeType.WATER : PathNodeType.OPEN; + return PathNodeType.OPEN; } else if (block != Blocks.trapdoor && block != Blocks.waterlily) { diff --git a/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java b/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java index 740e3f92a..725ca0dc6 100644 --- a/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java +++ b/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java @@ -1,6 +1,7 @@ package noppes.npcs.ai.pathfinder; import net.minecraft.block.Block; +import net.minecraft.block.material.Material; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.SharedMonsterAttributes; @@ -438,7 +439,7 @@ public class PathNavigateFlying extends PathNavigate { { Vec3 pos17 = Vec3.createVectorHelper(startPos.xCoord,startPos.yCoord, startPos.zCoord); Vec3 pos18 = Vec3.createVectorHelper(endPos.xCoord,endPos.yCoord, endPos.zCoord); - if (this.rayTraceBlocks(pos17, pos18, false, false, false, width, height)) + if (this.rayTraceBlocks(pos17, pos18, true, false, false, width, height)) return false; return true; @@ -656,15 +657,19 @@ public class PathNavigateFlying extends PathNavigate { Block block2 = this.worldObj.getBlock(l, i1, j1); int meta2 = this.worldObj.getBlockMetadata(l, i1, j1); - if (block2 != Blocks.air && (!p_147447_4_ || block2.getCollisionBoundingBoxFromPool(this.worldObj, l, i1, j1) != null) + if ((!p_147447_4_ || block2.getCollisionBoundingBoxFromPool(this.worldObj, l, i1, j1) != null) && block2.canCollideCheck(meta2, p_147447_3_)) { - if (!block2.getBlocksMovement(this.worldObj, l, i1, j1)) { + if (block2.getMaterial() == Material.lava && !this.theEntity.isImmuneToFire() || + block2.getMaterial() == Material.air && this.theEntity.stats.drowningType == 2 || + block2.getMaterial() == Material.water && this.theEntity.stats.drowningType == 1 || + !block2.getBlocksMovement(this.worldObj, l, i1, j1)) { value = true; l -= x; i1 -= y; j1 -= z; break; } + MovingObjectPosition movingobjectposition = block2.collisionRayTrace(this.worldObj, l, i1, j1, p_147447_1_, p_147447_2_); if (movingobjectposition != null && movingobjectposition.typeOfHit != MovingObjectPosition.MovingObjectType.MISS) { diff --git a/src/main/java/noppes/npcs/entity/EntityNPCFlying.java b/src/main/java/noppes/npcs/entity/EntityNPCFlying.java index 0d50392aa..172c62dc9 100644 --- a/src/main/java/noppes/npcs/entity/EntityNPCFlying.java +++ b/src/main/java/noppes/npcs/entity/EntityNPCFlying.java @@ -35,7 +35,7 @@ public abstract class EntityNPCFlying extends EntityNPCInterface { public void moveEntityWithHeading(float p_70612_1_, float p_70612_2_) { - if(!this.canFly() || this.hurtTime != 0) { + if(!this.canFly() || this.hurtTime != 0 || !this.canBreathe()) { super.moveEntityWithHeading(p_70612_1_, p_70612_2_); return; } diff --git a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java index 1a7f6a60f..e645409d5 100644 --- a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java +++ b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java @@ -6,6 +6,7 @@ import java.io.IOException; import java.util.*; import net.minecraft.block.Block; +import net.minecraft.block.material.Material; import net.minecraft.command.ICommandSender; import net.minecraft.command.IEntitySelector; import net.minecraft.entity.*; @@ -415,10 +416,14 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti } } + public boolean canBreathe() { + return this.isInWater() && this.stats.drowningType == 2 || !this.isInWater() && this.stats.drowningType == 1 || this.stats.drowningType == 0; + } + @Override protected void updateAITasks() { - if (this.isInWater() || this.stats.drowningType != 2) { + if (this.canBreathe()) { this.getNavigator().onUpdateNavigation(); this.getMoveHelper().onUpdateMoveHelper(); try { @@ -1054,7 +1059,7 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti this.setRevengeTarget(null); this.deathTime = 0; //fleeingTick = 0; - if(ai.returnToStart && !hasOwner()) + if(ai.returnToStart && !hasOwner() && !this.isRemote()) setLocationAndAngles(getStartXPos(), getStartYPos(), getStartZPos(), rotationYaw, rotationPitch); killedtime = 0; extinguish(); @@ -1351,7 +1356,7 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti } if (yy <= 0) setDead(); - yy += 0.5; + //yy += 0.5; return yy; } @@ -1632,7 +1637,23 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti public boolean handleWaterMovement() { - return stats.drowningType == 1 && super.handleWaterMovement(); + if (stats.drowningType != 1) { + if (this.worldObj.handleMaterialAcceleration(this.boundingBox.expand(0.0D, -0.4000000059604645D, 0.0D).contract(0.001D, 0.001D, 0.001D), Material.water, this)) { + this.fallDistance = 0.0F; + this.inWater = true; + this.setFire(0); + } else { + this.inWater = false; + } + return false; + } else { + return super.handleWaterMovement(); + } + } + + public boolean canBreatheUnderwater() + { + return stats.drowningType != 1; } public void setAvoidWater(boolean avoidWater) { diff --git a/src/main/java/noppes/npcs/scripted/entity/ScriptNpc.java b/src/main/java/noppes/npcs/scripted/entity/ScriptNpc.java index 851bf1617..f11a93abb 100644 --- a/src/main/java/noppes/npcs/scripted/entity/ScriptNpc.java +++ b/src/main/java/noppes/npcs/scripted/entity/ScriptNpc.java @@ -1071,6 +1071,10 @@ public class ScriptNpc extends ScriptLiving imp npc.stats.drowningType = type; } + public boolean canBreathe() { + return npc.canBreathe(); + } + @Override public long getAge(){ return npc.totalTicksAlive; diff --git a/src/main/java/noppes/npcs/scripted/interfaces/entity/ICustomNpc.java b/src/main/java/noppes/npcs/scripted/interfaces/entity/ICustomNpc.java index 8e684cc71..6f06b4133 100644 --- a/src/main/java/noppes/npcs/scripted/interfaces/entity/ICustomNpc.java +++ b/src/main/java/noppes/npcs/scripted/interfaces/entity/ICustomNpc.java @@ -371,6 +371,8 @@ public interface ICustomNpc extends IEntityLiving { */ void setDrowningType(int type); + boolean canBreathe(); + /** * @param type The AnimationType */ From 52563f1cfe996d95347e12d1464c76e78fd9a037 Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Sat, 12 Nov 2022 17:25:01 -0600 Subject: [PATCH 12/17] Reverted PathNavigateFlying. --- .../noppes/npcs/ai/pathfinder/PathNavigateFlying.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java b/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java index 725ca0dc6..740e3f92a 100644 --- a/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java +++ b/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java @@ -1,7 +1,6 @@ package noppes.npcs.ai.pathfinder; import net.minecraft.block.Block; -import net.minecraft.block.material.Material; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.SharedMonsterAttributes; @@ -439,7 +438,7 @@ public class PathNavigateFlying extends PathNavigate { { Vec3 pos17 = Vec3.createVectorHelper(startPos.xCoord,startPos.yCoord, startPos.zCoord); Vec3 pos18 = Vec3.createVectorHelper(endPos.xCoord,endPos.yCoord, endPos.zCoord); - if (this.rayTraceBlocks(pos17, pos18, true, false, false, width, height)) + if (this.rayTraceBlocks(pos17, pos18, false, false, false, width, height)) return false; return true; @@ -657,19 +656,15 @@ public class PathNavigateFlying extends PathNavigate { Block block2 = this.worldObj.getBlock(l, i1, j1); int meta2 = this.worldObj.getBlockMetadata(l, i1, j1); - if ((!p_147447_4_ || block2.getCollisionBoundingBoxFromPool(this.worldObj, l, i1, j1) != null) + if (block2 != Blocks.air && (!p_147447_4_ || block2.getCollisionBoundingBoxFromPool(this.worldObj, l, i1, j1) != null) && block2.canCollideCheck(meta2, p_147447_3_)) { - if (block2.getMaterial() == Material.lava && !this.theEntity.isImmuneToFire() || - block2.getMaterial() == Material.air && this.theEntity.stats.drowningType == 2 || - block2.getMaterial() == Material.water && this.theEntity.stats.drowningType == 1 || - !block2.getBlocksMovement(this.worldObj, l, i1, j1)) { + if (!block2.getBlocksMovement(this.worldObj, l, i1, j1)) { value = true; l -= x; i1 -= y; j1 -= z; break; } - MovingObjectPosition movingobjectposition = block2.collisionRayTrace(this.worldObj, l, i1, j1, p_147447_1_, p_147447_2_); if (movingobjectposition != null && movingobjectposition.typeOfHit != MovingObjectPosition.MovingObjectType.MISS) { From e1c9b69335fd380803d513832408490469de2f2e Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Sat, 12 Nov 2022 17:43:36 -0600 Subject: [PATCH 13/17] Removed LRU hashmap, increases performance. --- .../ai/pathfinder/PathNavigateFlying.java | 80 ------------------- 1 file changed, 80 deletions(-) diff --git a/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java b/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java index 740e3f92a..0ca408e6f 100644 --- a/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java +++ b/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java @@ -16,13 +16,9 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.ChunkCache; import net.minecraft.world.World; import noppes.npcs.entity.EntityNPCInterface; -import noppes.npcs.util.LRUHashMap; - import javax.annotation.Nullable; -import java.util.Map; public class PathNavigateFlying extends PathNavigate { - private static final Map pathClearCache = new LRUHashMap<>(5000); private EntityNPCInterface theEntity; private World worldObj; @@ -643,16 +639,6 @@ public class PathNavigateFlying extends PathNavigate { i1 += y; j1 += z; - CacheKey key = new CacheKey(this.theEntity, Vec3.createVectorHelper(l,i1,j1)); - Boolean hashCollides = PathNavigateFlying.pathClearCache.get(key); - if (hashCollides != null && hashCollides) { - value = true; - l -= x; - i1 -= y; - j1 -= z; - break; - } - Block block2 = this.worldObj.getBlock(l, i1, j1); int meta2 = this.worldObj.getBlockMetadata(l, i1, j1); @@ -685,27 +671,6 @@ public class PathNavigateFlying extends PathNavigate { } } - for (int x = 1 - width; x < width; x++) { - for (int y = 0; y <= height; y++) { - for (int z = 1 - width; z < width; z++) { - l += x; - i1 += y; - j1 += z; - CacheKey key = new CacheKey(this.theEntity, Vec3.createVectorHelper(l,i1,j1)); - - if (value) { - PathNavigateFlying.pathClearCache.put(key, true); - } else { - PathNavigateFlying.pathClearCache.put(key, false); - } - - l -= x; - i1 -= y; - j1 -= z; - } - } - } - if (value) { return true; } @@ -727,51 +692,6 @@ public class PathNavigateFlying extends PathNavigate { } } - static class CacheKey { - private final World world; - private final double posX, posY, posZ; - - public CacheKey(Entity entity, Vec3 vec3) { - this.world = entity.worldObj; - this.posX = vec3.xCoord; - this.posY = vec3.yCoord; - this.posZ = vec3.zCoord; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - - CacheKey cacheKey = (CacheKey) o; - - if (Double.compare(cacheKey.posX, posX) != 0) - return false; - if (Double.compare(cacheKey.posY, posY) != 0) - return false; - if (Double.compare(cacheKey.posZ, posZ) != 0) - return false; - - return world.equals(cacheKey.world); - } - - @Override - public int hashCode() { - int result; - long temp; - result = world.hashCode(); - temp = Double.doubleToLongBits(posX); - result = 31 * result + (int) (temp ^ (temp >>> 32)); - temp = Double.doubleToLongBits(posY); - result = 31 * result + (int) (temp ^ (temp >>> 32)); - temp = Double.doubleToLongBits(posZ); - result = 31 * result + (int) (temp ^ (temp >>> 32)); - return result; - } - } - protected void checkForStuck(Vec3 positionVec3) { if (this.totalTicks - this.ticksAtLastPos > 100) From 51b412a0bffd4140657c859901d9736ff7de07ae Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Sun, 13 Nov 2022 23:49:49 -0600 Subject: [PATCH 14/17] Pathing improvements. EntityAIReturn: -Fixed NPC still creating a new path when close to the NPC's home. EntityNPCInterface: -Fixed flying NPCs having their home Y position dip into the ground. -NPCs update their move helpers and navigators when they can't breathe. FlyingMoveHelper: -Reduced calls to Math.atan2 (very expensive operation to be unnecessarily calling every tick) FlyPathFinder: -Water opens an OPEN path point iff the NPC can swim, not iff the NPC's drowning type != 1. NPCPath: -Made PathPoint occurrences use NPCPathPoint PathNavigateFlying: -A slightly larger area of blocks with respect to width is checked om rayTraceBlocks(), and the function now also correctly checks for liquids. --- .../java/noppes/npcs/ai/EntityAIReturn.java | 4 +- .../npcs/ai/pathfinder/FlyPathFinder.java | 2 +- .../npcs/ai/pathfinder/FlyingMoveHelper.java | 3 +- .../noppes/npcs/ai/pathfinder/NPCPath.java | 14 +++---- .../ai/pathfinder/PathNavigateFlying.java | 19 +++++++--- .../npcs/entity/EntityNPCInterface.java | 37 ++++++++++++------- 6 files changed, 47 insertions(+), 32 deletions(-) diff --git a/src/main/java/noppes/npcs/ai/EntityAIReturn.java b/src/main/java/noppes/npcs/ai/EntityAIReturn.java index 94014013d..8920ac61a 100644 --- a/src/main/java/noppes/npcs/ai/EntityAIReturn.java +++ b/src/main/java/noppes/npcs/ai/EntityAIReturn.java @@ -137,7 +137,7 @@ public class EntityAIReturn extends EntityAIBase distance /= 2; if(distance > 2){ Vec3 start = Vec3.createVectorHelper(posX, posY, posZ); - Vec3 pos = RandomPositionGeneratorAlt.findRandomTargetBlockTowards(npc, distance,distance /2 > 7? 7:distance/2, start); + Vec3 pos = RandomPositionGeneratorAlt.findRandomTargetBlockTowards(npc, distance, Math.min(distance / 2, 7), start); if(pos != null){ posX = pos.xCoord; posY = pos.yCoord; @@ -146,7 +146,7 @@ public class EntityAIReturn extends EntityAIBase } } - if (range > 1f) { + if (range > 1.1f) { npc.getNavigator().clearPathEntity(); npc.getNavigator().tryMoveToXYZ(posX, posY, posZ, 1); } diff --git a/src/main/java/noppes/npcs/ai/pathfinder/FlyPathFinder.java b/src/main/java/noppes/npcs/ai/pathfinder/FlyPathFinder.java index 46d94f044..0aee35ccc 100644 --- a/src/main/java/noppes/npcs/ai/pathfinder/FlyPathFinder.java +++ b/src/main/java/noppes/npcs/ai/pathfinder/FlyPathFinder.java @@ -737,7 +737,7 @@ public class FlyPathFinder extends PathFinder { if (material == Material.water) { - return drowningType == 1 ? PathNodeType.WATER : PathNodeType.OPEN; + return ((EntityNPCInterface)this.theEntity).ai.canSwim ? PathNodeType.OPEN : PathNodeType.WATER; } else if (material == Material.lava) { diff --git a/src/main/java/noppes/npcs/ai/pathfinder/FlyingMoveHelper.java b/src/main/java/noppes/npcs/ai/pathfinder/FlyingMoveHelper.java index 00c1cb336..da6508f77 100644 --- a/src/main/java/noppes/npcs/ai/pathfinder/FlyingMoveHelper.java +++ b/src/main/java/noppes/npcs/ai/pathfinder/FlyingMoveHelper.java @@ -51,9 +51,8 @@ public class FlyingMoveHelper extends EntityMoveHelper{ } this.entity.velocityChanged = true; + this.entity.rotationYaw = this.limitAngle(this.entity.rotationYaw,(float) ((Math.atan2(-d0, -d2) + Math.PI) * -(180F / Math.PI)),20.0F); } - - this.entity.rotationYaw = this.limitAngle(this.entity.rotationYaw,(float) ((Math.atan2(-d0, -d2) + Math.PI) * -(180F / Math.PI)),20.0F); } } diff --git a/src/main/java/noppes/npcs/ai/pathfinder/NPCPath.java b/src/main/java/noppes/npcs/ai/pathfinder/NPCPath.java index 0f5cad721..254dd999e 100644 --- a/src/main/java/noppes/npcs/ai/pathfinder/NPCPath.java +++ b/src/main/java/noppes/npcs/ai/pathfinder/NPCPath.java @@ -6,13 +6,13 @@ import net.minecraft.pathfinding.PathPoint; import net.minecraft.util.Vec3; public class NPCPath extends PathEntity{ - public final PathPoint[] points; + public final NPCPathPoint[] points; /** PathEntity Array Index the Entity is currently targeting */ public int currentPathIndex; /** The total length of the path */ public int pathLength; - public NPCPath(PathPoint[] pointsIn) + public NPCPath(NPCPathPoint[] pointsIn) { super(pointsIn); this.points = pointsIn; @@ -38,7 +38,7 @@ public class NPCPath extends PathEntity{ /** * returns the last PathPoint of the Array */ - public PathPoint getFinalPathPoint() + public NPCPathPoint getFinalPathPoint() { return this.pathLength > 0 ? this.points[this.pathLength - 1] : null; } @@ -46,7 +46,7 @@ public class NPCPath extends PathEntity{ /** * return the PathPoint located at the specified PathIndex, usually the current one */ - public PathPoint getPathPointFromIndex(int p_75877_1_) + public NPCPathPoint getPathPointFromIndex(int p_75877_1_) { return this.points[p_75877_1_]; } @@ -77,7 +77,7 @@ public class NPCPath extends PathEntity{ public Vec3 getVectorFromIndex(Entity entity, int index) { double d0 = (double)this.points[index].xCoord + (double)((int)(entity.width + 1.0F)) * 0.5D; - double d1 = (double)this.points[index].yCoord; + double d1 = (double)this.points[index].yCoord + 0.05D; double d2 = (double)this.points[index].zCoord + (double)((int)(entity.width + 1.0F)) * 0.5D; return Vec3.createVectorHelper(d0, d1, d2); } @@ -92,7 +92,7 @@ public class NPCPath extends PathEntity{ public Vec3 getCurrentPos() { - PathPoint pathpoint = this.points[this.currentPathIndex]; + NPCPathPoint pathpoint = this.points[this.currentPathIndex]; return Vec3.createVectorHelper((double)pathpoint.xCoord, (double)pathpoint.yCoord, (double)pathpoint.zCoord); } @@ -129,7 +129,7 @@ public class NPCPath extends PathEntity{ */ public boolean isDestinationSame(Vec3 vec3) { - PathPoint pathpoint = this.getFinalPathPoint(); + NPCPathPoint pathpoint = this.getFinalPathPoint(); return pathpoint == null ? false : pathpoint.xCoord == (int)vec3.xCoord && pathpoint.zCoord == (int)vec3.zCoord; } } diff --git a/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java b/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java index 0ca408e6f..5a8ce0c64 100644 --- a/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java +++ b/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java @@ -1,6 +1,7 @@ package noppes.npcs.ai.pathfinder; import net.minecraft.block.Block; +import net.minecraft.block.material.Material; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.SharedMonsterAttributes; @@ -434,7 +435,7 @@ public class PathNavigateFlying extends PathNavigate { { Vec3 pos17 = Vec3.createVectorHelper(startPos.xCoord,startPos.yCoord, startPos.zCoord); Vec3 pos18 = Vec3.createVectorHelper(endPos.xCoord,endPos.yCoord, endPos.zCoord); - if (this.rayTraceBlocks(pos17, pos18, false, false, false, width, height)) + if (this.rayTraceBlocks(pos17, pos18, true, false, false, width, height)) return false; return true; @@ -626,7 +627,7 @@ public class PathNavigateFlying extends PathNavigate { } boolean value = false; - for (int x = 1 - width; x < width; x++) { + for (int x = -width; x <= width; x++) { if (value) { break; } @@ -634,7 +635,11 @@ public class PathNavigateFlying extends PathNavigate { if (value) { break; } - for (int z = 1 - width; z < width; z++) { + for (int z = -width; z <= width; z++) { + if (Math.abs(x) == Math.abs(z)) { + continue; + } + l += x; i1 += y; j1 += z; @@ -642,8 +647,11 @@ public class PathNavigateFlying extends PathNavigate { Block block2 = this.worldObj.getBlock(l, i1, j1); int meta2 = this.worldObj.getBlockMetadata(l, i1, j1); - if (block2 != Blocks.air && (!p_147447_4_ || block2.getCollisionBoundingBoxFromPool(this.worldObj, l, i1, j1) != null) - && block2.canCollideCheck(meta2, p_147447_3_)) { + boolean collideCheck = (!p_147447_4_ || block2.getCollisionBoundingBoxFromPool(this.worldObj, l, i1, j1) != null) && block2.canCollideCheck(meta2, p_147447_3_); + boolean noCollisionBlock = block2 == Blocks.air || block2.getMaterial() == Material.lava && this.theEntity.isImmuneToFire() || + block2.getMaterial() == Material.water && this.theEntity.stats.drowningType == 2; + + if (collideCheck && !noCollisionBlock) { if (!block2.getBlocksMovement(this.worldObj, l, i1, j1)) { value = true; l -= x; @@ -652,7 +660,6 @@ public class PathNavigateFlying extends PathNavigate { break; } MovingObjectPosition movingobjectposition = block2.collisionRayTrace(this.worldObj, l, i1, j1, p_147447_1_, p_147447_2_); - if (movingobjectposition != null && movingobjectposition.typeOfHit != MovingObjectPosition.MovingObjectType.MISS) { value = true; l -= x; diff --git a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java index e645409d5..8f38e32ef 100644 --- a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java +++ b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java @@ -21,6 +21,7 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.projectile.EntityArrow; import net.minecraft.entity.projectile.EntityThrowable; +import net.minecraft.init.Blocks; import net.minecraft.item.Item; import net.minecraft.item.ItemBow; import net.minecraft.item.ItemStack; @@ -423,13 +424,13 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti @Override protected void updateAITasks() { - if (this.canBreathe()) { - this.getNavigator().onUpdateNavigation(); - this.getMoveHelper().onUpdateMoveHelper(); - try { - super.updateAITasks(); - } catch (ConcurrentModificationException ignored){} - } else { + this.getNavigator().onUpdateNavigation(); + this.getMoveHelper().onUpdateMoveHelper(); + try { + super.updateAITasks(); + } catch (ConcurrentModificationException ignored){} + + if (!this.canBreathe()) { this.setAir(this.decreaseAirSupply(this.getAir())); if (this.getAir() <= -20) { @@ -1340,10 +1341,21 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti int j = getStartPos()[1]; int k = getStartPos()[2]; double yy = 0; - if (!this.canFly()) { - for (int ii = j; ii >= 0; ii--) { + for (int ii = j; ii >= 0; ii--) { + if (this.canFly()) { + if (ii < j - 1) { + yy = j; + break; + } Block block = worldObj.getBlock(i, ii, k); - if (block == null) + AxisAlignedBB bb = block.getCollisionBoundingBoxFromPool(worldObj, i, ii, k); + if (bb != null) { + yy = bb.maxY; + break; + } + } else { + Block block = worldObj.getBlock(i, ii, k); + if (block == null || block == Blocks.air) continue; AxisAlignedBB bb = block.getCollisionBoundingBoxFromPool(worldObj, i, ii, k); if (bb == null) @@ -1351,12 +1363,9 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti yy = bb.maxY; break; } - } else { - yy = j; } if (yy <= 0) setDead(); - //yy += 0.5; return yy; } @@ -1638,7 +1647,7 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti public boolean handleWaterMovement() { if (stats.drowningType != 1) { - if (this.worldObj.handleMaterialAcceleration(this.boundingBox.expand(0.0D, -0.4000000059604645D, 0.0D).contract(0.001D, 0.001D, 0.001D), Material.water, this)) { + if (this.worldObj.handleMaterialAcceleration(this.boundingBox.expand(0.0D, -this.height/2.0D, 0.0D).contract(0.001D, 0.001D, 0.001D), Material.water, this)) { this.fallDistance = 0.0F; this.inWater = true; this.setFire(0); From 69afa29e9cd5f8fd808ae5234e1380eacabe878c Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Mon, 14 Nov 2022 20:22:50 -0600 Subject: [PATCH 15/17] EntityNPCFlying: -Fixed fly height limit --- .../java/noppes/npcs/entity/EntityNPCFlying.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/main/java/noppes/npcs/entity/EntityNPCFlying.java b/src/main/java/noppes/npcs/entity/EntityNPCFlying.java index 172c62dc9..86dd84c19 100644 --- a/src/main/java/noppes/npcs/entity/EntityNPCFlying.java +++ b/src/main/java/noppes/npcs/entity/EntityNPCFlying.java @@ -1,6 +1,7 @@ package noppes.npcs.entity; -import net.minecraft.init.Blocks; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.Vec3; import net.minecraft.world.World; public abstract class EntityNPCFlying extends EntityNPCInterface { @@ -40,8 +41,19 @@ public abstract class EntityNPCFlying extends EntityNPCInterface { return; } + boolean aboveLimit = false; double heightOffGround = this.posY - this.worldObj.getTopSolidOrLiquidBlock((int) this.posX, (int) this.posZ); - if (heightOffGround > this.ai.flyHeightLimit && this.ai.hasFlyLimit || (heightOffGround < Math.ceil(this.height) && this.motionY == 0)) { + if (heightOffGround < 0) { + Vec3 pos = Vec3.createVectorHelper(this.posX,this.posY,this.posZ); + Vec3 posLimit = Vec3.createVectorHelper(this.posX,this.posY - this.ai.flyHeightLimit,this.posZ); + MovingObjectPosition mob = this.worldObj.rayTraceBlocks(pos,posLimit,true); + if (mob == null || mob.typeOfHit == MovingObjectPosition.MovingObjectType.MISS) { + aboveLimit = true; + } + } else if (heightOffGround > this.ai.flyHeightLimit) { + aboveLimit = true; + } + if (aboveLimit && this.ai.hasFlyLimit || (heightOffGround < Math.ceil(this.height) && this.motionY == 0)) { this.flyLimitAllow = false; if (!this.getNavigator().noPath() && this.motionY > 0) { this.motionY = 0; From a9ade876efbc2708dff4fe72d1874b54f68c068e Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Mon, 14 Nov 2022 20:28:19 -0600 Subject: [PATCH 16/17] ItemSoulstoneFilled: -Fixed soulstoned flying NPCs dipping into the ground --- src/main/java/noppes/npcs/items/ItemSoulstoneFilled.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/noppes/npcs/items/ItemSoulstoneFilled.java b/src/main/java/noppes/npcs/items/ItemSoulstoneFilled.java index 914ba7bba..0c92a194c 100644 --- a/src/main/java/noppes/npcs/items/ItemSoulstoneFilled.java +++ b/src/main/java/noppes/npcs/items/ItemSoulstoneFilled.java @@ -83,7 +83,7 @@ public class ItemSoulstoneFilled extends Item { EntityNPCInterface npc = (EntityNPCInterface) entity; npc.ai.startPos = new int[]{x, y, z}; npc.setHealth(npc.getMaxHealth()); - npc.setPosition((float)x + 0.5F, npc.getStartYPos() - 0.5, (float)z + 0.5F); + npc.setPosition((float)x + 0.5F, npc.getStartYPos(), (float)z + 0.5F); npc.advanced.soulStonePlayerName = player.getDisplayName(); npc.advanced.soulStoneInit = true; if(npc.advanced.role == EnumRoleType.Companion && player != null){ From be654e19e186b1ac7eead0248b52e523f59208ff Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Mon, 14 Nov 2022 20:47:13 -0600 Subject: [PATCH 17/17] ModelWings: -Fixed wings spazzing out on flying NPCs --- src/main/java/noppes/npcs/client/model/part/ModelWings.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/noppes/npcs/client/model/part/ModelWings.java b/src/main/java/noppes/npcs/client/model/part/ModelWings.java index f9550baa3..6984e7d17 100644 --- a/src/main/java/noppes/npcs/client/model/part/ModelWings.java +++ b/src/main/java/noppes/npcs/client/model/part/ModelWings.java @@ -41,7 +41,7 @@ public class ModelWings extends ModelPartInterface { lWing.rotateAngleZ = -0.5090659F; float motion = Math.abs(MathHelper.sin(par1 * 0.033F + (float)Math.PI) * 0.4F) * par2; - if(!entity.onGround || motion > 0.01){ + if ((!entity.worldObj.isRemote && !entity.onGround) || motion > 0.1D) { float speed = (float) (0.55f + 0.5f * motion); float y = MathHelper.sin(par3 * 0.67F); @@ -50,8 +50,7 @@ public class ModelWings extends ModelPartInterface { lWing.rotateAngleZ -= y * 0.5f * speed; lWing.rotateAngleX += y * 0.5f * speed; - } - else{ + } else { lWing.rotateAngleZ += MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; rWing.rotateAngleZ -= MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; lWing.rotateAngleX += MathHelper.sin(par3 * 0.067F) * 0.05F;