    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 (par1EntityLiving.boundingBox.maxY > this.taskOwner.boundingBox.minY && par1EntityLiving.boundingBox.minY < this.taskOwner.boundingBox.maxY)
    107            {
    108                if (!this.taskOwner.isExplosiveMob(par1EntityLiving.getClass()))
    109                {
    110                    return false;
    111                }
    112                else
    113                {
    114                    if (this.taskOwner instanceof EntityTameable && ((EntityTameable)this.taskOwner).isTamed())
    115                    {
    116                        if (par1EntityLiving instanceof EntityTameable && ((EntityTameable)par1EntityLiving).isTamed())
    117                        {
    118                            return false;
    119                        }
    120
    121                        if (par1EntityLiving == ((EntityTameable)this.taskOwner).getOwner())
    122                        {
    123                            return false;
    124                        }
    125                    }
    126                    else if (par1EntityLiving instanceof EntityPlayer && !par2 && ((EntityPlayer)par1EntityLiving).capabilities.disableDamage)
    127                    {
    128                        return false;
    129                    }
    130
    131                    if (!this.taskOwner.isWithinHomeDistance(MathHelper.floor_double(par1EntityLiving.posX), MathHelper.floor_double(par1EntityLiving.posY), MathHelper.floor_double(par1EntityLiving.posZ)))
    132                    {
    133                        return false;
    134                    }
    135                    else if (this.shouldCheckSight && !this.taskOwner.getEntitySenses().canSee(par1EntityLiving))
    136                    {
    137                        return false;
    138                    }
    139                    else
    140                    {
    141                        if (this.field_75303_a)
    142                        {
    143                            if (--this.field_75302_c <= 0)
    144                            {
    145                                this.field_75301_b = 0;
    146                            }
    147
    148                            if (this.field_75301_b == 0)
    149                            {
    150                                this.field_75301_b = this.func_75295_a(par1EntityLiving) ? 1 : 2;
    151                            }
    152
    153                            if (this.field_75301_b == 2)
    154                            {
    155                                return false;
    156                            }
    157                        }
    158
    159                        return true;
    160                    }
    161                }
    162            }
    163            else
    164            {
    165                return false;
    166            }
    167        }
    168
    169        private boolean func_75295_a(EntityLiving par1EntityLiving)
    170        {
    171            this.field_75302_c = 10 + this.taskOwner.getRNG().nextInt(5);
    172            PathEntity var2 = this.taskOwner.getNavigator().getPathToEntityLiving(par1EntityLiving);
    173
    174            if (var2 == null)
    175            {
    176                return false;
    177            }
    178            else
    179            {
    180                PathPoint var3 = var2.getFinalPathPoint();
    181
    182                if (var3 == null)
    183                {
    184                    return false;
    185                }
    186                else
    187                {
    188                    int var4 = var3.xCoord - MathHelper.floor_double(par1EntityLiving.posX);
    189                    int var5 = var3.zCoord - MathHelper.floor_double(par1EntityLiving.posZ);
    190                    return (double)(var4 * var4 + var5 * var5) <= 2.25D;
    191                }
    192            }
    193        }
    194    }