diff --git a/src/main/java/noppes/npcs/ai/pathfinder/FlyingMoveHelper.java b/src/main/java/noppes/npcs/ai/pathfinder/FlyingMoveHelper.java index 7031a9e00..078598d75 100644 --- a/src/main/java/noppes/npcs/ai/pathfinder/FlyingMoveHelper.java +++ b/src/main/java/noppes/npcs/ai/pathfinder/FlyingMoveHelper.java @@ -1,5 +1,6 @@ package noppes.npcs.ai.pathfinder; +import net.minecraft.entity.EntityLiving; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.ai.EntityMoveHelper; import net.minecraft.util.AxisAlignedBB; @@ -8,60 +9,83 @@ import noppes.npcs.entity.EntityNPCInterface; // Fly Change -public class FlyingMoveHelper extends EntityMoveHelper { +public class FlyingMoveHelper extends EntityMoveHelper{ private EntityNPCInterface entity; - private int field_179928_h; - protected boolean update; - - public double posX; - public double posY; - public double posZ; + private double posX; + private double posY; + private double posZ; + private double speed; + private boolean update; + private static final String __OBFID = "CL_00001573"; public FlyingMoveHelper(EntityNPCInterface entity){ super(entity); this.entity = entity; + this.posX = entity.posX; + this.posY = entity.posY; + this.posZ = entity.posZ; } - public void onUpdateMoveHelper(){ - if (this.update){ + public void onUpdateMoveHelper() { + this.entity.setMoveForward(0.0F); + + if (this.update) { + this.update = false; + int i = MathHelper.floor_double(this.entity.boundingBox.minY + 0.5D); double d0 = this.posX - this.entity.posX; - double d1 = this.posY - this.entity.posY; - double d2 = this.posZ - this.entity.posZ; - double d3 = d0 * d0 + d1 * d1 + d2 * d2; - - if (this.field_179928_h-- <= 0){ - this.field_179928_h += this.entity.getRNG().nextInt(5) + 2; - d3 = (double) MathHelper.sqrt_double(d3); + double d1 = this.posZ - this.entity.posZ; + double d2 = this.posY - (double)i; + double d3 = d0 * d0 + d2 * d2 + d1 * d1; - if (d3 > 1 && this.func_179926_b(this.posX, this.posY, this.posZ, d3)){ - double speed = entity.getEntityAttribute(SharedMonsterAttributes.movementSpeed).getAttributeValue() / 2.5; - this.entity.motionX += d0 / d3 * speed; - this.entity.motionY += d1 / d3 * speed; - this.entity.motionZ += d2 / d3 * speed; - this.entity.renderYawOffset = this.entity.rotationYaw = -((float)Math.atan2(this.entity.motionX, this.entity.motionZ)) * 180.0F / (float)Math.PI; - } - else{ - this.update = false; + if (d3 >= 2.500000277905201E-7D) { + float f = (float)(Math.atan2(d1, d0) * 180.0D / Math.PI) - 90.0F; + this.entity.rotationYaw = this.limitAngle(this.entity.rotationYaw, f, 30.0F); + this.entity.setAIMoveSpeed((float)(this.speed * this.entity.getEntityAttribute(SharedMonsterAttributes.movementSpeed).getAttributeValue())); + + if (d2 > 0.0D && d0 * d0 + d1 * d1 < 1.0D) { + this.entity.getJumpHelper().setJumping(); } } } } - private boolean func_179926_b(double p_179926_1_, double p_179926_3_, double p_179926_5_, double p_179926_7_){ - double d4 = (p_179926_1_ - this.entity.posX) / p_179926_7_; - double d5 = (p_179926_3_ - this.entity.posY) / p_179926_7_; - double d6 = (p_179926_5_ - this.entity.posZ) / p_179926_7_; - AxisAlignedBB axisalignedbb = this.entity.getBoundingBox(); + private float limitAngle(float p_75639_1_, float p_75639_2_, float p_75639_3_) + { + float f3 = MathHelper.wrapAngleTo180_float(p_75639_2_ - p_75639_1_); - for (int i = 1; (double)i < p_179926_7_; ++i){ - axisalignedbb = axisalignedbb.offset(d4, d5, d6); - - if (!this.entity.worldObj.getCollidingBoundingBoxes(this.entity, axisalignedbb).isEmpty()){ - return false; - } + if (f3 > p_75639_3_) + { + f3 = p_75639_3_; } - return true; + if (f3 < -p_75639_3_) + { + f3 = -p_75639_3_; + } + + return p_75639_1_ + f3; + } + + /** + * Sets the speed and location to move to + */ + public void setMoveTo(double p_75642_1_, double p_75642_3_, double p_75642_5_, double p_75642_7_) + { + this.posX = p_75642_1_; + this.posY = p_75642_3_; + this.posZ = p_75642_5_; + this.speed = p_75642_7_; + this.update = true; + } + + public boolean isUpdating() + { + return this.update; + } + + public double getSpeed() + { + return this.speed; } } diff --git a/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java b/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java index c2187dbeb..3e0bf41ee 100644 --- a/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java +++ b/src/main/java/noppes/npcs/ai/pathfinder/PathNavigateFlying.java @@ -1,25 +1,511 @@ 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.PathFinder; +import net.minecraft.pathfinding.PathNavigate; +import net.minecraft.pathfinding.PathPoint; +import net.minecraft.util.MathHelper; +import net.minecraft.util.Vec3; +import net.minecraft.world.ChunkCache; import net.minecraft.world.World; +import noppes.npcs.entity.EntityNPCInterface; -public class PathNavigateFlying extends PathNavigateSwimmer { +public class PathNavigateFlying extends PathNavigate { + private EntityNPCInterface theEntity; + private World worldObj; + /** The PathEntity being followed. */ + private PathEntity 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; + private boolean noSunPathfind; + /** Time, in number of ticks, following the current path */ + private int totalTicks; + /** The time when the last position check was done (to detect successful movement) */ + 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); + /** 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 */ + private boolean canPassClosedWoodenDoors; + /** If water blocks are avoided (at least by the pathfinder) */ + private boolean avoidsWater; + /** + * If the entity can swim. Swimming AI enables this and the pathfinder will also cause the entity to swim straight + * upwards when underwater + */ + private boolean canSwim; + private static final String __OBFID = "CL_00001627"; - public PathNavigateFlying(EntityLiving p_i45873_1_, World worldIn) { - super(p_i45873_1_, worldIn); - } - - protected PathFinder getPathFinder() + public PathNavigateFlying(EntityLiving p_i45873_1_, World worldIn) { + super(p_i45873_1_, worldIn); + this.theEntity = (EntityNPCInterface)p_i45873_1_; + this.worldObj = worldIn; + this.pathSearchRange = p_i45873_1_.getEntityAttribute(SharedMonsterAttributes.followRange); + } + + public void setAvoidsWater(boolean p_75491_1_) { - return new NPCPathFinder(new FlyNodeProcessor()); + this.avoidsWater = p_75491_1_; + } + + public boolean getAvoidsWater() + { + return this.avoidsWater; + } + + public void setBreakDoors(boolean p_75498_1_) + { + this.canPassClosedWoodenDoors = p_75498_1_; + } + + /** + * Sets if the entity can enter open doors + */ + public void setEnterDoors(boolean p_75490_1_) + { + this.canPassOpenWoodenDoors = p_75490_1_; + } + + /** + * Returns true if the entity can break doors, false otherwise + */ + public boolean getCanBreakDoors() + { + return this.canPassClosedWoodenDoors; + } + + /** + * Sets if the path should avoid sunlight + */ + public void setAvoidSun(boolean p_75504_1_) + { + this.noSunPathfind = p_75504_1_; + } + + /** + * Sets the speed + */ + public void setSpeed(double p_75489_1_) + { + this.speed = p_75489_1_; + } + + /** + * Sets if the entity can swim + */ + public void setCanSwim(boolean p_75495_1_) + { + this.canSwim = p_75495_1_; + } + + /** + * Gets the maximum distance that the path finding will search in. + */ + public float getPathSearchRange() + { + return (float)this.pathSearchRange.getAttributeValue(); + } + + /** + * Returns the path to the given coordinates + */ + public PathEntity getPathToXYZ(double p_75488_1_, double p_75488_3_, double p_75488_5_) + { + 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); + } + + /** + * Try to find and set a path to XYZ. Returns true if successful. + */ + public boolean tryMoveToXYZ(double p_75492_1_, double p_75492_3_, double p_75492_5_, double p_75492_7_) + { + PathEntity 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 PathEntity getPathToEntityLiving(Entity p_75494_1_) + { + return !this.canNavigate() ? null : this.getPathEntityToEntity(this.theEntity, p_75494_1_, this.getPathSearchRange(), this.canPassOpenWoodenDoors, this.canPassClosedWoodenDoors, this.avoidsWater, this.canSwim); + } + + /** + * Try to find and set a path to EntityLiving. Returns true if successful. + */ + public boolean tryMoveToEntityLiving(Entity p_75497_1_, double p_75497_2_) + { + PathEntity pathentity = this.getPathToEntityLiving(p_75497_1_); + return pathentity != null ? this.setPath(pathentity, p_75497_2_) : false; + } + + /** + * 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 p_75484_1_, double p_75484_2_) + { + if (p_75484_1_ == null) + { + this.currentPath = null; + return false; + } + else + { + if (!p_75484_1_.isSamePath(this.currentPath)) + { + this.currentPath = p_75484_1_; + } + + if (this.noSunPathfind) + { + this.removeSunnyPath(); + } + + if (this.currentPath.getCurrentPathLength() == 0) + { + return false; + } + else + { + this.speed = p_75484_2_; + Vec3 vec3 = this.getEntityPosition(); + this.ticksAtLastPos = this.totalTicks; + this.lastPosCheck.xCoord = vec3.xCoord; + this.lastPosCheck.yCoord = vec3.yCoord; + this.lastPosCheck.zCoord = vec3.zCoord; + return true; + } + } + } + + /** + * gets the actively used PathEntity + */ + public PathEntity getPath() + { + return this.currentPath; + } + + public void onUpdateNavigation() + { + ++this.totalTicks; + + if (!this.noPath()) + { + if (this.canNavigate()) + { + this.pathFollow(); + } + + 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); + } + } + } + } + + private void pathFollow() + { + Vec3 vec3 = this.getEntityPosition(); + int i = this.currentPath.getCurrentPathLength(); + + for (int j = this.currentPath.getCurrentPathIndex(); j < this.currentPath.getCurrentPathLength(); ++j) + { + if (this.currentPath.getPathPointFromIndex(j).yCoord != (int)vec3.yCoord) + { + i = j; + break; + } + } + + float f = this.theEntity.width * this.theEntity.width; + int k; + + for (k = this.currentPath.getCurrentPathIndex(); k < i; ++k) + { + if (vec3.squareDistanceTo(this.currentPath.getVectorFromIndex(this.theEntity, k)) < (double)f) + { + this.currentPath.setCurrentPathIndex(k + 1); + } + } + + k = MathHelper.ceiling_float_int(this.theEntity.width); + int l = (int)this.theEntity.height + 1; + 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; + } + } + + if (this.totalTicks - this.ticksAtLastPos > 100) + { + if (vec3.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; + } + } + + /** + * If null path or reached the end + */ + public boolean noPath() + { + return this.currentPath == null || this.currentPath.isFinished(); + } + + /** + * sets active PathEntity to null + */ + public void clearPathEntity() + { + this.currentPath = null; + } + + private Vec3 getEntityPosition() + { + return Vec3.createVectorHelper(this.theEntity.posX, (double)this.getPathableYPos(), this.theEntity.posZ); + } + + /** + * Gets the safe pathing Y position for the entity depending on if it can path swim or not + */ + private int getPathableYPos() + { + int i = (int)this.theEntity.boundingBox.minY; + Block block = this.worldObj.getBlock(MathHelper.floor_double(this.theEntity.posX), i, MathHelper.floor_double(this.theEntity.posZ)); + int j = 0; + + do + { + if (block != Blocks.air) + { + return i; + } + + ++i; + block = this.worldObj.getBlock(MathHelper.floor_double(this.theEntity.posX), i, MathHelper.floor_double(this.theEntity.posZ)); + ++j; + } + while (j <= 16); + + return (int)(this.theEntity.boundingBox.minY + 0.5D); } /** * If on ground or swimming and can swim */ - protected boolean canNavigate() + private boolean canNavigate() { return true; } + + /** + * Returns true when an entity could stand at a position, including solid blocks under the entire entity. Args: + * xOffset, yOffset, zOffset, entityXSize, entityYSize, entityZSize, originPosition, vecX, vecZ + */ + 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_) + { + return true; + } + + /** + * Trims path data from the end to the first sun covered block + */ + private void removeSunnyPath() + { + if (!this.worldObj.canBlockSeeTheSky(MathHelper.floor_double(this.theEntity.posX), (int)(this.theEntity.boundingBox.minY + 0.5D), MathHelper.floor_double(this.theEntity.posZ))) + { + for (int i = 0; i < this.currentPath.getCurrentPathLength(); ++i) + { + PathPoint pathpoint = this.currentPath.getPathPointFromIndex(i); + + if (this.worldObj.canBlockSeeTheSky(pathpoint.xCoord, pathpoint.yCoord, pathpoint.zCoord)) + { + this.currentPath.setCurrentPathLength(i - 1); + return; + } + } + } + } + + /** + * 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 p_75493_3_, int p_75493_4_, int p_75493_5_) + { + 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; + + if (d2 < 1.0E-8D) + { + return false; + } + else + { + double d3 = 1.0D / Math.sqrt(d2); + d0 *= d3; + d1 *= d3; + p_75493_3_ += 2; + p_75493_5_ += 2; + + if (!this.isSafeToStandAt(l, (int)p_75493_1_.yCoord, i1, p_75493_3_, p_75493_4_, p_75493_5_, p_75493_1_, d0, d1)) + { + return false; + } + else + { + p_75493_3_ -= 2; + p_75493_5_ -= 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, p_75493_3_, p_75493_4_, p_75493_5_, p_75493_1_, d0, d1)); + + return false; + } + } + } + + /** + * Returns true if an entity does not collide with any solid blocks at the position. Args: xOffset, yOffset, + * zOffset, entityXSize, entityYSize, entityZSize, originPosition, vecX, vecZ + */ + 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 PathEntity 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); + int j = MathHelper.floor_double(p_72865_1_.posY + 1.0D); + int k = MathHelper.floor_double(p_72865_1_.posZ); + int l = (int)(p_72865_3_ + 16.0F); + int i1 = i - l; + int j1 = j - l; + int k1 = k - l; + int l1 = i + l; + int i2 = j + l; + int j2 = k + l; + ChunkCache chunkcache = new ChunkCache(this.theEntity.worldObj, i1, j1, k1, l1, i2, j2, 0); + PathEntity pathentity = (new PathFinder(chunkcache, p_72865_4_, p_72865_5_, p_72865_6_, p_72865_7_)).createEntityPathTo(p_72865_1_, p_72865_2_, p_72865_3_); + this.theEntity.worldObj.theProfiler.endSection(); + return pathentity; + } + + public PathEntity 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_) + { + this.theEntity.worldObj.theProfiler.startSection("pathfind"); + int l = MathHelper.floor_double(p_72844_1_.posX); + int i1 = MathHelper.floor_double(p_72844_1_.posY); + int j1 = MathHelper.floor_double(p_72844_1_.posZ); + int k1 = (int)(p_72844_5_ + 8.0F); + int l1 = l - k1; + int i2 = i1 - k1; + int j2 = j1 - k1; + int k2 = l + k1; + int l2 = i1 + k1; + int i3 = j1 + k1; + ChunkCache chunkcache = new ChunkCache(this.theEntity.worldObj, l1, i2, j2, k2, l2, i3, 0); + PathEntity pathentity = (new PathFinder(chunkcache, p_72844_6_, p_72844_7_, p_72844_8_, p_72844_9_)).createEntityPathTo(p_72844_1_, p_72844_2_, p_72844_3_, p_72844_4_, p_72844_5_); + this.theEntity.worldObj.theProfiler.endSection(); + return pathentity; + } } diff --git a/src/main/java/noppes/npcs/entity/EntityNPCFlying.java b/src/main/java/noppes/npcs/entity/EntityNPCFlying.java index 610ac8055..85c53a223 100644 --- a/src/main/java/noppes/npcs/entity/EntityNPCFlying.java +++ b/src/main/java/noppes/npcs/entity/EntityNPCFlying.java @@ -31,7 +31,7 @@ public abstract class EntityNPCFlying extends EntityNPCInterface { public void onLivingUpdate() { - if(!canFly()){ + if(!canFly() || this.isJumping){ super.onLivingUpdate(); return; } @@ -41,23 +41,24 @@ public abstract class EntityNPCFlying extends EntityNPCInterface { if(isEntityAlive()) { if (!this.worldObj.isRemote) { - Entity entity = this.getAttackTarget(); - if (entity != null && entity.isEntityAlive()) { - double d0 = entity.posX - this.posX; - double d2 = entity.posZ - this.posZ; - double d3 = d0 * d0 + d2 * d2; + Entity target = this.getAttackTarget(); + if (target != null && target.isEntityAlive()) { + double d0 = target.posX - this.posX; + double d1 = target.posY - this.posY; + double d2 = target.posZ - this.posZ; + double d4 = d0 * d0 + d1 * d1 + d2 * d2; if(this.hurtTime == 0) { - if (this.posY != entity.posY) { - if (this.motionY * Math.signum(this.posY - entity.posY) > 0.0D) { + if (this.posY != target.posY) { + if (this.motionY * Math.signum(this.posY - target.posY) > 0.0D) { this.motionY = 0.0D; } - this.motionY -= Math.signum(this.posY - entity.posY) * (speed * speedMult) * this.ai.flySpeed; + this.motionY -= Math.signum(this.posY - target.posY) * (speed * speedMult) * this.ai.flySpeed; } - if (d3 > 9.0D) { - double d5 = MathHelper.sqrt_double(d3); + if (d4 > 0.5D) { + double d5 = MathHelper.sqrt_double(d4); this.motionX += (d0 / d5 * speed - this.motionX) * speed * speedMult; this.motionZ += (d2 / d5 * speed - this.motionZ) * speed * speedMult; } diff --git a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java index 79c43f23a..2ac01b37e 100644 --- a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java +++ b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java @@ -20,7 +20,6 @@ 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.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemBow; import net.minecraft.item.ItemStack; @@ -60,8 +59,8 @@ import noppes.npcs.ai.EntityAIMoveIndoors; import noppes.npcs.ai.EntityAIPanic; import noppes.npcs.ai.EntityAIWander; import noppes.npcs.ai.EntityAIWatchClosest; +import noppes.npcs.ai.pathfinder.FlyingMoveHelper; import noppes.npcs.ai.pathfinder.PathNavigateFlying; -import noppes.npcs.ai.pathfinder.PathNavigateGround; import noppes.npcs.ai.selector.NPCAttackSelector; import noppes.npcs.ai.target.EntityAIClearTarget; import noppes.npcs.ai.target.EntityAIClosestTarget; @@ -96,7 +95,6 @@ import noppes.npcs.roles.RoleCompanion; import noppes.npcs.roles.RoleFollower; import noppes.npcs.roles.RoleInterface; import noppes.npcs.scripted.entity.ScriptNpc; -import noppes.npcs.scripted.entity.ScriptPlayer; import noppes.npcs.scripted.event.ScriptEventAttack; import noppes.npcs.scripted.event.ScriptEventDamaged; import noppes.npcs.scripted.event.ScriptEventKilled; @@ -156,12 +154,19 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti public boolean updateAI = false; // Fly Change - //public EntityMoveHelper moveHelper; - public PathNavigate navigator; + public FlyingMoveHelper flyMoveHelper = new FlyingMoveHelper(this); + public PathNavigate flyNavigator = new PathNavigateFlying(this, worldObj); public EntityNPCInterface(World world) { super(world); try{ + if (canFly()) { + this.getNavigator().setCanSwim(true); + this.tasks.addTask(0, new EntityAISwimming(this)); + } else { + this.tasks.addTask(0, new EntityAIWaterNav(this)); + } + dialogs = new HashMap(); if(!CustomNpcs.DefaultInteractLine.isEmpty()) advanced.interactLines.lines.put(0, new Line(CustomNpcs.DefaultInteractLine)); @@ -405,6 +410,29 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti return true; } + + public PathNavigate getNavigator() { + if(canFly() && !this.onGround) + return this.flyNavigator; + else { + return super.getNavigator(); + } + } + + public EntityMoveHelper getMoveHelper() { + if(canFly() && !this.onGround) + return this.flyMoveHelper; + else { + return super.getMoveHelper(); + } + } + + protected void updateAITasks() + { + super.updateAITasks(); + this.getNavigator().onUpdateNavigation(); + this.getMoveHelper().onUpdateMoveHelper(); + } public void addInteract(EntityLivingBase entity){ if( !ai.stopAndInteract || isAttacking() || !entity.isEntityAlive()) @@ -600,15 +628,10 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti this.targetTasks.addTask(3, new EntityAIOwnerHurtByTarget(this)); this.targetTasks.addTask(4, new EntityAIOwnerHurtTarget(this)); - if(canFly()){ - //this.moveHelper = new FlyingMoveHelper(this); - this.navigator = new PathNavigateFlying(this, worldObj); + if (canFly()) { this.getNavigator().setCanSwim(true); this.tasks.addTask(0, new EntityAISwimming(this)); - } - else{ - //this.moveHelper = new EntityMoveHelper(this); - this.navigator = new PathNavigateGround(this, worldObj); + } else { this.tasks.addTask(0, new EntityAIWaterNav(this)); }