mirror of
https://github.com/PaperMC/Paper.git
synced 2024-11-23 19:15:32 +01:00
625 lines
26 KiB
Diff
625 lines
26 KiB
Diff
--- a/net/minecraft/server/Entity.java
|
|
+++ b/net/minecraft/server/Entity.java
|
|
@@ -15,8 +15,47 @@
|
|
import org.apache.logging.log4j.LogManager;
|
|
import org.apache.logging.log4j.Logger;
|
|
|
|
+// CraftBukkit start
|
|
+import org.bukkit.Bukkit;
|
|
+import org.bukkit.Location;
|
|
+import org.bukkit.Server;
|
|
+import org.bukkit.TravelAgent;
|
|
+import org.bukkit.block.BlockFace;
|
|
+import org.bukkit.entity.Hanging;
|
|
+import org.bukkit.entity.LivingEntity;
|
|
+import org.bukkit.entity.Vehicle;
|
|
+import org.bukkit.event.entity.EntityCombustByEntityEvent;
|
|
+import org.bukkit.event.hanging.HangingBreakByEntityEvent;
|
|
+import org.bukkit.event.vehicle.VehicleBlockCollisionEvent;
|
|
+import org.bukkit.event.vehicle.VehicleEnterEvent;
|
|
+import org.bukkit.event.vehicle.VehicleExitEvent;
|
|
+import org.bukkit.craftbukkit.CraftWorld;
|
|
+import org.bukkit.craftbukkit.entity.CraftEntity;
|
|
+import org.bukkit.craftbukkit.entity.CraftPlayer;
|
|
+import org.bukkit.craftbukkit.event.CraftEventFactory;
|
|
+import org.bukkit.event.entity.EntityCombustEvent;
|
|
+import org.bukkit.event.entity.EntityPortalEvent;
|
|
+import org.bukkit.plugin.PluginManager;
|
|
+// CraftBukkit end
|
|
+
|
|
public abstract class Entity implements ICommandListener {
|
|
|
|
+ // CraftBukkit start
|
|
+ private static final int CURRENT_LEVEL = 2;
|
|
+ static boolean isLevelAtLeast(NBTTagCompound tag, int level) {
|
|
+ return tag.hasKey("Bukkit.updateLevel") && tag.getInt("Bukkit.updateLevel") >= level;
|
|
+ }
|
|
+
|
|
+ protected CraftEntity bukkitEntity;
|
|
+
|
|
+ public CraftEntity getBukkitEntity() {
|
|
+ if (bukkitEntity == null) {
|
|
+ bukkitEntity = CraftEntity.getEntity(world.getServer(), this);
|
|
+ }
|
|
+ return bukkitEntity;
|
|
+ }
|
|
+ // CraftBukikt end
|
|
+
|
|
private static final Logger a = LogManager.getLogger();
|
|
private static final AxisAlignedBB b = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 0.0D, 0.0D, 0.0D);
|
|
private static double c = 1.0D;
|
|
@@ -97,6 +136,9 @@
|
|
public boolean glowing;
|
|
private final Set<String> aF;
|
|
private boolean aG;
|
|
+ public boolean valid; // CraftBukkit
|
|
+ public org.bukkit.projectiles.ProjectileSource projectileSource; // CraftBukkit - For projectiles only
|
|
+ public boolean forceExplosionKnockback; // CraftBukkit - SPIGOT-949
|
|
|
|
public Entity(World world) {
|
|
this.id = Entity.entityCount++;
|
|
@@ -193,6 +235,33 @@
|
|
}
|
|
|
|
protected void setYawPitch(float f, float f1) {
|
|
+ // CraftBukkit start - yaw was sometimes set to NaN, so we need to set it back to 0
|
|
+ if (Float.isNaN(f)) {
|
|
+ f = 0;
|
|
+ }
|
|
+
|
|
+ if (f == Float.POSITIVE_INFINITY || f == Float.NEGATIVE_INFINITY) {
|
|
+ if (this instanceof EntityPlayer) {
|
|
+ this.world.getServer().getLogger().warning(this.getName() + " was caught trying to crash the server with an invalid yaw");
|
|
+ ((CraftPlayer) this.getBukkitEntity()).kickPlayer("Nope");
|
|
+ }
|
|
+ f = 0;
|
|
+ }
|
|
+
|
|
+ // pitch was sometimes set to NaN, so we need to set it back to 0
|
|
+ if (Float.isNaN(f1)) {
|
|
+ f1 = 0;
|
|
+ }
|
|
+
|
|
+ if (f1 == Float.POSITIVE_INFINITY || f1 == Float.NEGATIVE_INFINITY) {
|
|
+ if (this instanceof EntityPlayer) {
|
|
+ this.world.getServer().getLogger().warning(this.getName() + " was caught trying to crash the server with an invalid pitch");
|
|
+ ((CraftPlayer) this.getBukkitEntity()).kickPlayer("Nope");
|
|
+ }
|
|
+ f1 = 0;
|
|
+ }
|
|
+ // CraftBukkit end
|
|
+
|
|
this.yaw = f % 360.0F;
|
|
this.pitch = f1 % 360.0F;
|
|
}
|
|
@@ -236,7 +305,7 @@
|
|
if (this.ak) {
|
|
MinecraftServer minecraftserver = this.world.getMinecraftServer();
|
|
|
|
- if (minecraftserver.getAllowNether()) {
|
|
+ if (true || minecraftserver.getAllowNether()) { // CraftBukkit
|
|
if (!this.isPassenger()) {
|
|
int i = this.V();
|
|
|
|
@@ -321,6 +390,27 @@
|
|
protected void burnFromLava() {
|
|
if (!this.fireProof) {
|
|
this.damageEntity(DamageSource.LAVA, 4.0F);
|
|
+
|
|
+ // CraftBukkit start - Fallen in lava TODO: this event spams!
|
|
+ if (this instanceof EntityLiving) {
|
|
+ if (fireTicks <= 0) {
|
|
+ // not on fire yet
|
|
+ // TODO: shouldn't be sending null for the block
|
|
+ org.bukkit.block.Block damager = null; // ((WorldServer) this.l).getWorld().getBlockAt(i, j, k);
|
|
+ org.bukkit.entity.Entity damagee = this.getBukkitEntity();
|
|
+ EntityCombustEvent combustEvent = new org.bukkit.event.entity.EntityCombustByBlockEvent(damager, damagee, 15);
|
|
+ this.world.getServer().getPluginManager().callEvent(combustEvent);
|
|
+
|
|
+ if (!combustEvent.isCancelled()) {
|
|
+ this.setOnFire(combustEvent.getDuration());
|
|
+ }
|
|
+ } else {
|
|
+ // This will be called every single tick the entity is in lava, so don't throw an event
|
|
+ this.setOnFire(15);
|
|
+ }
|
|
+ return;
|
|
+ }
|
|
+ // CraftBukkit end - we also don't throw an event unless the object in lava is living, to save on some event calls
|
|
this.setOnFire(15);
|
|
}
|
|
}
|
|
@@ -361,6 +451,22 @@
|
|
this.a(this.getBoundingBox().c(d0, d1, d2));
|
|
this.recalcPosition();
|
|
} else {
|
|
+ // CraftBukkit start - Don't do anything if we aren't moving
|
|
+ // We need to do this regardless of whether or not we are moving thanks to portals
|
|
+ try {
|
|
+ this.checkBlockCollisions();
|
|
+ } catch (Throwable throwable) {
|
|
+ CrashReport crashreport = CrashReport.a(throwable, "Checking entity block collision");
|
|
+ CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity being checked for collision");
|
|
+
|
|
+ this.appendEntityCrashDetails(crashreportsystemdetails);
|
|
+ throw new ReportedException(crashreport);
|
|
+ }
|
|
+ // Check if we're moving
|
|
+ if (d0 == 0 && d1 == 0 && d2 == 0 && this.isVehicle() && this.isPassenger()) {
|
|
+ return;
|
|
+ }
|
|
+ // CraftBukkit end
|
|
this.world.methodProfiler.a("move");
|
|
double d3 = this.locX;
|
|
double d4 = this.locY;
|
|
@@ -585,6 +691,26 @@
|
|
block1.a(this.world, this);
|
|
}
|
|
|
|
+ // CraftBukkit start
|
|
+ if (positionChanged && getBukkitEntity() instanceof Vehicle) {
|
|
+ Vehicle vehicle = (Vehicle) this.getBukkitEntity();
|
|
+ org.bukkit.block.Block bl = this.world.getWorld().getBlockAt(MathHelper.floor(this.locX), MathHelper.floor(this.locY), MathHelper.floor(this.locZ));
|
|
+
|
|
+ if (d6 > d0) {
|
|
+ bl = bl.getRelative(BlockFace.EAST);
|
|
+ } else if (d6 < d0) {
|
|
+ bl = bl.getRelative(BlockFace.WEST);
|
|
+ } else if (d8 > d2) {
|
|
+ bl = bl.getRelative(BlockFace.SOUTH);
|
|
+ } else if (d8 < d2) {
|
|
+ bl = bl.getRelative(BlockFace.NORTH);
|
|
+ }
|
|
+
|
|
+ VehicleBlockCollisionEvent event = new VehicleBlockCollisionEvent(vehicle, bl);
|
|
+ world.getServer().getPluginManager().callEvent(event);
|
|
+ }
|
|
+ // CraftBukkit end
|
|
+
|
|
if (this.playStepSound() && !flag && !this.isPassenger()) {
|
|
double d21 = this.locX - d3;
|
|
double d22 = this.locY - d4;
|
|
@@ -595,7 +721,7 @@
|
|
}
|
|
|
|
if (block1 != null && this.onGround) {
|
|
- block1.stepOn(this.world, blockposition, this);
|
|
+ // block1.stepOn(this.world, blockposition, this); // CraftBukkit moved down
|
|
}
|
|
|
|
this.J = (float) ((double) this.J + (double) MathHelper.sqrt(d21 * d21 + d10 * d10) * 0.6D);
|
|
@@ -613,9 +739,12 @@
|
|
}
|
|
|
|
this.a(blockposition, block1);
|
|
+ block1.stepOn(this.world, blockposition, this); // CraftBukkit moved from above
|
|
}
|
|
}
|
|
|
|
+ // CraftBukkit start - Move to the top of the method
|
|
+ /*
|
|
try {
|
|
this.checkBlockCollisions();
|
|
} catch (Throwable throwable) {
|
|
@@ -625,6 +754,8 @@
|
|
this.appendEntityCrashDetails(crashreportsystemdetails);
|
|
throw new ReportedException(crashreport);
|
|
}
|
|
+ */
|
|
+ // CraftBukkit end
|
|
|
|
boolean flag2 = this.ah();
|
|
|
|
@@ -632,7 +763,16 @@
|
|
this.burn(1);
|
|
if (!flag2) {
|
|
++this.fireTicks;
|
|
- if (this.fireTicks == 0) {
|
|
+ // CraftBukkit start - Not on fire yet
|
|
+ if (this.fireTicks <= 0) { // Only throw events on the first combust, otherwise it spams
|
|
+ EntityCombustEvent event = new EntityCombustEvent(getBukkitEntity(), 8);
|
|
+ world.getServer().getPluginManager().callEvent(event);
|
|
+
|
|
+ if (!event.isCancelled()) {
|
|
+ setOnFire(event.getDuration());
|
|
+ }
|
|
+ } else {
|
|
+ // CraftBukkit end
|
|
this.setOnFire(8);
|
|
}
|
|
}
|
|
@@ -745,7 +885,7 @@
|
|
return null;
|
|
}
|
|
|
|
- protected void burn(int i) {
|
|
+ protected void burn(float i) { // CraftBukkit - int -> float
|
|
if (!this.fireProof) {
|
|
this.damageEntity(DamageSource.FIRE, (float) i);
|
|
}
|
|
@@ -911,6 +1051,13 @@
|
|
}
|
|
|
|
public void spawnIn(World world) {
|
|
+ // CraftBukkit start
|
|
+ if (world == null) {
|
|
+ die();
|
|
+ this.world = ((CraftWorld) Bukkit.getServer().getWorlds().get(0)).getHandle();
|
|
+ return;
|
|
+ }
|
|
+ // CraftBukkit end
|
|
this.world = world;
|
|
}
|
|
|
|
@@ -1104,6 +1251,18 @@
|
|
try {
|
|
nbttagcompound.set("Pos", this.a(new double[] { this.locX, this.locY, this.locZ}));
|
|
nbttagcompound.set("Motion", this.a(new double[] { this.motX, this.motY, this.motZ}));
|
|
+
|
|
+ // CraftBukkit start - Checking for NaN pitch/yaw and resetting to zero
|
|
+ // TODO: make sure this is the best way to address this.
|
|
+ if (Float.isNaN(this.yaw)) {
|
|
+ this.yaw = 0;
|
|
+ }
|
|
+
|
|
+ if (Float.isNaN(this.pitch)) {
|
|
+ this.pitch = 0;
|
|
+ }
|
|
+ // CraftBukkit end
|
|
+
|
|
nbttagcompound.set("Rotation", this.a(new float[] { this.yaw, this.pitch}));
|
|
nbttagcompound.setFloat("FallDistance", this.fallDistance);
|
|
nbttagcompound.setShort("Fire", (short) this.fireTicks);
|
|
@@ -1113,6 +1272,12 @@
|
|
nbttagcompound.setBoolean("Invulnerable", this.invulnerable);
|
|
nbttagcompound.setInt("PortalCooldown", this.portalCooldown);
|
|
nbttagcompound.a("UUID", this.getUniqueID());
|
|
+ // CraftBukkit start
|
|
+ // PAIL: Check above UUID reads 1.8 properly, ie: UUIDMost / UUIDLeast
|
|
+ nbttagcompound.setLong("WorldUUIDLeast", this.world.getDataManager().getUUID().getLeastSignificantBits());
|
|
+ nbttagcompound.setLong("WorldUUIDMost", this.world.getDataManager().getUUID().getMostSignificantBits());
|
|
+ nbttagcompound.setInt("Bukkit.updateLevel", CURRENT_LEVEL);
|
|
+ // CraftBukkit end
|
|
if (this.getCustomName() != null && !this.getCustomName().isEmpty()) {
|
|
nbttagcompound.setString("CustomName", this.getCustomName());
|
|
}
|
|
@@ -1183,6 +1348,8 @@
|
|
this.motX = nbttaglist1.e(0);
|
|
this.motY = nbttaglist1.e(1);
|
|
this.motZ = nbttaglist1.e(2);
|
|
+
|
|
+ /* CraftBukkit start - Moved section down
|
|
if (Math.abs(this.motX) > 10.0D) {
|
|
this.motX = 0.0D;
|
|
}
|
|
@@ -1194,6 +1361,7 @@
|
|
if (Math.abs(this.motZ) > 10.0D) {
|
|
this.motZ = 0.0D;
|
|
}
|
|
+ // CraftBukkit end */
|
|
|
|
this.lastX = this.M = this.locX = nbttaglist.e(0);
|
|
this.lastY = this.N = this.locY = nbttaglist.e(1);
|
|
@@ -1241,6 +1409,58 @@
|
|
this.setPosition(this.locX, this.locY, this.locZ);
|
|
}
|
|
|
|
+ // CraftBukkit start
|
|
+ if (this instanceof EntityLiving) {
|
|
+ EntityLiving entity = (EntityLiving) this;
|
|
+
|
|
+ // Reset the persistence for tamed animals
|
|
+ if (entity instanceof EntityTameableAnimal && !isLevelAtLeast(nbttagcompound, 2) && !nbttagcompound.getBoolean("PersistenceRequired")) {
|
|
+ EntityInsentient entityinsentient = (EntityInsentient) entity;
|
|
+ entityinsentient.persistent = !entityinsentient.isTypeNotPersistent();
|
|
+ }
|
|
+ }
|
|
+ // CraftBukkit end
|
|
+
|
|
+ // CraftBukkit start - Exempt Vehicles from notch's sanity check
|
|
+ if (!(getBukkitEntity() instanceof Vehicle)) {
|
|
+ if (Math.abs(this.motX) > 10.0D) {
|
|
+ this.motX = 0.0D;
|
|
+ }
|
|
+
|
|
+ if (Math.abs(this.motY) > 10.0D) {
|
|
+ this.motY = 0.0D;
|
|
+ }
|
|
+
|
|
+ if (Math.abs(this.motZ) > 10.0D) {
|
|
+ this.motZ = 0.0D;
|
|
+ }
|
|
+ }
|
|
+ // CraftBukkit end
|
|
+
|
|
+ // CraftBukkit start - Reset world
|
|
+ if (this instanceof EntityPlayer) {
|
|
+ Server server = Bukkit.getServer();
|
|
+ org.bukkit.World bworld = null;
|
|
+
|
|
+ // TODO: Remove World related checks, replaced with WorldUID
|
|
+ String worldName = nbttagcompound.getString("world");
|
|
+
|
|
+ if (nbttagcompound.hasKey("WorldUUIDMost") && nbttagcompound.hasKey("WorldUUIDLeast")) {
|
|
+ UUID uid = new UUID(nbttagcompound.getLong("WorldUUIDMost"), nbttagcompound.getLong("WorldUUIDLeast"));
|
|
+ bworld = server.getWorld(uid);
|
|
+ } else {
|
|
+ bworld = server.getWorld(worldName);
|
|
+ }
|
|
+
|
|
+ if (bworld == null) {
|
|
+ EntityPlayer entityPlayer = (EntityPlayer) this;
|
|
+ bworld = ((org.bukkit.craftbukkit.CraftServer) server).getServer().getWorldServer(entityPlayer.dimension).getWorld();
|
|
+ }
|
|
+
|
|
+ spawnIn(bworld == null? null : ((CraftWorld) bworld).getHandle());
|
|
+ }
|
|
+ // CraftBukkit end
|
|
+
|
|
} catch (Throwable throwable) {
|
|
CrashReport crashreport = CrashReport.a(throwable, "Loading entity NBT");
|
|
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity being loaded");
|
|
@@ -1302,6 +1522,12 @@
|
|
|
|
public EntityItem a(ItemStack itemstack, float f) {
|
|
if (itemstack.count != 0 && itemstack.getItem() != null) {
|
|
+ // CraftBukkit start - Capture drops for death event
|
|
+ if (this instanceof EntityLiving && ((EntityLiving) this).drops != null) {
|
|
+ ((EntityLiving) this).drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack));
|
|
+ return null;
|
|
+ }
|
|
+ // CraftBukkit end
|
|
EntityItem entityitem = new EntityItem(this.world, this.locX, this.locY + (double) f, this.locZ, itemstack);
|
|
|
|
entityitem.q();
|
|
@@ -1422,6 +1648,22 @@
|
|
if (entity.by() != this) {
|
|
throw new IllegalStateException("Use x.startRiding(y), not y.addPassenger(x)");
|
|
} else {
|
|
+ // CraftBukkit start
|
|
+ CraftEntity craft = (CraftEntity) entity.getBukkitEntity().getVehicle();
|
|
+ Entity orig = craft == null ? null : craft.getHandle();
|
|
+ if (getBukkitEntity() instanceof Vehicle && entity.getBukkitEntity() instanceof LivingEntity) {
|
|
+ VehicleEnterEvent event = new VehicleEnterEvent(
|
|
+ (Vehicle) getBukkitEntity(),
|
|
+ entity.getBukkitEntity()
|
|
+ );
|
|
+ Bukkit.getPluginManager().callEvent(event);
|
|
+ CraftEntity craftn = (CraftEntity) entity.getBukkitEntity().getVehicle();
|
|
+ Entity n = craftn == null ? null : craftn.getHandle();
|
|
+ if (event.isCancelled() || n != orig) {
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+ // CraftBukkit end
|
|
if (!this.world.isClientSide && entity instanceof EntityHuman && !(this.bt() instanceof EntityHuman)) {
|
|
this.passengers.add(0, entity);
|
|
} else {
|
|
@@ -1435,6 +1677,22 @@
|
|
if (entity.by() == this) {
|
|
throw new IllegalStateException("Use x.stopRiding(y), not y.removePassenger(x)");
|
|
} else {
|
|
+ // CraftBukkit start
|
|
+ CraftEntity craft = (CraftEntity) entity.getBukkitEntity().getVehicle();
|
|
+ Entity orig = craft == null ? null : craft.getHandle();
|
|
+ if (getBukkitEntity() instanceof Vehicle && entity.getBukkitEntity() instanceof LivingEntity) {
|
|
+ VehicleExitEvent event = new VehicleExitEvent(
|
|
+ (Vehicle) getBukkitEntity(),
|
|
+ (LivingEntity) entity.getBukkitEntity()
|
|
+ );
|
|
+ Bukkit.getPluginManager().callEvent(event);
|
|
+ CraftEntity craftn = (CraftEntity) entity.getBukkitEntity().getVehicle();
|
|
+ Entity n = craftn == null ? null : craftn.getHandle();
|
|
+ if (event.isCancelled() || n != orig) {
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+ // CraftBukkit end
|
|
this.passengers.remove(entity);
|
|
entity.j = 60;
|
|
}
|
|
@@ -1577,10 +1835,38 @@
|
|
}
|
|
|
|
public void onLightningStrike(EntityLightning entitylightning) {
|
|
- this.damageEntity(DamageSource.LIGHTNING, 5.0F);
|
|
+ // CraftBukkit start
|
|
+ final org.bukkit.entity.Entity thisBukkitEntity = this.getBukkitEntity();
|
|
+ final org.bukkit.entity.Entity stormBukkitEntity = entitylightning.getBukkitEntity();
|
|
+ final PluginManager pluginManager = Bukkit.getPluginManager();
|
|
+
|
|
+ if (thisBukkitEntity instanceof Hanging) {
|
|
+ HangingBreakByEntityEvent hangingEvent = new HangingBreakByEntityEvent((Hanging) thisBukkitEntity, stormBukkitEntity);
|
|
+ pluginManager.callEvent(hangingEvent);
|
|
+
|
|
+ if (hangingEvent.isCancelled()) {
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (this.fireProof) {
|
|
+ return;
|
|
+ }
|
|
+ CraftEventFactory.entityDamage = entitylightning;
|
|
+ if (!this.damageEntity(DamageSource.LIGHTNING, 5.0F)) {
|
|
+ CraftEventFactory.entityDamage = null;
|
|
+ return;
|
|
+ }
|
|
+ // CraftBukkit end
|
|
++this.fireTicks;
|
|
if (this.fireTicks == 0) {
|
|
- this.setOnFire(8);
|
|
+ // CraftBukkit start - Call a combust event when lightning strikes
|
|
+ EntityCombustByEntityEvent entityCombustEvent = new EntityCombustByEntityEvent(stormBukkitEntity, thisBukkitEntity, 8);
|
|
+ pluginManager.callEvent(entityCombustEvent);
|
|
+ if (!entityCombustEvent.isCancelled()) {
|
|
+ this.setOnFire(entityCombustEvent.getDuration());
|
|
+ }
|
|
+ // CraftBukkit end
|
|
}
|
|
|
|
}
|
|
@@ -1715,19 +2001,67 @@
|
|
if (!this.world.isClientSide && !this.dead) {
|
|
this.world.methodProfiler.a("changeDimension");
|
|
MinecraftServer minecraftserver = this.h();
|
|
- int j = this.dimension;
|
|
- WorldServer worldserver = minecraftserver.getWorldServer(j);
|
|
- WorldServer worldserver1 = minecraftserver.getWorldServer(i);
|
|
+ // CraftBukkit start - Move logic into new function "teleportTo(Location,boolean)"
|
|
+ // int j = this.dimension;
|
|
+ // WorldServer worldserver = minecraftserver.getWorldServer(j);
|
|
+ // WorldServer worldserver1 = minecraftserver.getWorldServer(i);
|
|
+ WorldServer exitWorld = null;
|
|
+ if (this.dimension < CraftWorld.CUSTOM_DIMENSION_OFFSET) { // Plugins must specify exit from custom Bukkit worlds
|
|
+ // Only target existing worlds (compensate for allow-nether/allow-end as false)
|
|
+ for (WorldServer world : minecraftserver.worlds) {
|
|
+ if (world.dimension == i) {
|
|
+ exitWorld = world;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ BlockPosition blockposition = null; // PAIL: CHECK
|
|
+ Location enter = this.getBukkitEntity().getLocation();
|
|
+ Location exit;
|
|
+ if (exitWorld != null) {
|
|
+ if (blockposition != null) {
|
|
+ exit = new Location(exitWorld.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ());
|
|
+ } else {
|
|
+ exit = minecraftserver.getPlayerList().calculateTarget(enter, minecraftserver.getWorldServer(i));
|
|
+ }
|
|
+ }
|
|
+ else {
|
|
+ exit = null;
|
|
+ }
|
|
+ boolean useTravelAgent = exitWorld != null && !(this.dimension == 1 && exitWorld.dimension == 1); // don't use agent for custom worlds or return from THE_END
|
|
+
|
|
+ TravelAgent agent = exit != null ? (TravelAgent) ((CraftWorld) exit.getWorld()).getHandle().getTravelAgent() : org.bukkit.craftbukkit.CraftTravelAgent.DEFAULT; // return arbitrary TA to compensate for implementation dependent plugins
|
|
+ EntityPortalEvent event = new EntityPortalEvent(this.getBukkitEntity(), enter, exit, agent);
|
|
+ event.useTravelAgent(useTravelAgent);
|
|
+ event.getEntity().getServer().getPluginManager().callEvent(event);
|
|
+ if (event.isCancelled() || event.getTo() == null || event.getTo().getWorld() == null || !this.isAlive()) {
|
|
+ return null;
|
|
+ }
|
|
+ exit = event.useTravelAgent() ? event.getPortalTravelAgent().findOrCreate(event.getTo()) : event.getTo();
|
|
+ return this.teleportTo(exit, true);
|
|
+ }
|
|
+ return null;
|
|
+ }
|
|
+
|
|
+ public Entity teleportTo(Location exit, boolean portal) {
|
|
+ if (true) {
|
|
+ WorldServer worldserver = ((CraftWorld) getBukkitEntity().getLocation().getWorld()).getHandle();
|
|
+ WorldServer worldserver1 = ((CraftWorld) exit.getWorld()).getHandle();
|
|
+ int i = worldserver1.dimension;
|
|
+ // CraftBukkit end
|
|
|
|
this.dimension = i;
|
|
+ /* CraftBukkit start - TODO: Check if we need this
|
|
if (j == 1 && i == 1) {
|
|
worldserver1 = minecraftserver.getWorldServer(0);
|
|
this.dimension = 0;
|
|
}
|
|
+ // CraftBukkit end */
|
|
|
|
this.world.kill(this);
|
|
this.dead = false;
|
|
this.world.methodProfiler.a("reposition");
|
|
+ /* CraftBukkit start - Handled in calculateTarget
|
|
BlockPosition blockposition;
|
|
|
|
if (i == 1) {
|
|
@@ -1756,12 +2090,18 @@
|
|
blockposition = new BlockPosition(this);
|
|
}
|
|
|
|
- worldserver.entityJoinedWorld(this, false);
|
|
+ // CraftBukkit end */
|
|
+ // CraftBukkit start - Ensure chunks are loaded in case TravelAgent is not used which would initially cause chunks to load during find/create
|
|
+ // minecraftserver.getPlayerList().changeWorld(this, j, worldserver, worldserver1);
|
|
+ worldserver1.getMinecraftServer().getPlayerList().repositionEntity(this, exit, portal);
|
|
+ // worldserver.entityJoinedWorld(this, false); // Handled in repositionEntity
|
|
+ // CraftBukkit end
|
|
this.world.methodProfiler.c("reloading");
|
|
Entity entity = EntityTypes.createEntityByName(EntityTypes.b(this), worldserver1);
|
|
|
|
if (entity != null) {
|
|
entity.a(this);
|
|
+ /* CraftBukkit start - We need to do this...
|
|
if (j == 1 && i == 1) {
|
|
BlockPosition blockposition1 = worldserver1.q(worldserver1.getSpawn());
|
|
|
|
@@ -1769,6 +2109,7 @@
|
|
} else {
|
|
entity.setPositionRotation(blockposition, entity.yaw, entity.pitch);
|
|
}
|
|
+ // CraftBukkit end */
|
|
|
|
boolean flag = entity.attachedToPlayer;
|
|
|
|
@@ -1776,6 +2117,14 @@
|
|
worldserver1.addEntity(entity);
|
|
entity.attachedToPlayer = flag;
|
|
worldserver1.entityJoinedWorld(entity, false);
|
|
+ // CraftBukkit start - Forward the CraftEntity to the new entity
|
|
+ this.getBukkitEntity().setHandle(entity);
|
|
+ entity.bukkitEntity = this.getBukkitEntity();
|
|
+
|
|
+ if (this instanceof EntityInsentient) {
|
|
+ ((EntityInsentient)this).unleash(true, false); // Unleash to prevent duping of leads.
|
|
+ }
|
|
+ // CraftBukkit end
|
|
}
|
|
|
|
this.dead = true;
|
|
@@ -1881,6 +2230,11 @@
|
|
}
|
|
|
|
public void setCustomName(String s) {
|
|
+ // CraftBukkit start - Add a sane limit for name length
|
|
+ if (s.length() > 256) {
|
|
+ s = s.substring(0, 256);
|
|
+ }
|
|
+ // CraftBukkit end
|
|
this.datawatcher.set(Entity.az, s);
|
|
}
|
|
|
|
@@ -1938,7 +2292,26 @@
|
|
}
|
|
|
|
public void a(AxisAlignedBB axisalignedbb) {
|
|
- this.boundingBox = axisalignedbb;
|
|
+ // CraftBukkit start - block invalid bounding boxes
|
|
+ double a = axisalignedbb.a,
|
|
+ b = axisalignedbb.b,
|
|
+ c = axisalignedbb.c,
|
|
+ d = axisalignedbb.d,
|
|
+ e = axisalignedbb.e,
|
|
+ f = axisalignedbb.f;
|
|
+ double len = axisalignedbb.d - axisalignedbb.a;
|
|
+ if (len < 0) d = a;
|
|
+ if (len > 64) d = a + 64.0;
|
|
+
|
|
+ len = axisalignedbb.e - axisalignedbb.b;
|
|
+ if (len < 0) e = b;
|
|
+ if (len > 64) e = b + 64.0;
|
|
+
|
|
+ len = axisalignedbb.f - axisalignedbb.c;
|
|
+ if (len < 0) f = c;
|
|
+ if (len > 64) f = c + 64.0;
|
|
+ this.boundingBox = new AxisAlignedBB(a, b, c, d, e, f);
|
|
+ // CraftBukkit end
|
|
}
|
|
|
|
public float getHeadHeight() {
|
|
@@ -2110,7 +2483,7 @@
|
|
for (Iterator iterator = this.bu().iterator(); iterator.hasNext(); entity.a(oclass, set)) {
|
|
entity = (Entity) iterator.next();
|
|
if (oclass.isAssignableFrom(entity.getClass())) {
|
|
- set.add(entity);
|
|
+ set.add((T) entity); // CraftBukkit - decompile error
|
|
}
|
|
}
|
|
|