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 121d2d5c6..0aee35ccc 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,25 @@ 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; + + 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); this.theEntity = entityIn; this.worldMap = _worldMap; + + this.isWoodenDoorAllowed = doorsAllowed; + this.isMovementBlockAllowed = closedDoors; + this.isPathingInWater = canPathWater; + this.canEntityDrown = canDrown; } /** @@ -64,9 +79,14 @@ 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); - 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 +127,85 @@ 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_; + int x = 0; while (!this.path.isPathEmpty()) { - ++i; + x++; - if (i >= 200) - { + if (x >= 200) { break; } - NPCPathPoint pathpoint1 = this.path.dequeue(); + NPCPathPoint pathpoint4 = this.path.dequeue(); - if (pathpoint1.equals(pathTo)) + if (pathpoint4.equals(p_75861_3_)) { - pathpoint = pathTo; - break; + return this.createEntityPath(p_75861_2_, p_75861_3_); } - if (pathpoint1.distanceManhattan(pathTo) < pathpoint.distanceManhattan(pathTo)) + if (pathpoint4.distanceToSquared(p_75861_3_) < pathpoint3.distanceToSquared(p_75861_3_)) { - pathpoint = pathpoint1; + pathpoint3 = pathpoint4; } - pathpoint1.isFirst = true; - int j = this.findPathOptions(this.pathOptions, entityIn, pathpoint1, pathTo, maxDistance); + pathpoint4.isFirst = true; + int i = this.findPathOptions(p_75861_1_, pathpoint4, p_75861_4_, p_75861_3_, p_75861_5_); - for (int k = 0; k < j; ++k) + for (int j = 0; j < i; ++j) { - 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; + NPCPathPoint pathpoint5 = this.pathOptions[j]; + float f1 = pathpoint4.totalPathDistance + pathpoint4.distanceToSquared(pathpoint5); - 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 +213,63 @@ 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 entity, NPCPathPoint currentPoint, 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(entity, currentPoint.xCoord, currentPoint.yCoord + 1, currentPoint.zCoord, p_75860_3_) == 1) { - pathOptions[i++] = pathpoint; + b0 = 1; + } + + 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) + { + 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 != 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) { - NPCPathPoint pathpoint6 = this.openPoint(currentPoint.xCoord - 1, currentPoint.yCoord, currentPoint.zCoord - 1); + 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) { @@ -260,141 +279,230 @@ public class FlyPathFinder extends PathFinder if (flag && flag2) { - NPCPathPoint pathpoint7 = this.openPoint(currentPoint.xCoord + 1, currentPoint.yCoord, currentPoint.zCoord - 1); + NPCPathPoint pathpoint6 = this.getSafePoint(entity, currentPoint.xCoord + 1, currentPoint.yCoord, currentPoint.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(entity, currentPoint.xCoord - 1, currentPoint.yCoord, currentPoint.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(entity, currentPoint.xCoord + 1, currentPoint.yCoord, currentPoint.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(entity, currentPoint.xCoord, currentPoint.yCoord + 1, currentPoint.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(entity, currentPoint.xCoord, currentPoint.yCoord + 1, currentPoint.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(entity, currentPoint.xCoord + 1, currentPoint.yCoord + 1, currentPoint.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(entity, currentPoint.xCoord - 1, currentPoint.yCoord + 1, currentPoint.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(entity, currentPoint.xCoord, currentPoint.yCoord - 1, currentPoint.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(entity, currentPoint.xCoord, currentPoint.yCoord - 1, currentPoint.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(entity, currentPoint.xCoord + 1, currentPoint.yCoord - 1, currentPoint.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(entity, currentPoint.xCoord - 1, currentPoint.yCoord - 1, currentPoint.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 entity, int x, int y, int z, 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; + PathNodeType pathNodeType1 = this.getPathNodeType(entity,x,y,z); + int i1 = this.nodeTypeToOffset(pathNodeType1); - 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; - } + pathpoint1 = this.openPoint(x, y, z); + pathpoint1.costMalus = i1; + pathpoint1.nodeType = pathNodeType1; + return pathpoint1; } + else + { + if (i1 == 1) + { + pathpoint1 = this.openPoint(x, y, z); + pathpoint1.costMalus = i1; + pathpoint1.nodeType = pathNodeType1; + } - return pathnodetype != PathNodeType.OPEN && pathnodetype != PathNodeType.WALKABLE ? pathpoint : pathpoint; + 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(x, y + p_75858_6_, z); + pathpoint1.costMalus = vertOffset2; + pathpoint1.nodeType = pathNodeType2; + y += p_75858_6_; + } + + if (pathpoint1 != null) + { + int j1 = 0; + int k1 = 0; + + while (y > 0) + { + PathNodeType pathNodeType3 = this.getPathNodeType(entity,x, y - 1, z); + k1 = this.nodeTypeToOffset(pathNodeType3); + + if (this.isPathingInWater && k1 == -1) + { + return null; + } + + if (k1 != 1) + { + break; + } + + if (j1++ >= entity.getMaxSafePointTries()) + { + return null; + } + + --y; + + if (y > 0) + { + pathpoint1 = this.openPoint(x, y, z); + pathpoint1.costMalus = k1; + pathpoint1.nodeType = pathNodeType3; + } + } + + if (k1 == -2) + { + return null; + } + } + return pathpoint1; + } } - protected NPCPathPoint openPoint(int x, int y, int z, int b) + private PathNodeType getPathNodeType(Entity entity, int x, int y, int z) + { + return this.getPathNodeType((EntityLiving) entity, new BlockPos(x,y,z)); + } + + public int nodeTypeToOffset(PathNodeType nodeType) { + switch (nodeType) { + case TRAPDOOR: + return -4; + case FENCE: + return -3; + case LAVA: + case DAMAGE_FIRE: + case DAMAGE_CACTUS: + case DAMAGE_OTHER: + return -2; + case WATER: + case DANGER_FIRE: + case DANGER_CACTUS: + case DANGER_OTHER: + return -1; + case BLOCKED: + case DOOR_WOOD_CLOSED: + case DOOR_IRON_CLOSED: + return 0; + case WALKABLE: + case DOOR_OPEN: + return 1; + case OPEN: + case RAIL: + return 2; + } + + return 1; + } + + protected NPCPathPoint openPoint(int x, int y, int z) { int i = NPCPathPoint.makeHash(x, y, z); NPCPathPoint pathpoint = this.pointMap.lookup(i); @@ -576,7 +684,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; } @@ -603,7 +711,7 @@ public class FlyPathFinder extends PathFinder { if (block == Blocks.fire) { - return PathNodeType.DAMAGE_FIRE; + return immuneToFire ? PathNodeType.OPEN : PathNodeType.DAMAGE_FIRE; } else if (block == Blocks.cactus) { @@ -629,11 +737,11 @@ public class FlyPathFinder extends PathFinder { if (material == Material.water) { - return PathNodeType.WATER; + return ((EntityNPCInterface)this.theEntity).ai.canSwim ? PathNodeType.OPEN : PathNodeType.WATER; } else if (material == Material.lava) { - return PathNodeType.LAVA; + return immuneToFire ? PathNodeType.OPEN : PathNodeType.LAVA; } else { 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 bf1f4079a..5a8ce0c64 100644 --- a/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java +++ b/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java @@ -6,21 +6,21 @@ 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; import net.minecraft.world.World; -import noppes.npcs.entity.EntityCustomNpc; import noppes.npcs.entity.EntityNPCInterface; - import javax.annotation.Nullable; public class PathNavigateFlying extends PathNavigate { + private EntityNPCInterface theEntity; private World worldObj; /** The PathEntity being followed. */ @@ -328,16 +328,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); } @@ -364,20 +355,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); } @@ -435,157 +431,274 @@ 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 startPos, Vec3 endPos, int width, int height) { - 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) - { + 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)) return false; - } - else - { - double d3 = 1.0D / Math.sqrt(d2); - d0 *= d3; - d1 *= d3; - entityXSize += 2; - entityZSize += 2; - if (!this.isSafeToStandAt(l, (int)vec31.yCoord, i1, entityXSize, entityYSize, entityZSize, vec31, d0, d1)) + return true; + } + + 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); + + 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_); + + if (movingobjectposition != null && movingobjectposition.typeOfHit != MovingObjectPosition.MovingObjectType.MISS) + { + return true; + } + } + + MovingObjectPosition movingobjectposition2 = null; + k1 = 200; + + while (k1-- >= 0) + { + if (Double.isNaN(p_147447_1_.xCoord) || Double.isNaN(p_147447_1_.yCoord) || Double.isNaN(p_147447_1_.zCoord)) + { + return false; + } + + 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 = -width; x <= width; x++) { + if (value) { + break; + } + for (int y = 0; y <= height; y++) { + if (value) { + break; + } + for (int z = -width; z <= width; z++) { + if (Math.abs(x) == Math.abs(z)) { + continue; + } + + l += x; + i1 += y; + j1 += z; + + Block block2 = this.worldObj.getBlock(l, i1, j1); + int meta2 = this.worldObj.getBlockMetadata(l, i1, j1); + + 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; + 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; + } + } + } + + if (value) { + return true; + } + } + + if (p_147447_5_) { + return movingobjectposition2 != null && movingobjectposition2.typeOfHit != MovingObjectPosition.MovingObjectType.MISS; + } return false; } else { - entityXSize -= 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; } } - } - - 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_)) + else { 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) 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; diff --git a/src/main/java/noppes/npcs/entity/EntityNPCFlying.java b/src/main/java/noppes/npcs/entity/EntityNPCFlying.java index da9a40ff7..50184f63c 100644 --- a/src/main/java/noppes/npcs/entity/EntityNPCFlying.java +++ b/src/main/java/noppes/npcs/entity/EntityNPCFlying.java @@ -1,8 +1,7 @@ package noppes.npcs.entity; -import net.minecraft.init.Blocks; -import net.minecraft.util.MathHelper; -import net.minecraft.util.math.BlockPos; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.Vec3; import net.minecraft.world.World; public abstract class EntityNPCFlying extends EntityNPCInterface { @@ -48,13 +47,24 @@ public abstract class EntityNPCFlying extends EntityNPCInterface { public void moveFlyingWithHeading(float strafe, float forward) { - if(!this.canFly() || this.hurtTime != 0) { - super.moveEntityWithHeading(strafe, forward); + if(!this.canFly() || this.hurtTime != 0 || !this.canBreathe()) { + super.moveEntityWithHeading(p_70612_1_, p_70612_2_); 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; diff --git a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java index 121d9f607..8f38e32ef 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.*; @@ -20,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; @@ -220,7 +222,7 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti public int getMaxSafePointTries() { - return 10; + return 3; } @Override @@ -415,16 +417,20 @@ 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) { - 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) { @@ -1054,7 +1060,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(); @@ -1336,18 +1342,30 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti 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()) { + if (ii < j - 1) { + yy = j; + break; + } + Block block = worldObj.getBlock(i, ii, k); + 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) + continue; + yy = bb.maxY; + break; + } } if (yy <= 0) setDead(); - yy += 0.5; return yy; } @@ -1620,6 +1638,32 @@ 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() + { + if (stats.drowningType != 1) { + 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); + } else { + this.inWater = false; + } + return false; + } else { + return super.handleWaterMovement(); + } + } + + public boolean canBreatheUnderwater() + { + return stats.drowningType != 1; + } public void setAvoidWater(boolean avoidWater) { this.getNavigator().setAvoidsWater(avoidWater); 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){ 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 */