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