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 (!this.taskOwner.isExplosiveMob(par1EntityLiving.getClass()))
107 {
108 return false;
109 }
110 else
111 {
112 if (this.taskOwner instanceof EntityTameable && ((EntityTameable)this.taskOwner).isTamed())
113 {
114 if (par1EntityLiving instanceof EntityTameable && ((EntityTameable)par1EntityLiving).isTamed())
115 {
116 return false;
117 }
118
119 if (par1EntityLiving == ((EntityTameable)this.taskOwner).getOwner())
120 {
121 return false;
122 }
123 }
124 else if (par1EntityLiving instanceof EntityPlayer && !par2 && ((EntityPlayer)par1EntityLiving).capabilities.disableDamage)
125 {
126 return false;
127 }
128
129 if (!this.taskOwner.isWithinHomeDistance(MathHelper.floor_double(par1EntityLiving.posX), MathHelper.floor_double(par1EntityLiving.posY), MathHelper.floor_double(par1EntityLiving.posZ)))
130 {
131 return false;
132 }
133 else if (this.shouldCheckSight && !this.taskOwner.getEntitySenses().canSee(par1EntityLiving))
134 {
135 return false;
136 }
137 else
138 {
139 if (this.field_75303_a)
140 {
141 if (--this.field_75302_c <= 0)
142 {
143 this.field_75301_b = 0;
144 }
145
146 if (this.field_75301_b == 0)
147 {
148 this.field_75301_b = this.func_75295_a(par1EntityLiving) ? 1 : 2;
149 }
150
151 if (this.field_75301_b == 2)
152 {
153 return false;
154 }
155 }
156
157 return true;
158 }
159 }
160 }
161
162 private boolean func_75295_a(EntityLiving par1EntityLiving)
163 {
164 this.field_75302_c = 10 + this.taskOwner.getRNG().nextInt(5);
165 PathEntity var2 = this.taskOwner.getNavigator().getPathToEntityLiving(par1EntityLiving);
166
167 if (var2 == null)
168 {
169 return false;
170 }
171 else
172 {
173 PathPoint var3 = var2.getFinalPathPoint();
174
175 if (var3 == null)
176 {
177 return false;
178 }
179 else
180 {
181 int var4 = var3.xCoord - MathHelper.floor_double(par1EntityLiving.posX);
182 int var5 = var3.zCoord - MathHelper.floor_double(par1EntityLiving.posZ);
183 return (double)(var4 * var4 + var5 * var5) <= 2.25D;
184 }
185 }
186 }
187 }