Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
1package net.minecraft.server;
2
3import org.bukkit.Bukkit;
4import org.bukkit.block.BlockFace;
5import org.bukkit.craftbukkit.entity.CraftPlayer;
6import org.bukkit.entity.LivingEntity;
7import org.bukkit.entity.Vehicle;
8import org.bukkit.event.entity.EntityCombustEvent;
9import org.bukkit.event.entity.EntityDamageByBlockEvent;
10import org.bukkit.event.entity.EntityDamageByEntityEvent;
11import org.bukkit.event.entity.EntityDamageEvent;
12import org.bukkit.event.vehicle.VehicleBlockCollisionEvent;
13import org.bukkit.event.vehicle.VehicleExitEvent;
14
15import uk.betacraft.uberbukkit.UberbukkitConfig;
16
17import java.util.List;
18import java.util.Random;
19import java.util.UUID;
20
21// CraftBukkit start
22// CraftBukkit end
23
24public abstract class Entity {
25
26 // Poseidon start - Backport of 0070-Use-a-Shared-Random-for-Entities.patch from PaperSpigot
27 public static Random SHARED_RANDOM = new Random() {
28 private boolean locked = false;
29
30 @Override
31 public synchronized void setSeed(long seed) {
32 if (locked) {
33 // Ignoring setSeed on Entity.SHARED_RANDOM
34 } else {
35 super.setSeed(seed);
36 locked = true;
37 }
38 }
39 };
40 // Poseidon end
41 // uberbukkit
42 private static final boolean trampleFarmlandAboveFence = UberbukkitConfig.getInstance().getBoolean("mechanics.trample_farmland_above_fence", false);
43
44 private static int entityCount = 0;
45 public int id;
46 public double aH;
47 public boolean aI;
48 public Entity passenger;
49 public Entity vehicle;
50 public World world;
51 public double lastX;
52 public double lastY;
53 public double lastZ;
54 public double locX;
55 public double locY;
56 public double locZ;
57 public double motX;
58 public double motY;
59 public double motZ;
60 public float yaw;
61 public float pitch;
62 public float lastYaw;
63 public float lastPitch;
64 public final AxisAlignedBB boundingBox;
65 public boolean onGround;
66 public boolean positionChanged;
67 public boolean bc;
68 public boolean bd;
69 public boolean velocityChanged;
70 public boolean bf;
71 public boolean bg;
72 public boolean dead;
73 public float height;
74 public float length;
75 public float width;
76 public float bl;
77 public float bm;
78 public float fallDistance; // CraftBukkit - private -> public
79 private int b;
80 public double bo;
81 public double bp;
82 public double bq;
83 public float br;
84 public float bs;
85 public boolean bt;
86 public float bu;
87 protected Random random;
88 public int ticksLived;
89 public int maxFireTicks;
90 public int fireTicks;
91 public int maxAirTicks; // CraftBukkit - protected - >public
92 protected boolean bA;
93 public int noDamageTicks;
94 public int airTicks;
95 private boolean justCreated;
96 protected boolean fireProof;
97 protected DataWatcher datawatcher;
98 public float bF;
99 private double d;
100 private double e;
101 public boolean bG;
102 public int bH;
103 public int bI;
104 public int bJ;
105 public boolean bK;
106 public boolean airBorne;
107 public UUID uniqueId = UUID.randomUUID(); // CraftBukkit
108
109 public Entity(World world) {
110 this.id = entityCount++;
111 this.aH = 1.0D;
112 this.aI = false;
113 this.boundingBox = AxisAlignedBB.a(0.0D, 0.0D, 0.0D, 0.0D, 0.0D, 0.0D);
114 this.onGround = false;
115 this.bd = false;
116 this.velocityChanged = false;
117 this.bg = true;
118 this.dead = false;
119 this.height = 0.0F;
120 this.length = 0.6F;
121 this.width = 1.8F;
122 this.bl = 0.0F;
123 this.bm = 0.0F;
124 this.fallDistance = 0.0F;
125 this.b = 1;
126 this.br = 0.0F;
127 this.bs = 0.0F;
128 this.bt = false;
129 this.bu = 0.0F;
130 this.random = SHARED_RANDOM;
131 this.ticksLived = 0;
132 this.maxFireTicks = 1;
133 this.fireTicks = 0;
134 this.maxAirTicks = 300;
135 this.bA = false;
136 this.noDamageTicks = 0;
137 this.airTicks = 300;
138 this.justCreated = true;
139 this.fireProof = false;
140 this.datawatcher = new DataWatcher();
141 this.bF = 0.0F;
142 this.bG = false;
143 this.world = world;
144 this.setPosition(0.0D, 0.0D, 0.0D);
145 this.datawatcher.a(0, Byte.valueOf((byte) 0));
146 this.b();
147 }
148
149 protected abstract void b();
150
151 public DataWatcher aa() {
152 return this.datawatcher;
153 }
154
155 public boolean equals(Object object) {
156 return object instanceof Entity ? ((Entity) object).id == this.id : false;
157 }
158
159 public int hashCode() {
160 return this.id;
161 }
162
163 public void die() {
164 this.dead = true;
165 }
166
167 protected void b(float f, float f1) {
168 this.length = f;
169 this.width = f1;
170 }
171
172 protected void c(float f, float f1) {
173 // CraftBukkit start - yaw was sometimes set to NaN, so we need to set it back to 0.
174 if (Float.isNaN(f)) {
175 f = 0;
176 }
177
178 if ((f == Float.POSITIVE_INFINITY) || (f == Float.NEGATIVE_INFINITY)) {
179 if (this instanceof EntityPlayer) {
180 System.err.println(((CraftPlayer) this.getBukkitEntity()).getName() + " was caught trying to crash the server with an invalid yaw");
181 ((CraftPlayer) this.getBukkitEntity()).kickPlayer("Nope");
182 }
183 f = 0;
184 }
185
186 // pitch was sometimes set to NaN, so we need to set it back to 0.
187 if (Float.isNaN(f1)) {
188 f1 = 0;
189 }
190
191 if ((f1 == Float.POSITIVE_INFINITY) || (f1 == Float.NEGATIVE_INFINITY)) {
192 if (this instanceof EntityPlayer) {
193 System.err.println(((CraftPlayer) this.getBukkitEntity()).getName() + " was caught trying to crash the server with an invalid pitch");
194 ((CraftPlayer) this.getBukkitEntity()).kickPlayer("Nope");
195 }
196 f1 = 0;
197 }
198 // CraftBukkit end
199
200 this.yaw = f % 360.0F;
201 this.pitch = f1 % 360.0F;
202 }
203
204 public void setPosition(double d0, double d1, double d2) {
205 this.locX = d0;
206 this.locY = d1;
207 this.locZ = d2;
208 float f = this.length / 2.0F;
209 float f1 = this.width;
210
211 this.boundingBox.c(d0 - (double) f, d1 - (double) this.height + (double) this.br, d2 - (double) f, d0 + (double) f, d1 - (double) this.height + (double) this.br + (double) f1, d2 + (double) f);
212 }
213
214 public void m_() {
215 this.R();
216 }
217
218 public void R() {
219 if (this.vehicle != null && this.vehicle.dead) {
220 this.vehicle = null;
221 }
222
223 ++this.ticksLived;
224 this.bl = this.bm;
225 this.lastX = this.locX;
226 this.lastY = this.locY;
227 this.lastZ = this.locZ;
228 this.lastPitch = this.pitch;
229 this.lastYaw = this.yaw;
230 if (this.f_()) {
231 if (!this.bA && !this.justCreated) {
232 float f = MathHelper.a(this.motX * this.motX * 0.20000000298023224D + this.motY * this.motY + this.motZ * this.motZ * 0.20000000298023224D) * 0.2F;
233
234 if (f > 1.0F) {
235 f = 1.0F;
236 }
237
238 this.world.makeSound(this, "random.splash", f, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F);
239 float f1 = (float) MathHelper.floor(this.boundingBox.b);
240
241 int i;
242 float f2;
243 float f3;
244
245 for (i = 0; (float) i < 1.0F + this.length * 20.0F; ++i) {
246 f2 = (this.random.nextFloat() * 2.0F - 1.0F) * this.length;
247 f3 = (this.random.nextFloat() * 2.0F - 1.0F) * this.length;
248 this.world.a("bubble", this.locX + (double) f2, (double) (f1 + 1.0F), this.locZ + (double) f3, this.motX, this.motY - (double) (this.random.nextFloat() * 0.2F), this.motZ);
249 }
250
251 for (i = 0; (float) i < 1.0F + this.length * 20.0F; ++i) {
252 f2 = (this.random.nextFloat() * 2.0F - 1.0F) * this.length;
253 f3 = (this.random.nextFloat() * 2.0F - 1.0F) * this.length;
254 this.world.a("splash", this.locX + (double) f2, (double) (f1 + 1.0F), this.locZ + (double) f3, this.motX, this.motY, this.motZ);
255 }
256 }
257
258 this.fallDistance = 0.0F;
259 this.bA = true;
260 this.fireTicks = 0;
261 } else {
262 this.bA = false;
263 }
264
265 if (this.world.isStatic) {
266 this.fireTicks = 0;
267 } else if (this.fireTicks > 0) {
268 if (this.fireProof) {
269 this.fireTicks -= 4;
270 if (this.fireTicks < 0) {
271 this.fireTicks = 0;
272 }
273 } else {
274 if (this.fireTicks % 20 == 0) {
275 // CraftBukkit start - TODO: this event spams!
276 if (this instanceof EntityLiving) {
277 EntityDamageEvent event = new EntityDamageEvent(this.getBukkitEntity(), EntityDamageEvent.DamageCause.FIRE_TICK, 1);
278 this.world.getServer().getPluginManager().callEvent(event);
279
280 if (!event.isCancelled()) {
281 this.damageEntity((Entity) null, event.getDamage());
282 }
283 } else {
284 this.damageEntity((Entity) null, 1);
285 }
286 // CraftBukkit end
287 }
288
289 --this.fireTicks;
290 }
291 }
292
293 if (this.ae()) {
294 this.ab();
295 }
296
297 if (this.locY < -64.0D) {
298 this.Y();
299 }
300
301 if (!this.world.isStatic) {
302 this.a(0, this.fireTicks > 0);
303 this.a(2, this.vehicle != null);
304 }
305
306 this.justCreated = false;
307 }
308
309 protected void ab() {
310 if (!this.fireProof) {
311 // CraftBukkit start - TODO: this event spams!
312 if (this instanceof EntityLiving) {
313 org.bukkit.Server server = this.world.getServer();
314
315 // TODO: shouldn't be sending null for the block.
316 org.bukkit.block.Block damager = null; // ((WorldServer) this.l).getWorld().getBlockAt(i, j, k);
317 org.bukkit.entity.Entity damagee = this.getBukkitEntity();
318
319 EntityDamageByBlockEvent event = new EntityDamageByBlockEvent(damager, damagee, EntityDamageEvent.DamageCause.LAVA, 4);
320 server.getPluginManager().callEvent(event);
321
322 if (!event.isCancelled()) {
323 this.damageEntity((Entity) null, event.getDamage());
324 }
325
326 if (this.fireTicks <= 0) {
327 // not on fire yet
328 EntityCombustEvent combustEvent = new EntityCombustEvent(damagee);
329 server.getPluginManager().callEvent(combustEvent);
330
331 if (!combustEvent.isCancelled()) {
332 this.fireTicks = 600;
333 }
334 } else {
335 // reset fire level back to max
336 this.fireTicks = 600;
337 }
338 return;
339 }
340 // CraftBukkit end
341
342 this.damageEntity((Entity) null, 4);
343 this.fireTicks = 600;
344 }
345 }
346
347 protected void Y() {
348 this.die();
349 }
350
351 public boolean d(double d0, double d1, double d2) {
352 AxisAlignedBB axisalignedbb = this.boundingBox.c(d0, d1, d2);
353 List list = this.world.getEntities(this, axisalignedbb);
354
355 return list.size() > 0 ? false : !this.world.c(axisalignedbb);
356 }
357
358 public void move(double d0, double d1, double d2) {
359 if (this.bt) {
360 this.boundingBox.d(d0, d1, d2);
361 this.locX = (this.boundingBox.a + this.boundingBox.d) / 2.0D;
362 this.locY = this.boundingBox.b + (double) this.height - (double) this.br;
363 this.locZ = (this.boundingBox.c + this.boundingBox.f) / 2.0D;
364 } else {
365 this.br *= 0.4F;
366 double d3 = this.locX;
367 double d4 = this.locZ;
368
369 if (this.bf) {
370 this.bf = false;
371 d0 *= 0.25D;
372 d1 *= 0.05000000074505806D;
373 d2 *= 0.25D;
374 this.motX = 0.0D;
375 this.motY = 0.0D;
376 this.motZ = 0.0D;
377 }
378
379 double d5 = d0;
380 double d6 = d1;
381 double d7 = d2;
382 AxisAlignedBB axisalignedbb = this.boundingBox.clone();
383 boolean flag = this.onGround && this.isSneaking();
384
385 if (flag) {
386 double d8;
387
388 for (d8 = 0.05D; d0 != 0.0D && this.world.getEntities(this, this.boundingBox.c(d0, -1.0D, 0.0D)).size() == 0; d5 = d0) {
389 if (d0 < d8 && d0 >= -d8) {
390 d0 = 0.0D;
391 } else if (d0 > 0.0D) {
392 d0 -= d8;
393 } else {
394 d0 += d8;
395 }
396 }
397
398 for (; d2 != 0.0D && this.world.getEntities(this, this.boundingBox.c(0.0D, -1.0D, d2)).size() == 0; d7 = d2) {
399 if (d2 < d8 && d2 >= -d8) {
400 d2 = 0.0D;
401 } else if (d2 > 0.0D) {
402 d2 -= d8;
403 } else {
404 d2 += d8;
405 }
406 }
407 }
408
409 List list = this.world.getEntities(this, this.boundingBox.a(d0, d1, d2));
410
411 for (int i = 0; i < list.size(); ++i) {
412 d1 = ((AxisAlignedBB) list.get(i)).b(this.boundingBox, d1);
413 }
414
415 this.boundingBox.d(0.0D, d1, 0.0D);
416 if (!this.bg && d6 != d1) {
417 d2 = 0.0D;
418 d1 = 0.0D;
419 d0 = 0.0D;
420 }
421
422 boolean flag1 = this.onGround || d6 != d1 && d6 < 0.0D;
423
424 int j;
425
426 for (j = 0; j < list.size(); ++j) {
427 d0 = ((AxisAlignedBB) list.get(j)).a(this.boundingBox, d0);
428 }
429
430 this.boundingBox.d(d0, 0.0D, 0.0D);
431 if (!this.bg && d5 != d0) {
432 d2 = 0.0D;
433 d1 = 0.0D;
434 d0 = 0.0D;
435 }
436
437 for (j = 0; j < list.size(); ++j) {
438 d2 = ((AxisAlignedBB) list.get(j)).c(this.boundingBox, d2);
439 }
440
441 this.boundingBox.d(0.0D, 0.0D, d2);
442 if (!this.bg && d7 != d2) {
443 d2 = 0.0D;
444 d1 = 0.0D;
445 d0 = 0.0D;
446 }
447
448 double d9;
449 double d10;
450 int k;
451
452 if (this.bs > 0.0F && flag1 && (flag || this.br < 0.05F) && (d5 != d0 || d7 != d2)) {
453 d9 = d0;
454 d10 = d1;
455 double d11 = d2;
456
457 d0 = d5;
458 d1 = (double) this.bs;
459 d2 = d7;
460 AxisAlignedBB axisalignedbb1 = this.boundingBox.clone();
461
462 this.boundingBox.b(axisalignedbb);
463 list = this.world.getEntities(this, this.boundingBox.a(d5, d1, d7));
464
465 for (k = 0; k < list.size(); ++k) {
466 d1 = ((AxisAlignedBB) list.get(k)).b(this.boundingBox, d1);
467 }
468
469 this.boundingBox.d(0.0D, d1, 0.0D);
470 if (!this.bg && d6 != d1) {
471 d2 = 0.0D;
472 d1 = 0.0D;
473 d0 = 0.0D;
474 }
475
476 for (k = 0; k < list.size(); ++k) {
477 d0 = ((AxisAlignedBB) list.get(k)).a(this.boundingBox, d0);
478 }
479
480 this.boundingBox.d(d0, 0.0D, 0.0D);
481 if (!this.bg && d5 != d0) {
482 d2 = 0.0D;
483 d1 = 0.0D;
484 d0 = 0.0D;
485 }
486
487 for (k = 0; k < list.size(); ++k) {
488 d2 = ((AxisAlignedBB) list.get(k)).c(this.boundingBox, d2);
489 }
490
491 this.boundingBox.d(0.0D, 0.0D, d2);
492 if (!this.bg && d7 != d2) {
493 d2 = 0.0D;
494 d1 = 0.0D;
495 d0 = 0.0D;
496 }
497
498 if (!this.bg && d6 != d1) {
499 d2 = 0.0D;
500 d1 = 0.0D;
501 d0 = 0.0D;
502 } else {
503 d1 = (double) (-this.bs);
504
505 for (k = 0; k < list.size(); ++k) {
506 d1 = ((AxisAlignedBB) list.get(k)).b(this.boundingBox, d1);
507 }
508
509 this.boundingBox.d(0.0D, d1, 0.0D);
510 }
511
512 if (d9 * d9 + d11 * d11 >= d0 * d0 + d2 * d2) {
513 d0 = d9;
514 d1 = d10;
515 d2 = d11;
516 this.boundingBox.b(axisalignedbb1);
517 } else {
518 double d12 = this.boundingBox.b - (double) ((int) this.boundingBox.b);
519
520 if (d12 > 0.0D) {
521 this.br = (float) ((double) this.br + d12 + 0.01D);
522 }
523 }
524 }
525
526 this.locX = (this.boundingBox.a + this.boundingBox.d) / 2.0D;
527 this.locY = this.boundingBox.b + (double) this.height - (double) this.br;
528 this.locZ = (this.boundingBox.c + this.boundingBox.f) / 2.0D;
529 this.positionChanged = d5 != d0 || d7 != d2;
530 this.bc = d6 != d1;
531 this.onGround = d6 != d1 && d6 < 0.0D;
532 this.bd = this.positionChanged || this.bc;
533 this.a(d1, this.onGround);
534 if (d5 != d0) {
535 this.motX = 0.0D;
536 }
537
538 if (d6 != d1) {
539 this.motY = 0.0D;
540 }
541
542 if (d7 != d2) {
543 this.motZ = 0.0D;
544 }
545
546 d9 = this.locX - d3;
547 d10 = this.locZ - d4;
548 int l;
549 int i1;
550 int j1;
551
552 // CraftBukkit start
553 if ((this.positionChanged) && (this.getBukkitEntity() instanceof Vehicle)) {
554 Vehicle vehicle = (Vehicle) this.getBukkitEntity();
555 org.bukkit.block.Block block = this.world.getWorld().getBlockAt(MathHelper.floor(this.locX), MathHelper.floor(this.locY - 0.20000000298023224D - (double) this.height), MathHelper.floor(this.locZ));
556
557 if (d5 > d0) {
558 block = block.getRelative(BlockFace.SOUTH);
559 } else if (d5 < d0) {
560 block = block.getRelative(BlockFace.NORTH);
561 } else if (d7 > d2) {
562 block = block.getRelative(BlockFace.WEST);
563 } else if (d7 < d2) {
564 block = block.getRelative(BlockFace.EAST);
565 }
566
567 VehicleBlockCollisionEvent event = new VehicleBlockCollisionEvent(vehicle, block);
568 this.world.getServer().getPluginManager().callEvent(event);
569 }
570 // CraftBukkit end
571
572 if (this.n() && !flag && this.vehicle == null) {
573 this.bm = (float) ((double) this.bm + (double) MathHelper.a(d9 * d9 + d10 * d10) * 0.6D);
574 l = MathHelper.floor(this.locX);
575 i1 = MathHelper.floor(this.locY - 0.20000000298023224D - (double) this.height);
576 j1 = MathHelper.floor(this.locZ);
577 k = this.world.getTypeId(l, i1, j1);
578 // uberbukkit
579 if (!trampleFarmlandAboveFence) {
580 if (this.world.getTypeId(l, i1 - 1, j1) == Block.FENCE.id) {
581 k = this.world.getTypeId(l, i1 - 1, j1);
582 }
583 }
584
585 if (this.bm > (float) this.b && k > 0) {
586 ++this.b;
587 StepSound stepsound = Block.byId[k].stepSound;
588
589 if (this.world.getTypeId(l, i1 + 1, j1) == Block.SNOW.id) {
590 stepsound = Block.SNOW.stepSound;
591 this.world.makeSound(this, stepsound.getName(), stepsound.getVolume1() * 0.15F, stepsound.getVolume2());
592 } else if (!Block.byId[k].material.isLiquid()) {
593 this.world.makeSound(this, stepsound.getName(), stepsound.getVolume1() * 0.15F, stepsound.getVolume2());
594 }
595
596 Block.byId[k].b(this.world, l, i1, j1, this);
597 }
598 }
599
600 l = MathHelper.floor(this.boundingBox.a + 0.0010D);
601 i1 = MathHelper.floor(this.boundingBox.b + 0.0010D);
602 j1 = MathHelper.floor(this.boundingBox.c + 0.0010D);
603 k = MathHelper.floor(this.boundingBox.d - 0.0010D);
604 int k1 = MathHelper.floor(this.boundingBox.e - 0.0010D);
605 int l1 = MathHelper.floor(this.boundingBox.f - 0.0010D);
606
607 if (this.world.a(l, i1, j1, k, k1, l1)) {
608 for (int i2 = l; i2 <= k; ++i2) {
609 for (int j2 = i1; j2 <= k1; ++j2) {
610 for (int k2 = j1; k2 <= l1; ++k2) {
611 int l2 = this.world.getTypeId(i2, j2, k2);
612
613 if (l2 > 0) {
614 Block.byId[l2].a(this.world, i2, j2, k2, this);
615 }
616 }
617 }
618 }
619 }
620
621 boolean flag2 = this.ac();
622
623 if (this.world.d(this.boundingBox.shrink(0.0010D, 0.0010D, 0.0010D))) {
624 this.burn(1);
625 if (!flag2) {
626 ++this.fireTicks;
627 // CraftBukkit start - not on fire yet
628 if (this.fireTicks <= 0) {
629 EntityCombustEvent event = new EntityCombustEvent(this.getBukkitEntity());
630 this.world.getServer().getPluginManager().callEvent(event);
631
632 if (!event.isCancelled()) {
633 this.fireTicks = 300;
634 }
635 } else {
636 // CraftBukkit end - reset fire level back to max
637 this.fireTicks = 300;
638 }
639 }
640 } else if (this.fireTicks <= 0) {
641 this.fireTicks = -this.maxFireTicks;
642 }
643
644 if (flag2 && this.fireTicks > 0) {
645 this.world.makeSound(this, "random.fizz", 0.7F, 1.6F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F);
646 this.fireTicks = -this.maxFireTicks;
647 }
648 }
649 }
650
651 protected boolean n() {
652 return true;
653 }
654
655 protected void a(double d0, boolean flag) {
656 if (flag) {
657 if (this.fallDistance > 0.0F) {
658 this.a(this.fallDistance);
659 this.fallDistance = 0.0F;
660 }
661 } else if (d0 < 0.0D) {
662 this.fallDistance = (float) ((double) this.fallDistance - d0);
663 }
664 }
665
666 public AxisAlignedBB e_() {
667 return null;
668 }
669
670 protected void burn(int i) {
671 if (!this.fireProof) {
672 // CraftBukkit start
673 if (this instanceof EntityLiving) {
674 EntityDamageEvent event = new EntityDamageEvent(this.getBukkitEntity(), EntityDamageEvent.DamageCause.FIRE, i);
675 this.world.getServer().getPluginManager().callEvent(event);
676
677 if (event.isCancelled()) {
678 return;
679 }
680
681 i = event.getDamage();
682 }
683 // CraftBukkit end
684 this.damageEntity((Entity) null, i);
685 }
686 }
687
688 protected void a(float f) {
689 if (this.passenger != null) {
690 this.passenger.a(f);
691 }
692 }
693
694 public boolean ac() {
695 return this.bA || this.world.s(MathHelper.floor(this.locX), MathHelper.floor(this.locY), MathHelper.floor(this.locZ));
696 }
697
698 public boolean ad() {
699 return this.bA;
700 }
701
702 public boolean f_() {
703 return this.world.a(this.boundingBox.b(0.0D, -0.4000000059604645D, 0.0D).shrink(0.0010D, 0.0010D, 0.0010D), Material.WATER, this);
704 }
705
706 public boolean a(Material material) {
707 double d0 = this.locY + (double) this.t();
708 int i = MathHelper.floor(this.locX);
709 int j = MathHelper.d((float) MathHelper.floor(d0));
710 int k = MathHelper.floor(this.locZ);
711 int l = this.world.getTypeId(i, j, k);
712
713 if (l != 0 && Block.byId[l].material == material) {
714 float f = BlockFluids.c(this.world.getData(i, j, k)) - 0.11111111F;
715 float f1 = (float) (j + 1) - f;
716
717 return d0 < (double) f1;
718 } else {
719 return false;
720 }
721 }
722
723 public float t() {
724 return 0.0F;
725 }
726
727 public boolean ae() {
728 return this.world.a(this.boundingBox.b(-0.10000000149011612D, -0.4000000059604645D, -0.10000000149011612D), Material.LAVA);
729 }
730
731 public void a(float f, float f1, float f2) {
732 float f3 = MathHelper.c(f * f + f1 * f1);
733
734 if (f3 >= 0.01F) {
735 if (f3 < 1.0F) {
736 f3 = 1.0F;
737 }
738
739 f3 = f2 / f3;
740 f *= f3;
741 f1 *= f3;
742 float f4 = MathHelper.sin(this.yaw * 3.1415927F / 180.0F);
743 float f5 = MathHelper.cos(this.yaw * 3.1415927F / 180.0F);
744
745 this.motX += (double) (f * f5 - f1 * f4);
746 this.motZ += (double) (f1 * f5 + f * f4);
747 }
748 }
749
750 public float c(float f) {
751 int i = MathHelper.floor(this.locX);
752 double d0 = (this.boundingBox.e - this.boundingBox.b) * 0.66D;
753 int j = MathHelper.floor(this.locY - (double) this.height + d0);
754 int k = MathHelper.floor(this.locZ);
755
756 if (this.world.a(MathHelper.floor(this.boundingBox.a), MathHelper.floor(this.boundingBox.b), MathHelper.floor(this.boundingBox.c), MathHelper.floor(this.boundingBox.d), MathHelper.floor(this.boundingBox.e), MathHelper.floor(this.boundingBox.f))) {
757 float f1 = this.world.n(i, j, k);
758
759 if (f1 < this.bF) {
760 f1 = this.bF;
761 }
762
763 return f1;
764 } else {
765 return this.bF;
766 }
767 }
768
769 public void spawnIn(World world) {
770 // CraftBukkit start
771 if (world == null) {
772 this.die();
773 this.world = ((org.bukkit.craftbukkit.CraftWorld) Bukkit.getServer().getWorlds().get(0)).getHandle();
774 return;
775 }
776 // CraftBukkit end
777 this.world = world;
778 }
779
780 public void setLocation(double d0, double d1, double d2, float f, float f1) {
781 this.lastX = this.locX = d0;
782 this.lastY = this.locY = d1;
783 this.lastZ = this.locZ = d2;
784 this.lastYaw = this.yaw = f;
785 this.lastPitch = this.pitch = f1;
786 this.br = 0.0F;
787 double d3 = (double) (this.lastYaw - f);
788
789 if (d3 < -180.0D) {
790 this.lastYaw += 360.0F;
791 }
792
793 if (d3 >= 180.0D) {
794 this.lastYaw -= 360.0F;
795 }
796
797 this.setPosition(this.locX, this.locY, this.locZ);
798 this.c(f, f1);
799 }
800
801 public void setPositionRotation(double d0, double d1, double d2, float f, float f1) {
802 this.bo = this.lastX = this.locX = d0;
803 this.bp = this.lastY = this.locY = d1 + (double) this.height;
804 this.bq = this.lastZ = this.locZ = d2;
805 this.yaw = f;
806 this.pitch = f1;
807 this.setPosition(this.locX, this.locY, this.locZ);
808 }
809
810 public float f(Entity entity) {
811 float f = (float) (this.locX - entity.locX);
812 float f1 = (float) (this.locY - entity.locY);
813 float f2 = (float) (this.locZ - entity.locZ);
814
815 return MathHelper.c(f * f + f1 * f1 + f2 * f2);
816 }
817
818 public double e(double d0, double d1, double d2) {
819 double d3 = this.locX - d0;
820 double d4 = this.locY - d1;
821 double d5 = this.locZ - d2;
822
823 return d3 * d3 + d4 * d4 + d5 * d5;
824 }
825
826 public double f(double d0, double d1, double d2) {
827 double d3 = this.locX - d0;
828 double d4 = this.locY - d1;
829 double d5 = this.locZ - d2;
830
831 return (double) MathHelper.a(d3 * d3 + d4 * d4 + d5 * d5);
832 }
833
834 public double g(Entity entity) {
835 double d0 = this.locX - entity.locX;
836 double d1 = this.locY - entity.locY;
837 double d2 = this.locZ - entity.locZ;
838
839 return d0 * d0 + d1 * d1 + d2 * d2;
840 }
841
842 public void b(EntityHuman entityhuman) {
843 }
844
845 public void collide(Entity entity) {
846 if (entity.passenger != this && entity.vehicle != this) {
847 double d0 = entity.locX - this.locX;
848 double d1 = entity.locZ - this.locZ;
849 double d2 = MathHelper.a(d0, d1);
850
851 if (d2 >= 0.009999999776482582D) {
852 d2 = (double) MathHelper.a(d2);
853 d0 /= d2;
854 d1 /= d2;
855 double d3 = 1.0D / d2;
856
857 if (d3 > 1.0D) {
858 d3 = 1.0D;
859 }
860
861 d0 *= d3;
862 d1 *= d3;
863 d0 *= 0.05000000074505806D;
864 d1 *= 0.05000000074505806D;
865 d0 *= (double) (1.0F - this.bu);
866 d1 *= (double) (1.0F - this.bu);
867 this.b(-d0, 0.0D, -d1);
868 entity.b(d0, 0.0D, d1);
869 }
870 }
871 }
872
873 public void b(double d0, double d1, double d2) {
874 this.motX += d0;
875 this.motY += d1;
876 this.motZ += d2;
877 this.airBorne = true;
878 }
879
880 protected void af() {
881 this.velocityChanged = true;
882 }
883
884 public boolean damageEntity(Entity entity, int i) {
885 this.af();
886 return false;
887 }
888
889 public boolean l_() {
890 return false;
891 }
892
893 public boolean d_() {
894 return false;
895 }
896
897 public void c(Entity entity, int i) {
898 }
899
900 public boolean c(NBTTagCompound nbttagcompound) {
901 String s = this.ag();
902
903 if (!this.dead && s != null) {
904 nbttagcompound.setString("id", s);
905 this.d(nbttagcompound);
906 return true;
907 } else {
908 return false;
909 }
910 }
911
912 public void d(NBTTagCompound nbttagcompound) {
913 nbttagcompound.a("Pos", (NBTBase) this.a(new double[] { this.locX, this.locY + (double) this.br, this.locZ }));
914 nbttagcompound.a("Motion", (NBTBase) this.a(new double[] { this.motX, this.motY, this.motZ }));
915
916 // CraftBukkit start - checking for NaN pitch/yaw and resetting to zero
917 // TODO: make sure this is the best way to address this.
918 if (Float.isNaN(this.yaw)) {
919 this.yaw = 0;
920 }
921
922 if (Float.isNaN(this.pitch)) {
923 this.pitch = 0;
924 }
925 // CraftBukkit end
926
927 nbttagcompound.a("Rotation", (NBTBase) this.a(new float[] { this.yaw, this.pitch }));
928 nbttagcompound.a("FallDistance", this.fallDistance);
929 nbttagcompound.a("Fire", (short) this.fireTicks);
930 nbttagcompound.a("Air", (short) this.airTicks);
931 nbttagcompound.a("OnGround", this.onGround);
932 // CraftBukkit start
933 nbttagcompound.setLong("WorldUUIDLeast", this.world.getUUID().getLeastSignificantBits());
934 nbttagcompound.setLong("WorldUUIDMost", this.world.getUUID().getMostSignificantBits());
935 nbttagcompound.setLong("UUIDLeast", this.uniqueId.getLeastSignificantBits());
936 nbttagcompound.setLong("UUIDMost", this.uniqueId.getMostSignificantBits());
937 // CraftBukkit end
938 this.b(nbttagcompound);
939 }
940
941 public void e(NBTTagCompound nbttagcompound) {
942 NBTTagList nbttaglist = nbttagcompound.l("Pos");
943 NBTTagList nbttaglist1 = nbttagcompound.l("Motion");
944 NBTTagList nbttaglist2 = nbttagcompound.l("Rotation");
945
946 this.motX = ((NBTTagDouble) nbttaglist1.a(0)).a;
947 this.motY = ((NBTTagDouble) nbttaglist1.a(1)).a;
948 this.motZ = ((NBTTagDouble) nbttaglist1.a(2)).a;
949 /* CraftBukkit start - moved section down
950 if (Math.abs(this.motX) > 10.0D) {
951 this.motX = 0.0D;
952 }
953
954 if (Math.abs(this.motY) > 10.0D) {
955 this.motY = 0.0D;
956 }
957
958 if (Math.abs(this.motZ) > 10.0D) {
959 this.motZ = 0.0D;
960 }
961 // CraftBukkit end */
962
963 this.lastX = this.bo = this.locX = ((NBTTagDouble) nbttaglist.a(0)).a;
964 this.lastY = this.bp = this.locY = ((NBTTagDouble) nbttaglist.a(1)).a;
965 this.lastZ = this.bq = this.locZ = ((NBTTagDouble) nbttaglist.a(2)).a;
966 this.lastYaw = this.yaw = ((NBTTagFloat) nbttaglist2.a(0)).a;
967 this.lastPitch = this.pitch = ((NBTTagFloat) nbttaglist2.a(1)).a;
968 this.fallDistance = nbttagcompound.g("FallDistance");
969 this.fireTicks = nbttagcompound.d("Fire");
970 this.airTicks = nbttagcompound.d("Air");
971 this.onGround = nbttagcompound.m("OnGround");
972 this.setPosition(this.locX, this.locY, this.locZ);
973
974 // CraftBukkit start
975 long least = nbttagcompound.getLong("UUIDLeast");
976 long most = nbttagcompound.getLong("UUIDMost");
977
978 if (least != 0L && most != 0L) {
979 this.uniqueId = new UUID(most, least);
980 }
981 // CraftBukkit end
982
983 this.c(this.yaw, this.pitch);
984 this.a(nbttagcompound);
985
986 // CraftBukkit start - Exempt Vehicles from notch's sanity check
987 if (!(this.getBukkitEntity() instanceof Vehicle)) {
988 if (Math.abs(this.motX) > 10.0D) {
989 this.motX = 0.0D;
990 }
991
992 if (Math.abs(this.motY) > 10.0D) {
993 this.motY = 0.0D;
994 }
995
996 if (Math.abs(this.motZ) > 10.0D) {
997 this.motZ = 0.0D;
998 }
999 }
1000 // CraftBukkit end
1001
1002 // CraftBukkit start - reset world
1003 if (this instanceof EntityPlayer) {
1004 org.bukkit.Server server = Bukkit.getServer();
1005 org.bukkit.World bworld = null;
1006
1007 // TODO: Remove World related checks, replaced with WorldUID.
1008 String worldName = nbttagcompound.getString("World");
1009
1010 if (nbttagcompound.hasKey("WorldUUIDMost") && nbttagcompound.hasKey("WorldUUIDLeast")) {
1011 UUID uid = new UUID(nbttagcompound.getLong("WorldUUIDMost"), nbttagcompound.getLong("WorldUUIDLeast"));
1012 bworld = server.getWorld(uid);
1013 } else {
1014 bworld = server.getWorld(worldName);
1015 }
1016 if (bworld == null) {
1017 EntityPlayer entityPlayer = (EntityPlayer) this;
1018 bworld = ((org.bukkit.craftbukkit.CraftServer) server).getServer().getWorldServer(entityPlayer.dimension).getWorld();
1019 }
1020
1021 this.spawnIn(bworld == null ? null : ((org.bukkit.craftbukkit.CraftWorld) bworld).getHandle());
1022 }
1023 // CraftBukkit end
1024 }
1025
1026 protected final String ag() {
1027 return EntityTypes.b(this);
1028 }
1029
1030 protected abstract void a(NBTTagCompound nbttagcompound);
1031
1032 protected abstract void b(NBTTagCompound nbttagcompound);
1033
1034 protected NBTTagList a(double... adouble) {
1035 NBTTagList nbttaglist = new NBTTagList();
1036 double[] adouble1 = adouble;
1037 int i = adouble.length;
1038
1039 for (int j = 0; j < i; ++j) {
1040 double d0 = adouble1[j];
1041
1042 nbttaglist.a((NBTBase) (new NBTTagDouble(d0)));
1043 }
1044
1045 return nbttaglist;
1046 }
1047
1048 protected NBTTagList a(float... afloat) {
1049 NBTTagList nbttaglist = new NBTTagList();
1050 float[] afloat1 = afloat;
1051 int i = afloat.length;
1052
1053 for (int j = 0; j < i; ++j) {
1054 float f = afloat1[j];
1055
1056 nbttaglist.a((NBTBase) (new NBTTagFloat(f)));
1057 }
1058
1059 return nbttaglist;
1060 }
1061
1062 public EntityItem b(int i, int j) {
1063 return this.a(i, j, 0.0F);
1064 }
1065
1066 public EntityItem a(int i, int j, float f) {
1067 return this.a(new ItemStack(i, j, 0), f);
1068 }
1069
1070 public EntityItem a(ItemStack itemstack, float f) {
1071 EntityItem entityitem = new EntityItem(this.world, this.locX, this.locY + (double) f, this.locZ, itemstack);
1072
1073 entityitem.pickupDelay = 10;
1074 this.world.addEntity(entityitem);
1075 return entityitem;
1076 }
1077
1078 public boolean T() {
1079 return !this.dead;
1080 }
1081
1082 public boolean K() {
1083 for (int i = 0; i < 8; ++i) {
1084 float f = ((float) ((i >> 0) % 2) - 0.5F) * this.length * 0.9F;
1085 float f1 = ((float) ((i >> 1) % 2) - 0.5F) * 0.1F;
1086 float f2 = ((float) ((i >> 2) % 2) - 0.5F) * this.length * 0.9F;
1087 int j = MathHelper.floor(this.locX + (double) f);
1088 int k = MathHelper.floor(this.locY + (double) this.t() + (double) f1);
1089 int l = MathHelper.floor(this.locZ + (double) f2);
1090
1091 if (this.world.e(j, k, l)) {
1092 return true;
1093 }
1094 }
1095
1096 return false;
1097 }
1098
1099 public boolean a(EntityHuman entityhuman) {
1100 return false;
1101 }
1102
1103 public AxisAlignedBB a_(Entity entity) {
1104 return null;
1105 }
1106
1107 public void E() {
1108 if (this.vehicle.dead) {
1109 this.vehicle = null;
1110 } else {
1111 this.motX = 0.0D;
1112 this.motY = 0.0D;
1113 this.motZ = 0.0D;
1114 this.m_();
1115 if (this.vehicle != null) {
1116 this.vehicle.f();
1117 this.e += (double) (this.vehicle.yaw - this.vehicle.lastYaw);
1118
1119 for (this.d += (double) (this.vehicle.pitch - this.vehicle.lastPitch); this.e >= 180.0D; this.e -= 360.0D) {
1120 ;
1121 }
1122
1123 while (this.e < -180.0D) {
1124 this.e += 360.0D;
1125 }
1126
1127 while (this.d >= 180.0D) {
1128 this.d -= 360.0D;
1129 }
1130
1131 while (this.d < -180.0D) {
1132 this.d += 360.0D;
1133 }
1134
1135 double d0 = this.e * 0.5D;
1136 double d1 = this.d * 0.5D;
1137 float f = 10.0F;
1138
1139 if (d0 > (double) f) {
1140 d0 = (double) f;
1141 }
1142
1143 if (d0 < (double) (-f)) {
1144 d0 = (double) (-f);
1145 }
1146
1147 if (d1 > (double) f) {
1148 d1 = (double) f;
1149 }
1150
1151 if (d1 < (double) (-f)) {
1152 d1 = (double) (-f);
1153 }
1154
1155 this.e -= d0;
1156 this.d -= d1;
1157 this.yaw = (float) ((double) this.yaw + d0);
1158 this.pitch = (float) ((double) this.pitch + d1);
1159 }
1160 }
1161 }
1162
1163 public void f() {
1164 this.passenger.setPosition(this.locX, this.locY + this.m() + this.passenger.I(), this.locZ);
1165 }
1166
1167 public double I() {
1168 return (double) this.height;
1169 }
1170
1171 public double m() {
1172 return (double) this.width * 0.75D;
1173 }
1174
1175 public void mount(Entity entity) {
1176 // CraftBukkit start
1177 this.setPassengerOf(entity);
1178 }
1179
1180 protected org.bukkit.entity.Entity bukkitEntity;
1181
1182 public org.bukkit.entity.Entity getBukkitEntity() {
1183 if (this.bukkitEntity == null) {
1184 this.bukkitEntity = org.bukkit.craftbukkit.entity.CraftEntity.getEntity(this.world.getServer(), this);
1185 }
1186 return this.bukkitEntity;
1187 }
1188
1189 public void setPassengerOf(Entity entity) {
1190 // b(null) doesn't really fly for overloaded methods,
1191 // so this method is needed
1192
1193 // CraftBukkit end
1194 this.d = 0.0D;
1195 this.e = 0.0D;
1196 if (entity == null) {
1197 if (this.vehicle != null) {
1198 // CraftBukkit start
1199 if ((this.getBukkitEntity() instanceof LivingEntity) && (this.vehicle.getBukkitEntity() instanceof Vehicle)) {
1200 VehicleExitEvent event = new VehicleExitEvent((Vehicle) this.vehicle.getBukkitEntity(), (LivingEntity) this.getBukkitEntity());
1201 this.world.getServer().getPluginManager().callEvent(event);
1202 }
1203 // CraftBukkit end
1204
1205 this.setPositionRotation(this.vehicle.locX, this.vehicle.boundingBox.b + (double) this.vehicle.width, this.vehicle.locZ, this.yaw, this.pitch);
1206 this.vehicle.passenger = null;
1207 }
1208
1209 this.vehicle = null;
1210 } else if (this.vehicle == entity) {
1211 // CraftBukkit start
1212 if ((this.getBukkitEntity() instanceof LivingEntity) && (this.vehicle.getBukkitEntity() instanceof Vehicle)) {
1213 VehicleExitEvent event = new VehicleExitEvent((Vehicle) this.vehicle.getBukkitEntity(), (LivingEntity) this.getBukkitEntity());
1214 this.world.getServer().getPluginManager().callEvent(event);
1215 }
1216 // CraftBukkit end
1217
1218 this.vehicle.passenger = null;
1219 this.vehicle = null;
1220 this.setPositionRotation(entity.locX, entity.boundingBox.b + (double) entity.width, entity.locZ, this.yaw, this.pitch);
1221 } else {
1222 if (this.vehicle != null) {
1223 this.vehicle.passenger = null;
1224 }
1225
1226 if (entity.passenger != null) {
1227 entity.passenger.vehicle = null;
1228 }
1229
1230 this.vehicle = entity;
1231 entity.passenger = this;
1232 }
1233 }
1234
1235 public Vec3D Z() {
1236 return null;
1237 }
1238
1239 public void P() {
1240 }
1241
1242 public ItemStack[] getEquipment() {
1243 return null;
1244 }
1245
1246 public boolean isSneaking() {
1247 return this.d(1);
1248 }
1249
1250 public void setSneak(boolean flag) {
1251 this.a(1, flag);
1252 }
1253
1254 protected boolean d(int i) {
1255 return (this.datawatcher.a(0) & 1 << i) != 0;
1256 }
1257
1258 protected void a(int i, boolean flag) {
1259 byte b0 = this.datawatcher.a(0);
1260
1261 if (flag) {
1262 this.datawatcher.watch(0, Byte.valueOf((byte) (b0 | 1 << i)));
1263 } else {
1264 this.datawatcher.watch(0, Byte.valueOf((byte) (b0 & ~(1 << i))));
1265 }
1266 }
1267
1268 public void a(EntityWeatherStorm entityweatherstorm) {
1269 // CraftBukkit start
1270 EntityDamageByEntityEvent event = new EntityDamageByEntityEvent(entityweatherstorm.getBukkitEntity(), this.getBukkitEntity(), EntityDamageEvent.DamageCause.LIGHTNING, 5);
1271 Bukkit.getServer().getPluginManager().callEvent(event);
1272
1273 if (event.isCancelled()) {
1274 return;
1275 }
1276
1277 this.burn(event.getDamage());
1278 // CraftBukkit end
1279
1280 ++this.fireTicks;
1281 if (this.fireTicks == 0) {
1282 this.fireTicks = 300;
1283 }
1284 }
1285
1286 public void a(EntityLiving entityliving) {
1287 }
1288
1289 protected boolean g(double d0, double d1, double d2) {
1290 int i = MathHelper.floor(d0);
1291 int j = MathHelper.floor(d1);
1292 int k = MathHelper.floor(d2);
1293 double d3 = d0 - (double) i;
1294 double d4 = d1 - (double) j;
1295 double d5 = d2 - (double) k;
1296
1297 if (this.world.e(i, j, k)) {
1298 boolean flag = !this.world.e(i - 1, j, k);
1299 boolean flag1 = !this.world.e(i + 1, j, k);
1300 boolean flag2 = !this.world.e(i, j - 1, k);
1301 boolean flag3 = !this.world.e(i, j + 1, k);
1302 boolean flag4 = !this.world.e(i, j, k - 1);
1303 boolean flag5 = !this.world.e(i, j, k + 1);
1304 byte b0 = -1;
1305 double d6 = 9999.0D;
1306
1307 if (flag && d3 < d6) {
1308 d6 = d3;
1309 b0 = 0;
1310 }
1311
1312 if (flag1 && 1.0D - d3 < d6) {
1313 d6 = 1.0D - d3;
1314 b0 = 1;
1315 }
1316
1317 if (flag2 && d4 < d6) {
1318 d6 = d4;
1319 b0 = 2;
1320 }
1321
1322 if (flag3 && 1.0D - d4 < d6) {
1323 d6 = 1.0D - d4;
1324 b0 = 3;
1325 }
1326
1327 if (flag4 && d5 < d6) {
1328 d6 = d5;
1329 b0 = 4;
1330 }
1331
1332 if (flag5 && 1.0D - d5 < d6) {
1333 d6 = 1.0D - d5;
1334 b0 = 5;
1335 }
1336
1337 float f = this.random.nextFloat() * 0.2F + 0.1F;
1338
1339 if (b0 == 0) {
1340 this.motX = (double) (-f);
1341 }
1342
1343 if (b0 == 1) {
1344 this.motX = (double) f;
1345 }
1346
1347 if (b0 == 2) {
1348 this.motY = (double) (-f);
1349 }
1350
1351 if (b0 == 3) {
1352 this.motY = (double) f;
1353 }
1354
1355 if (b0 == 4) {
1356 this.motZ = (double) (-f);
1357 }
1358
1359 if (b0 == 5) {
1360 this.motZ = (double) f;
1361 }
1362 }
1363
1364 return false;
1365 }
1366}