Commits
md_5 authored e8010dc93fb
59 59 | + |
60 60 | + // CraftBukkit - SPIGOT-6907: re-implement LivingEntity#setMaximumAir() |
61 61 | + public int getDefaultMaxAirSupply() { |
62 62 | + return TOTAL_AIR_SUPPLY; |
63 63 | + } |
64 64 | + // CraftBukkit end |
65 65 | + |
66 66 | private static final Logger LOGGER = LogUtils.getLogger(); |
67 67 | public static final String ID_TAG = "id"; |
68 68 | public static final String PASSENGERS_TAG = "Passengers"; |
69 - | |
69 + | |
70 70 | public boolean hasVisualFire; |
71 71 | @Nullable |
72 72 | private IBlockData feetBlockState; |
73 73 | + // CraftBukkit start |
74 74 | + public boolean persist = true; |
75 + | + public boolean visibleByDefault = true; |
75 76 | + public boolean valid; |
76 77 | + public boolean generation; |
77 78 | + public int maxAirTicks = getDefaultMaxAirSupply(); // CraftBukkit - SPIGOT-6907: re-implement LivingEntity#setMaximumAir() |
78 79 | + public org.bukkit.projectiles.ProjectileSource projectileSource; // For projectiles only |
79 80 | + public boolean lastDamageCancelled; // SPIGOT-5339, SPIGOT-6252, SPIGOT-6777: Keep track if the event was canceled |
80 81 | + public boolean persistentInvisibility = false; |
81 82 | + public BlockPosition lastLavaContact; |
82 83 | + |
83 84 | + public float getBukkitYaw() { |
84 85 | + return this.yRot; |
85 86 | + } |
86 87 | + |
87 88 | + public boolean isChunkLoaded() { |
88 89 | + return level.hasChunk((int) Math.floor(this.getX()) >> 4, (int) Math.floor(this.getZ()) >> 4); |
89 90 | + } |
90 91 | + // CraftBukkit end |
91 92 | |
92 93 | public Entity(EntityTypes<?> entitytypes, World world) { |
93 94 | this.id = Entity.ENTITY_COUNTER.incrementAndGet(); |
94 - | |
95 + | |
95 96 | public void onClientRemoval() {} |
96 97 | |
97 98 | public void setPose(EntityPose entitypose) { |
98 99 | + // CraftBukkit start |
99 100 | + if (entitypose == this.getPose()) { |
100 101 | + return; |
101 102 | + } |
102 103 | + this.level.getCraftServer().getPluginManager().callEvent(new EntityPoseChangeEvent(this.getBukkitEntity(), Pose.values()[entitypose.ordinal()])); |
103 104 | + // CraftBukkit end |
104 105 | this.entityData.set(Entity.DATA_POSE, entitypose); |
105 106 | } |
106 107 | |
107 - | |
108 + | |
108 109 | } |
109 110 | |
110 111 | protected void setRot(float f, float f1) { |
111 112 | + // CraftBukkit start - yaw was sometimes set to NaN, so we need to set it back to 0 |
112 113 | + if (Float.isNaN(f)) { |
113 114 | + f = 0; |
114 115 | + } |
115 116 | + |
116 117 | + if (f == Float.POSITIVE_INFINITY || f == Float.NEGATIVE_INFINITY) { |
117 118 | + if (this instanceof EntityPlayer) { |
131 132 | + this.level.getCraftServer().getLogger().warning(this.getScoreboardName() + " was caught trying to crash the server with an invalid pitch"); |
132 133 | + ((CraftPlayer) this.getBukkitEntity()).kickPlayer("Infinite pitch (Hacking?)"); |
133 134 | + } |
134 135 | + f1 = 0; |
135 136 | + } |
136 137 | + // CraftBukkit end |
137 138 | + |
138 139 | this.setYRot(f % 360.0F); |
139 140 | this.setXRot(f1 % 360.0F); |
140 141 | } |
141 - | |
142 + | |
142 143 | this.baseTick(); |
143 144 | } |
144 145 | |
145 146 | + // CraftBukkit start |
146 147 | + public void postTick() { |
147 148 | + // No clean way to break out of ticking once the entity has been copied to a new world, so instead we move the portalling later in the tick cycle |
148 149 | + if (!(this instanceof EntityPlayer)) { |
149 150 | + this.handleNetherPortal(); |
150 151 | + } |
151 152 | + } |
152 153 | + // CraftBukkit end |
153 154 | + |
154 155 | public void baseTick() { |
155 156 | this.level.getProfiler().push("entityBaseTick"); |
156 157 | this.feetBlockState = null; |
157 - | |
158 + | |
158 159 | this.walkDistO = this.walkDist; |
159 160 | this.xRotO = this.getXRot(); |
160 161 | this.yRotO = this.getYRot(); |
161 162 | - this.handleNetherPortal(); |
162 163 | + if (this instanceof EntityPlayer) this.handleNetherPortal(); // CraftBukkit - // Moved up to postTick |
163 164 | if (this.canSpawnSprintParticle()) { |
164 165 | this.spawnSprintParticle(); |
165 166 | } |
166 - | |
167 + | |
167 168 | if (this.isInLava()) { |
168 169 | this.lavaHurt(); |
169 170 | this.fallDistance *= 0.5F; |
170 171 | + // CraftBukkit start |
171 172 | + } else { |
172 173 | + this.lastLavaContact = null; |
173 174 | + // CraftBukkit end |
174 175 | } |
175 176 | |
176 177 | this.checkOutOfWorld(); |
177 - | |
178 + | |
178 179 | |
179 180 | public void lavaHurt() { |
180 181 | if (!this.fireImmune()) { |
181 182 | - this.setSecondsOnFire(15); |
182 183 | + // CraftBukkit start - Fallen in lava TODO: this event spams! |
183 184 | + if (this instanceof EntityLiving && remainingFireTicks <= 0) { |
184 185 | + // not on fire yet |
185 186 | + org.bukkit.block.Block damager = (lastLavaContact == null) ? null : org.bukkit.craftbukkit.block.CraftBlock.at(level, lastLavaContact); |
186 187 | + org.bukkit.entity.Entity damagee = this.getBukkitEntity(); |
187 188 | + EntityCombustEvent combustEvent = new org.bukkit.event.entity.EntityCombustByBlockEvent(damager, damagee, 15); |
217 218 | + if (event.isCancelled()) { |
218 219 | + return; |
219 220 | + } |
220 221 | + |
221 222 | + i = event.getDuration(); |
222 223 | + } |
223 224 | + // CraftBukkit end |
224 225 | int j = i * 20; |
225 226 | |
226 227 | if (this instanceof EntityLiving) { |
227 - | |
228 + | |
228 229 | block.updateEntityAfterFallOn(this.level, this); |
229 230 | } |
230 231 | |
231 232 | + // CraftBukkit start |
232 233 | + if (horizontalCollision && getBukkitEntity() instanceof Vehicle) { |
233 234 | + Vehicle vehicle = (Vehicle) this.getBukkitEntity(); |
234 235 | + org.bukkit.block.Block bl = this.level.getWorld().getBlockAt(MathHelper.floor(this.getX()), MathHelper.floor(this.getY()), MathHelper.floor(this.getZ())); |
235 236 | + |
236 237 | + if (vec3d.x > vec3d1.x) { |
237 238 | + bl = bl.getRelative(BlockFace.EAST); |
246 247 | + if (!bl.getType().isAir()) { |
247 248 | + VehicleBlockCollisionEvent event = new VehicleBlockCollisionEvent(vehicle, bl); |
248 249 | + level.getCraftServer().getPluginManager().callEvent(event); |
249 250 | + } |
250 251 | + } |
251 252 | + // CraftBukkit end |
252 253 | + |
253 254 | if (this.onGround) { |
254 255 | block.stepOn(this.level, blockposition, iblockdata, this); |
255 256 | } |
256 - | |
257 + | |
257 258 | return SoundEffects.GENERIC_SPLASH; |
258 259 | } |
259 260 | |
260 261 | + // CraftBukkit start - Add delegate methods |
261 262 | + public SoundEffect getSwimSound0() { |
262 263 | + return getSwimSound(); |
263 264 | + } |
264 265 | + |
265 266 | + public SoundEffect getSwimSplashSound0() { |
266 267 | + return getSwimSplashSound(); |
267 268 | + } |
268 269 | + |
269 270 | + public SoundEffect getSwimHighSpeedSplashSound0() { |
270 271 | + return getSwimHighSpeedSplashSound(); |
271 272 | + } |
272 273 | + // CraftBukkit end |
273 274 | + |
274 275 | protected void checkInsideBlocks() { |
275 276 | AxisAlignedBB axisalignedbb = this.getBoundingBox(); |
276 277 | BlockPosition blockposition = new BlockPosition(axisalignedbb.minX + 1.0E-7D, axisalignedbb.minY + 1.0E-7D, axisalignedbb.minZ + 1.0E-7D); |
277 - | |
278 + | |
278 279 | this.yo = d1; |
279 280 | this.zo = d4; |
280 281 | this.setPos(d3, d1, d4); |
281 282 | + if (valid) level.getChunk((int) Math.floor(this.getX()) >> 4, (int) Math.floor(this.getZ()) >> 4); // CraftBukkit |
282 283 | } |
283 284 | |
284 285 | public void moveTo(Vec3D vec3d) { |
285 - | |
286 + | |
286 287 | return false; |
287 288 | } |
288 289 | |
289 290 | + // CraftBukkit start - collidable API |
290 291 | + public boolean canCollideWithBukkit(Entity entity) { |
291 292 | + return isPushable(); |
292 293 | + } |
293 294 | + // CraftBukkit end |
294 295 | + |
295 296 | public void awardKillScore(Entity entity, int i, DamageSource damagesource) { |
296 297 | if (entity instanceof EntityPlayer) { |
297 298 | CriterionTriggers.ENTITY_KILLED_PLAYER.trigger((EntityPlayer) entity, this, damagesource); |
298 - | |
299 + | |
299 300 | } else { |
300 301 | String s = this.getEncodeId(); |
301 302 | |
302 303 | - if (s == null) { |
303 304 | + if (!this.persist || s == null) { // CraftBukkit - persist flag |
304 305 | return false; |
305 306 | } else { |
306 307 | nbttagcompound.putString("id", s); |
307 - | |
308 + | |
308 309 | Vec3D vec3d = this.getDeltaMovement(); |
309 310 | |
310 311 | nbttagcompound.put("Motion", this.newDoubleList(vec3d.x, vec3d.y, vec3d.z)); |
311 312 | + |
312 313 | + // CraftBukkit start - Checking for NaN pitch/yaw and resetting to zero |
313 314 | + // TODO: make sure this is the best way to address this. |
314 315 | + if (Float.isNaN(this.yRot)) { |
315 316 | + this.yRot = 0; |
316 317 | + } |
317 318 | + |
318 319 | + if (Float.isNaN(this.xRot)) { |
319 320 | + this.xRot = 0; |
320 321 | + } |
321 322 | + // CraftBukkit end |
322 323 | + |
323 324 | nbttagcompound.put("Rotation", this.newFloatList(this.getYRot(), this.getXRot())); |
324 325 | nbttagcompound.putFloat("FallDistance", this.fallDistance); |
325 326 | nbttagcompound.putShort("Fire", (short) this.remainingFireTicks); |
326 - | |
327 + | |
327 328 | nbttagcompound.putBoolean("Invulnerable", this.invulnerable); |
328 329 | nbttagcompound.putInt("PortalCooldown", this.portalCooldown); |
329 330 | nbttagcompound.putUUID("UUID", this.getUUID()); |
330 331 | + // CraftBukkit start |
331 332 | + // PAIL: Check above UUID reads 1.8 properly, ie: UUIDMost / UUIDLeast |
332 333 | + nbttagcompound.putLong("WorldUUIDLeast", ((WorldServer) this.level).getWorld().getUID().getLeastSignificantBits()); |
333 334 | + nbttagcompound.putLong("WorldUUIDMost", ((WorldServer) this.level).getWorld().getUID().getMostSignificantBits()); |
334 335 | + nbttagcompound.putInt("Bukkit.updateLevel", CURRENT_LEVEL); |
335 336 | + if (!this.persist) { |
336 337 | + nbttagcompound.putBoolean("Bukkit.persist", this.persist); |
337 338 | + } |
339 + | + if (!this.visibleByDefault) { |
340 + | + nbttagcompound.putBoolean("Bukkit.visibleByDefault", this.visibleByDefault); |
341 + | + } |
338 342 | + if (this.persistentInvisibility) { |
339 343 | + nbttagcompound.putBoolean("Bukkit.invisible", this.persistentInvisibility); |
340 344 | + } |
341 345 | + // SPIGOT-6907: re-implement LivingEntity#setMaximumAir() |
342 346 | + if (maxAirTicks != getDefaultMaxAirSupply()) { |
343 347 | + nbttagcompound.putInt("Bukkit.MaxAirSupply", getMaxAirSupply()); |
344 348 | + } |
345 349 | + // CraftBukkit end |
346 350 | IChatBaseComponent ichatbasecomponent = this.getCustomName(); |
347 351 | |
348 352 | if (ichatbasecomponent != null) { |
349 - | |
353 + | |
350 354 | } |
351 355 | } |
352 356 | |
353 357 | + // CraftBukkit start - stores eventually existing bukkit values |
354 358 | + if (this.bukkitEntity != null) { |
355 359 | + this.bukkitEntity.storeBukkitValues(nbttagcompound); |
356 360 | + } |
357 361 | + // CraftBukkit end |
358 362 | return nbttagcompound; |
359 363 | } catch (Throwable throwable) { |
360 364 | CrashReport crashreport = CrashReport.forThrowable(throwable, "Saving entity NBT"); |
361 - | |
365 + | |
362 366 | } else { |
363 367 | throw new IllegalStateException("Entity has invalid position"); |
364 368 | } |
365 369 | + |
366 370 | + // CraftBukkit start |
367 371 | + this.persist = !nbttagcompound.contains("Bukkit.persist") || nbttagcompound.getBoolean("Bukkit.persist"); |
372 + | + this.visibleByDefault = !nbttagcompound.contains("Bukkit.visibleByDefault") || nbttagcompound.getBoolean("Bukkit.visibleByDefault"); |
368 373 | + // SPIGOT-6907: re-implement LivingEntity#setMaximumAir() |
369 374 | + if (nbttagcompound.contains("Bukkit.MaxAirSupply")) { |
370 375 | + maxAirTicks = nbttagcompound.getInt("Bukkit.MaxAirSupply"); |
371 376 | + } |
372 377 | + // CraftBukkit end |
373 378 | + |
374 379 | + // CraftBukkit start - Reset world |
375 380 | + if (this instanceof EntityPlayer) { |
376 381 | + Server server = Bukkit.getServer(); |
377 382 | + org.bukkit.World bworld = null; |
396 401 | + if (nbttagcompound.contains("Bukkit.invisible")) { |
397 402 | + boolean bukkitInvisible = nbttagcompound.getBoolean("Bukkit.invisible"); |
398 403 | + this.setInvisible(bukkitInvisible); |
399 404 | + this.persistentInvisibility = bukkitInvisible; |
400 405 | + } |
401 406 | + // CraftBukkit end |
402 407 | + |
403 408 | } catch (Throwable throwable) { |
404 409 | CrashReport crashreport = CrashReport.forThrowable(throwable, "Loading entity NBT"); |
405 410 | CrashReportSystemDetails crashreportsystemdetails = crashreport.addCategory("Entity being loaded"); |
406 - | |
411 + | |
407 412 | } else if (this.level.isClientSide) { |
408 413 | return null; |
409 414 | } else { |
410 415 | + // CraftBukkit start - Capture drops for death event |
411 416 | + if (this instanceof EntityLiving && !((EntityLiving) this).forceDrops) { |
412 417 | + ((EntityLiving) this).drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack)); |
413 418 | + return null; |
414 419 | + } |
415 420 | + // CraftBukkit end |
416 421 | EntityItem entityitem = new EntityItem(this.level, this.getX(), this.getY() + (double) f, this.getZ(), itemstack); |
419 424 | + // CraftBukkit start |
420 425 | + EntityDropItemEvent event = new EntityDropItemEvent(this.getBukkitEntity(), (org.bukkit.entity.Item) entityitem.getBukkitEntity()); |
421 426 | + Bukkit.getPluginManager().callEvent(event); |
422 427 | + if (event.isCancelled()) { |
423 428 | + return null; |
424 429 | + } |
425 430 | + // CraftBukkit end |
426 431 | this.level.addFreshEntity(entityitem); |
427 432 | return entityitem; |
428 433 | } |
429 - | |
434 + | |
430 435 | |
431 436 | this.setPose(EntityPose.STANDING); |
432 437 | this.vehicle = entity; |
433 438 | - this.vehicle.addPassenger(this); |
434 439 | + if (!this.vehicle.addPassenger(this)) this.vehicle = null; // CraftBukkit |
435 440 | entity.getIndirectPassengersStream().filter((entity2) -> { |
436 441 | return entity2 instanceof EntityPlayer; |
437 442 | }).forEach((entity2) -> { |
438 - | |
443 + | |
439 444 | Entity entity = this.vehicle; |
440 445 | |
441 446 | this.vehicle = null; |
442 447 | - entity.removePassenger(this); |
443 448 | + if (!entity.removePassenger(this)) this.vehicle = entity; // CraftBukkit |
444 449 | } |
445 450 | |
446 451 | } |
447 - | |
452 + | |
448 453 | this.removeVehicle(); |
449 454 | } |
450 455 | |
451 456 | - protected void addPassenger(Entity entity) { |
452 457 | + protected boolean addPassenger(Entity entity) { // CraftBukkit |
453 458 | if (entity.getVehicle() != this) { |
454 459 | throw new IllegalStateException("Use x.startRiding(y), not y.addPassenger(x)"); |
455 460 | } else { |
456 461 | + // CraftBukkit start |
457 462 | + com.google.common.base.Preconditions.checkState(!entity.passengers.contains(this), "Circular entity riding! %s %s", this, entity); |
470 475 | + CraftEntity craftn = (CraftEntity) entity.getBukkitEntity().getVehicle(); |
471 476 | + Entity n = craftn == null ? null : craftn.getHandle(); |
472 477 | + if (event.isCancelled() || n != orig) { |
473 478 | + return false; |
474 479 | + } |
475 480 | + } |
476 481 | + // CraftBukkit end |
477 482 | if (this.passengers.isEmpty()) { |
478 483 | this.passengers = ImmutableList.of(entity); |
479 484 | } else { |
480 - | |
485 + | |
481 486 | } |
482 487 | |
483 488 | } |
484 489 | + return true; // CraftBukkit |
485 490 | } |
486 491 | |
487 492 | - protected void removePassenger(Entity entity) { |
488 493 | + protected boolean removePassenger(Entity entity) { // CraftBukkit |
489 494 | if (entity.getVehicle() == this) { |
490 495 | throw new IllegalStateException("Use x.stopRiding(y), not y.removePassenger(x)"); |
504 509 | + CraftEntity craftn = (CraftEntity) entity.getBukkitEntity().getVehicle(); |
505 510 | + Entity n = craftn == null ? null : craftn.getHandle(); |
506 511 | + if (event.isCancelled() || n != orig) { |
507 512 | + return false; |
508 513 | + } |
509 514 | + } |
510 515 | + // CraftBukkit end |
511 516 | if (this.passengers.size() == 1 && this.passengers.get(0) == entity) { |
512 517 | this.passengers = ImmutableList.of(); |
513 518 | } else { |
514 - | |
519 + | |
515 520 | |
516 521 | entity.boardingCooldown = 60; |
517 522 | } |
518 523 | + return true; // CraftBukkit |
519 524 | } |
520 525 | |
521 526 | protected boolean canAddPassenger(Entity entity) { |
522 - | |
527 + | |
523 528 | |
524 529 | if (this.isInsidePortal) { |
525 530 | MinecraftServer minecraftserver = worldserver.getServer(); |
526 531 | - ResourceKey<World> resourcekey = this.level.dimension() == World.NETHER ? World.OVERWORLD : World.NETHER; |
527 532 | + ResourceKey<World> resourcekey = this.level.getTypeKey() == WorldDimension.NETHER ? World.OVERWORLD : World.NETHER; // CraftBukkit |
528 533 | WorldServer worldserver1 = minecraftserver.getLevel(resourcekey); |
529 534 | |
530 535 | - if (worldserver1 != null && minecraftserver.isNetherEnabled() && !this.isPassenger() && this.portalTime++ >= i) { |
531 536 | + if (true && !this.isPassenger() && this.portalTime++ >= i) { // CraftBukkit |
532 537 | this.level.getProfiler().push("portal"); |
536 541 | + // CraftBukkit start |
537 542 | + if (this instanceof EntityPlayer) { |
538 543 | + ((EntityPlayer) this).changeDimension(worldserver1, PlayerTeleportEvent.TeleportCause.NETHER_PORTAL); |
539 544 | + } else { |
540 545 | + this.changeDimension(worldserver1); |
541 546 | + } |
542 547 | + // CraftBukkit end |
543 548 | this.level.getProfiler().pop(); |
544 549 | } |
545 550 | |
546 - | |
551 + | |
547 552 | } |
548 553 | |
549 554 | public void setSwimming(boolean flag) { |
550 555 | + // CraftBukkit start |
551 556 | + if (valid && this.isSwimming() != flag && this instanceof EntityLiving) { |
552 557 | + if (CraftEventFactory.callToggleSwimEvent((EntityLiving) this, flag).isCancelled()) { |
553 558 | + return; |
554 559 | + } |
555 560 | + } |
556 561 | + // CraftBukkit end |
557 562 | this.setSharedFlag(4, flag); |
558 563 | } |
559 564 | |
560 - | |
565 + | |
561 566 | return this.getTeam() != null ? this.getTeam().isAlliedTo(scoreboardteambase) : false; |
562 567 | } |
563 568 | |
564 569 | + // CraftBukkit - start |
565 570 | public void setInvisible(boolean flag) { |
566 571 | - this.setSharedFlag(5, flag); |
567 572 | + if (!this.persistentInvisibility) { // Prevent Minecraft from removing our invisibility flag |
568 573 | + this.setSharedFlag(5, flag); |
569 574 | + } |
570 575 | + // CraftBukkit - end |
571 576 | } |
572 577 | |
573 578 | public boolean getSharedFlag(int i) { |
574 - | |
579 + | |
575 580 | } |
576 581 | |
577 582 | public int getMaxAirSupply() { |
578 583 | - return 300; |
579 584 | + return maxAirTicks; // CraftBukkit - SPIGOT-6907: re-implement LivingEntity#setMaximumAir() |
580 585 | } |
581 586 | |
582 587 | public int getAirSupply() { |
583 - | |
588 + | |
584 589 | } |
585 590 | |
586 591 | public void setAirSupply(int i) { |
587 592 | - this.entityData.set(Entity.DATA_AIR_SUPPLY_ID, i); |
588 593 | + // CraftBukkit start |
589 594 | + EntityAirChangeEvent event = new EntityAirChangeEvent(this.getBukkitEntity(), i); |
590 595 | + // Suppress during worldgen |
591 596 | + if (this.valid) { |
592 597 | + event.getEntity().getServer().getPluginManager().callEvent(event); |
593 598 | + } |
594 599 | + if (event.isCancelled() && this.getAirSupply() != i) { |
595 600 | + this.entityData.markDirty(Entity.DATA_AIR_SUPPLY_ID); |
596 601 | + return; |
597 602 | + } |
598 603 | + this.entityData.set(Entity.DATA_AIR_SUPPLY_ID, event.getAmount()); |
599 604 | + // CraftBukkit end |
600 605 | } |
601 606 | |
602 607 | public int getTicksFrozen() { |
603 - | |
608 + | |
604 609 | |
605 610 | public void thunderHit(WorldServer worldserver, EntityLightning entitylightning) { |
606 611 | this.setRemainingFireTicks(this.remainingFireTicks + 1); |
607 612 | + // CraftBukkit start |
608 613 | + final org.bukkit.entity.Entity thisBukkitEntity = this.getBukkitEntity(); |
609 614 | + final org.bukkit.entity.Entity stormBukkitEntity = entitylightning.getBukkitEntity(); |
610 615 | + final PluginManager pluginManager = Bukkit.getPluginManager(); |
611 616 | + // CraftBukkit end |
612 617 | + |
613 618 | if (this.remainingFireTicks == 0) { |
637 642 | + } |
638 643 | + CraftEventFactory.entityDamage = entitylightning; |
639 644 | + if (!this.hurt(DamageSource.LIGHTNING_BOLT, 5.0F)) { |
640 645 | + CraftEventFactory.entityDamage = null; |
641 646 | + return; |
642 647 | + } |
643 648 | + // CraftBukkit end |
644 649 | } |
645 650 | |
646 651 | public void onAboveBubbleCol(boolean flag) { |
647 - | |
652 + | |
648 653 | |
649 654 | @Nullable |
650 655 | public Entity changeDimension(WorldServer worldserver) { |
651 656 | + // CraftBukkit start |
652 657 | + return teleportTo(worldserver, null); |
653 658 | + } |
654 659 | + |
655 660 | + @Nullable |
656 661 | + public Entity teleportTo(WorldServer worldserver, Position location) { |
657 662 | + // CraftBukkit end |
678 683 | + moveTo(shapedetectorshape.pos.x, shapedetectorshape.pos.y, shapedetectorshape.pos.z, shapedetectorshape.yRot, shapedetectorshape.xRot); |
679 684 | + setDeltaMovement(shapedetectorshape.speed); |
680 685 | + return this; |
681 686 | + } |
682 687 | + this.unRide(); |
683 688 | + // CraftBukkit end |
684 689 | + |
685 690 | this.level.getProfiler().popPush("reloading"); |
686 691 | Entity entity = this.getType().create(worldserver); |
687 692 | |
688 - | |
693 + | |
689 694 | entity.moveTo(shapedetectorshape.pos.x, shapedetectorshape.pos.y, shapedetectorshape.pos.z, shapedetectorshape.yRot, entity.getXRot()); |
690 695 | entity.setDeltaMovement(shapedetectorshape.speed); |
691 696 | worldserver.addDuringTeleport(entity); |
692 697 | - if (worldserver.dimension() == World.END) { |
693 698 | - WorldServer.makeObsidianPlatform(worldserver); |
694 699 | + if (worldserver.getTypeKey() == WorldDimension.END) { // CraftBukkit |
695 700 | + WorldServer.makeObsidianPlatform(worldserver, this); // CraftBukkit |
696 701 | } |
697 702 | + // CraftBukkit start - Forward the CraftEntity to the new entity |
698 703 | + this.getBukkitEntity().setHandle(entity); |
699 704 | + entity.bukkitEntity = this.getBukkitEntity(); |
700 705 | + |
701 706 | + if (this instanceof EntityInsentient) { |
702 707 | + ((EntityInsentient) this).dropLeash(true, false); // Unleash to prevent duping of leads. |
703 708 | + } |
704 709 | + // CraftBukkit end |
705 710 | } |
706 711 | |
707 712 | this.removeAfterChangingDimensions(); |
708 - | |
713 + | |
709 714 | |
710 715 | @Nullable |
711 716 | protected ShapeDetectorShape findDimensionEntryPoint(WorldServer worldserver) { |
712 717 | - boolean flag = this.level.dimension() == World.END && worldserver.dimension() == World.OVERWORLD; |
713 718 | - boolean flag1 = worldserver.dimension() == World.END; |
714 719 | + // CraftBukkit start |
715 720 | + if (worldserver == null) { |
716 721 | + return null; |
717 722 | + } |
718 723 | + boolean flag = this.level.getTypeKey() == WorldDimension.END && worldserver.getTypeKey() == WorldDimension.OVERWORLD; // fromEndToOverworld |
738 743 | + final WorldServer worldserverFinal = worldserver = ((CraftWorld) event.getTo().getWorld()).getHandle(); |
739 744 | + worldborder = worldserverFinal.getWorldBorder(); |
740 745 | + blockposition = worldborder.clampToBounds(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ()); |
741 746 | |
742 747 | - return (ShapeDetectorShape) this.getExitPortal(worldserver, blockposition, flag2, worldborder).map((blockutil_rectangle) -> { |
743 748 | + return (ShapeDetectorShape) this.getExitPortal(worldserver, blockposition, flag2, worldborder, event.getSearchRadius(), event.getCanCreatePortal(), event.getCreationRadius()).map((blockutil_rectangle) -> { |
744 749 | + // CraftBukkit end |
745 750 | IBlockData iblockdata = this.level.getBlockState(this.portalEntrancePos); |
746 751 | EnumDirection.EnumAxis enumdirection_enumaxis; |
747 752 | Vec3D vec3d; |
748 - | |
753 + | |
749 754 | vec3d = new Vec3D(0.5D, 0.0D, 0.0D); |
750 755 | } |
751 756 | |
752 757 | - return BlockPortalShape.createPortalInfo(worldserver, blockutil_rectangle, enumdirection_enumaxis, vec3d, this, this.getDeltaMovement(), this.getYRot(), this.getXRot()); |
753 758 | - }).orElse((Object) null); |
754 759 | + return BlockPortalShape.createPortalInfo(worldserverFinal, blockutil_rectangle, enumdirection_enumaxis, vec3d, this, this.getDeltaMovement(), this.getYRot(), this.getXRot(), event); // CraftBukkit |
755 760 | + }).orElse(null); // CraftBukkit - decompile error |
756 761 | } |
757 762 | } else { |
758 763 | BlockPosition blockposition1; |
759 - | |
764 + | |
760 765 | } else { |
761 766 | blockposition1 = worldserver.getHeightmapPos(HeightMap.Type.MOTION_BLOCKING_NO_LEAVES, worldserver.getSharedSpawnPos()); |
762 767 | } |
763 768 | + // CraftBukkit start |
764 769 | + CraftPortalEvent event = callPortalEvent(this, worldserver, new Position(blockposition1.getX() + 0.5D, blockposition1.getY(), blockposition1.getZ() + 0.5D), PlayerTeleportEvent.TeleportCause.END_PORTAL, 0, 0); |
765 770 | + if (event == null) { |
766 771 | + return null; |
767 772 | + } |
768 773 | |
769 774 | - return new ShapeDetectorShape(new Vec3D((double) blockposition1.getX() + 0.5D, (double) blockposition1.getY(), (double) blockposition1.getZ() + 0.5D), this.getDeltaMovement(), this.getYRot(), this.getXRot()); |
770 775 | + return new ShapeDetectorShape(new Vec3D(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ()), this.getDeltaMovement(), this.getYRot(), this.getXRot(), ((CraftWorld) event.getTo().getWorld()).getHandle(), event); |
771 776 | + // CraftBukkit end |
772 777 | } |
773 778 | } |
774 779 | |
775 - | |
780 + | |
776 781 | return BlockPortalShape.getRelativePosition(blockutil_rectangle, enumdirection_enumaxis, this.position(), this.getDimensions(this.getPose())); |
777 782 | } |
778 783 | |
779 784 | - protected Optional<BlockUtil.Rectangle> getExitPortal(WorldServer worldserver, BlockPosition blockposition, boolean flag, WorldBorder worldborder) { |
780 785 | - return worldserver.getPortalForcer().findPortalAround(blockposition, flag, worldborder); |
781 786 | + // CraftBukkit start |
782 787 | + protected CraftPortalEvent callPortalEvent(Entity entity, WorldServer exitWorldServer, Position exitPosition, PlayerTeleportEvent.TeleportCause cause, int searchRadius, int creationRadius) { |
783 788 | + org.bukkit.entity.Entity bukkitEntity = entity.getBukkitEntity(); |
784 789 | + Location enter = bukkitEntity.getLocation(); |
785 790 | + Location exit = new Location(exitWorldServer.getWorld(), exitPosition.x(), exitPosition.y(), exitPosition.z()); |
791 796 | + } |
792 797 | + return new CraftPortalEvent(event); |
793 798 | + } |
794 799 | + |
795 800 | + protected Optional<BlockUtil.Rectangle> getExitPortal(WorldServer worldserver, BlockPosition blockposition, boolean flag, WorldBorder worldborder, int searchRadius, boolean canCreatePortal, int createRadius) { |
796 801 | + return worldserver.getPortalForcer().findPortalAround(blockposition, worldborder, searchRadius); |
797 802 | + // CraftBukkit end |
798 803 | } |
799 804 | |
800 805 | public boolean canChangeDimensions() { |
801 - | |
806 + | |
802 807 | } |
803 808 | |
804 809 | public final void setBoundingBox(AxisAlignedBB axisalignedbb) { |
805 810 | - this.bb = axisalignedbb; |
806 811 | + // CraftBukkit start - block invalid bounding boxes |
807 812 | + double minX = axisalignedbb.minX, |
808 813 | + minY = axisalignedbb.minY, |
809 814 | + minZ = axisalignedbb.minZ, |
810 815 | + maxX = axisalignedbb.maxX, |
811 816 | + maxY = axisalignedbb.maxY, |
819 824 | + if (len > 64) maxY = minY + 64.0; |
820 825 | + |
821 826 | + len = axisalignedbb.maxZ - axisalignedbb.minZ; |
822 827 | + if (len < 0) maxZ = minZ; |
823 828 | + if (len > 64) maxZ = minZ + 64.0; |
824 829 | + this.bb = new AxisAlignedBB(minX, minY, minZ, maxX, maxY, maxZ); |
825 830 | + // CraftBukkit end |
826 831 | } |
827 832 | |
828 833 | protected float getEyeHeight(EntityPose entitypose, EntitySize entitysize) { |
829 - | |
834 + | |
830 835 | vec3d = vec3d.add(vec3d1); |
831 836 | ++k1; |
832 837 | } |
833 838 | + // CraftBukkit start - store last lava contact location |
834 839 | + if (tagkey == TagsFluid.LAVA) { |
835 840 | + this.lastLavaContact = blockposition_mutableblockposition.immutable(); |
836 841 | + } |
837 842 | + // CraftBukkit end |
838 843 | } |
839 844 | } |
840 845 | } |