void CProjectileHandler::UpdateProjectileContainer(ProjectileContainer& pc, bool synced) { // WARNING: // we can't use iterators here because ProjectileCreated // and ProjectileDestroyed events may add new projectiles // to the container! for (size_t i = 0; i < pc.size(); /*no-op*/) { CProjectile* p = pc[i]; assert(p != nullptr); assert(p->synced == synced); #ifdef USING_CREG assert(p->synced == !!(p->GetClass()->binder->flags & creg::CF_Synced)); #endif // creation if (p->callEvent) { if (synced || !UNSYNCED_PROJ_NOEVENT) eventHandler.ProjectileCreated(p, p->GetAllyteamID()); eventHandler.RenderProjectileCreated(p); p->callEvent = false; } // deletion (FIXME: move outside of loop) if (p->deleteMe) { pc[i] = pc.back(); pc.pop_back(); eventHandler.RenderProjectileDestroyed(p); if (synced) { eventHandler.ProjectileDestroyed(p, p->GetAllyteamID()); syncedProjectileIDs[p->id] = nullptr; freeSyncedIDs.push_back(p->id); ASSERT_SYNCED(p->pos); ASSERT_SYNCED(p->id); } else { #if !UNSYNCED_PROJ_NOEVENT eventHandler.ProjectileDestroyed(p, p->GetAllyteamID()); unsyncedProjectileIDs[p->id] = nullptr; freeUnsyncedIDs.push_back(p->id); #endif } projMemPool.free(p); continue; } // neither ++i; } SCOPED_TIMER("Sim::Projectiles::Update"); // WARNING: same as above but for p->Update() for (size_t i = 0; i < pc.size(); ++i) { CProjectile* p = pc[i]; assert(p != nullptr); MAPPOS_SANITY_CHECK(p->pos); p->Update(); quadField->MovedProjectile(p); MAPPOS_SANITY_CHECK(p->pos); } }