Preventing Human Entities From Despawning

I’m Currently trying to get a better understanding of how Human Entities work. Is there a way to prevent them from de-spawning when you get too far away?

DestructEntityEvent https://github.com/SpongePowered/SpongeAPI/blob/bleeding/src/main/java/org/spongepowered/api/event/entity/DestructEntityEvent.java should fire when a entity is about to unload. From there check that it is humanoid and do something to stop them from unloading, such as saving a snapshot of the entity and when a player gets close then apply the same snapshot

Okay, I created a snapshot of the human when the DestructEntityEvent is ran. I’m just having trouble figuring out how I would go about restoring the snapshot of the human. Would the LoadChunkEvent and checking if the snapshots location is within that chunk be a viable solution? or would there be a better way to check if a player is in range of spawning the entity?

No. That consept is how I would do it too

Hmm. I cant seem to get it to work correctly

Here is the code i’m using

Any ideas?

also, The object called map is actually a List<Map<EntitySnapshot,Chunk>> map; Just a very terrible name for it

Yep. So I can see 2 issues.

The first one is that you are using GetChunk(x, y, z) with the x,y,z being block location. What you want is actually

getChunkAtBlock(x, y, z);

Or (and this one is the one I prefer)

Vector3I chunkPos = loc.getChunkPosition();
Chunk chunk = loc.getWorld().getChunk(chunkPos);

And the other issue is when comparing 2 objects. You are using “==” which only works with primitive class types (aka the class types that you type with lower case all the way through and normally show up in a different colour (purple for eclipse and Intelij in dark theme)).
What you actually want to do is use the .equals() function to compare two non-primitive objects. However due to the fact Sponge objects dont actually .equal correctly for some reason (I think its to do with mixen tech) your going to need to compare the chunks positions with each other and also the world.

if ((chunk.getPosition().equals(snapChunk.getPosition()) && (chunk.getWorld().getUniqueId().equals(snapChunk.getWorld().getUniquieId())

Still doesent seem to work. I think the root of the problem is the DestructEntityEvent. I set up a test to see what entities are despawning and no humans or humanoids seem to pop up.

It fires when friendly mobs despawns but not mobs or Human Entities

Here is the code for the event

@Listener
public void EntityDestructEvent(DestructEntityEvent e){

    Entity entity = e.getTargetEntity();

    if(entity instanceof Human){

        Sponge.getServer().getBroadcastChannel().send(Text.of("Human Destructed"));

        EntitySnapshot entitySnapshot = entity.createSnapshot().withLocation(entity.getLocation());
        Vector3i chunkPos = entity.getLocation().getChunkPosition();
        Optional<Chunk> chunkOptional = entity.getWorld().getChunk(chunkPos);

        if(chunkOptional.isPresent()){
            Chunk chunk = chunkOptional.get();

            Map<EntitySnapshot,Chunk> entSnapMap = new HashMap<>();
            entSnapMap.put(entitySnapshot,chunk);

            map.add(entSnapMap);
        }
    }
}

Hmm. That seems to be a issue. File a issue on spongeCommon if there isnt one already

Alright. Ill file an issue there. Thanks for the assistance. Ill mark it as solved :slight_smile: