use of com.bergerkiller.generated.net.minecraft.world.level.WorldHandle in project BKCommonLib by bergerhealer.
the class CommonEntity method teleport.
@Override
public boolean teleport(Location location, TeleportCause cause) {
if (isRemoved()) {
return false;
}
// Preparations prior to teleportation
final Location oldLocation = entity.getLocation();
final List<org.bukkit.entity.Entity> passengers = getPassengers();
final WorldHandle newworld = WorldHandle.fromBukkit(location.getWorld());
final boolean isWorldChange = !this.handle.getWorld().equals(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()) {
ExtendedEntity<Entity> extVeh = new ExtendedEntity<Entity>(getVehicle());
if (!extVeh.removePassenger(entity)) {
return false;
}
}
// If vehicle, eject the passenger first
if (hasPassenger()) {
this.setPassengersSilent(Collections.<org.bukkit.entity.Entity>emptyList());
}
// Perform actual teleportation
final boolean succ;
if (entity instanceof Player) {
// No special logic here. Just teleport.
succ = entity.teleport(location, cause);
} else if (!isWorldChange) {
// 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 the non-player entity
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
this.handle.getWorldServer().removeEntityWithoutDeath(this.handle);
this.handle.setDestroyed(false);
this.handle.setWorld(newworld);
this.handle.setLocation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
if (hasNetworkController) {
// Hook the entity tracker to cancel track() on this Entity
Object nmsWorldHandle = HandleConversion.toWorldHandle(location.getWorld());
EntityTrackerHook hook = hookWorldEntityTracker(nmsWorldHandle);
hook.ignoredEntities.add(this.handle.getRaw());
try {
// Spawn the entity. This will not create an entity tracker entry.
EntityUtil.addEntity(entity);
} finally {
// Remove the entity from the ignore list, restore Entity Tracker entry if last entity
hook.ignoredEntities.remove(this.handle.getRaw());
unhookWorldEntityTracker(nmsWorldHandle, hook);
}
} else {
// Simply add the entity, which will register a (default) network controller
EntityUtil.addEntity(entity);
}
succ = true;
}
// If there was a passenger, teleport it and let passenger enter again
if (succ && !passengers.isEmpty()) {
// Teleport the passenger, but ignore the chunk send check so vehicle is properly spawned to all players
List<org.bukkit.entity.Entity> teleportedPassengers = new ArrayList<org.bukkit.entity.Entity>();
this.handle.setIgnoreChunkCheck(true);
float yawChange = location.getYaw() - oldLocation.getYaw();
float pitchChange = location.getPitch() - oldLocation.getPitch();
for (org.bukkit.entity.Entity passenger : passengers) {
// Figure out a suitable location yaw and pitch based on what it was before
// We must make sure that when players are mounted, they still face the same way relatively
Location passengerOld = passenger.getLocation();
Location passengerLoc = location.clone();
passengerLoc.setYaw(passengerOld.getYaw() + yawChange);
passengerLoc.setPitch(passengerOld.getPitch() + pitchChange);
if (get(passenger).teleport(passengerLoc, cause)) {
teleportedPassengers.add(passenger);
}
}
;
this.handle.setIgnoreChunkCheck(false);
if (!teleportedPassengers.isEmpty()) {
if (hasNetworkController) {
// network controller is used; simply set the passengers of the entity handle
List<EntityHandle> passengerHandles = new ArrayList<EntityHandle>(teleportedPassengers.size());
for (org.bukkit.entity.Entity passenger : teleportedPassengers) {
EntityHandle phandle = EntityHandle.fromBukkit(passenger);
passengerHandles.add(phandle);
phandle.setVehicle(this.handle);
}
this.handle.setPassengers(passengerHandles);
} else {
setPassengersSilent(teleportedPassengers);
}
}
}
// Set network controller last, to make sure passenger mounting packets are sent properly
if (hasNetworkController) {
setNetworkController(oldNetworkController);
}
return succ;
}
Aggregations