diff --git a/src/ChunkManager.cpp b/src/ChunkManager.cpp index ce03ecc..876a120 100644 --- a/src/ChunkManager.cpp +++ b/src/ChunkManager.cpp @@ -85,7 +85,8 @@ void ChunkManager::destroyChunk(std::tuple chunkPos) { Chunk* chunk = chunks[chunkPos]; // unspawn all of the mobs/npcs - for (uint32_t id : chunk->NPCs) { + std::set npcIDs(chunk->NPCs); + for (uint32_t id : npcIDs) { NPCManager::destroyNPC(id); } diff --git a/src/ChunkManager.hpp b/src/ChunkManager.hpp index 73d90bc..2a8a049 100644 --- a/src/ChunkManager.hpp +++ b/src/ChunkManager.hpp @@ -15,9 +15,9 @@ public: }; enum { - INSTANCE_OVERWORLD, // default instance every player starts in - //INSTANCE_IZ, // all infected zones share an instance - //INSTANCE_UNIQUE // fusion lairs are generated as requested (+ uid) + INSTANCE_OVERWORLD // default instance every player starts in + //INSTANCE_IZ, // these aren't actually used + //INSTANCE_UNIQUE }; namespace ChunkManager { diff --git a/src/NPCManager.cpp b/src/NPCManager.cpp index 8a9f696..cd798b1 100644 --- a/src/NPCManager.cpp +++ b/src/NPCManager.cpp @@ -592,6 +592,8 @@ void NPCManager::handleWarp(CNSocket* sock, int32_t warpId) { MissionManager::failInstancedMissions(sock); // fail any missions that require the player's current instance + uint64_t fromInstance = plrv.plr->instanceID; // saved for post-warp + if (plrv.plr->instanceID == 0) { // save last uninstanced coords plrv.plr->lastX = plrv.plr->x; @@ -624,6 +626,18 @@ void NPCManager::handleWarp(CNSocket* sock, int32_t warpId) { plrv.plr->instanceID = INSTANCE_OVERWORLD; sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_WARP_USE_NPC_SUCC, sizeof(sP_FE2CL_REP_PC_WARP_USE_NPC_SUCC)); } + + // post-warp: check if the source instance has no more players in it and delete it if so + if ((fromInstance >> 32) == 0) + return; // don't clean up overworld/IZ chunks + + std::vector> sourceChunkCoords = ChunkManager::getChunksInMap(fromInstance); + for (std::tuple& coords : sourceChunkCoords) { + Chunk* chunk = ChunkManager::chunks[coords]; + if (chunk->players.size() > 0) + return; // there are still players inside + } + ChunkManager::destroyInstance(fromInstance); } /*