public boolean teleport(Location location, TeleportCause cause) {
if (isDead()) {
return false;
}
// Preparations prior to teleportation
final Entity entityHandle = CommonNMS.getNative(entity);
final CommonEntity<?> passenger = get(getPassenger());
final World newworld = CommonNMS.getNative(location.getWorld());
final boolean isWorldChange = entityHandle.world != newworld;
final EntityNetworkController<?> oldNetworkController = getNetworkController();
final boolean hasNetworkController = !(oldNetworkController instanceof DefaultEntityNetworkController);
WorldUtil.loadChunks(location, 3);
// If in a vehicle, make sure we eject first
if (isInsideVehicle()) {
getVehicle().eject();
}
// If vehicle, eject the passenger first
if (hasPassenger()) {
setPassengerSilent(null);
}
// Perform actual teleportation
final boolean succ;
if (!isWorldChange || entity instanceof Player) {
// First: stop tracking the entity
final EntityTracker tracker = WorldUtil.getTracker(getWorld());
tracker.stopTracking(entity);
// Destroy packets are queued: Make sure to send them RIGHT NOW
for (Player bukkitPlayer : WorldUtil.getPlayers(getWorld())) {
CommonPlayer player = get(bukkitPlayer);
if (player != null) {
player.flushEntityRemoveQueue();
}
}
// Teleport
succ = entity.teleport(location, cause);
// Start tracking the entity again
if (!hasNetworkController && !isWorldChange) {
tracker.startTracking(entity);
}
} else {
// Remove from one world and add to the other
entityHandle.world.removeEntity(entityHandle);
entityHandle.dead = false;
entityHandle.world = newworld;
entityHandle.setLocation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
entityHandle.world.addEntity(entityHandle);
succ = true;
}
if (hasNetworkController) {
this.setNetworkController(oldNetworkController);