package net.minecraft.server;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.koloboke.collect.set.hash.HashObjSets;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import javax.annotation.Nullable;
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 co.aikar.timings.MinecraftTimings; // Paper
import co.aikar.timings.Timing; // Paper
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.EntityAirChangeEvent;
import org.bukkit.event.entity.EntityCombustEvent;
import org.bukkit.event.entity.EntityPortalEvent;
import org.bukkit.plugin.PluginManager;
import org.torch.util.random.LightRandom;
public abstract class Entity implements ICommandListener {
// CraftBukkit start
private static final int CURRENT_LEVEL = 2;
public static Random SHARED_RANDOM = new LightRandom(); // Paper
static boolean isLevelAtLeast(NBTTagCompound tag, int level) {
return tag.hasKey("Bukkit.updateLevel") && tag.getInt("Bukkit.updateLevel") >= level;
}
protected volatile CraftEntity bukkitEntity;
EntityTrackerEntry tracker; // Paper
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 List<ItemStack> b = Collections.emptyList();
private static final AxisAlignedBB c = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 0.0D, 0.0D, 0.0D);
private static double f = 1.0D;
private static int entityCount;
private int id;
public boolean i; public boolean blocksEntitySpawning() { return i; } // Paper - OBFHELPER
public final List<Entity> passengers;
protected int j;
private Entity au;public void setVehicle(Entity entity) { this.au = entity; } // Paper // OBFHELPER
public boolean attachedToPlayer;
public World world;
public double lastX;
public double lastY;
public double lastZ;
public double locX;
public double locY;
public double locZ;
// Paper start - getters to implement HopperPusher
public double getX() {
return locX;
}
public double getY() {
return locY;
}
public double getZ() {
return locZ;
}
// Paper end
public double motX;
public double motY;
public double motZ;
public float yaw;
public float pitch;
public float lastYaw;
public float lastPitch;
private AxisAlignedBB boundingBox;
public boolean onGround;
public boolean positionChanged;
public boolean B;
public boolean C;
public boolean velocityChanged;
protected boolean E;
private boolean aw;
public boolean dead;
public float width;
public float length;
public float I;
public float J;
public float K;
public float fallDistance;
private int ax;
public double M;
public double N;
public double O;
public float P;
public boolean noclip;
public float R;
protected Random random;
public int ticksLived;
public int fireTicks;
public boolean inWater; // Spigot - protected -> public // PAIL
public int noDamageTicks;
protected boolean justCreated;
protected boolean fireProof;
protected DataWatcher datawatcher;
protected static final DataWatcherObject<Byte> Z = DataWatcher.a(Entity.class, DataWatcherRegistry.a);
private static final DataWatcherObject<Integer> az = DataWatcher.a(Entity.class, DataWatcherRegistry.b);
private static final DataWatcherObject<String> aA = DataWatcher.a(Entity.class, DataWatcherRegistry.d);
private static final DataWatcherObject<Boolean> aB = DataWatcher.a(Entity.class, DataWatcherRegistry.h);
private static final DataWatcherObject<Boolean> aC = DataWatcher.a(Entity.class, DataWatcherRegistry.h);
private static final DataWatcherObject<Boolean> aD = DataWatcher.a(Entity.class, DataWatcherRegistry.h);
public boolean aa; public boolean isAddedToChunk() { return aa; } // Paper - OBFHELPER
public int ab; public int getChunkX() { return ab; } // Paper - OBFHELPER
public int ac; public int getChunkY() { return ac; } // Paper - OBFHELPER
public int ad; public int getChunkZ() { return ad; } // Paper - OBFHELPER
public boolean ah;
public boolean impulse;
public int portalCooldown;
protected boolean ak; public boolean inPortal() { return ak; } // Paper - OBFHELPER
protected int al;
public int dimension;
protected BlockPosition an;
protected Vec3D ao;
protected EnumDirection ap;
private boolean invulnerable;
protected UUID uniqueID;
protected String ar;
private final CommandObjectiveExecutor aF;
public boolean glowing;
private final Set<String> aG;
private boolean aH;
private double[] aI;
private long aJ;
public boolean valid; // CraftBukkit
public org.bukkit.projectiles.ProjectileSource projectileSource; // CraftBukkit - For projectiles only
public boolean forceExplosionKnockback; // CraftBukkit - SPIGOT-949
public Timing tickTimer = MinecraftTimings.getEntityTimings(this); // Paper
public Location origin; // Paper
// Spigot start
public final byte activationType = org.spigotmc.ActivationRange.initializeEntityActivationType(this);
public final boolean defaultActivationState;
public long activatedTick = Integer.MIN_VALUE;
public boolean fromMobSpawner;
protected int numCollisions = 0; // Paper
public void inactiveTick() { }
// Spigot end
private boolean isInLava;
private int lastLavaCheck = MinecraftServer.currentTick;
public Entity(World world) {
this.id = Entity.entityCount++;
this.passengers = Lists.newArrayList();
this.boundingBox = Entity.c;
this.width = 0.6F;
this.length = 1.8F;
this.ax = 1;
this.random = SHARED_RANDOM; // Paper
this.fireTicks = -this.getMaxFireTicks();
this.justCreated = true;
this.uniqueID = MathHelper.a(this.random);
this.ar = this.uniqueID.toString();
this.aF = new CommandObjectiveExecutor();
this.aG = HashObjSets.newMutableSet();
this.aI = new double[] { 0.0D, 0.0D, 0.0D};
this.world = world;
this.setPosition(0.0D, 0.0D, 0.0D);
if (world != null) {
this.dimension = world.worldProvider.getDimensionManager().getDimensionID();
// Spigot start
this.defaultActivationState = org.spigotmc.ActivationRange.initializeEntityActivationState(this, world.spigotConfig);
} else {
this.defaultActivationState = false;
}
// Spigot end
this.datawatcher = new DataWatcher(this);
this.datawatcher.register(Entity.Z, Byte.valueOf((byte) 0));
this.datawatcher.register(Entity.az, Integer.valueOf(300));
this.datawatcher.register(Entity.aB, Boolean.valueOf(false));
this.datawatcher.register(Entity.aA, "");
this.datawatcher.register(Entity.aC, Boolean.valueOf(false));
this.datawatcher.register(Entity.aD, Boolean.valueOf(false));
this.i();
}
public int getId() {
return this.id;
}
public void h(int i) {
this.id = i;
}
public Set<String> P() {
return this.aG;
}
public boolean a(String s) {
if (this.aG.size() >= 1024) {
return false;
} else {
this.aG.add(s);
return true;
}
}
public boolean b(String s) {
return this.aG.remove(s);
}
public void Q() {
this.die();
}
protected abstract void i();
public DataWatcher getDataWatcher() {
return this.datawatcher;
}
@Override
public boolean equals(Object object) {
return object instanceof Entity ? ((Entity) object).id == this.id : false;
}
@Override
public int hashCode() {
return this.id;
}
public void die() {
this.dead = true;
}
public void b(boolean flag) {}
public void setSize(float f, float f1) {
if (f != this.width || f1 != this.length) {
float f2 = this.width;
this.width = f;
this.length = f1;
if (this.width < f2) {
double d0 = f / 2.0D;
this.a(new AxisAlignedBB(this.locX - d0, this.locY, this.locZ - d0, this.locX + d0, this.locY + this.length, this.locZ + d0));
return;
}
AxisAlignedBB axisalignedbb = this.getBoundingBox();
this.a(new AxisAlignedBB(axisalignedbb.a, axisalignedbb.b, axisalignedbb.c, axisalignedbb.a + this.width, axisalignedbb.b + this.length, axisalignedbb.c + this.width));
if (this.width > f2 && !this.justCreated && !this.world.isClientSide) {
this.move(EnumMoveType.SELF, f2 - this.width, 0.0D, f2 - this.width);
}
}
}
public 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("Infinite yaw (Hacking?)"); //Spigot "Nope" -> Descriptive reason
}
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("Infinite pitch (Hacking?)"); //Spigot "Nope" -> Descriptive reason
}
f1 = 0;
}
// CraftBukkit end
this.yaw = f % 360.0F;
this.pitch = f1 % 360.0F;
}
public void setPosition(double d0, double d1, double d2) {
this.locX = d0;
this.locY = d1;
this.locZ = d2;
float f = this.width / 2.0F;
float f1 = this.length;
this.a(new AxisAlignedBB(d0 - f, d1, d2 - f, d0 + f, d1 + f1, d2 + f));
}
public void A_() {
if (!this.world.isClientSide) {
this.setFlag(6, this.aO());
}
this.U();
}
// CraftBukkit start
public void postTick() {
// 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
if (!this.world.isClientSide && this.world instanceof WorldServer) {
this.world.methodProfiler.a("portal");
if (this.ak) {
MinecraftServer minecraftserver = this.world.getMinecraftServer();
if (true || minecraftserver.getAllowNether()) { // CraftBukkit
if (!this.isPassenger()) {
int i = this.V();
if (this.al++ >= i) {
this.al = i;
this.portalCooldown = this.aE();
byte b0;
if (this.world.worldProvider.getDimensionManager().getDimensionID() == -1) {
b0 = 0;
} else {
b0 = -1;
}
this.c(b0);
}
}
this.ak = false;
}
} else {
if (this.al > 0) {
this.al -= 4;
}
if (this.al < 0) {
this.al = 0;
}
}
this.H();
}
}
// CraftBukkit end
public void U() {
this.world.methodProfiler.a("entityBaseTick");
if (this.isPassenger() && this.bB().dead) {
this.stopRiding();
}
if (this.j > 0) {
--this.j;
}
this.I = this.J;
this.lastX = this.locX;
this.lastY = this.locY;
this.lastZ = this.locZ;
this.lastPitch = this.pitch;
this.lastYaw = this.yaw;
// Moved up to postTick
/*
if (!this.world.isClientSide && this.world instanceof WorldServer) {
this.world.methodProfiler.a("portal");
if (this.ak) {
MinecraftServer minecraftserver = this.world.getMinecraftServer();
if (true || minecraftserver.getAllowNether()) { // CraftBukkit
if (!this.isPassenger()) {
int i = this.V();
if (this.al++ >= i) {
this.al = i;
this.portalCooldown = this.aE();
byte b0;
if (this.world.worldProvider.getDimensionManager().getDimensionID() == -1) {
b0 = 0;
} else {
b0 = -1;
}
this.c(b0);
}
}
this.ak = false;
}
} else {
if (this.al > 0) {
this.al -= 4;
}
if (this.al < 0) {
this.al = 0;
}
}
this.H();
}
*/
this.am();
this.ak();
if (this.world.isClientSide) {
this.extinguish();
} else if (this.fireTicks > 0) {
if (this.fireProof) {
this.fireTicks -= 4;
if (this.fireTicks < 0) {
this.extinguish();
}
} else {
if (this.fireTicks % 20 == 0) {
this.damageEntity(DamageSource.BURN, 1.0F);
}
--this.fireTicks;
}
}
if (this.ao()) {
this.burnFromLava();
this.fallDistance *= 0.5F;
}
// Paper start - Configurable nether ceiling damage
// Extracted to own function
/*
if (this.locY < -64.0D) {
this.Y();
}
*/
this.checkAndDoHeightDamage();
// Paper end
if (!this.world.isClientSide) {
this.setFlag(0, this.fireTicks > 0);
}
this.justCreated = false;
}
// Paper start - Configurable top of nether void damage
private boolean paperNetherCheck() {
return this.world.paperConfig.netherVoidTopDamage && this.world.getWorld().getEnvironment() == org.bukkit.World.Environment.NETHER && this.locY >= 128.0D;
}
protected void checkAndDoHeightDamage() {
if (this.locY < -64.0D || paperNetherCheck()) {
this.kill();
}
}
// Paper end
protected void H() {
if (this.portalCooldown > 0) {
--this.portalCooldown;
}
}
public int V() {
return 1;
}
protected void burnFromLava() {
if (!this.fireProof && !this.isInWater()) {
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);
}
}
public void setOnFire(int i) {
int j = i * 20;
if (this instanceof EntityLiving) {
j = EnchantmentProtection.a((EntityLiving) this, j);
}
if (this.fireTicks < j) {
this.fireTicks = j;
}
}
public void extinguish() {
this.fireTicks = 0;
}
protected final void kill() { this.Y(); } // Paper - OBFHELPER
protected void Y() {
this.die();
}
public boolean c(double d0, double d1, double d2) {
AxisAlignedBB axisalignedbb = this.getBoundingBox().d(d0, d1, d2);
return this.b(axisalignedbb);
}
private boolean b(AxisAlignedBB axisalignedbb) {
return this.world.getCubes(this, axisalignedbb).isEmpty() && !this.world.containsLiquid(axisalignedbb);
}
public void move(EnumMoveType enummovetype, double d0, double d1, double d2) {
if (this.noclip) {
this.a(this.getBoundingBox().d(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
if (enummovetype == EnumMoveType.PISTON) {
long i = this.world.getTime();
if (i != this.aJ) {
Arrays.fill(this.aI, 0.0D);
this.aJ = i;
}
int j;
double d3;
if (d0 != 0.0D) {
j = EnumDirection.EnumAxis.X.ordinal();
d3 = MathHelper.a(d0 + this.aI[j], -0.51D, 0.51D);
d0 = d3 - this.aI[j];
this.aI[j] = d3;
if (Math.abs(d0) <= 9.999999747378752E-6D) {
return;
}
} else if (d1 != 0.0D) {
j = EnumDirection.EnumAxis.Y.ordinal();
d3 = MathHelper.a(d1 + this.aI[j], -0.51D, 0.51D);
d1 = d3 - this.aI[j];
this.aI[j] = d3;
if (Math.abs(d1) <= 9.999999747378752E-6D) {
return;
}
} else {
if (d2 == 0.0D) {
return;
}
j = EnumDirection.EnumAxis.Z.ordinal();
d3 = MathHelper.a(d2 + this.aI[j], -0.51D, 0.51D);
d2 = d3 - this.aI[j];
this.aI[j] = d3;
if (Math.abs(d2) <= 9.999999747378752E-6D) {
return;
}
}
}
this.world.methodProfiler.a("move");
double d4 = this.locX;
double d5 = this.locY;
double d6 = this.locZ;
if (this.E) {
this.E = false;
d0 *= 0.25D;
d1 *= 0.05000000074505806D;
d2 *= 0.25D;
this.motX = 0.0D;
this.motY = 0.0D;
this.motZ = 0.0D;
}
double d7 = d0;
double d8 = d1;
double d9 = d2;
if ((enummovetype == EnumMoveType.SELF || enummovetype == EnumMoveType.PLAYER) && this.onGround && this.isSneaking() && this instanceof EntityHuman) {
for (double d10 = 0.05D; d0 != 0.0D && this.world.getCubes(this, this.getBoundingBox().d(d0, (-this.P), 0.0D)).isEmpty(); d7 = d0) {
if (d0 < 0.05D && d0 >= -0.05D) {
d0 = 0.0D;
} else if (d0 > 0.0D) {
d0 -= 0.05D;
} else {
d0 += 0.05D;
}
}
for (; d2 != 0.0D && this.world.getCubes(this, this.getBoundingBox().d(0.0D, (-this.P), d2)).isEmpty(); d9 = d2) {
if (d2 < 0.05D && d2 >= -0.05D) {
d2 = 0.0D;
} else if (d2 > 0.0D) {
d2 -= 0.05D;
} else {
d2 += 0.05D;
}
}
for (; d0 != 0.0D && d2 != 0.0D && this.world.getCubes(this, this.getBoundingBox().d(d0, (-this.P), d2)).isEmpty(); d9 = d2) {
if (d0 < 0.05D && d0 >= -0.05D) {
d0 = 0.0D;
} else if (d0 > 0.0D) {
d0 -= 0.05D;
} else {
d0 += 0.05D;
}
d7 = d0;
if (d2 < 0.05D && d2 >= -0.05D) {
d2 = 0.0D;
} else if (d2 > 0.0D) {
d2 -= 0.05D;
} else {
d2 += 0.05D;
}
}
}
List list = this.world.getCubes(this, this.getBoundingBox().b(d0, d1, d2));
AxisAlignedBB axisalignedbb = this.getBoundingBox();
int k;
int l;
if (d1 != 0.0D) {
k = 0;
for (l = list.size(); k < l; ++k) {
d1 = ((AxisAlignedBB) list.get(k)).b(this.getBoundingBox(), d1);
}
this.a(this.getBoundingBox().d(0.0D, d1, 0.0D));
}
if (d0 != 0.0D) {
k = 0;
for (l = list.size(); k < l; ++k) {
d0 = ((AxisAlignedBB) list.get(k)).a(this.getBoundingBox(), d0);
}
if (d0 != 0.0D) {
this.a(this.getBoundingBox().d(d0, 0.0D, 0.0D));
}
}
if (d2 != 0.0D) {
k = 0;
for (l = list.size(); k < l; ++k) {
d2 = ((AxisAlignedBB) list.get(k)).c(this.getBoundingBox(), d2);
}
if (d2 != 0.0D) {
this.a(this.getBoundingBox().d(0.0D, 0.0D, d2));
}
}
boolean flag = this.onGround || d1 != d8 && d1 < 0.0D; // CraftBukkit - decompile error
double d11;
if (this.P > 0.0F && flag && (d7 != d0 || d9 != d2)) {
double d12 = d0;
double d13 = d1;
double d14 = d2;
AxisAlignedBB axisalignedbb1 = this.getBoundingBox();
this.a(axisalignedbb);
d1 = this.P;
List list1 = this.world.getCubes(this, this.getBoundingBox().b(d7, d1, d9));
AxisAlignedBB axisalignedbb2 = this.getBoundingBox();
AxisAlignedBB axisalignedbb3 = axisalignedbb2.b(d7, 0.0D, d9);
d11 = d1;
int i1 = 0;
for (int j1 = list1.size(); i1 < j1; ++i1) {
d11 = ((AxisAlignedBB) list1.get(i1)).b(axisalignedbb3, d11);
}
axisalignedbb2 = axisalignedbb2.d(0.0D, d11, 0.0D);
double d15 = d7;
int k1 = 0;
for (int l1 = list1.size(); k1 < l1; ++k1) {
d15 = ((AxisAlignedBB) list1.get(k1)).a(axisalignedbb2, d15);
}
axisalignedbb2 = axisalignedbb2.d(d15, 0.0D, 0.0D);
double d16 = d9;
int i2 = 0;
for (int j2 = list1.size(); i2 < j2; ++i2) {
d16 = ((AxisAlignedBB) list1.get(i2)).c(axisalignedbb2, d16);
}
axisalignedbb2 = axisalignedbb2.d(0.0D, 0.0D, d16);
AxisAlignedBB axisalignedbb4 = this.getBoundingBox();
double d17 = d1;
int k2 = 0;
for (int l2 = list1.size(); k2 < l2; ++k2) {
d17 = ((AxisAlignedBB) list1.get(k2)).b(axisalignedbb4, d17);
}
axisalignedbb4 = axisalignedbb4.d(0.0D, d17, 0.0D);
double d18 = d7;
int i3 = 0;
for (int j3 = list1.size(); i3 < j3; ++i3) {
d18 = ((AxisAlignedBB) list1.get(i3)).a(axisalignedbb4, d18);
}
axisalignedbb4 = axisalignedbb4.d(d18, 0.0D, 0.0D);
double d19 = d9;
int k3 = 0;
for (int l3 = list1.size(); k3 < l3; ++k3) {
d19 = ((AxisAlignedBB) list1.get(k3)).c(axisalignedbb4, d19);
}
axisalignedbb4 = axisalignedbb4.d(0.0D, 0.0D, d19);
double d20 = d15 * d15 + d16 * d16;
double d21 = d18 * d18 + d19 * d19;
if (d20 > d21) {
d0 = d15;
d2 = d16;
d1 = -d11;
this.a(axisalignedbb2);
} else {
d0 = d18;
d2 = d19;
d1 = -d17;
this.a(axisalignedbb4);
}
int i4 = 0;
for (int j4 = list1.size(); i4 < j4; ++i4) {
d1 = ((AxisAlignedBB) list1.get(i4)).b(this.getBoundingBox(), d1);
}
this.a(this.getBoundingBox().d(0.0D, d1, 0.0D));
if (d12 * d12 + d14 * d14 >= d0 * d0 + d2 * d2) {
d0 = d12;
d1 = d13;
d2 = d14;
this.a(axisalignedbb1);
}
}
this.world.methodProfiler.a("rest");
this.recalcPosition();
this.positionChanged = d7 != d0 || d9 != d2;
this.B = d1 != d8; // CraftBukkit - decompile error
this.onGround = this.B && d8 < 0.0D;
this.C = this.positionChanged || this.B;
l = MathHelper.floor(this.locX);
int k4 = MathHelper.floor(this.locY - 0.20000000298023224D);
int l4 = MathHelper.floor(this.locZ);
BlockPosition blockposition = new BlockPosition(l, k4, l4);
IBlockData iblockdata = this.world.getType(blockposition);
if (iblockdata.getMaterial() == Material.AIR) {
BlockPosition blockposition1 = blockposition.down();
IBlockData iblockdata1 = this.world.getType(blockposition1);
Block block = iblockdata1.getBlock();
if (block instanceof BlockFence || block instanceof BlockCobbleWall || block instanceof BlockFenceGate) {
iblockdata = iblockdata1;
blockposition = blockposition1;
}
}
this.a(d1, this.onGround, iblockdata, blockposition);
if (d7 != d0) {
this.motX = 0.0D;
}
if (d9 != d2) {
this.motZ = 0.0D;
}
Block block1 = iblockdata.getBlock();
if (d8 != d1) {
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);
}
if (bl.getType() != org.bukkit.Material.AIR) {
VehicleBlockCollisionEvent event = new VehicleBlockCollisionEvent(vehicle, bl);
world.getServer().getPluginManager().callEvent(event);
}
}
// CraftBukkit end
if (this.playStepSound() && (!this.onGround || !this.isSneaking() || !(this instanceof EntityHuman)) && !this.isPassenger()) {
double d22 = this.locX - d4;
double d23 = this.locY - d5;
d11 = this.locZ - d6;
if (block1 != Blocks.LADDER) {
d23 = 0.0D;
}
if (block1 != null && this.onGround) {
block1.stepOn(this.world, blockposition, this);
}
this.J = (float) (this.J + MathHelper.sqrt(d22 * d22 + d11 * d11) * 0.6D);
this.K = (float) (this.K + MathHelper.sqrt(d22 * d22 + d23 * d23 + d11 * d11) * 0.6D);
if (this.K > this.ax && iblockdata.getMaterial() != Material.AIR) {
this.ax = (int) this.K + 1;
if (this.isInWater()) {
Entity entity = this.isVehicle() && this.bw() != null ? this.bw() : this;
float f = entity == this ? 0.35F : 0.4F;
float f1 = MathHelper.sqrt(entity.motX * entity.motX * 0.20000000298023224D + entity.motY * entity.motY + entity.motZ * entity.motZ * 0.20000000298023224D) * f;
if (f1 > 1.0F) {
f1 = 1.0F;
}
this.a(this.aa(), f1, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F);
} else {
this.a(blockposition, block1);
}
}
}
// CraftBukkit start - Move to the top of the method
/*
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);
}
*/
// CraftBukkit end
boolean flag1 = this.ai();
if (this.world.e(this.getBoundingBox().shrink(0.001D)) && !this.isInWater()) {
this.burn(1);
if (!flag1) {
++this.fireTicks;
if (this.fireTicks == 0) {
// CraftBukkit start
EntityCombustEvent event = new org.bukkit.event.entity.EntityCombustByBlockEvent(null, getBukkitEntity(), 8);
world.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) {
this.setOnFire(event.getDuration());
}
// CraftBukkit end
}
}
} else if (this.fireTicks <= 0) {
this.fireTicks = -this.getMaxFireTicks();
}
if (flag1 && this.isBurning()) {
this.a(SoundEffects.bQ, 0.7F, 1.6F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F);
this.fireTicks = -this.getMaxFireTicks();
}
}
}
public void recalcPosition() {
AxisAlignedBB axisalignedbb = this.getBoundingBox();
this.locX = (axisalignedbb.a + axisalignedbb.d) / 2.0D;
this.locY = axisalignedbb.b;
this.locZ = (axisalignedbb.c + axisalignedbb.f) / 2.0D;
}
protected SoundEffect aa() {
return SoundEffects.bU;
}
protected SoundEffect ab() {
return SoundEffects.bT;
}
protected void checkBlockCollisions() {
AxisAlignedBB axisalignedbb = this.getBoundingBox();
BlockPosition.PooledBlockPosition blockposition_pooledblockposition = BlockPosition.PooledBlockPosition.d(axisalignedbb.a + 0.001D, axisalignedbb.b + 0.001D, axisalignedbb.c + 0.001D);
BlockPosition.PooledBlockPosition blockposition_pooledblockposition1 = BlockPosition.PooledBlockPosition.d(axisalignedbb.d - 0.001D, axisalignedbb.e - 0.001D, axisalignedbb.f - 0.001D);
BlockPosition.PooledBlockPosition blockposition_pooledblockposition2 = BlockPosition.PooledBlockPosition.s();
if (this.world.areChunksLoadedBetween(blockposition_pooledblockposition, blockposition_pooledblockposition1)) {
for (int i = blockposition_pooledblockposition.getX(); i <= blockposition_pooledblockposition1.getX(); ++i) {
for (int j = blockposition_pooledblockposition.getY(); j <= blockposition_pooledblockposition1.getY(); ++j) {
for (int k = blockposition_pooledblockposition.getZ(); k <= blockposition_pooledblockposition1.getZ(); ++k) {
blockposition_pooledblockposition2.f(i, j, k);
IBlockData iblockdata = this.world.getType(blockposition_pooledblockposition2);
try {
iblockdata.getBlock().a(this.world, blockposition_pooledblockposition2, iblockdata, this);
} catch (Throwable throwable) {
CrashReport crashreport = CrashReport.a(throwable, "Colliding entity with block");
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Block being collided with");
CrashReportSystemDetails.a(crashreportsystemdetails, blockposition_pooledblockposition2, iblockdata);
throw new ReportedException(crashreport);
}
}
}
}
}
blockposition_pooledblockposition.t();
blockposition_pooledblockposition1.t();
blockposition_pooledblockposition2.t();
}
protected void a(BlockPosition blockposition, Block block) {
SoundEffectType soundeffecttype = block.getStepSound();
if (this.world.getType(blockposition.up()).getBlock() == Blocks.SNOW_LAYER) {
soundeffecttype = Blocks.SNOW_LAYER.getStepSound();
this.a(soundeffecttype.d(), soundeffecttype.a() * 0.15F, soundeffecttype.b());
} else if (!block.getBlockData().getMaterial().isLiquid()) {
this.a(soundeffecttype.d(), soundeffecttype.a() * 0.15F, soundeffecttype.b());
}
}
public void a(SoundEffect soundeffect, float f, float f1) {
if (!this.isSilent()) {
this.world.a((EntityHuman) null, this.locX, this.locY, this.locZ, soundeffect, this.bC(), f, f1);
}
}
public boolean isSilent() {
return this.datawatcher.get(Entity.aC).booleanValue();
}
public void setSilent(boolean flag) {
this.datawatcher.set(Entity.aC, Boolean.valueOf(flag));
}
public boolean isNoGravity() {
return this.datawatcher.get(Entity.aD).booleanValue();
}
public void setNoGravity(boolean flag) {
this.datawatcher.set(Entity.aD, Boolean.valueOf(flag));
}
protected boolean playStepSound() {
return true;
}
protected void a(double d0, boolean flag, IBlockData iblockdata, BlockPosition blockposition) {
if (flag) {
if (this.fallDistance > 0.0F) {
iblockdata.getBlock().fallOn(this.world, blockposition, this, this.fallDistance);
}
this.fallDistance = 0.0F;
} else if (d0 < 0.0D) {
this.fallDistance = (float) (this.fallDistance - d0);
}
}
@Nullable
public AxisAlignedBB ag() {
return null;
}
protected void burn(float i) { // CraftBukkit - int -> float
if (!this.fireProof) {
this.damageEntity(DamageSource.FIRE, i);
}
}
public final boolean isFireProof() {
return this.fireProof;
}
public void e(float f, float f1) {
if (this.isVehicle()) {
Iterator iterator = this.bx().iterator();
while (iterator.hasNext()) {
Entity entity = (Entity) iterator.next();
entity.e(f, f1);
}
}
}
public boolean ai() {
if (this.inWater) {
return true;
} else {
BlockPosition.PooledBlockPosition blockposition_pooledblockposition = BlockPosition.PooledBlockPosition.d(this.locX, this.locY, this.locZ);
if (!this.world.isRainingAt(blockposition_pooledblockposition) && !this.world.isRainingAt(blockposition_pooledblockposition.e(this.locX, this.locY + this.length, this.locZ))) {
blockposition_pooledblockposition.t();
return false;
} else {
blockposition_pooledblockposition.t();
return true;
}
}
}
public boolean isInWater() {
return this.inWater;
}
public boolean ak() {
// Paper start - OBFHELPER
return this.doWaterMovement();
}
public boolean doWaterMovement() {
// Paper end
if (this.bB() instanceof EntityBoat) {
this.inWater = false;
} else if (this.world.a(this.getBoundingBox().grow(0.0D, -0.4000000059604645D, 0.0D).shrink(0.001D), Material.WATER, this)) {
if (!this.inWater && !this.justCreated) {
this.al();
}
this.fallDistance = 0.0F;
this.inWater = true;
this.extinguish();
} else {
this.inWater = false;
}
return this.inWater;
}
protected void al() {
Entity entity = this.isVehicle() && this.bw() != null ? this.bw() : this;
float f = entity == this ? 0.2F : 0.9F;
float f1 = MathHelper.sqrt(entity.motX * entity.motX * 0.20000000298023224D + entity.motY * entity.motY + entity.motZ * entity.motZ * 0.20000000298023224D) * f;
if (f1 > 1.0F) {
f1 = 1.0F;
}
this.a(this.ab(), f1, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F);
float f2 = MathHelper.floor(this.getBoundingBox().b);
int i;
float f3;
float f4;
for (i = 0; i < 1.0F + this.width * 20.0F; ++i) {
f3 = (this.random.nextFloat() * 2.0F - 1.0F) * this.width;
f4 = (this.random.nextFloat() * 2.0F - 1.0F) * this.width;
this.world.addParticle(EnumParticle.WATER_BUBBLE, this.locX + f3, f2 + 1.0F, this.locZ + f4, this.motX, this.motY - this.random.nextFloat() * 0.2F, this.motZ, new int[0]);
}
for (i = 0; i < 1.0F + this.width * 20.0F; ++i) {
f3 = (this.random.nextFloat() * 2.0F - 1.0F) * this.width;
f4 = (this.random.nextFloat() * 2.0F - 1.0F) * this.width;
this.world.addParticle(EnumParticle.WATER_SPLASH, this.locX + f3, f2 + 1.0F, this.locZ + f4, this.motX, this.motY, this.motZ, new int[0]);
}
}
public void am() {
if (this.isSprinting() && !this.isInWater()) {
this.an();
}
}
protected void an() {
int i = MathHelper.floor(this.locX);
int j = MathHelper.floor(this.locY - 0.20000000298023224D);
int k = MathHelper.floor(this.locZ);
BlockPosition blockposition = new BlockPosition(i, j, k);
IBlockData iblockdata = this.world.getType(blockposition);
if (iblockdata.j() != EnumRenderType.INVISIBLE) {
this.world.addParticle(EnumParticle.BLOCK_CRACK, this.locX + (this.random.nextFloat() - 0.5D) * this.width, this.getBoundingBox().b + 0.1D, this.locZ + (this.random.nextFloat() - 0.5D) * this.width, -this.motX * 4.0D, 1.5D, -this.motZ * 4.0D, new int[] { Block.getCombinedId(iblockdata)});
}
}
public boolean a(Material material) {
if (this.bB() instanceof EntityBoat) {
return false;
} else {
double d0 = this.locY + this.getHeadHeight();
BlockPosition blockposition = new BlockPosition(this.locX, d0, this.locZ);
IBlockData iblockdata = this.world.getType(blockposition);
if (iblockdata.getMaterial() == material) {
float f = BlockFluids.e(iblockdata.getBlock().toLegacyData(iblockdata)) - 0.11111111F;
float f1 = blockposition.getY() + 1 - f;
boolean flag = d0 < f1;
return !flag && this instanceof EntityHuman ? false : flag;
} else {
return false;
}
}
}
public boolean isInLava() { return this.ao(); } // OBFHELPER
public boolean ao() {
// Only check for lava once per tick
if (this.lastLavaCheck != MinecraftServer.currentTick) {
this.lastLavaCheck = MinecraftServer.currentTick;
this.isInLava = this.world.a(this.getBoundingBox().grow(-0.10000000149011612D, -0.4000000059604645D, -0.10000000149011612D), Material.LAVA);
}
return this.isInLava;
}
public void a(float f, float f1, float f2) {
float f3 = f * f + f1 * f1;
if (f3 >= 1.0E-4F) {
f3 = MathHelper.c(f3);
if (f3 < 1.0F) {
f3 = 1.0F;
}
f3 = f2 / f3;
f *= f3;
f1 *= f3;
float f4 = MathHelper.sin(this.yaw * 0.017453292F);
float f5 = MathHelper.cos(this.yaw * 0.017453292F);
this.motX += f * f5 - f1 * f4;
this.motZ += f1 * f5 + f * f4;
}
}
public float e(float f) {
BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(MathHelper.floor(this.locX), 0, MathHelper.floor(this.locZ));
if (this.world.isLoaded(blockposition_mutableblockposition)) {
blockposition_mutableblockposition.p(MathHelper.floor(this.locY + this.getHeadHeight()));
return this.world.n(blockposition_mutableblockposition);
} else {
return 0.0F;
}
}
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;
}
public void setLocation(double d0, double d1, double d2, float f, float f1) {
this.locX = MathHelper.a(d0, -3.0E7D, 3.0E7D);
this.locY = d1;
this.locZ = MathHelper.a(d2, -3.0E7D, 3.0E7D);
this.lastX = this.locX;
this.lastY = this.locY;
this.lastZ = this.locZ;
f1 = MathHelper.a(f1, -90.0F, 90.0F);
this.yaw = f;
this.pitch = f1;
this.lastYaw = this.yaw;
this.lastPitch = this.pitch;
double d3 = this.lastYaw - f;
if (d3 < -180.0D) {
this.lastYaw += 360.0F;
}
if (d3 >= 180.0D) {
this.lastYaw -= 360.0F;
}
this.setPosition(this.locX, this.locY, this.locZ);
this.setYawPitch(f, f1);
}
public void setPositionRotation(BlockPosition blockposition, float f, float f1) {
this.setPositionRotation(blockposition.getX() + 0.5D, blockposition.getY(), blockposition.getZ() + 0.5D, f, f1);
}
public void setPositionRotation(double d0, double d1, double d2, float f, float f1) {
this.locX = d0;
this.locY = d1;
this.locZ = d2;
this.lastX = this.locX;
this.lastY = this.locY;
this.lastZ = this.locZ;
this.M = this.locX;
this.N = this.locY;
this.O = this.locZ;
this.yaw = f;
this.pitch = f1;
this.setPosition(this.locX, this.locY, this.locZ);
}
public float g(Entity entity) {
float f = (float) (this.locX - entity.locX);
float f1 = (float) (this.locY - entity.locY);
float f2 = (float) (this.locZ - entity.locZ);
return MathHelper.c(f * f + f1 * f1 + f2 * f2);
}
public double d(double d0, double d1, double d2) {
double d3 = this.locX - d0;
double d4 = this.locY - d1;
double d5 = this.locZ - d2;
return d3 * d3 + d4 * d4 + d5 * d5;
}
public double c(BlockPosition blockposition) {
return blockposition.distanceSquared(this.locX, this.locY, this.locZ);
}
public double d(BlockPosition blockposition) {
return blockposition.g(this.locX, this.locY, this.locZ);
}
public double e(double d0, double d1, double d2) {
// Paper start - OBFHELPER
return this.getDistance(d0, d1, d2);
}
public double getDistance(double d0, double d1, double d2) {
// Paper end
double d3 = this.locX - d0;
double d4 = this.locY - d1;
double d5 = this.locZ - d2;
return MathHelper.sqrt(d3 * d3 + d4 * d4 + d5 * d5);
}
public double h(Entity entity) {
double d0 = this.locX - entity.locX;
double d1 = this.locY - entity.locY;
double d2 = this.locZ - entity.locZ;
return d0 * d0 + d1 * d1 + d2 * d2;
}
public void d(EntityHuman entityhuman) {}
public void collide(Entity entity) {
if (!this.x(entity)) {
if (!entity.noclip && !this.noclip) {
double d0 = entity.locX - this.locX;
double d1 = entity.locZ - this.locZ;
double d2 = MathHelper.a(d0, d1);
if (d2 >= 0.009999999776482582D) {
d2 = MathHelper.sqrt(d2);
d0 /= d2;
d1 /= d2;
double d3 = 1.0D / d2;
if (d3 > 1.0D) {
d3 = 1.0D;
}
d0 *= d3;
d1 *= d3;
d0 *= 0.05000000074505806D;
d1 *= 0.05000000074505806D;
d0 *= 1.0F - this.R;
d1 *= 1.0F - this.R;
if (!this.isVehicle()) {
this.f(-d0, 0.0D, -d1);
}
if (!entity.isVehicle()) {
entity.f(d0, 0.0D, d1);
}
}
}
}
}
public void f(double d0, double d1, double d2) {
// Paper start - OBFHELPER
this.addVelocity(d0, d1, d2);
}
public void addVelocity(double d0, double d1, double d2) {
this.motX += d0;
this.motY += d1;
this.motZ += d2;
this.impulse = true;
}
protected void ap() {
this.velocityChanged = true;
}
public boolean damageEntity(DamageSource damagesource, float f) {
if (this.isInvulnerable(damagesource)) {
return false;
} else {
this.ap();
return false;
}
}
public Vec3D f(float f) {
if (f == 1.0F) {
return this.f(this.pitch, this.yaw);
} else {
float f1 = this.lastPitch + (this.pitch - this.lastPitch) * f;
float f2 = this.lastYaw + (this.yaw - this.lastYaw) * f;
return this.f(f1, f2);
}
}
protected final Vec3D f(float f, float f1) {
float f2 = MathHelper.cos(-f1 * 0.017453292F - 3.1415927F);
float f3 = MathHelper.sin(-f1 * 0.017453292F - 3.1415927F);
float f4 = -MathHelper.cos(-f * 0.017453292F);
float f5 = MathHelper.sin(-f * 0.017453292F);
return new Vec3D(f3 * f4, f5, f2 * f4);
}
public Vec3D g(float f) {
if (f == 1.0F) {
return new Vec3D(this.locX, this.locY + this.getHeadHeight(), this.locZ);
} else {
double d0 = this.lastX + (this.locX - this.lastX) * f;
double d1 = this.lastY + (this.locY - this.lastY) * f + this.getHeadHeight();
double d2 = this.lastZ + (this.locZ - this.lastZ) * f;
return new Vec3D(d0, d1, d2);
}
}
public boolean isInteractable() {
return false;
}
public boolean isCollidable() {
return false;
}
public void b(Entity entity, int i) {}
public boolean c(NBTTagCompound nbttagcompound) {
String s = this.at();
if (!this.dead && s != null) {
nbttagcompound.setString("id", s);
this.e(nbttagcompound);
return true;
} else {
return false;
}
}
public boolean d(NBTTagCompound nbttagcompound) {
String s = this.at();
if (!this.dead && s != null && !this.isPassenger()) {
nbttagcompound.setString("id", s);
this.e(nbttagcompound);
return true;
} else {
return false;
}
}
public static void b(DataConverterManager dataconvertermanager) {
dataconvertermanager.a(DataConverterTypes.ENTITY, new DataInspector() {
@Override
public NBTTagCompound a(DataConverter dataconverter, NBTTagCompound nbttagcompound, int i) {
if (nbttagcompound.hasKeyOfType("Passengers", 9)) {
NBTTagList nbttaglist = nbttagcompound.getList("Passengers", 10);
for (int j = 0; j < nbttaglist.size(); ++j) {
nbttaglist.a(j, dataconverter.a(DataConverterTypes.ENTITY, nbttaglist.get(j), i));
}
}
return nbttagcompound;
}
});
}
public NBTTagCompound e(NBTTagCompound nbttagcompound) {
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);
nbttagcompound.setShort("Air", (short) this.getAirTicks());
nbttagcompound.setBoolean("OnGround", this.onGround);
nbttagcompound.setInt("Dimension", this.dimension);
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);
nbttagcompound.setInt("Spigot.ticksLived", this.ticksLived);
// CraftBukkit end
if (this.hasCustomName()) {
nbttagcompound.setString("CustomName", this.getCustomName());
}
if (this.getCustomNameVisible()) {
nbttagcompound.setBoolean("CustomNameVisible", this.getCustomNameVisible());
}
this.aF.b(nbttagcompound);
if (this.isSilent()) {
nbttagcompound.setBoolean("Silent", this.isSilent());
}
if (this.isNoGravity()) {
nbttagcompound.setBoolean("NoGravity", this.isNoGravity());
}
if (this.glowing) {
nbttagcompound.setBoolean("Glowing", this.glowing);
}
NBTTagList nbttaglist;
Iterator iterator;
if (this.aG.size() > 0) {
nbttaglist = new NBTTagList();
iterator = this.aG.iterator();
while (iterator.hasNext()) {
String s = (String) iterator.next();
nbttaglist.add(new NBTTagString(s));
}
nbttagcompound.set("Tags", nbttaglist);
}
this.b(nbttagcompound);
if (this.isVehicle()) {
nbttaglist = new NBTTagList();
iterator = this.bx().iterator();
while (iterator.hasNext()) {
Entity entity = (Entity) iterator.next();
NBTTagCompound nbttagcompound1 = new NBTTagCompound();
if (entity.c(nbttagcompound1)) {
nbttaglist.add(nbttagcompound1);
}
}
if (!nbttaglist.isEmpty()) {
nbttagcompound.set("Passengers", nbttaglist);
}
}
// Paper start - Save the entity's origin location
if (origin != null) {
nbttagcompound.set("Paper.Origin", this.createList(origin.getX(), origin.getY(), origin.getZ()));
}
// Paper end
return nbttagcompound;
} catch (Throwable throwable) {
CrashReport crashreport = CrashReport.a(throwable, "Saving entity NBT");
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity being saved");
this.appendEntityCrashDetails(crashreportsystemdetails);
throw new ReportedException(crashreport);
}
}
public void f(NBTTagCompound nbttagcompound) {
try {
NBTTagList nbttaglist = nbttagcompound.getList("Pos", 6);
NBTTagList nbttaglist1 = nbttagcompound.getList("Motion", 6);
NBTTagList nbttaglist2 = nbttagcompound.getList("Rotation", 5);
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;
}
if (Math.abs(this.motY) > 10.0D) {
this.motY = 0.0D;
}
if (Math.abs(this.motZ) > 10.0D) {
this.motZ = 0.0D;
}
// CraftBukkit end */
this.locX = nbttaglist.e(0);
this.locY = nbttaglist.e(1);
this.locZ = nbttaglist.e(2);
this.M = this.locX;
this.N = this.locY;
this.O = this.locZ;
this.lastX = this.locX;
this.lastY = this.locY;
this.lastZ = this.locZ;
this.yaw = nbttaglist2.f(0);
this.pitch = nbttaglist2.f(1);
this.lastYaw = this.yaw;
this.lastPitch = this.pitch;
this.h(this.yaw);
this.i(this.yaw);
this.fallDistance = nbttagcompound.getFloat("FallDistance");
this.fireTicks = nbttagcompound.getShort("Fire");
this.setAirTicks(nbttagcompound.getShort("Air"));
this.onGround = nbttagcompound.getBoolean("OnGround");
if (nbttagcompound.hasKey("Dimension")) {
this.dimension = nbttagcompound.getInt("Dimension");
}
this.invulnerable = nbttagcompound.getBoolean("Invulnerable");
this.portalCooldown = nbttagcompound.getInt("PortalCooldown");
if (nbttagcompound.b("UUID")) {
this.uniqueID = nbttagcompound.a("UUID");
this.ar = this.uniqueID.toString();
}
this.setPosition(this.locX, this.locY, this.locZ);
this.setYawPitch(this.yaw, this.pitch);
if (nbttagcompound.hasKeyOfType("CustomName", 8)) {
this.setCustomName(nbttagcompound.getString("CustomName"));
}
this.setCustomNameVisible(nbttagcompound.getBoolean("CustomNameVisible"));
this.aF.a(nbttagcompound);
this.setSilent(nbttagcompound.getBoolean("Silent"));
this.setNoGravity(nbttagcompound.getBoolean("NoGravity"));
this.g(nbttagcompound.getBoolean("Glowing"));
if (nbttagcompound.hasKeyOfType("Tags", 9)) {
this.aG.clear();
NBTTagList nbttaglist3 = nbttagcompound.getList("Tags", 8);
int i = Math.min(nbttaglist3.size(), 1024);
for (int j = 0; j < i; ++j) {
this.aG.add(nbttaglist3.getString(j));
}
}
this.a(nbttagcompound);
if (this.as()) {
this.setPosition(this.locX, this.locY, this.locZ);
}
// CraftBukkit start
if (this instanceof EntityLiving) {
EntityLiving entity = (EntityLiving) this;
this.ticksLived = nbttagcompound.getInt("Spigot.ticksLived");
// 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
// Paper start - Restore the entity's origin location
NBTTagList originTag = nbttagcompound.getList("Paper.Origin", 6);
if (!originTag.isEmpty()) {
origin = new Location(world.getWorld(), originTag.e(0), originTag.e(1), originTag.e(2));
}
// Paper end
} catch (Throwable throwable) {
CrashReport crashreport = CrashReport.a(throwable, "Loading entity NBT");
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity being loaded");
this.appendEntityCrashDetails(crashreportsystemdetails);
throw new ReportedException(crashreport);
}
}
protected boolean as() {
return true;
}
@Nullable
protected final String at() {
MinecraftKey minecraftkey = EntityTypes.a(this);
return minecraftkey == null ? null : minecraftkey.toString();
}
protected abstract void a(NBTTagCompound nbttagcompound);
protected abstract void b(NBTTagCompound nbttagcompound);
protected NBTTagList createList(double... adouble) { return a(adouble); } // Paper - OBFHELPER
protected NBTTagList a(double... adouble) {
NBTTagList nbttaglist = new NBTTagList();
double[] adouble1 = adouble;
int i = adouble.length;
for (int j = 0; j < i; ++j) {
double d0 = adouble1[j];
nbttaglist.add(new NBTTagDouble(d0));
}
return nbttaglist;
}
protected NBTTagList a(float... afloat) {
NBTTagList nbttaglist = new NBTTagList();
float[] afloat1 = afloat;
int i = afloat.length;
for (int j = 0; j < i; ++j) {
float f = afloat1[j];
nbttaglist.add(new NBTTagFloat(f));
}
return nbttaglist;
}
@Nullable
public EntityItem a(Item item, int i) {
return this.a(item, i, 0.0F);
}
@Nullable
public EntityItem a(Item item, int i, float f) {
return this.a(new ItemStack(item, i, 0), f);
}
@Nullable
public EntityItem a(ItemStack itemstack, float f) {
if (itemstack.isEmpty()) {
return null;
} else {
// CraftBukkit start - Capture drops for death event
if (this instanceof EntityLiving && !((EntityLiving) this).forceDrops) {
((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 + f, this.locZ, itemstack);
entityitem.q();
this.world.addEntity(entityitem);
return entityitem;
}
}
public boolean isAlive() {
return !this.dead;
}
public boolean inBlock() {
if (this.noclip) {
return false;
} else {
BlockPosition.PooledBlockPosition blockposition_pooledblockposition = BlockPosition.PooledBlockPosition.s();
for (int i = 0; i < 8; ++i) {
int j = MathHelper.floor(this.locY + ((i >> 0) % 2 - 0.5F) * 0.1F + this.getHeadHeight());
int k = MathHelper.floor(this.locX + ((i >> 1) % 2 - 0.5F) * this.width * 0.8F);
int l = MathHelper.floor(this.locZ + ((i >> 2) % 2 - 0.5F) * this.width * 0.8F);
if (blockposition_pooledblockposition.getX() != k || blockposition_pooledblockposition.getY() != j || blockposition_pooledblockposition.getZ() != l) {
blockposition_pooledblockposition.f(k, j, l);
if (this.world.getType(blockposition_pooledblockposition).s()) {
blockposition_pooledblockposition.t();
return true;
}
}
}
blockposition_pooledblockposition.t();
return false;
}
}
public boolean b(EntityHuman entityhuman, EnumHand enumhand) {
return false;
}
@Nullable
public AxisAlignedBB j(Entity entity) {
return null;
}
public void aw() {
Entity entity = this.bB();
if (this.isPassenger() && entity.dead) {
this.stopRiding();
} else {
this.motX = 0.0D;
this.motY = 0.0D;
this.motZ = 0.0D;
this.A_();
if (this.isPassenger()) {
entity.k(this);
}
}
}
public void k(Entity entity) {
if (this.w(entity)) {
entity.setPosition(this.locX, this.locY + this.ay() + entity.ax(), this.locZ);
}
}
public double ax() {
return 0.0D;
}
public double ay() {
return this.length * 0.75D;
}
public boolean startRiding(Entity entity) {
return this.a(entity, false);
}
public boolean a(Entity entity, boolean flag) {
for (Entity entity1 = entity; entity1.au != null; entity1 = entity1.au) {
if (entity1.au == this) {
return false;
}
}
if (!flag && (!this.n(entity) || !entity.q(this))) {
return false;
} else {
if (this.isPassenger()) {
this.stopRiding();
}
this.au = entity;
this.au.o(this);
return true;
}
}
protected boolean n(Entity entity) {
return this.j <= 0;
}
public void az() {
for (int i = this.passengers.size() - 1; i >= 0; --i) {
this.passengers.get(i).stopRiding();
}
}
public void stopRiding() {
if (this.au != null) {
Entity entity = this.au;
this.au = null;
entity.p(this);
}
}
protected void o(Entity entity) {
if (entity == this) throw new IllegalArgumentException("Entities cannot become a passenger of themselves"); // Paper - issue 572
if (entity.bB() != this) {
throw new IllegalStateException("Use x.startRiding(y), not y.addPassenger(x)");
} else {
// CraftBukkit start
com.google.common.base.Preconditions.checkState(!entity.passengers.contains(this), "Circular entity riding! %s %s", this, entity);
CraftEntity craft = (CraftEntity) entity.getBukkitEntity().getVehicle();
Entity orig = craft == null ? null : craft.getHandle();
if (getBukkitEntity() instanceof Vehicle && entity.getBukkitEntity() instanceof LivingEntity && entity.world.isChunkLoaded((int) entity.locX >> 4, (int) entity.locZ >> 4, false)) { // Boolean not used
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
// Spigot start
org.spigotmc.event.entity.EntityMountEvent event = new org.spigotmc.event.entity.EntityMountEvent(entity.getBukkitEntity(), this.getBukkitEntity());
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
// Spigot end
if (!this.world.isClientSide && entity instanceof EntityHuman && !(this.bw() instanceof EntityHuman)) {
this.passengers.add(0, entity);
} else {
this.passengers.add(entity);
}
}
}
protected void p(Entity entity) {
if (entity.bB() == this) {
throw new IllegalStateException("Use x.stopRiding(y), not y.removePassenger(x)");
} else {
// CraftBukkit start
entity.setVehicle(this); // Paper - Set the vehicle back for the event
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
// Paper start - make EntityDismountEvent cancellable
if (!new org.spigotmc.event.entity.EntityDismountEvent(entity.getBukkitEntity(), this.getBukkitEntity()).callEvent()) {
return;
}
entity.setVehicle(null);
// Paper end
this.passengers.remove(entity);
entity.j = 60;
}
}
protected boolean q(Entity entity) {
return this.bx().size() < 1;
}
public float aA() {
return 0.0F;
}
public Vec3D aB() {
return null;
}
public void e(BlockPosition blockposition) {
if (this.portalCooldown > 0) {
this.portalCooldown = this.aE();
} else {
if (!this.world.isClientSide && !blockposition.equals(this.an)) {
this.an = new BlockPosition(blockposition);
ShapeDetector.ShapeDetectorCollection shapedetector_shapedetectorcollection = Blocks.PORTAL.c(this.world, this.an);
double d0 = shapedetector_shapedetectorcollection.getFacing().k() == EnumDirection.EnumAxis.X ? (double) shapedetector_shapedetectorcollection.a().getZ() : (double) shapedetector_shapedetectorcollection.a().getX();
double d1 = shapedetector_shapedetectorcollection.getFacing().k() == EnumDirection.EnumAxis.X ? this.locZ : this.locX;
d1 = Math.abs(MathHelper.c(d1 - (shapedetector_shapedetectorcollection.getFacing().e().c() == EnumDirection.EnumAxisDirection.NEGATIVE ? 1 : 0), d0, d0 - shapedetector_shapedetectorcollection.d()));
double d2 = MathHelper.c(this.locY - 1.0D, shapedetector_shapedetectorcollection.a().getY(), shapedetector_shapedetectorcollection.a().getY() - shapedetector_shapedetectorcollection.e());
this.ao = new Vec3D(d1, d2, 0.0D);
this.ap = shapedetector_shapedetectorcollection.getFacing();
}
this.ak = true;
}
}
public int aE() {
return 300;
}
public Iterable<ItemStack> aG() {
return Entity.b;
}
public Iterable<ItemStack> getArmorItems() {
return Entity.b;
}
public Iterable<ItemStack> aI() {
return Iterables.concat(this.aG(), this.getArmorItems());
}
public void setEquipment(EnumItemSlot enumitemslot, ItemStack itemstack) {}
public boolean isBurning() {
boolean flag = this.world != null && this.world.isClientSide;
return !this.fireProof && (this.fireTicks > 0 || flag && this.getFlag(0));
}
public boolean isPassenger() {
return this.bB() != null;
}
public boolean isVehicle() {
return !this.bx().isEmpty();
}
public boolean isSneaking() {
return this.getFlag(1);
}
public void setSneaking(boolean flag) {
this.setFlag(1, flag);
}
public boolean isSprinting() {
return this.getFlag(3);
}
public void setSprinting(boolean flag) {
this.setFlag(3, flag);
}
public boolean aO() {
return this.glowing || this.world.isClientSide && this.getFlag(6);
}
public void g(boolean flag) {
this.glowing = flag;
if (!this.world.isClientSide) {
this.setFlag(6, this.glowing);
}
}
public boolean isInvisible() {
return this.getFlag(5);
}
@Nullable public ScoreboardTeamBase getTeam() { return this.aQ(); } // Paper - OBFHELPER
@Nullable
public ScoreboardTeamBase aQ() {
if (!this.world.paperConfig.nonPlayerEntitiesOnScoreboards && !(this instanceof EntityHuman)) { return null; } // Paper
return this.world.getScoreboard().getPlayerTeam(this.bf());
}
public boolean r(Entity entity) {
return this.a(entity.aQ());
}
public boolean a(ScoreboardTeamBase scoreboardteambase) {
return this.aQ() != null ? this.aQ().isAlly(scoreboardteambase) : false;
}
public void setInvisible(boolean flag) {
this.setFlag(5, flag);
}
public boolean getFlag(int i) {
return (this.datawatcher.get(Entity.Z).byteValue() & 1 << i) != 0;
}
public void setFlag(int i, boolean flag) {
byte b0 = this.datawatcher.get(Entity.Z).byteValue();
if (flag) {
this.datawatcher.set(Entity.Z, Byte.valueOf((byte) (b0 | 1 << i)));
} else {
this.datawatcher.set(Entity.Z, Byte.valueOf((byte) (b0 & ~(1 << i))));
}
}
public int getAirTicks() {
return this.datawatcher.get(Entity.az).intValue();
}
public void setAirTicks(int i) {
// CraftBukkit start
EntityAirChangeEvent event = new EntityAirChangeEvent(this.getBukkitEntity(), i);
event.getEntity().getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
this.datawatcher.set(Entity.az, Integer.valueOf(event.getAmount()));
// CraftBukkit end
}
public void onLightningStrike(EntityLightning entitylightning) {
// 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.isInWater()) {
// 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
}
}
public void b(EntityLiving entityliving) {}
protected boolean i(double d0, double d1, double d2) {
BlockPosition blockposition = new BlockPosition(d0, d1, d2);
double d3 = d0 - blockposition.getX();
double d4 = d1 - blockposition.getY();
double d5 = d2 - blockposition.getZ();
if (!this.world.a(this.getBoundingBox())) {
return false;
} else {
EnumDirection enumdirection = EnumDirection.UP;
double d6 = Double.MAX_VALUE;
if (!this.world.t(blockposition.west()) && d3 < d6) {
d6 = d3;
enumdirection = EnumDirection.WEST;
}
if (!this.world.t(blockposition.east()) && 1.0D - d3 < d6) {
d6 = 1.0D - d3;
enumdirection = EnumDirection.EAST;
}
if (!this.world.t(blockposition.north()) && d5 < d6) {
d6 = d5;
enumdirection = EnumDirection.NORTH;
}
if (!this.world.t(blockposition.south()) && 1.0D - d5 < d6) {
d6 = 1.0D - d5;
enumdirection = EnumDirection.SOUTH;
}
if (!this.world.t(blockposition.up()) && 1.0D - d4 < d6) {
d6 = 1.0D - d4;
enumdirection = EnumDirection.UP;
}
float f = this.random.nextFloat() * 0.2F + 0.1F;
float f1 = enumdirection.c().a();
if (enumdirection.k() == EnumDirection.EnumAxis.X) {
this.motX = f1 * f;
this.motY *= 0.75D;
this.motZ *= 0.75D;
} else if (enumdirection.k() == EnumDirection.EnumAxis.Y) {
this.motX *= 0.75D;
this.motY = f1 * f;
this.motZ *= 0.75D;
} else if (enumdirection.k() == EnumDirection.EnumAxis.Z) {
this.motX *= 0.75D;
this.motY *= 0.75D;
this.motZ = f1 * f;
}
return true;
}
}
public void aS() {
this.E = true;
this.fallDistance = 0.0F;
}
@Override
public String getName() {
if (this.hasCustomName()) {
return this.getCustomName();
} else {
String s = EntityTypes.b(this);
if (s == null) {
s = "generic";
}
return LocaleI18n.get("entity." + s + ".name");
}
}
@Nullable
public Entity[] aT() {
return null;
}
public boolean s(Entity entity) {
return this == entity;
}
public float getHeadRotation() {
return 0.0F;
}
public void h(float f) {}
public void i(float f) {}
public boolean aV() {
return true;
}
public boolean t(Entity entity) {
return false;
}
@Override
public String toString() {
return String.format("%s[\'%s\'/%d, l=\'%s\', x=%.2f, y=%.2f, z=%.2f]", new Object[] { this.getClass().getSimpleName(), this.getName(), Integer.valueOf(this.id), this.world == null ? "~NULL~" : this.world.getWorldData().getName(), Double.valueOf(this.locX), Double.valueOf(this.locY), Double.valueOf(this.locZ)});
}
public boolean isInvulnerable(DamageSource damagesource) {
return this.invulnerable && damagesource != DamageSource.OUT_OF_WORLD && !damagesource.u();
}
public boolean aW() {
return this.invulnerable;
}
public void setInvulnerable(boolean flag) {
this.invulnerable = flag;
}
public void u(Entity entity) {
this.setPositionRotation(entity.locX, entity.locY, entity.locZ, entity.yaw, entity.pitch);
}
private void a(Entity entity) {
NBTTagCompound nbttagcompound = entity.e(new NBTTagCompound());
nbttagcompound.remove("Dimension");
this.f(nbttagcompound);
this.portalCooldown = entity.portalCooldown;
this.an = entity.an;
this.ao = entity.ao;
this.ap = entity.ap;
}
@Nullable
public Entity c(int i) {
if (!this.world.isClientSide && !this.dead) {
this.world.methodProfiler.a("changeDimension");
MinecraftServer minecraftserver = this.B_();
// 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();
// Need to make sure the profiler state is reset afterwards (but we still want to time the call)
Entity entity = this.teleportTo(exit, true);
return entity;
}
return null;
}
public Entity teleportTo(Location exit, boolean portal) {
if (!this.dead) { // Paper
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) {
blockposition = worldserver1.getDimensionSpawn();
} else {
double d0 = this.locX;
double d1 = this.locZ;
double d2 = 8.0D;
if (i == -1) {
d0 = MathHelper.a(d0 / 8.0D, worldserver1.getWorldBorder().b() + 16.0D, worldserver1.getWorldBorder().d() - 16.0D);
d1 = MathHelper.a(d1 / 8.0D, worldserver1.getWorldBorder().c() + 16.0D, worldserver1.getWorldBorder().e() - 16.0D);
} else if (i == 0) {
d0 = MathHelper.a(d0 * 8.0D, worldserver1.getWorldBorder().b() + 16.0D, worldserver1.getWorldBorder().d() - 16.0D);
d1 = MathHelper.a(d1 * 8.0D, worldserver1.getWorldBorder().c() + 16.0D, worldserver1.getWorldBorder().e() - 16.0D);
}
d0 = (double) MathHelper.clamp((int) d0, -29999872, 29999872);
d1 = (double) MathHelper.clamp((int) d1, -29999872, 29999872);
float f = this.yaw;
this.setPositionRotation(d0, this.locY, d1, 90.0F, 0.0F);
PortalTravelAgent portaltravelagent = worldserver1.getTravelAgent();
portaltravelagent.b(this, f);
blockposition = new BlockPosition(this);
}
// 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.a(this.getClass(), 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());
entity.setPositionRotation(blockposition1, entity.yaw, entity.pitch);
} else {
entity.setPositionRotation(blockposition, entity.yaw, entity.pitch);
}
// CraftBukkit end */
boolean flag = entity.attachedToPlayer;
entity.attachedToPlayer = true;
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;
worldserver.m();
worldserver1.m();
// // CraftBukkit: Moved up to keep balanced
return entity;
} else {
return null;
}
}
public boolean aX() {
return true;
}
public float a(Explosion explosion, World world, BlockPosition blockposition, IBlockData iblockdata) {
return iblockdata.getBlock().a(this);
}
public boolean a(Explosion explosion, World world, BlockPosition blockposition, IBlockData iblockdata, float f) {
return true;
}
public int aY() {
return 3;
}
public Vec3D getPortalOffset() {
return this.ao;
}
public EnumDirection getPortalDirection() {
return this.ap;
}
public boolean isIgnoreBlockTrigger() {
return false;
}
public void appendEntityCrashDetails(CrashReportSystemDetails crashreportsystemdetails) {
crashreportsystemdetails.a("Entity Type", new CrashReportCallable() {
public String a() throws Exception {
return EntityTypes.a(Entity.this) + " (" + Entity.this.getClass().getCanonicalName() + ")";
}
@Override
public Object call() throws Exception {
return this.a();
}
});
crashreportsystemdetails.a("Entity ID", Integer.valueOf(this.id));
crashreportsystemdetails.a("Entity Name", new CrashReportCallable() {
public String a() throws Exception {
return Entity.this.getName();
}
@Override
public Object call() throws Exception {
return this.a();
}
});
crashreportsystemdetails.a("Entity\'s Exact location", String.format("%.2f, %.2f, %.2f", new Object[] { Double.valueOf(this.locX), Double.valueOf(this.locY), Double.valueOf(this.locZ)}));
crashreportsystemdetails.a("Entity\'s Block location", CrashReportSystemDetails.a(MathHelper.floor(this.locX), MathHelper.floor(this.locY), MathHelper.floor(this.locZ)));
crashreportsystemdetails.a("Entity\'s Momentum", String.format("%.2f, %.2f, %.2f", new Object[] { Double.valueOf(this.motX), Double.valueOf(this.motY), Double.valueOf(this.motZ)}));
crashreportsystemdetails.a("Entity\'s Passengers", new CrashReportCallable() {
public String a() throws Exception {
return Entity.this.bx().toString();
}
@Override
public Object call() throws Exception {
return this.a();
}
});
crashreportsystemdetails.a("Entity\'s Vehicle", new CrashReportCallable() {
public String a() throws Exception {
return Entity.this.bB().toString();
}
@Override
public Object call() throws Exception {
return this.a();
}
});
}
public void a(UUID uuid) {
this.uniqueID = uuid;
this.ar = this.uniqueID.toString();
}
public UUID getUniqueID() {
return this.uniqueID;
}
public String getUUIDString() { return this.bf(); } // OBFHELPER
public String bf() {
return this.ar;
}
public boolean bg() {
// Paper start - OBFHELPER
return this.pushedByWater();
}
public boolean pushedByWater() {
// Paper end
return true;
}
@Override
public IChatBaseComponent getScoreboardDisplayName() {
ChatComponentText chatcomponenttext = new ChatComponentText(ScoreboardTeam.getPlayerDisplayName(this.aQ(), this.getName()));
chatcomponenttext.getChatModifier().setChatHoverable(this.bn());
chatcomponenttext.getChatModifier().setInsertion(this.bf());
return chatcomponenttext;
}
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.aA, s);
}
public String getCustomName() {
return this.datawatcher.get(Entity.aA);
}
public boolean hasCustomName() {
return !this.datawatcher.get(Entity.aA).isEmpty();
}
public void setCustomNameVisible(boolean flag) {
this.datawatcher.set(Entity.aB, Boolean.valueOf(flag));
}
public boolean getCustomNameVisible() {
return this.datawatcher.get(Entity.aB).booleanValue();
}
public void enderTeleportTo(double d0, double d1, double d2) {
this.aH = true;
this.setPositionRotation(d0, d1, d2, this.yaw, this.pitch);
this.world.entityJoinedWorld(this, false);
}
public void a(DataWatcherObject<?> datawatcherobject) {}
public EnumDirection getDirection() {
return EnumDirection.fromType2(MathHelper.floor(this.yaw * 4.0F / 360.0F + 0.5D) & 3);
}
public EnumDirection bm() {
return this.getDirection();
}
protected ChatHoverable bn() {
NBTTagCompound nbttagcompound = new NBTTagCompound();
MinecraftKey minecraftkey = EntityTypes.a(this);
nbttagcompound.setString("id", this.bf());
if (minecraftkey != null) {
nbttagcompound.setString("type", minecraftkey.toString());
}
nbttagcompound.setString("name", this.getName());
return new ChatHoverable(ChatHoverable.EnumHoverAction.SHOW_ENTITY, new ChatComponentText(nbttagcompound.toString()));
}
public boolean a(EntityPlayer entityplayer) {
return true;
}
public AxisAlignedBB getBoundingBox() {
return this.boundingBox;
}
public void a(AxisAlignedBB 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() {
return this.length * 0.85F;
}
public boolean br() {
return this.aw;
}
public void k(boolean flag) {
this.aw = flag;
}
public boolean c(int i, ItemStack itemstack) {
return false;
}
@Override
public void sendMessage(IChatBaseComponent ichatbasecomponent) {}
@Override
public boolean a(int i, String s) {
return true;
}
@Override
public BlockPosition getChunkCoordinates() {
return new BlockPosition(this.locX, this.locY + 0.5D, this.locZ);
}
@Override
public Vec3D d() {
return new Vec3D(this.locX, this.locY, this.locZ);
}
@Override
public World getWorld() {
return this.world;
}
@Override
public Entity f() {
return this;
}
@Override
public boolean getSendCommandFeedback() {
return false;
}
@Override
public void a(CommandObjectiveExecutor.EnumCommandResult commandobjectiveexecutor_enumcommandresult, int i) {
if (this.world != null && !this.world.isClientSide) {
this.aF.a(this.world.getMinecraftServer(), this, commandobjectiveexecutor_enumcommandresult, i);
}
}
@Override
@Nullable
public MinecraftServer B_() {
return this.world.getMinecraftServer();
}
public CommandObjectiveExecutor bs() {
return this.aF;
}
public void v(Entity entity) {
this.aF.a(entity.bs());
}
public EnumInteractionResult a(EntityHuman entityhuman, Vec3D vec3d, EnumHand enumhand) {
return EnumInteractionResult.PASS;
}
public boolean bt() {
return false;
}
protected void a(EntityLiving entityliving, Entity entity) {
if (entity instanceof EntityLiving) {
EnchantmentManager.a((EntityLiving) entity, (Entity) entityliving);
}
EnchantmentManager.b(entityliving, entity);
}
public void b(EntityPlayer entityplayer) {}
public void c(EntityPlayer entityplayer) {}
public float a(EnumBlockRotation enumblockrotation) {
float f = MathHelper.g(this.yaw);
switch (enumblockrotation) {
case CLOCKWISE_180:
return f + 180.0F;
case COUNTERCLOCKWISE_90:
return f + 270.0F;
case CLOCKWISE_90:
return f + 90.0F;
default:
return f;
}
}
public float a(EnumBlockMirror enumblockmirror) {
float f = MathHelper.g(this.yaw);
switch (enumblockmirror) {
case LEFT_RIGHT:
return -f;
case FRONT_BACK:
return 180.0F - f;
default:
return f;
}
}
public boolean bu() {
return false;
}
public boolean bv() {
boolean flag = this.aH;
this.aH = false;
return flag;
}
@Nullable
public Entity bw() {
return null;
}
public List<Entity> bx() {
return (List) (this.passengers.isEmpty() ? Collections.emptyList() : Lists.newArrayList(this.passengers));
}
public boolean w(Entity entity) {
Iterator iterator = this.bx().iterator();
Entity entity1;
do {
if (!iterator.hasNext()) {
return false;
}
entity1 = (Entity) iterator.next();
} while (!entity1.equals(entity));
return true;
}
public Collection<Entity> by() {
HashSet hashset = Sets.newHashSet();
this.a(Entity.class, (Set) hashset);
return hashset;
}
public <T extends Entity> Collection<T> b(Class<T> oclass) {
HashSet hashset = Sets.newHashSet();
this.a(oclass, (Set) hashset);
return hashset;
}
private <T extends Entity> void a(Class<T> oclass, Set<T> set) {
Entity entity;
for (Iterator iterator = this.bx().iterator(); iterator.hasNext(); entity.a(oclass, set)) {
entity = (Entity) iterator.next();
if (oclass.isAssignableFrom(entity.getClass())) {
set.add((T) entity); // CraftBukkit - decompile error
}
}
}
public Entity getVehicle() {
Entity entity;
for (entity = this; entity.isPassenger(); entity = entity.bB()) {
;
}
return entity;
}
public boolean x(Entity entity) {
return this.getVehicle() == entity.getVehicle();
}
public boolean y(Entity entity) {
Iterator iterator = this.bx().iterator();
Entity entity1;
do {
if (!iterator.hasNext()) {
return false;
}
entity1 = (Entity) iterator.next();
if (entity1.equals(entity)) {
return true;
}
} while (!entity1.y(entity));
return true;
}
public boolean bA() {
Entity entity = this.bw();
return entity instanceof EntityHuman ? ((EntityHuman) entity).cR() : !this.world.isClientSide;
}
@Nullable
public Entity bB() {
return this.au;
}
public EnumPistonReaction o_() {
return EnumPistonReaction.NORMAL;
}
public SoundCategory bC() {
return SoundCategory.NEUTRAL;
}
public int getMaxFireTicks() {
return 1;
}
}