001 package net.minecraft.src; 002 003 public abstract class EntityAITarget extends EntityAIBase 004 { 005 /** The entity that this task belongs to */ 006 protected EntityLiving taskOwner; 007 protected float targetDistance; 008 009 /** 010 * If true, EntityAI targets must be able to be seen (cannot be blocked by walls) to be suitable targets. 011 */ 012 protected boolean shouldCheckSight; 013 private boolean field_75303_a; 014 private int field_75301_b; 015 private int field_75302_c; 016 private int field_75298_g; 017 018 public EntityAITarget(EntityLiving par1EntityLiving, float par2, boolean par3) 019 { 020 this(par1EntityLiving, par2, par3, false); 021 } 022 023 public EntityAITarget(EntityLiving par1EntityLiving, float par2, boolean par3, boolean par4) 024 { 025 this.field_75301_b = 0; 026 this.field_75302_c = 0; 027 this.field_75298_g = 0; 028 this.taskOwner = par1EntityLiving; 029 this.targetDistance = par2; 030 this.shouldCheckSight = par3; 031 this.field_75303_a = par4; 032 } 033 034 /** 035 * Returns whether an in-progress EntityAIBase should continue executing 036 */ 037 public boolean continueExecuting() 038 { 039 EntityLiving var1 = this.taskOwner.getAttackTarget(); 040 041 if (var1 == null) 042 { 043 return false; 044 } 045 else if (!var1.isEntityAlive()) 046 { 047 return false; 048 } 049 else if (this.taskOwner.getDistanceSqToEntity(var1) > (double)(this.targetDistance * this.targetDistance)) 050 { 051 return false; 052 } 053 else 054 { 055 if (this.shouldCheckSight) 056 { 057 if (this.taskOwner.getEntitySenses().canSee(var1)) 058 { 059 this.field_75298_g = 0; 060 } 061 else if (++this.field_75298_g > 60) 062 { 063 return false; 064 } 065 } 066 067 return true; 068 } 069 } 070 071 /** 072 * Execute a one shot task or start executing a continuous task 073 */ 074 public void startExecuting() 075 { 076 this.field_75301_b = 0; 077 this.field_75302_c = 0; 078 this.field_75298_g = 0; 079 } 080 081 /** 082 * Resets the task 083 */ 084 public void resetTask() 085 { 086 this.taskOwner.setAttackTarget((EntityLiving)null); 087 } 088 089 /** 090 * A method used to see if an entity is a suitable target through a number of checks. 091 */ 092 protected boolean isSuitableTarget(EntityLiving par1EntityLiving, boolean par2) 093 { 094 if (par1EntityLiving == null) 095 { 096 return false; 097 } 098 else if (par1EntityLiving == this.taskOwner) 099 { 100 return false; 101 } 102 else if (!par1EntityLiving.isEntityAlive()) 103 { 104 return false; 105 } 106 else if (par1EntityLiving.boundingBox.maxY > this.taskOwner.boundingBox.minY && par1EntityLiving.boundingBox.minY < this.taskOwner.boundingBox.maxY) 107 { 108 if (!this.taskOwner.isExplosiveMob(par1EntityLiving.getClass())) 109 { 110 return false; 111 } 112 else 113 { 114 if (this.taskOwner instanceof EntityTameable && ((EntityTameable)this.taskOwner).isTamed()) 115 { 116 if (par1EntityLiving instanceof EntityTameable && ((EntityTameable)par1EntityLiving).isTamed()) 117 { 118 return false; 119 } 120 121 if (par1EntityLiving == ((EntityTameable)this.taskOwner).getOwner()) 122 { 123 return false; 124 } 125 } 126 else if (par1EntityLiving instanceof EntityPlayer && !par2 && ((EntityPlayer)par1EntityLiving).capabilities.disableDamage) 127 { 128 return false; 129 } 130 131 if (!this.taskOwner.isWithinHomeDistance(MathHelper.floor_double(par1EntityLiving.posX), MathHelper.floor_double(par1EntityLiving.posY), MathHelper.floor_double(par1EntityLiving.posZ))) 132 { 133 return false; 134 } 135 else if (this.shouldCheckSight && !this.taskOwner.getEntitySenses().canSee(par1EntityLiving)) 136 { 137 return false; 138 } 139 else 140 { 141 if (this.field_75303_a) 142 { 143 if (--this.field_75302_c <= 0) 144 { 145 this.field_75301_b = 0; 146 } 147 148 if (this.field_75301_b == 0) 149 { 150 this.field_75301_b = this.func_75295_a(par1EntityLiving) ? 1 : 2; 151 } 152 153 if (this.field_75301_b == 2) 154 { 155 return false; 156 } 157 } 158 159 return true; 160 } 161 } 162 } 163 else 164 { 165 return false; 166 } 167 } 168 169 private boolean func_75295_a(EntityLiving par1EntityLiving) 170 { 171 this.field_75302_c = 10 + this.taskOwner.getRNG().nextInt(5); 172 PathEntity var2 = this.taskOwner.getNavigator().getPathToEntityLiving(par1EntityLiving); 173 174 if (var2 == null) 175 { 176 return false; 177 } 178 else 179 { 180 PathPoint var3 = var2.getFinalPathPoint(); 181 182 if (var3 == null) 183 { 184 return false; 185 } 186 else 187 { 188 int var4 = var3.xCoord - MathHelper.floor_double(par1EntityLiving.posX); 189 int var5 = var3.zCoord - MathHelper.floor_double(par1EntityLiving.posZ); 190 return (double)(var4 * var4 + var5 * var5) <= 2.25D; 191 } 192 } 193 } 194 }