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 }