001package net.minecraft.entity.ai;
002
003import net.minecraft.entity.EntityLiving;
004import net.minecraft.pathfinding.PathEntity;
005import net.minecraft.util.MathHelper;
006import net.minecraft.world.World;
007
008public class EntityAIAttackOnCollide extends EntityAIBase
009{
010    World worldObj;
011    EntityLiving attacker;
012    EntityLiving entityTarget;
013
014    /**
015     * An amount of decrementing ticks that allows the entity to attack once the tick reaches 0.
016     */
017    int attackTick;
018    float field_75440_e;
019    boolean field_75437_f;
020
021    /** The PathEntity of our entity. */
022    PathEntity entityPathEntity;
023    Class classTarget;
024    private int field_75445_i;
025
026    public EntityAIAttackOnCollide(EntityLiving par1EntityLiving, Class par2Class, float par3, boolean par4)
027    {
028        this(par1EntityLiving, par3, par4);
029        this.classTarget = par2Class;
030    }
031
032    public EntityAIAttackOnCollide(EntityLiving par1EntityLiving, float par2, boolean par3)
033    {
034        this.attackTick = 0;
035        this.attacker = par1EntityLiving;
036        this.worldObj = par1EntityLiving.worldObj;
037        this.field_75440_e = par2;
038        this.field_75437_f = par3;
039        this.setMutexBits(3);
040    }
041
042    /**
043     * Returns whether the EntityAIBase should begin execution.
044     */
045    public boolean shouldExecute()
046    {
047        EntityLiving entityliving = this.attacker.getAttackTarget();
048
049        if (entityliving == null)
050        {
051            return false;
052        }
053        else if (this.classTarget != null && !this.classTarget.isAssignableFrom(entityliving.getClass()))
054        {
055            return false;
056        }
057        else
058        {
059            this.entityTarget = entityliving;
060            this.entityPathEntity = this.attacker.getNavigator().getPathToEntityLiving(this.entityTarget);
061            return this.entityPathEntity != null;
062        }
063    }
064
065    /**
066     * Returns whether an in-progress EntityAIBase should continue executing
067     */
068    public boolean continueExecuting()
069    {
070        EntityLiving entityliving = this.attacker.getAttackTarget();
071        return entityliving == null ? false : (!this.entityTarget.isEntityAlive() ? false : (!this.field_75437_f ? !this.attacker.getNavigator().noPath() : this.attacker.isWithinHomeDistance(MathHelper.floor_double(this.entityTarget.posX), MathHelper.floor_double(this.entityTarget.posY), MathHelper.floor_double(this.entityTarget.posZ))));
072    }
073
074    /**
075     * Execute a one shot task or start executing a continuous task
076     */
077    public void startExecuting()
078    {
079        this.attacker.getNavigator().setPath(this.entityPathEntity, this.field_75440_e);
080        this.field_75445_i = 0;
081    }
082
083    /**
084     * Resets the task
085     */
086    public void resetTask()
087    {
088        this.entityTarget = null;
089        this.attacker.getNavigator().clearPathEntity();
090    }
091
092    /**
093     * Updates the task
094     */
095    public void updateTask()
096    {
097        this.attacker.getLookHelper().setLookPositionWithEntity(this.entityTarget, 30.0F, 30.0F);
098
099        if ((this.field_75437_f || this.attacker.getEntitySenses().canSee(this.entityTarget)) && --this.field_75445_i <= 0)
100        {
101            this.field_75445_i = 4 + this.attacker.getRNG().nextInt(7);
102            this.attacker.getNavigator().tryMoveToEntityLiving(this.entityTarget, this.field_75440_e);
103        }
104
105        this.attackTick = Math.max(this.attackTick - 1, 0);
106        double d0 = (double)(this.attacker.width * 2.0F * this.attacker.width * 2.0F);
107
108        if (this.attacker.getDistanceSq(this.entityTarget.posX, this.entityTarget.boundingBox.minY, this.entityTarget.posZ) <= d0)
109        {
110            if (this.attackTick <= 0)
111            {
112                this.attackTick = 20;
113
114                if (this.attacker.getHeldItem() != null)
115                {
116                    this.attacker.swingItem();
117                }
118
119                this.attacker.attackEntityAsMob(this.entityTarget);
120            }
121        }
122    }
123}