package common.ai; import java.util.List; import common.collect.Lists; import common.entity.types.EntityLiving; import common.pathfinding.PathEntity; import common.pathfinding.PathNavigateGround; import common.util.ExtMath; import common.village.Village; import common.village.VillageDoorInfo; import common.world.BlockPos; import common.world.Vec3; import common.world.WorldServer; public class EntityAIMoveThroughVillage extends EntityAIBase { private EntityLiving theEntity; private double movementSpeed; /** The PathNavigate of our entity. */ private PathEntity entityPathNavigate; private VillageDoorInfo doorInfo; private boolean isNocturnal; private List doorList = Lists.newArrayList(); public EntityAIMoveThroughVillage(EntityLiving theEntityIn, double movementSpeedIn, boolean isNocturnalIn) { this.theEntity = theEntityIn; this.movementSpeed = movementSpeedIn; this.isNocturnal = isNocturnalIn; this.setMutexBits(1); if (!(theEntityIn.getNavigator() instanceof PathNavigateGround)) { throw new IllegalArgumentException("Unsupported mob for MoveThroughVillageGoal"); } } /** * Returns whether the EntityAIBase should begin execution. */ public boolean shouldExecute() { this.resizeDoorList(); if (this.isNocturnal && ((WorldServer)this.theEntity.worldObj).isDaytime()) { return false; } else { Village village = ((WorldServer)this.theEntity.worldObj).getNearestVillage(new BlockPos(this.theEntity), 0); if (village == null) { return false; } else { this.doorInfo = this.findNearestDoor(village); if (this.doorInfo == null) { return false; } else { PathNavigateGround pathnavigateground = (PathNavigateGround)this.theEntity.getNavigator(); boolean flag = pathnavigateground.getEnterDoors(); pathnavigateground.setBreakDoors(false); this.entityPathNavigate = pathnavigateground.getPathToPos(this.doorInfo.getDoorBlockPos()); pathnavigateground.setBreakDoors(flag); if (this.entityPathNavigate != null) { return true; } else { Vec3 vec3 = RandomPositionGenerator.findRandomTargetBlockTowards(this.theEntity, 10, 7, new Vec3((double)this.doorInfo.getDoorBlockPos().getX(), (double)this.doorInfo.getDoorBlockPos().getY(), (double)this.doorInfo.getDoorBlockPos().getZ())); if (vec3 == null) { return false; } else { pathnavigateground.setBreakDoors(false); this.entityPathNavigate = this.theEntity.getNavigator().getPathToXYZ(vec3.xCoord, vec3.yCoord, vec3.zCoord); pathnavigateground.setBreakDoors(flag); return this.entityPathNavigate != null; } } } } } } /** * Returns whether an in-progress EntityAIBase should continue executing */ public boolean continueExecuting() { if (this.theEntity.getNavigator().noPath()) { return false; } else { float f = this.theEntity.width + 4.0F; return this.theEntity.getDistanceSq(this.doorInfo.getDoorBlockPos()) > (double)(f * f); } } /** * Execute a one shot task or start executing a continuous task */ public void startExecuting() { this.theEntity.getNavigator().setPath(this.entityPathNavigate, this.movementSpeed); } /** * Resets the task */ public void resetTask() { if (this.theEntity.getNavigator().noPath() || this.theEntity.getDistanceSq(this.doorInfo.getDoorBlockPos()) < 16.0D) { this.doorList.add(this.doorInfo); } } private VillageDoorInfo findNearestDoor(Village villageIn) { VillageDoorInfo villagedoorinfo = null; int i = Integer.MAX_VALUE; for (VillageDoorInfo villagedoorinfo1 : villageIn.getDoorList()) { int j = villagedoorinfo1.getDistanceSquared(ExtMath.floord(this.theEntity.posX), ExtMath.floord(this.theEntity.posY), ExtMath.floord(this.theEntity.posZ)); if (j < i && !this.doesDoorListContain(villagedoorinfo1)) { villagedoorinfo = villagedoorinfo1; i = j; } } return villagedoorinfo; } private boolean doesDoorListContain(VillageDoorInfo doorInfoIn) { for (VillageDoorInfo villagedoorinfo : this.doorList) { if (doorInfoIn.getDoorBlockPos().equals(villagedoorinfo.getDoorBlockPos())) { return true; } } return false; } private void resizeDoorList() { if (this.doorList.size() > 15) { this.doorList.remove(0); } } }