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