Beispiel #1
0
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);
	}
}