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 }