Search in sources :

Example 1 with CommonPlayer

use of com.bergerkiller.bukkit.common.entity.type.CommonPlayer 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;
}
Also used : CommonLivingEntity(com.bergerkiller.bukkit.common.entity.type.CommonLivingEntity) ExtendedEntity(com.bergerkiller.bukkit.common.bases.ExtendedEntity) ExtendedEntity(com.bergerkiller.bukkit.common.bases.ExtendedEntity) CommonPlayer(com.bergerkiller.bukkit.common.entity.type.CommonPlayer) WorldHandle(com.bergerkiller.generated.net.minecraft.world.level.WorldHandle) EntityTracker(com.bergerkiller.bukkit.common.wrappers.EntityTracker) ArrayList(java.util.ArrayList) EntityHandle(com.bergerkiller.generated.net.minecraft.world.entity.EntityHandle) CraftEntityHandle(com.bergerkiller.generated.org.bukkit.craftbukkit.entity.CraftEntityHandle) CommonPlayer(com.bergerkiller.bukkit.common.entity.type.CommonPlayer) EntityTrackerHook(com.bergerkiller.bukkit.common.internal.hooks.EntityTrackerHook) org.bukkit.entity(org.bukkit.entity) Location(org.bukkit.Location)

Aggregations

ExtendedEntity (com.bergerkiller.bukkit.common.bases.ExtendedEntity)1 CommonLivingEntity (com.bergerkiller.bukkit.common.entity.type.CommonLivingEntity)1 CommonPlayer (com.bergerkiller.bukkit.common.entity.type.CommonPlayer)1 EntityTrackerHook (com.bergerkiller.bukkit.common.internal.hooks.EntityTrackerHook)1 EntityTracker (com.bergerkiller.bukkit.common.wrappers.EntityTracker)1 EntityHandle (com.bergerkiller.generated.net.minecraft.world.entity.EntityHandle)1 WorldHandle (com.bergerkiller.generated.net.minecraft.world.level.WorldHandle)1 CraftEntityHandle (com.bergerkiller.generated.org.bukkit.craftbukkit.entity.CraftEntityHandle)1 ArrayList (java.util.ArrayList)1 Location (org.bukkit.Location)1 org.bukkit.entity (org.bukkit.entity)1