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 }