001    package net.minecraft.entity.ai;
002    
003    import net.minecraft.entity.EntityLiving;
004    import net.minecraft.pathfinding.PathEntity;
005    import net.minecraft.util.MathHelper;
006    import net.minecraft.world.World;
007    
008    public 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 var1 = this.attacker.getAttackTarget();
048    
049            if (var1 == null)
050            {
051                return false;
052            }
053            else if (this.classTarget != null && !this.classTarget.isAssignableFrom(var1.getClass()))
054            {
055                return false;
056            }
057            else
058            {
059                this.entityTarget = var1;
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 var1 = this.attacker.getAttackTarget();
071            return var1 == 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 var1 = (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) <= var1)
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    }