SpawnEntityEvent.ChunkLoad not firing for all loaded entities?

I can’t detect some ArmorStands and Items loading using this event, even though I see them in the world. Is there a problem on my end?

https://github.com/Limeth/LimeFun/blob/master/src/main/java/cz/creeper/limefun/pipe/PipeSystem.java#L134

Call me crazy, but this event will only get entities that were actually spawned during this event and ignore any entities spawned after it. You could either get all entities load in the world, (world.getentities()), Change to a ChunkLoadEvent and get all entities in the chunk, (Which will once again ignore anythign spawned after the chunkloads)

Thanks for the response. Is there actually a use case for this event? I still don’t really get what entities it fires for.

You are using the wrong event. ChunkLoad is for natural spawns during chunk gen.

What you want is actually

https://github.com/SpongePowered/SpongeAPI/blob/bleeding/src/main/java/org/spongepowered/api/event/entity/ConstructEntityEvent.java#L70

The behavior of this event you suggested is odd. All Items it are of type stone but shouldn’t be. Seems like they are not initialized properly yet?

eg.:

EntityItem['item.tile.stone.stone'/435, l='world', x=0,00, y=0,00, z=0,00]

Try listening to Pre and filter for SpawnTypes.CHUNK_LOAD

I don’t see how that would help me. Pre isn’t a TargetEntityEvent, I could only get the type of the entity.

What I am trying to figure out here is, that I want to load all entities with custom data to a collection and keep track of them.

Use SpawnEntityEvent base event. Do not use the sub interfaces.

@Listener
public void onSpawnEntity(SpawnEntityEvent event) {
    Cause cause = event.getCause();

    for(Entity entity : event.getEntities()) {
        if(entity instanceof ArmorStand || entity instanceof Item) {
            System.out.println(entity);
        }
    }
}

I booted up the server, joined it, now I am looking at a lime wool block with an armor stand as the vehicle it is attached to and the logs are completely silent about it’s existence.

[18:31:04 INFO] [STDOUT]: [cz.creeper.limefun.pipe.PipeSystem.onSpawnEntity(PipeSystem.java:187)]: EntityItem['item.item.chickenRaw'/443, l='world', x=-159,88, y=90,00, z=175,88]
[18:31:04 INFO] [STDOUT]: [cz.creeper.limefun.pipe.PipeSystem.onSpawnEntity(PipeSystem.java:187)]: EntityItem['item.tile.gravel'/505, l='world', x=-147,13, y=63,00, z=399,35]
[18:31:05 INFO] [STDOUT]: [cz.creeper.limefun.pipe.PipeSystem.onSpawnEntity(PipeSystem.java:187)]: EntityItem['item.tile.doublePlant.syringa'/521, l='world', x=-6,48, y=64,73, z=418,38]
[18:31:05 INFO] [STDOUT]: [cz.creeper.limefun.pipe.PipeSystem.onSpawnEntity(PipeSystem.java:187)]: EntityItem['item.item.bone'/527, l='world', x=10,13, y=69,00, z=400,12]
[18:31:05 INFO] [STDOUT]: [cz.creeper.limefun.pipe.PipeSystem.onSpawnEntity(PipeSystem.java:187)]: EntityItem['item.item.arrow'/529, l='world', x=8,42, y=70,00, z=112,84]
[18:31:05 INFO] [STDOUT]: [cz.creeper.limefun.pipe.PipeSystem.onSpawnEntity(PipeSystem.java:187)]: EntityItem['item.item.seeds'/540, l='world', x=160,73, y=63,74, z=425,62]

Were the armor stand and wool already in the world before you joined? If so then this event wouldn’t have been triggered

Yes, they were. I am looking for an event that would let me find out when they were loaded.

So… I do this now. The problem is, it’s quite expensive, because it has to loop through all the entities in the world.

@Listener
public void onLoadChunk(LoadChunkEvent event) {
    Chunk chunk = event.getTargetChunk();

    for(Entity entity : chunk.getWorld().getEntities()) {
        if(!(entity instanceof Item))
            continue;

        Item item = (Item) entity;

        if(item.get(PipeItemData.class).isPresent() && !isRegistered(item))
            loadItem(item);
    }
}

SpawnEntityEvent will only be triggered when an entity is spawned for the first time, not when they are loaded along with a chunk.

IMO ConstructEntityEvent.Post may be the best for you - it’ll be called whenever an entity is being created, whether from chunk load, entity spawn or for any other reason.

FYI: You could save a lot of time with your chunk listener and instead call getEntities on the Chunk directly - it’s an EntityUniverse just like a world.

2 Likes

Right, this was the case in 1.8.9 but I just found out SpawnEntityEvent.ChunkLoad was changed to actual chunk loads and has nothing to do with chunk gen. So listening to SpawnEntityEvent.ChunkLoad should work when an entity loads during a chunk load.

Change your chunk.getWorld().getEntities() to event.getTargetChunk().getEntities(), this will only get the entities in the loaded chunk. Or alternatively,

for (World world : Sponge.getServer().getWorlds()) {
for (Entity entity : world.getEntities()) {