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