diff options
| author | oy <Tom_Adams@web.de> | 2011-01-19 15:31:42 +0100 |
|---|---|---|
| committer | oy <Tom_Adams@web.de> | 2011-01-19 15:31:42 +0100 |
| commit | 1359db54763739d65895d9fe48c13de95570bbe5 (patch) | |
| tree | 6e7729259c39439cdf1af83fba8ce4bad77327ca /src/game | |
| parent | 68faba809c9c0be9c63a462f91d5dac3c540a8b6 (diff) | |
| download | zcatch-1359db54763739d65895d9fe48c13de95570bbe5.tar.gz zcatch-1359db54763739d65895d9fe48c13de95570bbe5.zip | |
prevent that removing an entity aborts traversing the entity list in gameworld
Diffstat (limited to 'src/game')
| -rw-r--r-- | src/game/server/gameworld.cpp | 32 | ||||
| -rw-r--r-- | src/game/server/gameworld.h | 1 |
2 files changed, 27 insertions, 6 deletions
diff --git a/src/game/server/gameworld.cpp b/src/game/server/gameworld.cpp index e2d08ed6..8fc9fec8 100644 --- a/src/game/server/gameworld.cpp +++ b/src/game/server/gameworld.cpp @@ -107,6 +107,10 @@ void CGameWorld::RemoveEntity(CEntity *pEnt) if(pEnt->m_pNextTypeEntity) pEnt->m_pNextTypeEntity->m_pPrevTypeEntity = pEnt->m_pPrevTypeEntity; + // keep list traversing valid + if(m_pNextTraverseEntity == pEnt) + m_pNextTraverseEntity = pEnt->m_pNextEntity; + pEnt->m_pNextEntity = 0; pEnt->m_pPrevEntity = 0; pEnt->m_pNextTypeEntity = 0; @@ -116,15 +120,23 @@ void CGameWorld::RemoveEntity(CEntity *pEnt) // void CGameWorld::Snap(int SnappingClient) { - for(CEntity *pEnt = m_pFirstEntity; pEnt; pEnt = pEnt->m_pNextEntity) + for(CEntity *pEnt = m_pFirstEntity; pEnt; ) + { + m_pNextTraverseEntity = pEnt->m_pNextEntity; pEnt->Snap(SnappingClient); + pEnt = m_pNextTraverseEntity; + } } void CGameWorld::Reset() { // reset all entities - for(CEntity *pEnt = m_pFirstEntity; pEnt; pEnt = pEnt->m_pNextEntity) + for(CEntity *pEnt = m_pFirstEntity; pEnt; ) + { + m_pNextTraverseEntity = pEnt->m_pNextEntity; pEnt->Reset(); + pEnt = m_pNextTraverseEntity; + } RemoveEntities(); GameServer()->m_pController->PostReset(); @@ -139,13 +151,13 @@ void CGameWorld::RemoveEntities() CEntity *pEnt = m_pFirstEntity; while(pEnt) { - CEntity *pNext = pEnt->m_pNextEntity; + m_pNextTraverseEntity = pEnt->m_pNextEntity; if(pEnt->m_MarkedForDestroy) { RemoveEntity(pEnt); pEnt->Destroy(); } - pEnt = pNext; + pEnt = m_pNextTraverseEntity; } } @@ -159,11 +171,19 @@ void CGameWorld::Tick() if(GameServer()->m_pController->IsForceBalanced()) GameServer()->SendChat(-1, CGameContext::CHAT_ALL, "Teams have been balanced"); // update all objects - for(CEntity *pEnt = m_pFirstEntity; pEnt; pEnt = pEnt->m_pNextEntity) + for(CEntity *pEnt = m_pFirstEntity; pEnt; ) + { + m_pNextTraverseEntity = pEnt->m_pNextEntity; pEnt->Tick(); + pEnt = m_pNextTraverseEntity; + } - for(CEntity *pEnt = m_pFirstEntity; pEnt; pEnt = pEnt->m_pNextEntity) + for(CEntity *pEnt = m_pFirstEntity; pEnt; ) + { + m_pNextTraverseEntity = pEnt->m_pNextEntity; pEnt->TickDefered(); + pEnt = m_pNextTraverseEntity; + } } RemoveEntities(); diff --git a/src/game/server/gameworld.h b/src/game/server/gameworld.h index 86ac6a0c..62d1e58c 100644 --- a/src/game/server/gameworld.h +++ b/src/game/server/gameworld.h @@ -24,6 +24,7 @@ class CGameWorld }; // TODO: two lists seams kinda not good, shouldn't be needed + CEntity *m_pNextTraverseEntity; CEntity *m_pFirstEntity; CEntity *m_apFirstEntityTypes[NUM_ENT_TYPES]; |