void CProjectileHandler::Update()
{
    SCOPED_TIMER("Projectile handler");

    Projectile_List::iterator psi=ps.begin();
    while(psi!= ps.end()) {
        CProjectile *p = *psi;
        if(p->deleteMe) {
            Projectile_List::iterator prev=psi++;
            ps.erase(prev);
            delete p;
        } else {
            (*psi)->Update();
            ++psi;
        }
    }

    for(unsigned int i = 0; i < groundFlashes.size();)
    {
        CGroundFlash *gf = groundFlashes[i];
        if (!gf->Update ())
        {
            // swap gf with the groundflash at the end of the list, so pop_back() can be used to erase it
            if ( i < groundFlashes.size()-1 )
                std::swap (groundFlashes.back(), groundFlashes[i]);
            groundFlashes.pop_back();
            delete gf;
        } else i++;
    }

    for(std::list<FlyingPiece_List*>::iterator pti=flyingPieces.begin(); pti!=flyingPieces.end(); ++pti) {
        FlyingPiece_List * fpl = *pti;
        /* Note: nothing in the third clause of this loop. TODO Rewrite it as a while */
        for(std::list<FlyingPiece*>::iterator pi=fpl->begin(); pi!=fpl->end();) {
            (*pi)->pos+=(*pi)->speed;
            (*pi)->speed*=0.996f;
            (*pi)->speed.y+=gs->gravity;
            (*pi)->rot+=(*pi)->rotSpeed;
            if((*pi)->pos.y<ground->GetApproximateHeight((*pi)->pos.x,(*pi)->pos.z)-10) {
                delete *pi;
                pi=fpl->erase(pi);
            } else {
                ++pi;
            }
        }
    }
}
void CProjectileHandler::Update()
{
	CheckCollisions();

	{
		SCOPED_TIMER("ProjectileHandler::Update");
		GML_UPDATE_TICKS();

		UpdateProjectileContainer(syncedProjectiles, true);
		UpdateProjectileContainer(unsyncedProjectiles, false);


		{
			GML_STDMUTEX_LOCK(rproj); // Update

			if (syncedProjectiles.can_delete_synced()) {
#if !DETACH_SYNCED
				GML_RECMUTEX_LOCK(proj); // Update
#endif

				eventHandler.DeleteSyncedProjectiles();
				//! delete all projectiles that were
				//! queued (push_back'ed) for deletion
#if DETACH_SYNCED
				syncedProjectiles.detach_erased_synced();
#else
				syncedProjectiles.delete_erased_synced();
#endif
			}

			eventHandler.UpdateProjectiles();
		}


		GroundFlashContainer::iterator gfi = groundFlashes.begin();
		while (gfi != groundFlashes.end()) {
			CGroundFlash* gf = *gfi;

			if (!gf->Update()) {
				gfi = groundFlashes.erase_delete(gfi);
			} else {
				++gfi;
			}
		}

		{
			GML_STDMUTEX_LOCK(rflash); // Update

			groundFlashes.delay_delete();
			groundFlashes.delay_add();
		}

		#define UPDATE_FLYING_PIECES(fpContainer)                                        \
			FlyingPieceContainer::iterator pti = fpContainer.begin();                    \
                                                                                         \
			while (pti != fpContainer.end()) {                                           \
				FlyingPiece* p = *pti;                                                   \
				p->pos     += p->speed;                                                  \
				p->speed   *= 0.996f;                                                    \
				p->speed.y += mapInfo->map.gravity; /* fp's are not projectiles */       \
				p->rot     += p->rotSpeed;                                               \
                                                                                         \
				if (p->pos.y < ground->GetApproximateHeight(p->pos.x, p->pos.z - 10)) {  \
					pti = fpContainer.erase_delete_set(pti);                             \
				} else {                                                                 \
					++pti;                                                               \
				}                                                                        \
			}

		{ UPDATE_FLYING_PIECES(flyingPieces3DO); }
		{ UPDATE_FLYING_PIECES(flyingPiecesS3O); }
		#undef UPDATE_FLYING_PIECES

		{
			GML_STDMUTEX_LOCK(rpiece); // Update

			flyingPieces3DO.delay_delete();
			flyingPieces3DO.delay_add();
			flyingPiecesS3O.delay_delete();
			flyingPiecesS3O.delay_add();
		}
	}
}
void CProjectileHandler::Update()
{
	SCOPED_TIMER("Projectile Update");

	GML_UPDATE_TICKS();

	UpdateProjectileContainer(syncedProjectiles, true);
	UpdateProjectileContainer(unsyncedProjectiles, false);


	{
		GML_STDMUTEX_LOCK(rproj); // Update

		if (syncedProjectiles.can_delete_synced()) {
			GML_STDMUTEX_LOCK(proj); // Update

			//! delete all projectiles that were
			//! queued (push_back'ed) for deletion
			syncedProjectiles.delete_erased_synced();
		}

		//! prepare projectile batches for
		//! addition into the render queue
		syncedProjectiles.delay_add();

		unsyncedProjectiles.delay_delete();
		unsyncedProjectiles.delay_add();
	}


	GroundFlashContainer::iterator gfi = groundFlashes.begin();
	while (gfi != groundFlashes.end()) {
		CGroundFlash* gf = *gfi;

		if (!gf->Update())
			gfi = groundFlashes.erase_delete(gfi);
		else
			++gfi;
	}

	{
		GML_STDMUTEX_LOCK(rflash); // Update

		groundFlashes.delay_delete();
		groundFlashes.delay_add();
	}

	FlyingPieceContainer::iterator pti = flyingPieces.begin();
	while (pti != flyingPieces.end()) {
		FlyingPiece* p = *pti;
		p->pos     += p->speed;
		p->speed   *= 0.996f;
		p->speed.y += mapInfo->map.gravity; //! fp's are not projectiles
		p->rot     += p->rotSpeed;

		if (p->pos.y < ground->GetApproximateHeight(p->pos.x, p->pos.z - 10))
			pti = flyingPieces.erase_delete_set(pti);
		else
			++pti;
	}

	{
		GML_STDMUTEX_LOCK(rpiece); // Update

		flyingPieces.delay_delete();
		flyingPieces.delay_add();
	}
}
Exemple #4
0
void CProjectileHandler::Update()
{
	GML_RECMUTEX_LOCK(lua); // Update
	GML_RECMUTEX_LOCK(proj); // Update

	SCOPED_TIMER("Projectile handler");

	GML_UPDATE_TICKS();

	Projectile_List::iterator psi = ps.begin();
	while (psi != ps.end()) {
		CProjectile* p = *psi;

		if (p->deleteMe) {
			Projectile_List::iterator prev = psi++;
			ps.erase(prev);

			if (p->synced && p->weapon) {
				// iterator is always valid
				ProjectileMap::iterator it = weaponProjectileIDs.find(p->id);
				const ProjectileMapPair& pp = it->second;

				eventHandler.ProjectileDestroyed(pp.first, pp.second);
				weaponProjectileIDs.erase(it);
				if (p->id != 0) {
					freeIDs.push_back(p->id);
				}
			}

			delete p;
		} else {
			p->Update();
			GML_GET_TICKS(p->lastProjUpdate);
			++psi;
		}
	}

	for (unsigned int i = 0; i < groundFlashes.size(); /* do nothing */) {
		CGroundFlash *gf = groundFlashes[i];
		if (!gf->Update ()) {
			// swap gf with the groundflash at the end of the list, so pop_back() can be used to erase it
			if (i < groundFlashes.size() - 1) {
				std::swap(groundFlashes.back(), groundFlashes[i]);
			}
			groundFlashes.pop_back();
			delete gf;
		} else {
			i++;
		}
	}

	for (list<FlyingPiece_List*>::iterator pti = flyingPieces.begin(); pti != flyingPieces.end(); ++pti) {
		FlyingPiece_List* fpl = *pti;
		FlyingPiece_List::iterator pi = fpl->begin();
		while ( pi != fpl->end() ) {
			FlyingPiece* p = *pi;
			p->pos     += p->speed;
			p->speed   *= 0.996f;
			p->speed.y += mapInfo->map.gravity;
			p->rot     += p->rotSpeed;

			if (p->pos.y < ground->GetApproximateHeight(p->pos.x, p->pos.z - 10)) {
				if (p->verts != NULL){
					delete[] p->verts;
				}
				delete p;
				pi = fpl->erase(pi);
			} else {
				++pi;
			}
		}
	}
}