diff --git a/src/main/java/noppes/npcs/ai/pathfinder/FlyPathFinder.java b/src/main/java/noppes/npcs/ai/pathfinder/FlyPathFinder.java index b008790d1..4eaed930e 100644 --- a/src/main/java/noppes/npcs/ai/pathfinder/FlyPathFinder.java +++ b/src/main/java/noppes/npcs/ai/pathfinder/FlyPathFinder.java @@ -1,14 +1,13 @@ package noppes.npcs.ai.pathfinder; import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import net.minecraft.block.*; import net.minecraft.block.material.Material; -import net.minecraft.block.state.IBlockState; 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; @@ -19,17 +18,18 @@ import noppes.npcs.entity.EntityNPCInterface; import javax.annotation.Nullable; import java.util.EnumSet; import java.util.Map; +import java.util.Set; public class FlyPathFinder extends PathFinder { /** Used to find obstacles */ private IBlockAccess worldMap; /** The path being generated */ - private FlyPath path = new FlyPath(); + private PathHeap path = new PathHeap(); /** The points in the path */ - protected final IntHashMap pointMap = new IntHashMap(); + protected final IntHashMap pointMap = new IntHashMap(); /** Selection of path points to add to the path */ - private FlyPathPoint[] pathOptions = new FlyPathPoint[32]; + private NPCPathPoint[] pathOptions = new NPCPathPoint[32]; /** should the PathFinder go through wodden door blocks */ private boolean isWoddenDoorAllowed; /** should the PathFinder disregard BlockMovement type materials in its path */ @@ -41,140 +41,171 @@ public class FlyPathFinder extends PathFinder private Entity theEntity; private final Map mapPathPriority = Maps.newEnumMap(PathNodeType.class); - public FlyPathFinder(IBlockAccess p_i2137_1_, boolean p_i2137_2_, boolean p_i2137_3_, boolean p_i2137_4_, boolean p_i2137_5_, Entity p_72865_1_) + public FlyPathFinder(IBlockAccess _worldMap, boolean doorsAllowed, boolean closedDoors, boolean canPathWater, boolean canDrown, Entity entityIn) { - super(p_i2137_1_,p_i2137_2_,p_i2137_3_,p_i2137_4_,p_i2137_5_); - this.theEntity = p_72865_1_; - this.worldMap = p_i2137_1_; - this.isWoddenDoorAllowed = p_i2137_2_; - this.isMovementBlockAllowed = p_i2137_3_; - this.isPathingInWater = p_i2137_4_; - this.canEntityDrown = p_i2137_5_; + super(_worldMap,doorsAllowed,closedDoors,canPathWater,canDrown); + this.theEntity = entityIn; + this.worldMap = _worldMap; + this.isWoddenDoorAllowed = doorsAllowed; + this.isMovementBlockAllowed = closedDoors; + this.isPathingInWater = canPathWater; + this.canEntityDrown = canDrown; } /** * Creates a path from one entity to another within a minimum distance */ - public FlyPathEntity createEntityPathTo(Entity p_75856_1_, Entity p_75856_2_, float p_75856_3_) + public NPCPath createEntityPathTo(Entity entityFrom, Entity entityTo, float distance) { - return this.createEntityPathTo(p_75856_1_, p_75856_2_.posX, p_75856_2_.boundingBox.minY, p_75856_2_.posZ, p_75856_3_); + return this.createEntityPathTo(entityFrom, entityTo.posX, entityTo.boundingBox.minY, entityTo.posZ, distance); } /** * Creates a path from an entity to a specified location within a minimum distance */ - public FlyPathEntity createEntityPathTo(Entity p_75859_1_, int p_75859_2_, int p_75859_3_, int p_75859_4_, float p_75859_5_) + public NPCPath createEntityPathTo(Entity entityFrom, int xTo, int yTo, int zTo, float distance) { - return this.createEntityPathTo(p_75859_1_, (double)((float)p_75859_2_ + 0.5F), (double)((float)p_75859_3_ + 0.5F), (double)((float)p_75859_4_ + 0.5F), p_75859_5_); + return this.createEntityPathTo(entityFrom, (double)((float)xTo + 0.5F), (double)((float)yTo + 0.5F), (double)((float)zTo + 0.5F), distance); } /** * Internal implementation of creating a path from an entity to a point */ - private FlyPathEntity createEntityPathTo(Entity entityIn, double x, double y, double z, float distance) + private NPCPath createEntityPathTo(Entity entityIn, double x, double y, double z, float distance) { this.path.clearPath(); this.pointMap.clearMap(); - FlyPathPoint pathpoint = this.getPathPointTo(entityIn); - FlyPathPoint pathpoint1 = this.getPathPointToCoords(entityIn, x, y, z); - FlyPathEntity pathentity = addToPath(entityIn, pathpoint, pathpoint1, distance); + NPCPathPoint pathpoint = this.getStart(); + NPCPathPoint pathpoint1 = this.getPathPointToCoords(entityIn, x, y, z); + NPCPath pathentity = addToPath(entityIn, pathpoint, pathpoint1, distance); return pathentity; } - public FlyPathPoint getPathPointTo(Entity entity) + public NPCPathPoint getStart() { int i; - if (((EntityNPCInterface) entity).ai.canSwim && entity.isInWater()) + if (((EntityNPCInterface)theEntity).ai.canSwim && this.theEntity.isInWater()) { - i = (int)entity.boundingBox.minY; - BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(MathHelper.floor_double(entity.posX), i, MathHelper.floor_double(entity.posZ)); + i = (int)this.theEntity.boundingBox.minY; + BlockPos.MutableBlockPos muteBlock = new BlockPos.MutableBlockPos(MathHelper.floor_double(this.theEntity.posX), i, MathHelper.floor_double(this.theEntity.posZ)); - for (Block block = this.worldMap.getBlock(blockpos$mutableblockpos.getX(), blockpos$mutableblockpos.getY(), blockpos$mutableblockpos.getZ()); - block == Blocks.flowing_water || block == Blocks.water; - block = this.worldMap.getBlock(blockpos$mutableblockpos.getX(), blockpos$mutableblockpos.getY(), blockpos$mutableblockpos.getZ())) + for (Block block = this.worldMap.getBlock(muteBlock.getX(), muteBlock.getY(), muteBlock.getZ()); block == Blocks.flowing_water || block == Blocks.water; block = this.worldMap.getBlock(muteBlock.getX(), muteBlock.getY(), muteBlock.getZ())) { ++i; - blockpos$mutableblockpos.setPos(MathHelper.floor_double(entity.posX), i, MathHelper.floor_double(entity.posZ)); + muteBlock.setPos(MathHelper.floor_double(this.theEntity.posX), i, MathHelper.floor_double(this.theEntity.posZ)); } } else { - i = MathHelper.floor_double(entity.boundingBox.minY + 0.5D); + i = MathHelper.floor_double(this.theEntity.boundingBox.minY + 0.5D); } - BlockPos blockpos1 = new BlockPos(entity); + BlockPos blockpos1 = new BlockPos(this.theEntity); + PathNodeType pathnodetype1 = this.getPathNodeType((EntityLiving) this.theEntity, blockpos1.getX(), i, blockpos1.getZ()); - return this.openPoint(blockpos1.getX(), i, blockpos1.getZ(), i); + if (this.getPathPriority(pathnodetype1) < 0.0F) + { + Set set = Sets.newHashSet(); + set.add(new BlockPos(this.theEntity.boundingBox.minX, (double)i, this.theEntity.boundingBox.minZ)); + set.add(new BlockPos(this.theEntity.boundingBox.minX, (double)i, this.theEntity.boundingBox.maxZ)); + set.add(new BlockPos(this.theEntity.boundingBox.maxX, (double)i, this.theEntity.boundingBox.minZ)); + set.add(new BlockPos(this.theEntity.boundingBox.maxX, (double)i, this.theEntity.boundingBox.maxZ)); + + for (BlockPos blockpos : set) + { + PathNodeType pathnodetype = this.getPathNodeType((EntityLiving)this.theEntity, blockpos); + + if (this.getPathPriority(pathnodetype) >= 0.0F) + { + return openPoint(blockpos.getX(), blockpos.getY(), blockpos.getZ(), 0); + } + } + } + + return openPoint(blockpos1.getX(), i, blockpos1.getZ(), 0); } + - public FlyPathPoint getPathPointToCoords(Entity entityIn, double x, double y, double z) + 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), (int)z); + return openPoint(MathHelper.floor_double(x), MathHelper.floor_double(y), MathHelper.floor_double(z), 0); } /** * Adds a path from start to end and returns the whole path (args: unused, start, end, unused, maxDistance) */ - private FlyPathEntity addToPath(Entity entityIn, FlyPathPoint pathpointStart, FlyPathPoint pathpointEnd, float maxDistance) + private NPCPath addToPath(Entity entityIn, NPCPathPoint pathFrom, NPCPathPoint pathTo, float maxDistance) { - pathpointStart.totalPathDistance = 0.0F; - pathpointStart.distanceToNext = pathpointStart.distanceToSquared(pathpointEnd); - pathpointStart.distanceToTarget = pathpointStart.distanceToNext; + pathFrom.totalPathDistance = 0.0F; + pathFrom.distanceToNext = pathFrom.distanceManhattan(pathTo); + pathFrom.distanceToTarget = pathFrom.distanceToNext; this.path.clearPath(); - this.path.addPoint(pathpointStart); - FlyPathPoint pathpoint3 = pathpointStart; + this.path.addPoint(pathFrom); + NPCPathPoint pathpoint = pathFrom; + int i = 0; while (!this.path.isPathEmpty()) { - FlyPathPoint pathpoint4 = this.path.dequeue(); + ++i; - if (pathpoint4.equals(pathpointEnd)) + if (i >= 200) { - return this.createEntityPath(pathpointStart, pathpointEnd); + break; } - if (pathpoint4.distanceToSquared(pathpointEnd) < pathpoint3.distanceToSquared(pathpointEnd)) + NPCPathPoint pathpoint1 = this.path.dequeue(); + + if (pathpoint1.equals(pathTo)) { - pathpoint3 = pathpoint4; + pathpoint = pathTo; + break; } - pathpoint4.isFirst = true; - int i = this.findPathOptions(this.pathOptions, entityIn, pathpoint4, pathpointEnd, maxDistance); - - for (int j = 0; j < i; ++j) + if (pathpoint1.distanceManhattan(pathTo) < pathpoint.distanceManhattan(pathTo)) { - FlyPathPoint pathpoint5 = this.pathOptions[j]; - float f1 = pathpoint4.totalPathDistance + pathpoint4.distanceToSquared(pathpoint5); + pathpoint = pathpoint1; + } - if (!pathpoint5.isAssigned() || f1 < pathpoint5.totalPathDistance) + 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)) { - pathpoint5.previous = pathpoint4; - pathpoint5.totalPathDistance = f1; - pathpoint5.distanceToNext = pathpoint5.distanceToSquared(pathpointEnd); + pathpoint2.previous = pathpoint1; + pathpoint2.totalPathDistance = f1; + pathpoint2.distanceToNext = pathpoint2.distanceManhattan(pathTo) + pathpoint2.costMalus; - if (pathpoint5.isAssigned()) + if (pathpoint2.isAssigned()) { - this.path.changeDistance(pathpoint5, pathpoint5.totalPathDistance + pathpoint5.distanceToNext); + this.path.changeDistance(pathpoint2, pathpoint2.totalPathDistance + pathpoint2.distanceToNext); } else { - pathpoint5.distanceToTarget = pathpoint5.totalPathDistance + pathpoint5.distanceToNext; - this.path.addPoint(pathpoint5); + pathpoint2.distanceToTarget = pathpoint2.totalPathDistance + pathpoint2.distanceToNext; + this.path.addPoint(pathpoint2); } } } } - if (pathpoint3 == pathpointStart) + if (pathpoint == pathFrom) { return null; } else { - return this.createEntityPath(pathpointStart, pathpoint3); + return this.createEntityPath(pathFrom, pathpoint); } } @@ -182,15 +213,15 @@ 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(FlyPathPoint[] pathOptions, Entity entityIn, FlyPathPoint currentPoint, FlyPathPoint targetPoint, float maxDistance) + public int findPathOptions(NPCPathPoint[] pathOptions, Entity entityIn, NPCPathPoint currentPoint, NPCPathPoint targetPoint, float maxDistance) { int i = 0; - FlyPathPoint pathpoint = this.openPoint(currentPoint.xCoord, currentPoint.yCoord, currentPoint.zCoord + 1); - FlyPathPoint pathpoint1 = this.openPoint(currentPoint.xCoord - 1, currentPoint.yCoord, currentPoint.zCoord); - FlyPathPoint pathpoint2 = this.openPoint(currentPoint.xCoord + 1, currentPoint.yCoord, currentPoint.zCoord); - FlyPathPoint pathpoint3 = this.openPoint(currentPoint.xCoord, currentPoint.yCoord, currentPoint.zCoord - 1); - FlyPathPoint pathpoint4 = this.openPoint(currentPoint.xCoord, currentPoint.yCoord + 1, currentPoint.zCoord); - FlyPathPoint pathpoint5 = this.openPoint(currentPoint.xCoord, currentPoint.yCoord - 1, currentPoint.zCoord); + 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); if (pathpoint != null && !pathpoint.isFirst && pathpoint.distanceTo(targetPoint) < maxDistance) { @@ -222,16 +253,16 @@ public class FlyPathFinder extends PathFinder pathOptions[i++] = pathpoint5; } - boolean flag = pathpoint3 == null; - boolean flag1 = pathpoint == null; - boolean flag2 = pathpoint2 == null; - boolean flag3 = pathpoint1 == null; - boolean flag4 = pathpoint4 == null; - boolean flag5 = pathpoint5 == null; + 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; if (flag && flag3) { - FlyPathPoint pathpoint6 = this.openPoint(currentPoint.xCoord - 1, currentPoint.yCoord, currentPoint.zCoord - 1); + NPCPathPoint pathpoint6 = this.openPoint(currentPoint.xCoord - 1, currentPoint.yCoord, currentPoint.zCoord - 1); if (pathpoint6 != null && !pathpoint6.isFirst && pathpoint6.distanceTo(targetPoint) < maxDistance) { @@ -241,7 +272,7 @@ public class FlyPathFinder extends PathFinder if (flag && flag2) { - FlyPathPoint pathpoint7 = this.openPoint(currentPoint.xCoord + 1, currentPoint.yCoord, currentPoint.zCoord - 1); + NPCPathPoint pathpoint7 = this.openPoint(currentPoint.xCoord + 1, currentPoint.yCoord, currentPoint.zCoord - 1); if (pathpoint7 != null && !pathpoint7.isFirst && pathpoint7.distanceTo(targetPoint) < maxDistance) { @@ -251,7 +282,7 @@ public class FlyPathFinder extends PathFinder if (flag1 && flag3) { - FlyPathPoint pathpoint8 = this.openPoint(currentPoint.xCoord - 1, currentPoint.yCoord, currentPoint.zCoord + 1); + NPCPathPoint pathpoint8 = this.openPoint(currentPoint.xCoord - 1, currentPoint.yCoord, currentPoint.zCoord + 1); if (pathpoint8 != null && !pathpoint8.isFirst && pathpoint8.distanceTo(targetPoint) < maxDistance) { @@ -261,7 +292,7 @@ public class FlyPathFinder extends PathFinder if (flag1 && flag2) { - FlyPathPoint pathpoint9 = this.openPoint(currentPoint.xCoord + 1, currentPoint.yCoord, currentPoint.zCoord + 1); + NPCPathPoint pathpoint9 = this.openPoint(currentPoint.xCoord + 1, currentPoint.yCoord, currentPoint.zCoord + 1); if (pathpoint9 != null && !pathpoint9.isFirst && pathpoint9.distanceTo(targetPoint) < maxDistance) { @@ -271,7 +302,7 @@ public class FlyPathFinder extends PathFinder if (flag && flag4) { - FlyPathPoint pathpoint10 = this.openPoint(currentPoint.xCoord, currentPoint.yCoord + 1, currentPoint.zCoord - 1); + NPCPathPoint pathpoint10 = this.openPoint(currentPoint.xCoord, currentPoint.yCoord + 1, currentPoint.zCoord - 1); if (pathpoint10 != null && !pathpoint10.isFirst && pathpoint10.distanceTo(targetPoint) < maxDistance) { @@ -281,7 +312,7 @@ public class FlyPathFinder extends PathFinder if (flag1 && flag4) { - FlyPathPoint pathpoint11 = this.openPoint(currentPoint.xCoord, currentPoint.yCoord + 1, currentPoint.zCoord + 1); + NPCPathPoint pathpoint11 = this.openPoint(currentPoint.xCoord, currentPoint.yCoord + 1, currentPoint.zCoord + 1); if (pathpoint11 != null && !pathpoint11.isFirst && pathpoint11.distanceTo(targetPoint) < maxDistance) { @@ -291,7 +322,7 @@ public class FlyPathFinder extends PathFinder if (flag2 && flag4) { - FlyPathPoint pathpoint12 = this.openPoint(currentPoint.xCoord + 1, currentPoint.yCoord + 1, currentPoint.zCoord); + NPCPathPoint pathpoint12 = this.openPoint(currentPoint.xCoord + 1, currentPoint.yCoord + 1, currentPoint.zCoord); if (pathpoint12 != null && !pathpoint12.isFirst && pathpoint12.distanceTo(targetPoint) < maxDistance) { @@ -301,7 +332,7 @@ public class FlyPathFinder extends PathFinder if (flag3 && flag4) { - FlyPathPoint pathpoint13 = this.openPoint(currentPoint.xCoord - 1, currentPoint.yCoord + 1, currentPoint.zCoord); + NPCPathPoint pathpoint13 = this.openPoint(currentPoint.xCoord - 1, currentPoint.yCoord + 1, currentPoint.zCoord); if (pathpoint13 != null && !pathpoint13.isFirst && pathpoint13.distanceTo(targetPoint) < maxDistance) { @@ -311,7 +342,7 @@ public class FlyPathFinder extends PathFinder if (flag && flag5) { - FlyPathPoint pathpoint14 = this.openPoint(currentPoint.xCoord, currentPoint.yCoord - 1, currentPoint.zCoord - 1); + NPCPathPoint pathpoint14 = this.openPoint(currentPoint.xCoord, currentPoint.yCoord - 1, currentPoint.zCoord - 1); if (pathpoint14 != null && !pathpoint14.isFirst && pathpoint14.distanceTo(targetPoint) < maxDistance) { @@ -321,7 +352,7 @@ public class FlyPathFinder extends PathFinder if (flag1 && flag5) { - FlyPathPoint pathpoint15 = this.openPoint(currentPoint.xCoord, currentPoint.yCoord - 1, currentPoint.zCoord + 1); + NPCPathPoint pathpoint15 = this.openPoint(currentPoint.xCoord, currentPoint.yCoord - 1, currentPoint.zCoord + 1); if (pathpoint15 != null && !pathpoint15.isFirst && pathpoint15.distanceTo(targetPoint) < maxDistance) { @@ -331,7 +362,7 @@ public class FlyPathFinder extends PathFinder if (flag2 && flag5) { - FlyPathPoint pathpoint16 = this.openPoint(currentPoint.xCoord + 1, currentPoint.yCoord - 1, currentPoint.zCoord); + NPCPathPoint pathpoint16 = this.openPoint(currentPoint.xCoord + 1, currentPoint.yCoord - 1, currentPoint.zCoord); if (pathpoint16 != null && !pathpoint16.isFirst && pathpoint16.distanceTo(targetPoint) < maxDistance) { @@ -341,7 +372,7 @@ public class FlyPathFinder extends PathFinder if (flag3 && flag5) { - FlyPathPoint pathpoint17 = this.openPoint(currentPoint.xCoord - 1, currentPoint.yCoord - 1, currentPoint.zCoord); + NPCPathPoint pathpoint17 = this.openPoint(currentPoint.xCoord - 1, currentPoint.yCoord - 1, currentPoint.zCoord); if (pathpoint17 != null && !pathpoint17.isFirst && pathpoint17.distanceTo(targetPoint) < maxDistance) { @@ -353,9 +384,9 @@ public class FlyPathFinder extends PathFinder } @Nullable - protected FlyPathPoint openPoint(int x, int y, int z) + protected NPCPathPoint openPoint(int x, int y, int z) { - FlyPathPoint pathpoint = null; + NPCPathPoint pathpoint = null; BlockPos blockPos = new BlockPos(x, y, z); PathNodeType pathnodetype = this.getPathNodeType((EntityLiving) this.theEntity, blockPos); float f = getPathPriority(pathnodetype); @@ -375,14 +406,14 @@ public class FlyPathFinder extends PathFinder return pathnodetype != PathNodeType.OPEN && pathnodetype != PathNodeType.WALKABLE ? pathpoint : pathpoint; } - protected FlyPathPoint openPoint(int x, int y, int z, int b) + protected NPCPathPoint openPoint(int x, int y, int z, int b) { - int i = FlyPathPoint.makeHash(x, y, z); - FlyPathPoint pathpoint = this.pointMap.lookup(i); + int i = NPCPathPoint.makeHash(x, y, z); + NPCPathPoint pathpoint = this.pointMap.lookup(i); if (pathpoint == null) { - pathpoint = new FlyPathPoint(x, y, z); + pathpoint = new NPCPathPoint(x, y, z); this.pointMap.addKey(i, pathpoint); } @@ -392,27 +423,27 @@ public class FlyPathFinder extends PathFinder /** * Returns a new FlyPathEntity for a given start and end point */ - private FlyPathEntity createEntityPath(FlyPathPoint p_75853_1_, FlyPathPoint p_75853_2_) + private NPCPath createEntityPath(NPCPathPoint pathFrom, NPCPathPoint pathTo) { int i = 1; - FlyPathPoint pathpoint2; + NPCPathPoint pathpoint2; - for (pathpoint2 = p_75853_2_; pathpoint2.previous != null; pathpoint2 = pathpoint2.previous) + for (pathpoint2 = pathTo; pathpoint2.previous != null; pathpoint2 = pathpoint2.previous) { ++i; } - FlyPathPoint[] apathpoint = new FlyPathPoint[i]; - pathpoint2 = p_75853_2_; + NPCPathPoint[] apathpoint = new NPCPathPoint[i]; + pathpoint2 = pathTo; --i; - for (apathpoint[i] = p_75853_2_; pathpoint2.previous != null; apathpoint[i] = pathpoint2) + for (apathpoint[i] = pathTo; pathpoint2.previous != null; apathpoint[i] = pathpoint2) { pathpoint2 = pathpoint2.previous; --i; } - return new FlyPathEntity(apathpoint); + return new NPCPath(apathpoint); } @@ -455,7 +486,7 @@ public class FlyPathFinder extends PathFinder } } - public PathNodeType getPathNodeType(IBlockAccess p_193577_1_, int x, int y, int z, int xSize, int ySize, int zSize, boolean canOpenDoorsIn, boolean canEnterDoorsIn, EnumSet p_193577_10_, PathNodeType p_193577_11_, BlockPos p_193577_12_) + public PathNodeType getPathNodeType(IBlockAccess blockAccess, int x, int y, int z, int xSize, int ySize, int zSize, boolean canOpenDoorsIn, boolean canEnterDoorsIn, EnumSet p_193577_10_, PathNodeType p_193577_11_, BlockPos p_193577_12_) { for (int i = 0; i < xSize; ++i) { @@ -466,7 +497,7 @@ public class FlyPathFinder extends PathFinder int l = i + x; int i1 = j + y; int j1 = k + z; - PathNodeType pathnodetype = this.getPathNodeType(p_193577_1_, l, i1, j1); + PathNodeType pathnodetype = this.getPathNodeType(blockAccess, l, i1, j1); if (pathnodetype == PathNodeType.DOOR_WOOD_CLOSED && canOpenDoorsIn && canEnterDoorsIn) { @@ -478,7 +509,7 @@ public class FlyPathFinder extends PathFinder pathnodetype = PathNodeType.BLOCKED; } - if (pathnodetype == PathNodeType.RAIL && !(p_193577_1_.getBlock(p_193577_12_.getX(), p_193577_12_.getY(), p_193577_12_.getZ()) instanceof BlockRailBase) && !(p_193577_1_.getBlock(p_193577_12_.down().getX(), p_193577_12_.down().getY(), p_193577_12_.down().getZ()) instanceof BlockRailBase)) + if (pathnodetype == PathNodeType.RAIL && !(blockAccess.getBlock(p_193577_12_.getX(), p_193577_12_.getY(), p_193577_12_.getZ()) instanceof BlockRailBase) && !(blockAccess.getBlock(p_193577_12_.down().getX(), p_193577_12_.down().getY(), p_193577_12_.down().getZ()) instanceof BlockRailBase)) { pathnodetype = PathNodeType.FENCE; } diff --git a/src/main/java/noppes/npcs/ai/pathfinder/FlyPathEntity.java b/src/main/java/noppes/npcs/ai/pathfinder/NPCPath.java similarity index 69% rename from src/main/java/noppes/npcs/ai/pathfinder/FlyPathEntity.java rename to src/main/java/noppes/npcs/ai/pathfinder/NPCPath.java index a6715e6c6..0f5cad721 100644 --- a/src/main/java/noppes/npcs/ai/pathfinder/FlyPathEntity.java +++ b/src/main/java/noppes/npcs/ai/pathfinder/NPCPath.java @@ -5,19 +5,18 @@ import net.minecraft.pathfinding.PathEntity; import net.minecraft.pathfinding.PathPoint; import net.minecraft.util.Vec3; -public class FlyPathEntity extends PathEntity{ +public class NPCPath extends PathEntity{ public final PathPoint[] points; /** PathEntity Array Index the Entity is currently targeting */ public int currentPathIndex; /** The total length of the path */ public int pathLength; - private static final String __OBFID = "CL_00000575"; - public FlyPathEntity(PathPoint[] p_i2136_1_) + public NPCPath(PathPoint[] pointsIn) { - super(p_i2136_1_); - this.points = p_i2136_1_; - this.pathLength = p_i2136_1_.length; + super(pointsIn); + this.points = pointsIn; + this.pathLength = pointsIn.length; } /** @@ -75,11 +74,11 @@ public class FlyPathEntity extends PathEntity{ /** * Gets the vector of the PathPoint associated with the given index. */ - public Vec3 getVectorFromIndex(Entity p_75881_1_, int p_75881_2_) + public Vec3 getVectorFromIndex(Entity entity, int index) { - double d0 = (double)this.points[p_75881_2_].xCoord + (double)((int)(p_75881_1_.width + 1.0F)) * 0.5D; - double d1 = (double)this.points[p_75881_2_].yCoord; - double d2 = (double)this.points[p_75881_2_].zCoord + (double)((int)(p_75881_1_.width + 1.0F)) * 0.5D; + double d0 = (double)this.points[index].xCoord + (double)((int)(entity.width + 1.0F)) * 0.5D; + double d1 = (double)this.points[index].yCoord; + double d2 = (double)this.points[index].zCoord + (double)((int)(entity.width + 1.0F)) * 0.5D; return Vec3.createVectorHelper(d0, d1, d2); } @@ -91,17 +90,23 @@ public class FlyPathEntity extends PathEntity{ return this.getVectorFromIndex(p_75878_1_, this.currentPathIndex); } + public Vec3 getCurrentPos() + { + PathPoint pathpoint = this.points[this.currentPathIndex]; + return Vec3.createVectorHelper((double)pathpoint.xCoord, (double)pathpoint.yCoord, (double)pathpoint.zCoord); + } + /** * Returns true if the EntityPath are the same. Non instance related equals. */ public boolean isSamePath(PathEntity pathEntity) { - FlyPathEntity p_75876_1_ = (FlyPathEntity) pathEntity; - if (p_75876_1_ == null) + NPCPath NPCPath = (NPCPath) pathEntity; + if (NPCPath == null) { return false; } - else if (p_75876_1_.points.length != this.points.length) + else if (NPCPath.points.length != this.points.length) { return false; } @@ -109,7 +114,7 @@ public class FlyPathEntity extends PathEntity{ { for (int i = 0; i < this.points.length; ++i) { - if (this.points[i].xCoord != p_75876_1_.points[i].xCoord || this.points[i].yCoord != p_75876_1_.points[i].yCoord || this.points[i].zCoord != p_75876_1_.points[i].zCoord) + if (this.points[i].xCoord != NPCPath.points[i].xCoord || this.points[i].yCoord != NPCPath.points[i].yCoord || this.points[i].zCoord != NPCPath.points[i].zCoord) { return false; } @@ -122,9 +127,9 @@ public class FlyPathEntity extends PathEntity{ /** * Returns true if the final PathPoint in the PathEntity is equal to Vec3D coords. */ - public boolean isDestinationSame(Vec3 p_75880_1_) + public boolean isDestinationSame(Vec3 vec3) { PathPoint pathpoint = this.getFinalPathPoint(); - return pathpoint == null ? false : pathpoint.xCoord == (int)p_75880_1_.xCoord && pathpoint.zCoord == (int)p_75880_1_.zCoord; + return pathpoint == null ? false : pathpoint.xCoord == (int)vec3.xCoord && pathpoint.zCoord == (int)vec3.zCoord; } } diff --git a/src/main/java/noppes/npcs/ai/pathfinder/FlyPathPoint.java b/src/main/java/noppes/npcs/ai/pathfinder/NPCPathPoint.java similarity index 57% rename from src/main/java/noppes/npcs/ai/pathfinder/FlyPathPoint.java rename to src/main/java/noppes/npcs/ai/pathfinder/NPCPathPoint.java index e08dd1bd0..b611b9651 100644 --- a/src/main/java/noppes/npcs/ai/pathfinder/FlyPathPoint.java +++ b/src/main/java/noppes/npcs/ai/pathfinder/NPCPathPoint.java @@ -3,7 +3,7 @@ package noppes.npcs.ai.pathfinder; import net.minecraft.pathfinding.PathPoint; import net.minecraft.util.MathHelper; -public class FlyPathPoint extends PathPoint +public class NPCPathPoint extends PathPoint { /** The x coordinate of this point */ public final int xCoord; @@ -22,58 +22,67 @@ public class FlyPathPoint extends PathPoint /** The distance to the target */ public float distanceToTarget; /** The point preceding this in its assigned path */ - public FlyPathPoint previous; + public NPCPathPoint previous; /** Indicates this is the origin */ public boolean isFirst; public float costMalus; + public float cost; + public float distanceFromOrigin; public PathNodeType nodeType = PathNodeType.BLOCKED; - private static final String __OBFID = "CL_00000574"; - public FlyPathPoint(int p_i2135_1_, int p_i2135_2_, int p_i2135_3_) + public NPCPathPoint(int xIn, int yIn, int zIn) { - super(p_i2135_1_,p_i2135_2_,p_i2135_3_); - this.xCoord = p_i2135_1_; - this.yCoord = p_i2135_2_; - this.zCoord = p_i2135_3_; - this.hash = makeHash(p_i2135_1_, p_i2135_2_, p_i2135_3_); + super(xIn,yIn,zIn); + this.xCoord = xIn; + this.yCoord = yIn; + this.zCoord = zIn; + this.hash = makeHash(xIn, yIn, zIn); } - public static int makeHash(int p_75830_0_, int p_75830_1_, int p_75830_2_) + public static int makeHash(int xIn, int yIn, int zIn) { - return p_75830_1_ & 255 | (p_75830_0_ & 32767) << 8 | (p_75830_2_ & 32767) << 24 | (p_75830_0_ < 0 ? Integer.MIN_VALUE : 0) | (p_75830_2_ < 0 ? 32768 : 0); + return yIn & 255 | (xIn & 32767) << 8 | (zIn & 32767) << 24 | (xIn < 0 ? Integer.MIN_VALUE : 0) | (zIn < 0 ? 32768 : 0); } /** * Returns the linear distance to another path point */ - public float distanceTo(FlyPathPoint p_75829_1_) + public float distanceTo(NPCPathPoint point) { - float f = (float)(p_75829_1_.xCoord - this.xCoord); - float f1 = (float)(p_75829_1_.yCoord - this.yCoord); - float f2 = (float)(p_75829_1_.zCoord - this.zCoord); + float f = (float)(point.xCoord - this.xCoord); + float f1 = (float)(point.yCoord - this.yCoord); + float f2 = (float)(point.zCoord - this.zCoord); return MathHelper.sqrt_float(f * f + f1 * f1 + f2 * f2); } /** * Returns the squared distance to another path point */ - public float distanceToSquared(FlyPathPoint p_75832_1_) + public float distanceToSquared(NPCPathPoint point) { - float f = (float)(p_75832_1_.xCoord - this.xCoord); - float f1 = (float)(p_75832_1_.yCoord - this.yCoord); - float f2 = (float)(p_75832_1_.zCoord - this.zCoord); + float f = (float)(point.xCoord - this.xCoord); + float f1 = (float)(point.yCoord - this.yCoord); + float f2 = (float)(point.zCoord - this.zCoord); return f * f + f1 * f1 + f2 * f2; } - public boolean equals(Object p_equals_1_) + public float distanceManhattan(NPCPathPoint point) { - if (!(p_equals_1_ instanceof FlyPathPoint)) + float f = (float)Math.abs(point.xCoord - this.xCoord); + float f1 = (float)Math.abs(point.yCoord - this.yCoord); + float f2 = (float)Math.abs(point.zCoord - this.zCoord); + return f + f1 + f2; + } + + public boolean equals(Object point) + { + if (!(point instanceof NPCPathPoint)) { return false; } else { - FlyPathPoint pathpoint = (FlyPathPoint)p_equals_1_; + NPCPathPoint pathpoint = (NPCPathPoint)point; return this.hash == pathpoint.hash && this.xCoord == pathpoint.xCoord && this.yCoord == pathpoint.yCoord && this.zCoord == pathpoint.zCoord; } } diff --git a/src/main/java/noppes/npcs/ai/pathfinder/FlyPath.java b/src/main/java/noppes/npcs/ai/pathfinder/PathHeap.java similarity index 53% rename from src/main/java/noppes/npcs/ai/pathfinder/FlyPath.java rename to src/main/java/noppes/npcs/ai/pathfinder/PathHeap.java index 1f36db860..991ccc507 100644 --- a/src/main/java/noppes/npcs/ai/pathfinder/FlyPath.java +++ b/src/main/java/noppes/npcs/ai/pathfinder/PathHeap.java @@ -1,17 +1,16 @@ package noppes.npcs.ai.pathfinder; -public class FlyPath { - private FlyPathPoint[] pathPoints = new FlyPathPoint[1024]; +public class PathHeap { + private NPCPathPoint[] pathPoints = new NPCPathPoint[128]; /** The number of points in this path */ private int count; - private static final String __OBFID = "CL_00000573"; /** * Adds a point to the path */ - public FlyPathPoint addPoint(FlyPathPoint p_75849_1_) + public NPCPathPoint addPoint(NPCPathPoint pathPoint) { - if (p_75849_1_.index >= 0) + if (pathPoint.index >= 0) { throw new IllegalStateException("OW KNOWS!"); } @@ -19,15 +18,15 @@ public class FlyPath { { if (this.count == this.pathPoints.length) { - FlyPathPoint[] apathpoint = new FlyPathPoint[this.count << 1]; + NPCPathPoint[] apathpoint = new NPCPathPoint[this.count << 1]; System.arraycopy(this.pathPoints, 0, apathpoint, 0, this.count); this.pathPoints = apathpoint; } - this.pathPoints[this.count] = p_75849_1_; - p_75849_1_.index = this.count; + this.pathPoints[this.count] = pathPoint; + pathPoint.index = this.count; this.sortBack(this.count++); - return p_75849_1_; + return pathPoint; } } @@ -42,9 +41,9 @@ public class FlyPath { /** * Returns and removes the first point in the path */ - public FlyPathPoint dequeue() + public NPCPathPoint dequeue() { - FlyPathPoint pathpoint = this.pathPoints[0]; + NPCPathPoint pathpoint = this.pathPoints[0]; this.pathPoints[0] = this.pathPoints[--this.count]; this.pathPoints[this.count] = null; @@ -60,58 +59,58 @@ public class FlyPath { /** * Changes the provided point's distance to target */ - public void changeDistance(FlyPathPoint p_75850_1_, float p_75850_2_) + public void changeDistance(NPCPathPoint point, float distance) { - float f1 = p_75850_1_.distanceToTarget; - p_75850_1_.distanceToTarget = p_75850_2_; + float f1 = point.distanceToTarget; + point.distanceToTarget = distance; - if (p_75850_2_ < f1) + if (distance < f1) { - this.sortBack(p_75850_1_.index); + this.sortBack(point.index); } else { - this.sortForward(p_75850_1_.index); + this.sortForward(point.index); } } /** * Sorts a point to the left */ - private void sortBack(int p_75847_1_) + private void sortBack(int index) { - FlyPathPoint pathpoint = this.pathPoints[p_75847_1_]; + NPCPathPoint pathpoint = this.pathPoints[index]; int j; - for (float f = pathpoint.distanceToTarget; p_75847_1_ > 0; p_75847_1_ = j) + for (float f = pathpoint.distanceToTarget; index > 0; index = j) { - j = p_75847_1_ - 1 >> 1; - FlyPathPoint pathpoint1 = this.pathPoints[j]; + j = index - 1 >> 1; + NPCPathPoint pathpoint1 = this.pathPoints[j]; if (f >= pathpoint1.distanceToTarget) { break; } - this.pathPoints[p_75847_1_] = pathpoint1; - pathpoint1.index = p_75847_1_; + this.pathPoints[index] = pathpoint1; + pathpoint1.index = index; } - this.pathPoints[p_75847_1_] = pathpoint; - pathpoint.index = p_75847_1_; + this.pathPoints[index] = pathpoint; + pathpoint.index = index; } /** * Sorts a point to the right */ - private void sortForward(int p_75846_1_) + private void sortForward(int index) { - FlyPathPoint pathpoint = this.pathPoints[p_75846_1_]; + NPCPathPoint pathpoint = this.pathPoints[index]; float f = pathpoint.distanceToTarget; while (true) { - int j = 1 + (p_75846_1_ << 1); + int j = 1 + (index << 1); int k = j + 1; if (j >= this.count) @@ -119,9 +118,9 @@ public class FlyPath { break; } - FlyPathPoint pathpoint1 = this.pathPoints[j]; + NPCPathPoint pathpoint1 = this.pathPoints[j]; float f1 = pathpoint1.distanceToTarget; - FlyPathPoint pathpoint2; + NPCPathPoint pathpoint2; float f2; if (k >= this.count) @@ -142,9 +141,9 @@ public class FlyPath { break; } - this.pathPoints[p_75846_1_] = pathpoint1; - pathpoint1.index = p_75846_1_; - p_75846_1_ = j; + this.pathPoints[index] = pathpoint1; + pathpoint1.index = index; + index = j; } else { @@ -153,21 +152,18 @@ public class FlyPath { break; } - this.pathPoints[p_75846_1_] = pathpoint2; - pathpoint2.index = p_75846_1_; - p_75846_1_ = k; + this.pathPoints[index] = pathpoint2; + pathpoint2.index = index; + index = k; } } - this.pathPoints[p_75846_1_] = pathpoint; - pathpoint.index = p_75846_1_; + this.pathPoints[index] = pathpoint; + pathpoint.index = index; } /** * Returns true if this path contains no points */ - public boolean isPathEmpty() - { - return this.count == 0; - } + public boolean isPathEmpty() { return this.count == 0; } } diff --git a/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java b/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java index ee8b76e40..f10fc5edc 100644 --- a/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java +++ b/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java @@ -1,31 +1,30 @@ 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.entity.monster.EntityZombie; -import net.minecraft.entity.passive.EntityChicken; -import net.minecraft.init.Blocks; import net.minecraft.pathfinding.PathEntity; import net.minecraft.pathfinding.PathNavigate; import net.minecraft.pathfinding.PathPoint; import net.minecraft.util.MathHelper; 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.EntityNPCInterface; +import javax.annotation.Nullable; + public class PathNavigateFlying extends PathNavigate { private EntityNPCInterface theEntity; private World worldObj; /** The PathEntity being followed. */ - private FlyPathEntity currentPath; + protected NPCPath currentPath; private double speed; /** The number of blocks (extra) +/- in each axis that get pulled out as cache for the pathfinder's search space */ private IAttributeInstance pathSearchRange; + protected float maxDistanceToWaypoint = 0.5F; private boolean noSunPathfind; /** Time, in number of ticks, following the current path */ private int totalTicks; @@ -33,6 +32,10 @@ public class PathNavigateFlying extends PathNavigate { private int ticksAtLastPos; /** Coordinates of the entity's position last time a check was done (part of monitoring getting 'stuck') */ private Vec3 lastPosCheck = Vec3.createVectorHelper(0.0D, 0.0D, 0.0D); + private Vec3 timeoutCachedNode = Vec3.createVectorHelper(0.0D, 0.0D, 0.0D); + private long timeoutTimer; + private long lastTimeoutCheck; + private double timeoutLimit; /** Specifically, if a wooden door block is even considered to be passable by the pathfinder */ private boolean canPassOpenWoodenDoors = true; /** If door blocks are considered passable even when closed */ @@ -46,14 +49,33 @@ public class PathNavigateFlying extends PathNavigate { private boolean canSwim; private static final String __OBFID = "CL_00001627"; - private int pathCooldown = 0; - private int maxCooldown = 2; + protected BlockPos targetPos; + protected boolean tryUpdatePath; + protected long lastTimeUpdated; - public PathNavigateFlying(EntityLiving p_i45873_1_, World worldIn) { - super(p_i45873_1_, worldIn); - this.theEntity = (EntityNPCInterface)p_i45873_1_; + public PathNavigateFlying(EntityLiving entityIN, World worldIn) { + super(entityIN, worldIn); + this.theEntity = (EntityNPCInterface)entityIN; this.worldObj = worldIn; - this.pathSearchRange = p_i45873_1_.getEntityAttribute(SharedMonsterAttributes.followRange); + this.pathSearchRange = entityIN.getEntityAttribute(SharedMonsterAttributes.followRange); + } + + public void updatePath() + { + if (this.worldObj.getTotalWorldTime() - this.lastTimeUpdated > 20L) + { + if (this.targetPos != null) + { + this.currentPath = null; + this.currentPath = this.getPathToXYZ(this.targetPos.getX(), this.targetPos.getY(), this.targetPos.getZ()); + this.lastTimeUpdated = this.worldObj.getTotalWorldTime(); + this.tryUpdatePath = false; + } + } + else + { + this.tryUpdatePath = true; + } } public void setAvoidsWater(boolean p_75491_1_) @@ -122,9 +144,21 @@ public class PathNavigateFlying extends PathNavigate { /** * Returns the path to the given coordinates */ - public FlyPathEntity getPathToXYZ(double p_75488_1_, double p_75488_3_, double p_75488_5_) + public NPCPath getPathToXYZ(double x, double y, double z) { - return !this.canNavigate() ? null : this.getEntityPathToXYZ(this.theEntity, MathHelper.floor_double(p_75488_1_), (int)p_75488_3_, MathHelper.floor_double(p_75488_5_), this.getPathSearchRange(), this.canPassOpenWoodenDoors, this.canPassClosedWoodenDoors, this.avoidsWater, this.canSwim); + BlockPos pos = new BlockPos(x, y, z); + if (!this.canNavigate()) + { + return null; + } + else if (this.currentPath != null && !this.currentPath.isFinished() && pos.equals(this.targetPos)) + { + return this.currentPath; + } + else { + this.targetPos = pos; + return this.getEntityPathToXYZ(this.theEntity, MathHelper.floor_double(x), (int)y, MathHelper.floor_double(z), this.getPathSearchRange(), this.canPassOpenWoodenDoors, this.canPassClosedWoodenDoors, this.avoidsWater, this.canSwim); + } } /** @@ -132,23 +166,32 @@ public class PathNavigateFlying extends PathNavigate { */ public boolean tryMoveToXYZ(double p_75492_1_, double p_75492_3_, double p_75492_5_, double p_75492_7_) { - if (this.pathCooldown == 0) { - this.pathCooldown = this.maxCooldown; - } else { - this.pathCooldown--; - return false; - } - - FlyPathEntity pathentity = this.getPathToXYZ((double)MathHelper.floor_double(p_75492_1_), (double)((int)p_75492_3_), (double)MathHelper.floor_double(p_75492_5_)); + NPCPath pathentity = this.getPathToXYZ((double)MathHelper.floor_double(p_75492_1_), (double)((int)p_75492_3_), (double)MathHelper.floor_double(p_75492_5_)); return this.setPath(pathentity, p_75492_7_); } /** * Returns the path to the given EntityLiving */ - public FlyPathEntity getPathToEntityLiving(Entity p_75494_1_) + public NPCPath getPathToEntityLiving(Entity entity) { - return !this.canNavigate() ? null : this.getPathEntityToEntity(this.theEntity, p_75494_1_, this.getPathSearchRange(), this.canPassOpenWoodenDoors, this.canPassClosedWoodenDoors, this.avoidsWater, this.canSwim); + if (!this.canNavigate()) + { + return null; + } + else + { + BlockPos blockpos = new BlockPos(entity); + if (this.currentPath != null && !this.currentPath.isFinished() && blockpos.equals(this.targetPos)) + { + return this.currentPath; + } + else + { + this.targetPos = blockpos; + return this.getPathEntityToEntity(this.theEntity, entity, this.getPathSearchRange(), this.canPassOpenWoodenDoors, this.canPassClosedWoodenDoors, this.avoidsWater, this.canSwim); + } + } } /** @@ -156,14 +199,7 @@ public class PathNavigateFlying extends PathNavigate { */ public boolean tryMoveToEntityLiving(Entity p_75497_1_, double p_75497_2_) { - if (this.pathCooldown == 0) { - this.pathCooldown = this.maxCooldown; - } else { - this.pathCooldown--; - return false; - } - - FlyPathEntity pathentity = this.getPathToEntityLiving(p_75497_1_); + NPCPath pathentity = this.getPathToEntityLiving(p_75497_1_); return pathentity != null && this.setPath(pathentity, p_75497_2_); } @@ -171,19 +207,19 @@ public class PathNavigateFlying extends PathNavigate { * sets the active path data if path is 100% unique compared to old path, checks to adjust path for sun avoiding * ents and stores end coords */ - public boolean setPath(PathEntity pathEntity, double p_75484_2_) + public boolean setPath(@Nullable PathEntity pathEntity, double speed) { - FlyPathEntity p_75484_1_ = (FlyPathEntity) pathEntity; - if (p_75484_1_ == null) + NPCPath NPCPath = (NPCPath) pathEntity; + if (NPCPath == null) { this.currentPath = null; return false; } else { - if (!p_75484_1_.isSamePath(this.currentPath)) + if (!NPCPath.isSamePath(this.currentPath)) { - this.currentPath = p_75484_1_; + this.currentPath = NPCPath; } if (this.noSunPathfind) @@ -197,12 +233,10 @@ public class PathNavigateFlying extends PathNavigate { } else { - this.speed = p_75484_2_; + this.speed = speed; Vec3 vec3 = this.getEntityPosition(); this.ticksAtLastPos = this.totalTicks; - this.lastPosCheck.xCoord = vec3.xCoord; - this.lastPosCheck.yCoord = vec3.yCoord; - this.lastPosCheck.zCoord = vec3.zCoord; + this.lastPosCheck = vec3; return true; } } @@ -230,21 +264,31 @@ public class PathNavigateFlying extends PathNavigate { { ++this.totalTicks; + if (this.tryUpdatePath) + { + this.updatePath(); + } + if (!this.noPath()) { if (this.canNavigate()) { this.pathFollow(); } + else if (this.currentPath != null && this.currentPath.getCurrentPathIndex() < this.currentPath.getCurrentPathLength()) + { + Vec3 vec3d = this.currentPath.getVectorFromIndex(this.theEntity, this.currentPath.getCurrentPathIndex()); + + if (MathHelper.floor_double(this.theEntity.posX) == MathHelper.floor_double(vec3d.xCoord) && MathHelper.floor_double(this.theEntity.posY) == MathHelper.floor_double(vec3d.yCoord) && MathHelper.floor_double(this.theEntity.posZ) == MathHelper.floor_double(vec3d.zCoord)) + { + this.currentPath.setCurrentPathIndex(this.currentPath.getCurrentPathIndex() + 1); + } + } if (!this.noPath()) { - Vec3 vec3 = this.currentPath.getPosition(this.theEntity); - - if (vec3 != null) - { - this.theEntity.getMoveHelper().setMoveTo(vec3.xCoord, vec3.yCoord, vec3.zCoord, this.speed); - } + Vec3 vec3d1 = this.currentPath.getPosition(this.theEntity); + this.theEntity.getMoveHelper().setMoveTo(vec3d1.xCoord, vec3d1.yCoord, vec3d1.zCoord, this.speed); } } } @@ -253,20 +297,25 @@ public class PathNavigateFlying extends PathNavigate { { Vec3 vec3 = this.getEntityPosition(); int i = this.currentPath.getCurrentPathLength(); - - float f = this.theEntity.width * this.theEntity.width; - int k; - - for (k = this.currentPath.getCurrentPathIndex(); k < i; ++k) + for (int j = this.currentPath.getCurrentPathIndex(); j < this.currentPath.getCurrentPathLength(); ++j) { - if (vec3.squareDistanceTo(this.currentPath.getVectorFromIndex(this.theEntity, k)) < (double)f) + if ((double)this.currentPath.getPathPointFromIndex(j).yCoord != Math.floor(vec3.yCoord)) { - this.currentPath.setCurrentPathIndex(k + 1); + i = j; + break; } } - k = MathHelper.ceiling_float_int(this.theEntity.width); - int l = (int)this.theEntity.height + 1; + this.maxDistanceToWaypoint = this.theEntity.width > 0.75F ? this.theEntity.width / 2.0F : 0.75F - this.theEntity.width / 2.0F; + Vec3 vec3d1 = this.currentPath.getCurrentPos(); + + if (MathHelper.abs((float)(this.theEntity.posX - (vec3d1.xCoord + 0.5D))) < this.maxDistanceToWaypoint && MathHelper.abs((float)(this.theEntity.posZ - (vec3d1.zCoord + 0.5D))) < this.maxDistanceToWaypoint && Math.abs(this.theEntity.posY - vec3d1.yCoord) < 1.0D) + { + this.currentPath.setCurrentPathIndex(this.currentPath.getCurrentPathIndex() + 1); + } + + int k = MathHelper.ceiling_double_int(this.theEntity.width); + int l = MathHelper.ceiling_double_int(this.theEntity.height); int i1 = k; for (int j1 = i - 1; j1 >= this.currentPath.getCurrentPathIndex(); --j1) @@ -278,17 +327,46 @@ public class PathNavigateFlying extends PathNavigate { } } + this.checkForStuck(vec3); + } + + protected void checkForStuck(Vec3 positionVec3) + { if (this.totalTicks - this.ticksAtLastPos > 100) { - if (vec3.squareDistanceTo(this.lastPosCheck) < 2.25D) + if (positionVec3.squareDistanceTo(this.lastPosCheck) < 2.25D) { this.clearPathEntity(); } this.ticksAtLastPos = this.totalTicks; - this.lastPosCheck.xCoord = vec3.xCoord; - this.lastPosCheck.yCoord = vec3.yCoord; - this.lastPosCheck.zCoord = vec3.zCoord; + this.lastPosCheck = positionVec3; + } + + if (this.currentPath != null && !this.currentPath.isFinished()) + { + Vec3 vec3d = this.currentPath.getCurrentPos(); + + if (vec3d.equals(this.timeoutCachedNode)) + { + this.timeoutTimer += System.currentTimeMillis() - this.lastTimeoutCheck; + } + else + { + this.timeoutCachedNode = vec3d; + double d0 = positionVec3.distanceTo(this.timeoutCachedNode); + this.timeoutLimit = this.theEntity.getAIMoveSpeed() > 0.0F ? d0 / (double)this.theEntity.getAIMoveSpeed() * 1000.0D : 0.0D; + } + + if (this.timeoutLimit > 0.0D && (double)this.timeoutTimer > this.timeoutLimit * 3.0D) + { + this.timeoutCachedNode = Vec3.createVectorHelper(0.0D, 0.0D, 0.0D);; + this.timeoutTimer = 0L; + this.timeoutLimit = 0.0D; + this.clearPathEntity(); + } + + this.lastTimeoutCheck = System.currentTimeMillis(); } } @@ -345,118 +423,80 @@ 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 p_75493_1_, Vec3 p_75493_2_, int entityXSize, int entityYSize, int entityZSize) + private boolean isDirectPathBetweenPoints(Vec3 posVec31, Vec3 posVec32, int sizeX, int sizeY, int sizeZ) { - int l = MathHelper.floor_double(p_75493_1_.xCoord); - int i1 = MathHelper.floor_double(p_75493_1_.zCoord); - double d0 = p_75493_2_.xCoord - p_75493_1_.xCoord; - double d1 = p_75493_2_.zCoord - p_75493_1_.zCoord; - double d2 = d0 * d0 + d1 * d1; + int i = MathHelper.floor_double(posVec31.xCoord); + int j = MathHelper.floor_double(posVec31.yCoord); + int k = MathHelper.floor_double(posVec31.zCoord); + double d0 = posVec32.xCoord - posVec31.xCoord; + double d1 = posVec32.yCoord - posVec31.yCoord; + double d2 = posVec32.zCoord - posVec31.zCoord; + double d3 = d0 * d0 + d1 * d1 + d2 * d2; - if (d2 < 1.0E-8D) + if (d3 < 1.0E-8D) { return false; } else { - double d3 = 1.0D / Math.sqrt(d2); - d0 *= d3; - d1 *= d3; - entityXSize += 2; - entityZSize += 2; + double d4 = 1.0D / Math.sqrt(d3); + d0 = d0 * d4; + d1 = d1 * d4; + d2 = d2 * d4; + double d5 = 1.0D / Math.abs(d0); + double d6 = 1.0D / Math.abs(d1); + double d7 = 1.0D / Math.abs(d2); + double d8 = (double)i - posVec31.xCoord; + double d9 = (double)j - posVec31.yCoord; + double d10 = (double)k - posVec31.zCoord; - if (!this.isSafeToStandAt(l, (int)p_75493_1_.yCoord, i1, entityXSize, entityYSize, entityZSize, p_75493_1_, d0, d1)) + if (d0 >= 0.0D) { - return false; + ++d8; } - else + + if (d1 >= 0.0D) { - entityXSize -= 2; - entityZSize -= 2; - double d4 = 1.0D / Math.abs(d0); - double d5 = 1.0D / Math.abs(d1); - double d6 = (double)(l * 1) - p_75493_1_.xCoord; - double d7 = (double)(i1 * 1) - p_75493_1_.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(p_75493_2_.xCoord); - int i2 = MathHelper.floor_double(p_75493_2_.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)p_75493_1_.yCoord, i1, entityXSize, entityYSize, entityZSize, p_75493_1_, d0, d1)); - - return false; + ++d9; } - } - } - 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) + if (d2 >= 0.0D) { - for (int j2 = l1; j2 < l1 + p_75483_6_; ++j2) + ++d10; + } + + d8 = d8 / d0; + d9 = d9 / d1; + d10 = d10 / d2; + int l = d0 < 0.0D ? -1 : 1; + int i1 = d1 < 0.0D ? -1 : 1; + int j1 = d2 < 0.0D ? -1 : 1; + int k1 = MathHelper.floor_double(posVec32.xCoord); + int l1 = MathHelper.floor_double(posVec32.yCoord); + int i2 = MathHelper.floor_double(posVec32.zCoord); + int j2 = k1 - i; + int k2 = l1 - j; + int l2 = i2 - k; + + while (j2 * l > 0 || k2 * i1 > 0 || l2 * j1 > 0) + { + if (d8 < d10 && d8 <= d9) { - 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; - } - } + d8 += d5; + i += l; + j2 = k1 - i; + } + else if (d9 < d8 && d9 <= d10) + { + d9 += d6; + j += i1; + k2 = l1 - j; + } + else + { + d10 += d7; + k += j1; + l2 = i2 - k; } } @@ -464,34 +504,7 @@ public class PathNavigateFlying extends PathNavigate { } } - 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; - } - - public FlyPathEntity getPathEntityToEntity(Entity p_72865_1_, Entity p_72865_2_, float p_72865_3_, boolean p_72865_4_, boolean p_72865_5_, boolean p_72865_6_, boolean p_72865_7_) + public NPCPath getPathEntityToEntity(Entity p_72865_1_, Entity p_72865_2_, float p_72865_3_, boolean p_72865_4_, boolean p_72865_5_, boolean p_72865_6_, boolean p_72865_7_) { this.theEntity.worldObj.theProfiler.startSection("pathfind"); int i = MathHelper.floor_double(p_72865_1_.posX); @@ -505,12 +518,12 @@ public class PathNavigateFlying extends PathNavigate { int i2 = j + l; int j2 = k + l; ChunkCache chunkcache = new ChunkCache(this.theEntity.worldObj, i1, j1, k1, l1, i2, j2, 0); - FlyPathEntity pathentity = (new FlyPathFinder(chunkcache, p_72865_4_, p_72865_5_, p_72865_6_, p_72865_7_, p_72865_1_)).createEntityPathTo(p_72865_1_, p_72865_2_, p_72865_3_); + NPCPath pathentity = (new FlyPathFinder(chunkcache, p_72865_4_, p_72865_5_, p_72865_6_, p_72865_7_, p_72865_1_)).createEntityPathTo(p_72865_1_, p_72865_2_, p_72865_3_); this.theEntity.worldObj.theProfiler.endSection(); return pathentity; } - public FlyPathEntity getEntityPathToXYZ(Entity p_72844_1_, int p_72844_2_, int p_72844_3_, int p_72844_4_, float p_72844_5_, boolean p_72844_6_, boolean p_72844_7_, boolean p_72844_8_, boolean p_72844_9_) + public NPCPath getEntityPathToXYZ(Entity p_72844_1_, int x, int y, int z, float p_72844_5_, boolean p_72844_6_, boolean p_72844_7_, boolean p_72844_8_, boolean p_72844_9_) { this.theEntity.worldObj.theProfiler.startSection("pathfind"); int l = MathHelper.floor_double(p_72844_1_.posX); @@ -524,7 +537,7 @@ public class PathNavigateFlying extends PathNavigate { int l2 = i1 + k1; int i3 = j1 + k1; ChunkCache chunkcache = new ChunkCache(this.theEntity.worldObj, l1, i2, j2, k2, l2, i3, 0); - FlyPathEntity pathentity = (new FlyPathFinder(chunkcache, p_72844_6_, p_72844_7_, p_72844_8_, p_72844_9_, p_72844_1_)).createEntityPathTo(p_72844_1_, p_72844_2_, p_72844_3_, p_72844_4_, p_72844_5_); + NPCPath pathentity = (new FlyPathFinder(chunkcache, p_72844_6_, p_72844_7_, p_72844_8_, p_72844_9_, p_72844_1_)).createEntityPathTo(p_72844_1_, x, y, z, p_72844_5_); this.theEntity.worldObj.theProfiler.endSection(); return pathentity; }