Player Load Entity

Discussion in 'Plugin Development' started by RingOfStorms, Sep 30, 2012.

Thread Status:
Not open for further replies.
  1. Offline

    RingOfStorms

    Is there an event for players loading entities. The tagAPI uses a player event to see when a player is cumming into view, but is there a way to do it with any Entity?

    I've been looking for this for quite some time now and am thinking of alternatives, the best I can think of is doing an onplayermove event which seems like overkill just to get entities that have been loaded for a player, and another idea I had was just have a scheduler that ran constantly every configurable seconds and that would update each player's loaded entities.

    So unless there is a way to get a PlayerLoadEntityEvent or something which route do you think I should take?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 29, 2016
  2. Offline

    Comphenix

    There's no Bukkit event for it, but I'm pretty sure you can get this information by looking into the EntityTracker class for the player.

    In ProtocolLib I use EntityTracker to refresh entities (like updating the display name of a player). Here's a simplified version of that code:
    Code:java
    1. @SuppressWarnings("unchecked")
    2. public static void updateEntity2(Entity entity, List<Player> observers) {
    3.  
    4. World world = entity.getWorld();
    5. WorldServer worldServer = ((CraftWorld) world).getHandle();
    6.  
    7. EntityTracker tracker = worldServer.tracker;
    8. EntityTrackerEntry entry = (EntityTrackerEntry) tracker.trackedEntities
    9. .get(entity.getEntityId());
    10.  
    11. List<EntityPlayer> nmsPlayers = getNmsPlayers(observers);
    12.  
    13. entry.trackedPlayers.removeAll(nmsPlayers);
    14. entry.scanPlayers(nmsPlayers);
    15. }
    16.  
    17. private static List<EntityPlayer> getNmsPlayers(List<Player> players) {
    18. List<EntityPlayer> nsmPlayers = new ArrayList<EntityPlayer>();
    19.  
    20. for (Player bukkitPlayer : players) {
    21. CraftPlayer craftPlayer = (CraftPlayer) bukkitPlayer;
    22. nsmPlayers.add(craftPlayer.getHandle());
    23. }
    24.  
    25. return nsmPlayers;
    26. }

    The "entry.trackedPlayers" list will contain every player that is aware (not necessarily in view) of this entity/player.

    But, depending on CraftBukkit is a bit of a pain. Are you sure you can't just scan for nearby players at a regular interval instead? That might be easier than digging into obfuscated code.
     
  3. Offline

    RingOfStorms

    Well thanks for the help, i'll probably do intervals as it seems to be the best way to go.
     
  4. Offline

    RingOfStorms

    Wanted to revisit this and ask you if you think there is a way to make an event for this. Such as PlayerLoadEntityEvent, and PLayerUnloadEntityEvent. Would that even be possible in the current Bukkit state?

    Thanks for your help.
     
  5. Offline

    Comphenix

    It is, although it might have a impact on performance. Such events might be called extremely frequently, so you should be as efficient as possible when handling the event.

    I wrote an API implementing these events. All you need to do, is download the java-files from Github Gist and put them into a package called "com.comphenix.proximity". That ensures the API is compatible with other plugins. Then you simply initialize the entity proximity detector when your plugin is enabled:
    Code:java
    1. public class ExampleMod extends JavaPlugin implements Listener {
    2.  
    3. private EntityProximityDetector detector;
    4.  
    5. @Override
    6. public void onEnable() {
    7. Server server = getServer();
    8. PluginManager manager = server.getPluginManager();
    9.  
    10. detector = new EntityProximityDetector(this);
    11. detector.initialize(server.getWorlds());
    12. manager.registerEvents(this, this);
    13. }
    14.  
    15. @EventHandler
    16. public void onPlayerLoadEntityEvent(PlayerLoadEntityEvent event) {
    17. System.out.println(String.format("Player %s is nearby entity %s.",
    18. event.getPlayer().getName(),
    19. event.getLoadedEntity()
    20. ));
    21. }
    22.  
    23. @EventHandler
    24. public void onPlayerUnloadEntityEvent(PlayerUnloadEntityEvent event) {
    25. System.out.println(String.format("Player %s lost track of entity %s.",
    26. event.getPlayer().getName(),
    27. event.getUnloadedEntity()
    28. ));
    29. }
    30.  
    31. @Override
    32. public void onDisable() {
    33. detector.close();
    34. }
    35. }
     
Thread Status:
Not open for further replies.

Share This Page