Tracking Entity Removal

Discussion in 'Plugin Development' started by Superckl1, Apr 18, 2013.

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

    Superckl1

    Hey everyone,

    I'm making a plugin that requires me to track the location of entities in relation to their spawn location (already have that made), but I'm running into a problem. When an entity spawns with CreatureSpawnEvent, a store them in a Map with their UUID as the key. I then listen to EntityDeathEvent and ChunkUnloadEvent to know when to clear the entity from the Map. The only problem is, I am missing about 2,000 entities an hour (The Map contains 2,000 entities that don't exist). Am I missing some other event for entities being removed? I was thinking it may have to do with Entity.remove(), but I'm not sure. Here are my listeners:

    Code:
    @EventHandler(priority = EventPriority.MONITOR)
        public void onEntitySpawn(final CreatureSpawnEvent e) {
            if (e.isCancelled())
                return;
            if (e.getEntityType() == EntityType.ZOMBIE
                    | e.getEntityType() == EntityType.SKELETON) {
                this.entities.put(e.getEntity().getUniqueId(),
                        new CustomItemsEntity(e.getEntity(), e.getLocation()));
            }
        }
    Code:
        @EventHandler(priority = EventPriority.HIGHEST)
        public void onEntityDeath(final EntityDeathEvent e) {
            if (e.getEntityType() != EntityType.ZOMBIE
                    & e.getEntityType() != EntityType.SKELETON)
                return;
            this.entities.remove(e.getEntity().getUniqueId());
            e.setDroppedExp(0);
            e.getDrops().clear();
        }
     
        @EventHandler(priority = EventPriority.HIGHEST)
        public void onChunkUnload(final ChunkUnloadEvent e) {
            if (e.isCancelled())
                return;
            final Entity[] entities = e.getChunk().getEntities();
            for (final Entity entity : entities)
                this.entities.remove(entity.getUniqueId());
        }
     
  2. Superckl1
    I'm not sure why you're using bitwise operators there... & and | are bitwise operators, && and || are logic operators which you should use.

    But I suggest you run a repeating task once a second or (or more if you don't really care that much for accuracy or memory) that iterates through the hashmap and checks the entity's existance.... make sure you use an Iterator and not for() loop or you'll have concurency issues when removing them.
     
  3. Offline

    Superckl1

    I actually already have that, but I was hoping there would be less intensive way to do it. The iterator has to iterate over all the entities that do exist entities.size times. Or is there a more efficient way to iterate?
     
  4. Superckl1
    A queue ? Process groups of X of elements each N ticks until queue is empty then re-do the process.
     
  5. Offline

    Superckl1

    Is this really the only way? I would really like to avoid iterating. Are you sure there is no event I'm missing?
     
  6. Superckl1
    I don't think so... those bitwise operators might screw your results too.

    Are you checking entity validity and removing if not valid when getting a tracked entity ?

    You could start debugging with log messages and stuff... additionally you could edit CB (or use reflection) to add a debug message on the remove method of skeletons and zombies.
    EDIT:
    Actually I belive that would actually be the most effective way, use reflection on remove() method to detect when it gets removed.
     
  7. Offline

    Superckl1

    All right, thanks for the help.
     
Thread Status:
Not open for further replies.

Share This Page