Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
1package net.minecraft.server;
2
3import com.legacyminecraft.poseidon.PoseidonConfig;
4import org.bukkit.craftbukkit.TrigMath;
5import org.bukkit.craftbukkit.entity.CraftEntity;
6import org.bukkit.event.entity.EntityDamageByBlockEvent;
7import org.bukkit.event.entity.EntityDamageEvent;
8import org.bukkit.event.entity.EntityDeathEvent;
9import org.bukkit.event.entity.EntityRegainHealthEvent;
10import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
11
12import uk.betacraft.uberbukkit.UberbukkitConfig;
13
14import java.util.List;
15
16// CraftBukkit start
17// CraftBukkit end
18
19public abstract class EntityLiving extends Entity {
20
21 public int maxNoDamageTicks = 20;
22 public float I;
23 public float J;
24 public float K = 0.0F;
25 public float L = 0.0F;
26 protected float M;
27 protected float N;
28 protected float O;
29 protected float P;
30 protected boolean Q = true;
31 protected String texture = "/mob/char.png";
32 protected boolean S = true;
33 protected float T = 0.0F;
34 protected String U = null;
35 protected float V = 1.0F;
36 protected int W = 0;
37 protected float X = 0.0F;
38 public boolean Y = false;
39 public float Z;
40 public float aa;
41 public int health = 10;
42 public int ac;
43 private int a;
44 public int hurtTicks;
45 public int ae;
46 public float af = 0.0F;
47 public int deathTicks = 0;
48 public int attackTicks = 0;
49 public float ai;
50 public float aj;
51 protected boolean ak = false;
52 public int al = -1;
53 public float am = (float) (Math.random() * 0.8999999761581421D + 0.10000000149011612D);
54 public float an;
55 public float ao;
56 public float ap;
57 protected int aq;
58 protected double ar;
59 protected double as;
60 protected double at;
61 protected double au;
62 protected double av;
63 float aw = 0.0F;
64 public int lastDamage = 0; // CraftBukkit - protected -> public
65 protected int ay = 0;
66 protected float az;
67 protected float aA;
68 protected float aB;
69 protected boolean aC = false;
70 protected float aD = 0.0F;
71 protected float aE = 0.7F;
72 private Entity b;
73 protected int aF = 0;
74
75 public EntityLiving(World world) {
76 super(world);
77 this.aI = true;
78 this.J = (float) (Math.random() + 1.0D) * 0.01F;
79 this.setPosition(this.locX, this.locY, this.locZ);
80 this.I = (float) Math.random() * 12398.0F;
81 this.yaw = (float) (Math.random() * 3.1415927410125732D * 2.0D);
82 this.bs = 0.5F;
83 }
84
85 protected void b() {
86 }
87
88 // hasLineOfSight
89 public boolean e(Entity entity) {
90 return this.world.a(Vec3D.create(this.locX, this.locY + (double) this.t(), this.locZ), Vec3D.create(entity.locX, entity.locY + (double) entity.t(), entity.locZ)) == null;
91 }
92
93 public boolean l_() {
94 return !this.dead;
95 }
96
97 public boolean d_() {
98 return !this.dead;
99 }
100
101 public float t() {
102 return this.width * 0.85F;
103 }
104
105 public int e() {
106 return 80;
107 }
108
109 public void Q() {
110 String s = this.g();
111
112 if (s != null) {
113 this.world.makeSound(this, s, this.k(), (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F);
114 }
115 }
116
117 public void R() {
118 this.Z = this.aa;
119 super.R();
120 if (this.random.nextInt(1000) < this.a++) {
121 this.a = -this.e();
122 this.Q();
123 }
124
125 if (this.T() && this.K()) {
126 // CraftBukkit start
127 EntityDamageEvent event = new EntityDamageEvent(this.getBukkitEntity(), EntityDamageEvent.DamageCause.SUFFOCATION, 1);
128 this.world.getServer().getPluginManager().callEvent(event);
129
130 if (!event.isCancelled()) {
131 this.damageEntity((Entity) null, event.getDamage());
132 }
133 // CraftBukkit end
134 }
135
136 if (this.fireProof || this.world.isStatic) {
137 this.fireTicks = 0;
138 }
139
140 int i;
141
142 if (this.T() && this.a(Material.WATER) && !this.b_()) {
143 --this.airTicks;
144 if (this.airTicks == -20) {
145 this.airTicks = 0;
146
147 for (i = 0; i < 8; ++i) {
148 float f = this.random.nextFloat() - this.random.nextFloat();
149 float f1 = this.random.nextFloat() - this.random.nextFloat();
150 float f2 = this.random.nextFloat() - this.random.nextFloat();
151
152 this.world.a("bubble", this.locX + (double) f, this.locY + (double) f1, this.locZ + (double) f2, this.motX, this.motY, this.motZ);
153 }
154
155 // CraftBukkit start
156 EntityDamageEvent event = new EntityDamageEvent(this.getBukkitEntity(), EntityDamageEvent.DamageCause.DROWNING, 2);
157 this.world.getServer().getPluginManager().callEvent(event);
158
159 if (!event.isCancelled() && event.getDamage() != 0) {
160 boolean vc = this.velocityChanged;
161 this.damageEntity((Entity) null, event.getDamage());
162 if (PoseidonConfig.getInstance().getBoolean("settings.fix-drowning-push-down.enabled", true))
163 this.velocityChanged = vc;
164 }
165 // CraftBukkit end
166 }
167
168 this.fireTicks = 0;
169 } else {
170 this.airTicks = this.maxAirTicks;
171 }
172
173 this.ai = this.aj;
174 if (this.attackTicks > 0) {
175 --this.attackTicks;
176 }
177
178 if (this.hurtTicks > 0) {
179 --this.hurtTicks;
180 }
181
182 if (this.noDamageTicks > 0) {
183 --this.noDamageTicks;
184 }
185
186 if (this.health <= 0) {
187 ++this.deathTicks;
188 if (this.deathTicks > 20) {
189 this.X();
190 this.die();
191
192 for (i = 0; i < 20; ++i) {
193 double d0 = this.random.nextGaussian() * 0.02D;
194 double d1 = this.random.nextGaussian() * 0.02D;
195 double d2 = this.random.nextGaussian() * 0.02D;
196
197 this.world.a("explode", this.locX + (double) (this.random.nextFloat() * this.length * 2.0F) - (double) this.length, this.locY + (double) (this.random.nextFloat() * this.width), this.locZ + (double) (this.random.nextFloat() * this.length * 2.0F) - (double) this.length, d0, d1, d2);
198 }
199 }
200 }
201
202 this.P = this.O;
203 this.L = this.K;
204 this.lastYaw = this.yaw;
205 this.lastPitch = this.pitch;
206 }
207
208 public void S() {
209 for (int i = 0; i < 20; ++i) {
210 double d0 = this.random.nextGaussian() * 0.02D;
211 double d1 = this.random.nextGaussian() * 0.02D;
212 double d2 = this.random.nextGaussian() * 0.02D;
213 double d3 = 10.0D;
214
215 this.world.a("explode", this.locX + (double) (this.random.nextFloat() * this.length * 2.0F) - (double) this.length - d0 * d3, this.locY + (double) (this.random.nextFloat() * this.width) - d1 * d3, this.locZ + (double) (this.random.nextFloat() * this.length * 2.0F) - (double) this.length - d2 * d3, d0, d1, d2);
216 }
217 }
218
219 public void E() {
220 super.E();
221 this.M = this.N;
222 this.N = 0.0F;
223 }
224
225 public void m_() {
226 super.m_();
227 this.v();
228 double d0 = this.locX - this.lastX;
229 double d1 = this.locZ - this.lastZ;
230 float f = MathHelper.a(d0 * d0 + d1 * d1);
231 float f1 = this.K;
232 float f2 = 0.0F;
233
234 this.M = this.N;
235 float f3 = 0.0F;
236
237 if (f > 0.05F) {
238 f3 = 1.0F;
239 f2 = f * 3.0F;
240 // CraftBukkit - Math -> TrigMath
241 f1 = (float) TrigMath.atan2(d1, d0) * 180.0F / 3.1415927F - 90.0F;
242 }
243
244 if (this.aa > 0.0F) {
245 f1 = this.yaw;
246 }
247
248 if (!this.onGround) {
249 f3 = 0.0F;
250 }
251
252 this.N += (f3 - this.N) * 0.3F;
253
254 float f4;
255
256 for (f4 = f1 - this.K; f4 < -180.0F; f4 += 360.0F) {
257 ;
258 }
259
260 while (f4 >= 180.0F) {
261 f4 -= 360.0F;
262 }
263
264 this.K += f4 * 0.3F;
265
266 float f5;
267
268 for (f5 = this.yaw - this.K; f5 < -180.0F; f5 += 360.0F) {
269 ;
270 }
271
272 while (f5 >= 180.0F) {
273 f5 -= 360.0F;
274 }
275
276 boolean flag = f5 < -90.0F || f5 >= 90.0F;
277
278 if (f5 < -75.0F) {
279 f5 = -75.0F;
280 }
281
282 if (f5 >= 75.0F) {
283 f5 = 75.0F;
284 }
285
286 this.K = this.yaw - f5;
287 if (f5 * f5 > 2500.0F) {
288 this.K += f5 * 0.2F;
289 }
290
291 if (flag) {
292 f2 *= -1.0F;
293 }
294
295 while (this.yaw - this.lastYaw < -180.0F) {
296 this.lastYaw -= 360.0F;
297 }
298
299 while (this.yaw - this.lastYaw >= 180.0F) {
300 this.lastYaw += 360.0F;
301 }
302
303 while (this.K - this.L < -180.0F) {
304 this.L -= 360.0F;
305 }
306
307 while (this.K - this.L >= 180.0F) {
308 this.L += 360.0F;
309 }
310
311 while (this.pitch - this.lastPitch < -180.0F) {
312 this.lastPitch -= 360.0F;
313 }
314
315 while (this.pitch - this.lastPitch >= 180.0F) {
316 this.lastPitch += 360.0F;
317 }
318
319 this.O += f2;
320 }
321
322 protected void b(float f, float f1) {
323 super.b(f, f1);
324 }
325
326 // CraftBukkit start - delegate so we can handle providing a reason for health being regained
327 public void b(int i) {
328 b(i, RegainReason.CUSTOM);
329 }
330
331 public void b(int i, RegainReason regainReason) {
332 if (this.health > 0) {
333 EntityRegainHealthEvent event = new EntityRegainHealthEvent(this.getBukkitEntity(), i, regainReason);
334 this.world.getServer().getPluginManager().callEvent(event);
335
336 if (!event.isCancelled()) {
337 this.health += event.getAmount();
338 }
339 // CraftBukkit end
340 if (this.health > 20) {
341 this.health = 20;
342 }
343
344 this.noDamageTicks = this.maxNoDamageTicks / 2;
345 }
346 }
347
348 public boolean damageEntity(Entity entity, int i) {
349 if (this.world.isStatic) {
350 return false;
351 } else {
352 this.ay = 0;
353 if (this.health <= 0) {
354 return false;
355 } else {
356 this.ao = 1.5F;
357 boolean flag = true;
358
359 if ((float) this.noDamageTicks > (float) this.maxNoDamageTicks / 2.0F) {
360 if (i <= this.lastDamage) {
361 return false;
362 }
363
364 this.c(i - this.lastDamage);
365 this.lastDamage = i;
366 flag = false;
367 } else {
368 this.lastDamage = i;
369 this.ac = this.health;
370 this.noDamageTicks = this.maxNoDamageTicks;
371 this.c(i);
372 this.hurtTicks = this.ae = 10;
373 }
374
375 this.af = 0.0F;
376 if (flag) {
377 this.world.a(this, (byte) 2);
378 this.af();
379 if (entity != null) {
380 this.airBorne = true;
381 double d0 = entity.locX - this.locX;
382
383 double d1;
384
385 for (d1 = entity.locZ - this.locZ; d0 * d0 + d1 * d1 < 1.0E-4D; d1 = (Math.random() - Math.random()) * 0.01D) {
386 d0 = (Math.random() - Math.random()) * 0.01D;
387 }
388
389 this.af = (float) (Math.atan2(d1, d0) * 180.0D / 3.1415927410125732D) - this.yaw;
390 this.a(entity, i, d0, d1);
391 } else {
392 this.af = (float) ((int) (Math.random() * 2.0D) * 180);
393 }
394 }
395
396 if (this.health <= 0) {
397 if (flag) {
398 this.world.makeSound(this, this.i(), this.k(), (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F);
399 }
400
401 this.die(entity);
402 } else if (flag) {
403 this.world.makeSound(this, this.h(), this.k(), (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F);
404 }
405
406 return true;
407 }
408 }
409 }
410
411 protected void c(int i) {
412 this.health -= i;
413 }
414
415 protected float k() {
416 return 1.0F;
417 }
418
419 protected String g() {
420 return null;
421 }
422
423 protected String h() {
424 return "random.hurt";
425 }
426
427 protected String i() {
428 return "random.hurt";
429 }
430
431 public void a(Entity entity, int i, double d0, double d1) {
432 float f = MathHelper.a(d0 * d0 + d1 * d1);
433 float f1 = 0.4F;
434
435 this.motX /= 2.0D;
436 this.motY /= 2.0D;
437 this.motZ /= 2.0D;
438 this.motX -= d0 / (double) f * (double) f1;
439 this.motY += 0.4000000059604645D;
440 this.motZ -= d1 / (double) f * (double) f1;
441 if (this.motY > 0.4000000059604645D) {
442 this.motY = 0.4000000059604645D;
443 }
444 }
445
446 public void die(Entity entity) {
447 if (this.W >= 0 && entity != null) {
448 entity.c(this, this.W);
449 }
450
451 if (entity != null) {
452 entity.a(this);
453 }
454
455 this.ak = true;
456 if (!this.world.isStatic) {
457 this.q();
458 }
459
460 this.world.a(this, (byte) 3);
461 }
462
463 protected void q() {
464 int i = this.j();
465
466 // CraftBukkit start - whole method
467 List<org.bukkit.inventory.ItemStack> loot = new java.util.ArrayList<org.bukkit.inventory.ItemStack>();
468 int count = this.random.nextInt(3);
469
470 if ((i > 0) && (count > 0)) {
471 loot.add(new org.bukkit.inventory.ItemStack(i, count));
472 }
473
474 CraftEntity entity = (CraftEntity) this.getBukkitEntity();
475 EntityDeathEvent event = new EntityDeathEvent(entity, loot);
476 org.bukkit.World bworld = this.world.getWorld();
477 this.world.getServer().getPluginManager().callEvent(event);
478
479 for (org.bukkit.inventory.ItemStack stack : event.getDrops()) {
480 bworld.dropItemNaturally(entity.getLocation(), stack);
481 }
482 // CraftBukkit end
483 }
484
485 protected int j() {
486 return 0;
487 }
488
489 protected void a(float f) {
490 super.a(f);
491 int i = (int) Math.ceil((double) (f - 3.0F));
492
493 if (i > 0) {
494 // CraftBukkit start
495 EntityDamageEvent event = new EntityDamageEvent(this.getBukkitEntity(), EntityDamageEvent.DamageCause.FALL, i);
496 this.world.getServer().getPluginManager().callEvent(event);
497
498 if (!event.isCancelled() && event.getDamage() != 0) {
499 this.damageEntity((Entity) null, event.getDamage());
500 }
501 // CraftBukkit end
502
503 int j = this.world.getTypeId(MathHelper.floor(this.locX), MathHelper.floor(this.locY - 0.20000000298023224D - (double) this.height), MathHelper.floor(this.locZ));
504
505 if (j > 0) {
506 StepSound stepsound = Block.byId[j].stepSound;
507
508 this.world.makeSound(this, stepsound.getName(), stepsound.getVolume1() * 0.5F, stepsound.getVolume2() * 0.75F);
509 }
510 }
511 }
512
513 public void a(float f, float f1) {
514 double d0;
515
516 if (this.ad()) {
517 d0 = this.locY;
518 this.a(f, f1, 0.02F);
519 this.move(this.motX, this.motY, this.motZ);
520 this.motX *= 0.800000011920929D;
521 this.motY *= 0.800000011920929D;
522 this.motZ *= 0.800000011920929D;
523 this.motY -= 0.02D;
524 if (this.positionChanged && this.d(this.motX, this.motY + 0.6000000238418579D - this.locY + d0, this.motZ)) {
525 this.motY = 0.30000001192092896D;
526 }
527 } else if (this.ae()) {
528 d0 = this.locY;
529 this.a(f, f1, 0.02F);
530 this.move(this.motX, this.motY, this.motZ);
531 this.motX *= 0.5D;
532 this.motY *= 0.5D;
533 this.motZ *= 0.5D;
534 this.motY -= 0.02D;
535 if (this.positionChanged && this.d(this.motX, this.motY + 0.6000000238418579D - this.locY + d0, this.motZ)) {
536 this.motY = 0.30000001192092896D;
537 }
538 } else {
539 float f2 = 0.91F;
540
541 if (this.onGround) {
542 f2 = 0.54600006F;
543 int i = this.world.getTypeId(MathHelper.floor(this.locX), MathHelper.floor(this.boundingBox.b) - 1, MathHelper.floor(this.locZ));
544
545 if (i > 0) {
546 f2 = Block.byId[i].frictionFactor * 0.91F;
547 }
548 }
549
550 float f3 = 0.16277136F / (f2 * f2 * f2);
551
552 this.a(f, f1, this.onGround ? 0.1F * f3 : 0.02F);
553 f2 = 0.91F;
554 if (this.onGround) {
555 f2 = 0.54600006F;
556 int j = this.world.getTypeId(MathHelper.floor(this.locX), MathHelper.floor(this.boundingBox.b) - 1, MathHelper.floor(this.locZ));
557
558 if (j > 0) {
559 f2 = Block.byId[j].frictionFactor * 0.91F;
560 }
561 }
562
563 if (this.p()) {
564 float f4 = 0.15F;
565
566 if (this.motX < (double) (-f4)) {
567 this.motX = (double) (-f4);
568 }
569
570 if (this.motX > (double) f4) {
571 this.motX = (double) f4;
572 }
573
574 if (this.motZ < (double) (-f4)) {
575 this.motZ = (double) (-f4);
576 }
577
578 if (this.motZ > (double) f4) {
579 this.motZ = (double) f4;
580 }
581
582 this.fallDistance = 0.0F;
583 if (this.motY < -0.15D) {
584 this.motY = -0.15D;
585 }
586
587 if (this.isSneaking() && this.motY < 0.0D) {
588 this.motY = 0.0D;
589 }
590 }
591
592 this.move(this.motX, this.motY, this.motZ);
593 if (this.positionChanged && this.p()) {
594 this.motY = 0.2D;
595 }
596
597 this.motY -= 0.08D;
598 this.motY *= 0.9800000190734863D;
599 this.motX *= (double) f2;
600 this.motZ *= (double) f2;
601 }
602
603 this.an = this.ao;
604 d0 = this.locX - this.lastX;
605 double d1 = this.locZ - this.lastZ;
606 float f5 = MathHelper.a(d0 * d0 + d1 * d1) * 4.0F;
607
608 if (f5 > 1.0F) {
609 f5 = 1.0F;
610 }
611
612 this.ao += (f5 - this.ao) * 0.4F;
613 this.ap += this.ao;
614 }
615
616 public boolean p() {
617 int i = MathHelper.floor(this.locX);
618 int j = MathHelper.floor(this.boundingBox.b);
619 int k = MathHelper.floor(this.locZ);
620
621 return this.world.getTypeId(i, j, k) == Block.LADDER.id ||
622 // uberbukkit
623 (UberbukkitConfig.getInstance().getBoolean("mechanics.allow_ladder_gap", false) && this.world.getTypeId(i, j + 1, k) == Block.LADDER.id);
624 }
625
626 public void b(NBTTagCompound nbttagcompound) {
627 nbttagcompound.a("Health", (short) this.health);
628 nbttagcompound.a("HurtTime", (short) this.hurtTicks);
629 nbttagcompound.a("DeathTime", (short) this.deathTicks);
630 nbttagcompound.a("AttackTime", (short) this.attackTicks);
631 }
632
633 public void a(NBTTagCompound nbttagcompound) {
634 this.health = nbttagcompound.d("Health");
635 if (!nbttagcompound.hasKey("Health")) {
636 this.health = 10;
637 }
638
639 this.hurtTicks = nbttagcompound.d("HurtTime");
640 this.deathTicks = nbttagcompound.d("DeathTime");
641 this.attackTicks = nbttagcompound.d("AttackTime");
642 }
643
644 public boolean T() {
645 return !this.dead && this.health > 0;
646 }
647
648 public boolean b_() {
649 return false;
650 }
651
652 public void v() {
653 if (this.aq > 0) {
654 double d0 = this.locX + (this.ar - this.locX) / (double) this.aq;
655 double d1 = this.locY + (this.as - this.locY) / (double) this.aq;
656 double d2 = this.locZ + (this.at - this.locZ) / (double) this.aq;
657
658 double d3;
659
660 for (d3 = this.au - (double) this.yaw; d3 < -180.0D; d3 += 360.0D) {
661 ;
662 }
663
664 while (d3 >= 180.0D) {
665 d3 -= 360.0D;
666 }
667
668 this.yaw = (float) ((double) this.yaw + d3 / (double) this.aq);
669 this.pitch = (float) ((double) this.pitch + (this.av - (double) this.pitch) / (double) this.aq);
670 --this.aq;
671 this.setPosition(d0, d1, d2);
672 this.c(this.yaw, this.pitch);
673 List list = this.world.getEntities(this, this.boundingBox.shrink(0.03125D, 0.0D, 0.03125D));
674
675 if (list.size() > 0) {
676 double d4 = 0.0D;
677
678 for (int i = 0; i < list.size(); ++i) {
679 AxisAlignedBB axisalignedbb = (AxisAlignedBB) list.get(i);
680
681 if (axisalignedbb.e > d4) {
682 d4 = axisalignedbb.e;
683 }
684 }
685
686 d1 += d4 - this.boundingBox.b;
687 this.setPosition(d0, d1, d2);
688 }
689 }
690
691 if (this.D()) {
692 this.aC = false;
693 this.az = 0.0F;
694 this.aA = 0.0F;
695 this.aB = 0.0F;
696 } else if (!this.Y) {
697 this.c_();
698 }
699
700 boolean flag = this.ad();
701 boolean flag1 = this.ae();
702
703 if (this.aC) {
704 if (flag) {
705 this.motY += 0.03999999910593033D;
706 } else if (flag1) {
707 this.motY += 0.03999999910593033D;
708 } else if (this.onGround) {
709 this.O();
710 }
711 }
712
713 this.az *= 0.98F;
714 this.aA *= 0.98F;
715 this.aB *= 0.9F;
716 this.a(this.az, this.aA);
717 List list1 = this.world.b((Entity) this, this.boundingBox.b(0.20000000298023224D, 0.0D, 0.20000000298023224D));
718
719 if (list1 != null && list1.size() > 0) {
720 for (int j = 0; j < list1.size(); ++j) {
721 Entity entity = (Entity) list1.get(j);
722
723 if (entity.d_()) {
724 entity.collide(this);
725 }
726 }
727 }
728 }
729
730 protected boolean D() {
731 return this.health <= 0;
732 }
733
734 protected void O() {
735 this.motY = 0.41999998688697815D;
736 this.airBorne = true;
737 }
738
739 protected boolean h_() {
740 return true;
741 }
742
743 protected void U() {
744 EntityHuman entityhuman = this.world.findNearbyPlayer(this, -1.0D);
745
746 if (this.h_() && entityhuman != null) {
747 double d0 = entityhuman.locX - this.locX;
748 double d1 = entityhuman.locY - this.locY;
749 double d2 = entityhuman.locZ - this.locZ;
750 double d3 = d0 * d0 + d1 * d1 + d2 * d2;
751
752 if (d3 > 16384.0D) {
753 this.die();
754 }
755
756 if (this.ay > 600 && this.random.nextInt(800) == 0) {
757 if (d3 < 1024.0D) {
758 this.ay = 0;
759 } else {
760 this.die();
761 }
762 }
763 }
764 }
765
766 protected void c_() {
767 ++this.ay;
768 EntityHuman entityhuman = this.world.findNearbyPlayer(this, -1.0D);
769
770 this.U();
771 this.az = 0.0F;
772 this.aA = 0.0F;
773 float f = 8.0F;
774
775 if (this.random.nextFloat() < 0.02F) {
776 entityhuman = this.world.findNearbyPlayer(this, (double) f);
777 if (entityhuman != null) {
778 this.b = entityhuman;
779 this.aF = 10 + this.random.nextInt(20);
780 } else {
781 this.aB = (this.random.nextFloat() - 0.5F) * 20.0F;
782 }
783 }
784
785 if (this.b != null) {
786 this.a(this.b, 10.0F, (float) this.u());
787 if (this.aF-- <= 0 || this.b.dead || this.b.g(this) > (double) (f * f)) {
788 this.b = null;
789 }
790 } else {
791 if (this.random.nextFloat() < 0.05F) {
792 this.aB = (this.random.nextFloat() - 0.5F) * 20.0F;
793 }
794
795 this.yaw += this.aB;
796 this.pitch = this.aD;
797 }
798
799 boolean flag = this.ad();
800 boolean flag1 = this.ae();
801
802 if (flag || flag1) {
803 this.aC = this.random.nextFloat() < 0.8F;
804 }
805 }
806
807 protected int u() {
808 return 40;
809 }
810
811 public void a(Entity entity, float f, float f1) {
812 double d0 = entity.locX - this.locX;
813 double d1 = entity.locZ - this.locZ;
814 double d2;
815
816 if (entity instanceof EntityLiving) {
817 EntityLiving entityliving = (EntityLiving) entity;
818
819 d2 = this.locY + (double) this.t() - (entityliving.locY + (double) entityliving.t());
820 } else {
821 d2 = (entity.boundingBox.b + entity.boundingBox.e) / 2.0D - (this.locY + (double) this.t());
822 }
823
824 double d3 = (double) MathHelper.a(d0 * d0 + d1 * d1);
825 float f2 = (float) (Math.atan2(d1, d0) * 180.0D / 3.1415927410125732D) - 90.0F;
826 float f3 = (float) (-(Math.atan2(d2, d3) * 180.0D / 3.1415927410125732D));
827
828 this.pitch = -this.b(this.pitch, f3, f1);
829 this.yaw = this.b(this.yaw, f2, f);
830 }
831
832 public boolean V() {
833 return this.b != null;
834 }
835
836 public Entity W() {
837 return this.b;
838 }
839
840 private float b(float f, float f1, float f2) {
841 float f3;
842
843 for (f3 = f1 - f; f3 < -180.0F; f3 += 360.0F) {
844 ;
845 }
846
847 while (f3 >= 180.0F) {
848 f3 -= 360.0F;
849 }
850
851 if (f3 > f2) {
852 f3 = f2;
853 }
854
855 if (f3 < -f2) {
856 f3 = -f2;
857 }
858
859 return f + f3;
860 }
861
862 public void X() {
863 }
864
865 public boolean d() {
866 return this.world.containsEntity(this.boundingBox) && this.world.getEntities(this, this.boundingBox).size() == 0 && !this.world.c(this.boundingBox);
867 }
868
869 protected void Y() {
870 // CraftBukkit start
871 EntityDamageByBlockEvent event = new EntityDamageByBlockEvent(null, this.getBukkitEntity(), EntityDamageEvent.DamageCause.VOID, 4);
872 this.world.getServer().getPluginManager().callEvent(event);
873
874 if (event.isCancelled() || event.getDamage() == 0) {
875 return;
876 }
877
878 this.damageEntity((Entity) null, event.getDamage());
879 // CraftBukkit end
880 }
881
882 public Vec3D Z() {
883 return this.b(1.0F);
884 }
885
886 public Vec3D b(float f) {
887 float f1;
888 float f2;
889 float f3;
890 float f4;
891
892 if (f == 1.0F) {
893 f1 = MathHelper.cos(-this.yaw * 0.017453292F - 3.1415927F);
894 f2 = MathHelper.sin(-this.yaw * 0.017453292F - 3.1415927F);
895 f3 = -MathHelper.cos(-this.pitch * 0.017453292F);
896 f4 = MathHelper.sin(-this.pitch * 0.017453292F);
897 return Vec3D.create((double) (f2 * f3), (double) f4, (double) (f1 * f3));
898 } else {
899 f1 = this.lastPitch + (this.pitch - this.lastPitch) * f;
900 f2 = this.lastYaw + (this.yaw - this.lastYaw) * f;
901 f3 = MathHelper.cos(-f2 * 0.017453292F - 3.1415927F);
902 f4 = MathHelper.sin(-f2 * 0.017453292F - 3.1415927F);
903 float f5 = -MathHelper.cos(-f1 * 0.017453292F);
904 float f6 = MathHelper.sin(-f1 * 0.017453292F);
905
906 return Vec3D.create((double) (f4 * f5), (double) f6, (double) (f3 * f5));
907 }
908 }
909
910 public int l() {
911 return 4;
912 }
913
914 public boolean isSleeping() {
915 return false;
916 }
917}