    001    package net.minecraft.src;
    002
    003    public abstract class EntityAITarget extends EntityAIBase
    004    {
    005        /** The entity that this task belongs to */
    006        protected EntityLiving taskOwner;
    007        protected float targetDistance;
    008
    009        /**
    010         * If true, EntityAI targets must be able to be seen (cannot be blocked by walls) to be suitable targets.
    011         */
    012        protected boolean shouldCheckSight;
    013        private boolean field_75303_a;
    014        private int field_75301_b;
    015        private int field_75302_c;
    016        private int field_75298_g;
    017
    018        public EntityAITarget(EntityLiving par1EntityLiving, float par2, boolean par3)
    019        {
    020            this(par1EntityLiving, par2, par3, false);
    021        }
    022
    023        public EntityAITarget(EntityLiving par1EntityLiving, float par2, boolean par3, boolean par4)
    024        {
    025            this.field_75301_b = 0;
    026            this.field_75302_c = 0;
    027            this.field_75298_g = 0;
    028            this.taskOwner = par1EntityLiving;
    029            this.targetDistance = par2;
    030            this.shouldCheckSight = par3;
    031            this.field_75303_a = par4;
    032        }
    033
    034        /**
    035         * Returns whether an in-progress EntityAIBase should continue executing
    036         */
    037        public boolean continueExecuting()
    038        {
    039            EntityLiving var1 = this.taskOwner.getAttackTarget();
    040
    041            if (var1 == null)
    042            {
    043                return false;
    044            }
    045            else if (!var1.isEntityAlive())
    046            {
    047                return false;
    048            }
    049            else if (this.taskOwner.getDistanceSqToEntity(var1) > (double)(this.targetDistance * this.targetDistance))
    050            {
    051                return false;
    052            }
    053            else
    054            {
    055                if (this.shouldCheckSight)
    056                {
    057                    if (this.taskOwner.getEntitySenses().canSee(var1))
    058                    {
    059                        this.field_75298_g = 0;
    060                    }
    061                    else if (++this.field_75298_g > 60)
    062                    {
    063                        return false;
    064                    }
    065                }
    066
    067                return true;
    068            }
    069        }
    070
    071        /**
    072         * Execute a one shot task or start executing a continuous task
    073         */
    074        public void startExecuting()
    075        {
    076            this.field_75301_b = 0;
    077            this.field_75302_c = 0;
    078            this.field_75298_g = 0;
    079        }
    080
    081        /**
    082         * Resets the task
    083         */
    084        public void resetTask()
    085        {
    086            this.taskOwner.setAttackTarget((EntityLiving)null);
    087        }
    088
    089        /**
    090         * A method used to see if an entity is a suitable target through a number of checks.
    091         */
    092        protected boolean isSuitableTarget(EntityLiving par1EntityLiving, boolean par2)
    093        {
    094            if (par1EntityLiving == null)
    095            {
    096                return false;
    097            }
    098            else if (par1EntityLiving == this.taskOwner)
    099            {
    100                return false;
    101            }
    102            else if (!par1EntityLiving.isEntityAlive())
    103            {
    104                return false;
    105            }
    106            else if (!this.taskOwner.isExplosiveMob(par1EntityLiving.getClass()))
    107            {
    108                return false;
    109            }
    110            else
    111            {
    112                if (this.taskOwner instanceof EntityTameable && ((EntityTameable)this.taskOwner).isTamed())
    113                {
    114                    if (par1EntityLiving instanceof EntityTameable && ((EntityTameable)par1EntityLiving).isTamed())
    115                    {
    116                        return false;
    117                    }
    118
    119                    if (par1EntityLiving == ((EntityTameable)this.taskOwner).getOwner())
    120                    {
    121                        return false;
    122                    }
    123                }
    124                else if (par1EntityLiving instanceof EntityPlayer && !par2 && ((EntityPlayer)par1EntityLiving).capabilities.disableDamage)
    125                {
    126                    return false;
    127                }
    128
    129                if (!this.taskOwner.isWithinHomeDistance(MathHelper.floor_double(par1EntityLiving.posX), MathHelper.floor_double(par1EntityLiving.posY), MathHelper.floor_double(par1EntityLiving.posZ)))
    130                {
    131                    return false;
    132                }
    133                else if (this.shouldCheckSight && !this.taskOwner.getEntitySenses().canSee(par1EntityLiving))
    134                {
    135                    return false;
    136                }
    137                else
    138                {
    139                    if (this.field_75303_a)
    140                    {
    141                        if (--this.field_75302_c <= 0)
    142                        {
    143                            this.field_75301_b = 0;
    144                        }
    145
    146                        if (this.field_75301_b == 0)
    147                        {
    148                            this.field_75301_b = this.func_75295_a(par1EntityLiving) ? 1 : 2;
    149                        }
    150
    151                        if (this.field_75301_b == 2)
    152                        {
    153                            return false;
    154                        }
    155                    }
    156
    157                    return true;
    158                }
    159            }
    160        }
    161
    162        private boolean func_75295_a(EntityLiving par1EntityLiving)
    163        {
    164            this.field_75302_c = 10 + this.taskOwner.getRNG().nextInt(5);
    165            PathEntity var2 = this.taskOwner.getNavigator().getPathToEntityLiving(par1EntityLiving);
    166
    167            if (var2 == null)
    168            {
    169                return false;
    170            }
    171            else
    172            {
    173                PathPoint var3 = var2.getFinalPathPoint();
    174
    175                if (var3 == null)
    176                {
    177                    return false;
    178                }
    179                else
    180                {
    181                    int var4 = var3.xCoord - MathHelper.floor_double(par1EntityLiving.posX);
    182                    int var5 = var3.zCoord - MathHelper.floor_double(par1EntityLiving.posZ);
    183                    return (double)(var4 * var4 + var5 * var5) <= 2.25D;
    184                }
    185            }
    186        }
    187    }