001    package net.minecraft.src;
002    
003    import java.util.List;
004    
005    public class EntityAIAvoidEntity extends EntityAIBase
006    {
007        /** The entity we are attached to */
008        private EntityCreature theEntity;
009        private float farSpeed;
010        private float nearSpeed;
011        private Entity closestLivingEntity;
012        private float distanceFromEntity;
013    
014        /** The PathEntity of our entity */
015        private PathEntity entityPathEntity;
016    
017        /** The PathNavigate of our entity */
018        private PathNavigate entityPathNavigate;
019    
020        /** The class of the entity we should avoid */
021        private Class targetEntityClass;
022    
023        public EntityAIAvoidEntity(EntityCreature par1EntityCreature, Class par2Class, float par3, float par4, float par5)
024        {
025            this.theEntity = par1EntityCreature;
026            this.targetEntityClass = par2Class;
027            this.distanceFromEntity = par3;
028            this.farSpeed = par4;
029            this.nearSpeed = par5;
030            this.entityPathNavigate = par1EntityCreature.getNavigator();
031            this.setMutexBits(1);
032        }
033    
034        /**
035         * Returns whether the EntityAIBase should begin execution.
036         */
037        public boolean shouldExecute()
038        {
039            if (this.targetEntityClass == EntityPlayer.class)
040            {
041                if (this.theEntity instanceof EntityTameable && ((EntityTameable)this.theEntity).isTamed())
042                {
043                    return false;
044                }
045    
046                this.closestLivingEntity = this.theEntity.worldObj.getClosestPlayerToEntity(this.theEntity, (double)this.distanceFromEntity);
047    
048                if (this.closestLivingEntity == null)
049                {
050                    return false;
051                }
052            }
053            else
054            {
055                List var1 = this.theEntity.worldObj.getEntitiesWithinAABB(this.targetEntityClass, this.theEntity.boundingBox.expand((double)this.distanceFromEntity, 3.0D, (double)this.distanceFromEntity));
056    
057                if (var1.isEmpty())
058                {
059                    return false;
060                }
061    
062                this.closestLivingEntity = (Entity)var1.get(0);
063            }
064    
065            if (!this.theEntity.getEntitySenses().canSee(this.closestLivingEntity))
066            {
067                return false;
068            }
069            else
070            {
071                Vec3 var2 = RandomPositionGenerator.findRandomTargetBlockAwayFrom(this.theEntity, 16, 7, this.theEntity.worldObj.getWorldVec3Pool().getVecFromPool(this.closestLivingEntity.posX, this.closestLivingEntity.posY, this.closestLivingEntity.posZ));
072    
073                if (var2 == null)
074                {
075                    return false;
076                }
077                else if (this.closestLivingEntity.getDistanceSq(var2.xCoord, var2.yCoord, var2.zCoord) < this.closestLivingEntity.getDistanceSqToEntity(this.theEntity))
078                {
079                    return false;
080                }
081                else
082                {
083                    this.entityPathEntity = this.entityPathNavigate.getPathToXYZ(var2.xCoord, var2.yCoord, var2.zCoord);
084                    return this.entityPathEntity == null ? false : this.entityPathEntity.isDestinationSame(var2);
085                }
086            }
087        }
088    
089        /**
090         * Returns whether an in-progress EntityAIBase should continue executing
091         */
092        public boolean continueExecuting()
093        {
094            return !this.entityPathNavigate.noPath();
095        }
096    
097        /**
098         * Execute a one shot task or start executing a continuous task
099         */
100        public void startExecuting()
101        {
102            this.entityPathNavigate.setPath(this.entityPathEntity, this.farSpeed);
103        }
104    
105        /**
106         * Resets the task
107         */
108        public void resetTask()
109        {
110            this.closestLivingEntity = null;
111        }
112    
113        /**
114         * Updates the task
115         */
116        public void updateTask()
117        {
118            if (this.theEntity.getDistanceSqToEntity(this.closestLivingEntity) < 49.0D)
119            {
120                this.theEntity.getNavigator().setSpeed(this.nearSpeed);
121            }
122            else
123            {
124                this.theEntity.getNavigator().setSpeed(this.farSpeed);
125            }
126        }
127    }