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