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