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 }