001    package net.minecraft.src;
002    
003    public class EntityAIArrowAttack extends EntityAIBase
004    {
005        /** The entity the AI instance has been applied to */
006        private final EntityLiving entityHost;
007    
008        /**
009         * The entity (as a RangedAttackMob) the AI instance has been applied to.
010         */
011        private final IRangedAttackMob rangedAttackEntityHost;
012        private EntityLiving attackTarget;
013    
014        /**
015         * A decrementing tick that spawns a ranged attack once this value reaches 0. It is then set back to the
016         * maxRangedAttackTime.
017         */
018        private int rangedAttackTime = 0;
019        private float entityMoveSpeed;
020        private int field_75318_f = 0;
021    
022        /**
023         * The maximum time the AI has to wait before peforming another ranged attack.
024         */
025        private int maxRangedAttackTime;
026        private float field_82642_h;
027    
028        public EntityAIArrowAttack(IRangedAttackMob par1IRangedAttackMob, float par2, int par3, float par4)
029        {
030            if (!(par1IRangedAttackMob instanceof EntityLiving))
031            {
032                throw new IllegalArgumentException("ArrowAttackGoal requires Mob implements RangedAttackMob");
033            }
034            else
035            {
036                this.rangedAttackEntityHost = par1IRangedAttackMob;
037                this.entityHost = (EntityLiving)par1IRangedAttackMob;
038                this.entityMoveSpeed = par2;
039                this.maxRangedAttackTime = par3;
040                this.field_82642_h = par4 * par4;
041                this.setMutexBits(3);
042            }
043        }
044    
045        /**
046         * Returns whether the EntityAIBase should begin execution.
047         */
048        public boolean shouldExecute()
049        {
050            EntityLiving var1 = this.entityHost.getAttackTarget();
051    
052            if (var1 == null)
053            {
054                return false;
055            }
056            else
057            {
058                this.attackTarget = var1;
059                return true;
060            }
061        }
062    
063        /**
064         * Returns whether an in-progress EntityAIBase should continue executing
065         */
066        public boolean continueExecuting()
067        {
068            return this.shouldExecute() || !this.entityHost.getNavigator().noPath();
069        }
070    
071        /**
072         * Resets the task
073         */
074        public void resetTask()
075        {
076            this.attackTarget = null;
077            this.field_75318_f = 0;
078        }
079    
080        /**
081         * Updates the task
082         */
083        public void updateTask()
084        {
085            double var1 = this.entityHost.getDistanceSq(this.attackTarget.posX, this.attackTarget.boundingBox.minY, this.attackTarget.posZ);
086            boolean var3 = this.entityHost.getEntitySenses().canSee(this.attackTarget);
087    
088            if (var3)
089            {
090                ++this.field_75318_f;
091            }
092            else
093            {
094                this.field_75318_f = 0;
095            }
096    
097            if (var1 <= (double)this.field_82642_h && this.field_75318_f >= 20)
098            {
099                this.entityHost.getNavigator().clearPathEntity();
100            }
101            else
102            {
103                this.entityHost.getNavigator().tryMoveToEntityLiving(this.attackTarget, this.entityMoveSpeed);
104            }
105    
106            this.entityHost.getLookHelper().setLookPositionWithEntity(this.attackTarget, 30.0F, 30.0F);
107            this.rangedAttackTime = Math.max(this.rangedAttackTime - 1, 0);
108    
109            if (this.rangedAttackTime <= 0)
110            {
111                if (var1 <= (double)this.field_82642_h && var3)
112                {
113                    this.rangedAttackEntityHost.attackEntityWithRangedAttack(this.attackTarget);
114                    this.rangedAttackTime = this.maxRangedAttackTime;
115                }
116            }
117        }
118    }