use of com.bergerkiller.bukkit.common.wrappers.EntityTracker in project BKCommonLib by bergerhealer.
the class CommonEntity method replaceInEntityTracker.
private static void replaceInEntityTracker(int entityId, EntityHandle newInstance) {
final EntityTracker trackerMap = WorldUtil.getTracker(newInstance.getWorld().getWorld());
Object entry = trackerMap.getEntry(entityId);
if (entry != null) {
EntityHandle tracker = EntityHandle.createHandle(NMSEntityTrackerEntry.tracker.getInternal(entry));
if (tracker != null && tracker.getId() == newInstance.getId()) {
NMSEntityTrackerEntry.tracker.setInternal(entry, newInstance.getRaw());
}
replaceInList((List<?>) NMSEntityTrackerEntry.passengers.getInternal(entry), newInstance);
}
}
use of com.bergerkiller.bukkit.common.wrappers.EntityTracker in project BKCommonLib by bergerhealer.
the class CommonEntity method setNetworkController.
/**
* Sets an Entity Network Controller for this Entity. To stop tracking this
* minecart, pass in Null. To default back to the net.minecraft.server
* implementation, pass in a new {@link DefaultEntityNetworkController}
* instance.<br>
* <br>
* This method only works if the Entity world has previously been set.
*
* @param controller to set to
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public void setNetworkController(EntityNetworkController controller) {
if (getWorld() == null) {
throw new RuntimeException("Can not set the network controller when no world is known! (need to spawn it?)");
}
final EntityTracker tracker = WorldUtil.getTracker(getWorld());
final Object storedEntry = tracker.getEntry(entity);
// Properly handle a previously set controller
EntityTrackerHook hook = EntityTrackerHook.get(storedEntry, EntityTrackerHook.class);
if (hook != null) {
final EntityNetworkController<CommonEntity<org.bukkit.entity.Entity>> oldController = (EntityNetworkController<CommonEntity<org.bukkit.entity.Entity>>) hook.getController();
if (oldController == controller) {
return;
} else if (oldController != null) {
oldController.onDetached();
}
}
// Take care of null controllers - stop tracking
if (controller == null) {
tracker.stopTracking(entity);
return;
}
final Object newEntry;
if (controller instanceof DefaultEntityNetworkController) {
// Assign the default Entity Tracker Entry
if (NMSEntityTrackerEntry.T.isType(storedEntry)) {
// Nothing to be done here
newEntry = storedEntry;
} else {
// Create a new unmodified, default server network entry
newEntry = NMSEntityTracker.createDummyEntry(entity);
// Transfer data if needed
if (storedEntry != null) {
NMSEntityTrackerEntry.T.transfer(storedEntry, newEntry);
}
}
} else if (controller instanceof ExternalEntityNetworkController) {
// Use the entry as stored by the external network controller
newEntry = controller.getHandle();
// Be sure to refresh stats using the old entry
if (storedEntry != null && newEntry != null) {
NMSEntityTrackerEntry.T.transfer(storedEntry, newEntry);
}
} else if (hook != null) {
// Use the previous hooked entry - hotswap the controller
newEntry = storedEntry;
NMSEntityTrackerEntry.viewers.get(newEntry).clear();
} else if (storedEntry != null) {
// Convert the original entry into a hooked entry
newEntry = new EntityTrackerHook().hook(storedEntry);
} else {
// Create a brand new entry hook from a dummy entry
newEntry = new EntityTrackerHook().hook(NMSEntityTracker.createDummyEntry(entity));
}
// Attach the entry to the controller
controller.bind(this, newEntry);
// Attach (new?) entry to the world
if (storedEntry != newEntry) {
tracker.setEntry(entity, newEntry);
// Make sure to update the viewers
NMSEntityTrackerEntry.scanPlayers(newEntry, getWorld().getPlayers());
}
}
use of com.bergerkiller.bukkit.common.wrappers.EntityTracker in project BKCommonLib by bergerhealer.
the class CommonEntity method teleport.
@Override
public boolean teleport(Location location, TeleportCause cause) {
if (isDead()) {
return false;
}
// Preparations prior to teleportation
final Location oldLocation = entity.getLocation();
final EntityHandle entityHandle = EntityHandle.createHandle(Conversion.toEntityHandle.convert(this.entity));
final List<org.bukkit.entity.Entity> passengers = getPassengers();
final WorldHandle newworld = WorldHandle.createHandle(Conversion.toWorldHandle.convert(location.getWorld()));
final boolean isWorldChange = !entityHandle.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()) {
getVehicle().removePassenger(entity);
}
// If vehicle, eject the passenger first
if (hasPassenger()) {
this.setPassengersSilent(Collections.<org.bukkit.entity.Entity>emptyList());
}
// 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.getWorld().removeEntity(entityHandle);
entityHandle.setDead(false);
entityHandle.setWorld(newworld);
entityHandle.setLocation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
entityHandle.getWorld().addEntity(entityHandle);
succ = true;
}
if (hasNetworkController) {
this.setNetworkController(oldNetworkController);
}
if (!succ) {
return false;
}
// If there was a passenger, teleport it and let passenger enter again
if (passengers.size() > 0) {
// 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>();
entityHandle.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);
}
}
;
entityHandle.setIgnoreChunkCheck(false);
if (teleportedPassengers.size() > 0) {
setPassengersSilent(teleportedPassengers);
}
}
return true;
}
use of com.bergerkiller.bukkit.common.wrappers.EntityTracker in project BKCommonLib by bergerhealer.
the class PacketUtil method broadcastEntityPacket.
/**
* Sends a packet relating a certain entity to all players that can see it
*
* @param entity the packet is about
* @param packet to send
* @param sendToSelf whether to also send to the player itself, if the entity is a player
*/
public static void broadcastEntityPacket(Entity entity, CommonPacket packet, boolean sendToSelf) {
if (entity == null || packet == null)
return;
EntityTracker tracker = WorldUtil.getTracker(entity.getWorld());
Object entry = tracker.getEntry(entity);
if (entry != null) {
Set<Player> viewers = NMSEntityTrackerEntry.viewers.get(entry);
for (Player viewer : viewers) {
sendPacket(viewer, packet);
}
}
if (sendToSelf && entity instanceof Player) {
sendPacket((Player) entity, packet);
}
}
Aggregations