void CArrow::Update(float eTime) { IScene::Update(eTime); pos.x += cos(rot) * speed * eTime; pos.y += sin(rot) * speed * eTime; if (pos.y > App::HEIGHT + 200) { this->parent->PopScene(this); return; } RECT arrowRect, playerRect, tempRect; //RECT ¼³Á¤ arrowRect.left = pos.x + rotatingCenter.x - 1; arrowRect.right = pos.x + rotatingCenter.x + 1; arrowRect.top = pos.y + rotatingCenter.y - 1; arrowRect.bottom = pos.y + rotatingCenter.y + 1; CGameScene *gs = (CGameScene*)this->parent->parent; CPlayer *player = gs->m_pPlayer; playerRect.left = player->pos.x; playerRect.right = player->pos.x + player->normalAni->width; playerRect.top = player->pos.y; playerRect.bottom = player->pos.y + player->normalAni->height; // if (IntersectRect(&tempRect, &playerRect, &arrowRect) == true) { CParticleSystem *p = gs->PushEffect(pos.x + rotatingCenter.x, pos.y + rotatingCenter.y); p->start(); this->parent->PopScene(this); return; } }
CParticleSystem* CGameScene::PushEffect(float x, float y) { CParticleSystem *p = new CParticleSystem("resource/particle/particle.png",50); p->SetPosition(x, y); m_pEffectScene->PushScene(p); return p; }
//======================================================================= ///////////////////////////////////////// // temp until there is a clone method // ///////////////////////////////////////// NL3D::CPSLocatedBindable *DupPSLocatedBindable(CPSLocatedBindable *in) { if (!in) return NULL; try { // if no owner, can copy the object directy if (in->getOwner() == NULL) { return DupSerializable<CDupPolymorphicObjPolicy>(in); } else { CParticleSystem *srcPS = in->getOwner()->getOwner(); std::auto_ptr<CParticleSystem> newPS(DupSerializable<CDupObjPolicy>(srcPS)); // scene pointer is not serialised, but 'detach' may need the scene to be specified newPS->setScene(in->getOwner()->getOwner()->getScene()); // uint index = srcPS->getIndexOf(*(in->getOwner())); uint subIndex = in->getOwner()->getIndexOf(in); // newPS->setScene(in->getOwner()->getScene()); // 'unbind' require the scene to be attached CPSLocated *loc = NLMISC::safe_cast<CPSLocated *>(newPS->getProcess(index)); return loc->unbind(subIndex); } } catch (NLMISC::EStream &e) { nlwarning (e.what()); return NULL; } }
void CParticleSystemManager::AddNewSystem(const std::string &name) { TParticleSystemSettings* settings = CORE->GetParticleSettingsManager()->GetResource(name); assert(settings); CParticleSystem* system = new CParticleSystem(name, settings); this->AddResource(name, system); system->Initialize(); }
void CParticleSystemManager :: UpdateSystems( void ) { float frametime; static int framecount = -1; AURSTATE state; // HACKHACK: don't evaluate particles when executes many times at same frame // e.g. mirror rendering if( framecount != tr.realframecount ) { frametime = RI.refdef.frametime; framecount = tr.realframecount; } else frametime = 0.0f; CParticleSystem *pSystem; CParticleSystem *pLast = NULL; pSystem = m_pFirstSystem; while( pSystem ) { state = pSystem->UpdateSystem( frametime ); if( state != AURORA_REMOVE ) { if( state == AURORA_DRAW ) pSystem->DrawSystem(); pLast = pSystem; pSystem = pSystem->m_pNextSystem; } else { // delete this system if( pLast ) { pLast->m_pNextSystem = pSystem->m_pNextSystem; delete pSystem; pSystem = pLast->m_pNextSystem; } else { // deleting the first system m_pFirstSystem = pSystem->m_pNextSystem; delete pSystem; pSystem = m_pFirstSystem; } } } gEngfuncs.pTriAPI->RenderMode(kRenderNormal); }
void CParticleManager::Cleanup (void) { WaitForEffectsThread (); int nCurrent = -1; for (CParticleSystem* systemP = GetFirst (nCurrent), * nextP = NULL; systemP; systemP = nextP) { nextP = GetNext (nCurrent); if (systemP->m_bDestroy) { systemP->Destroy (); m_systems.Push (systemP->m_nId); } } }
void CParticleManager::Render(LPDIRECT3DDEVICE7 _lpD3DDevice) { int ilekel = 0; list<CParticleSystem *>::iterator i; for (i = listParticleSystem.begin(); i != listParticleSystem.end(); ++i) { CParticleSystem * p = *i; p->Render(_lpD3DDevice); ilekel++; } }
void CEnemy1::Update(float eTime) { IEnemy::Update(eTime); CGameScene *gs = (CGameScene*)this->parent->parent; if (hp <= 0) { CParticleSystem *p = gs->PushEffect(pos.x + ani->width/2, pos.y + ani->height/2 + 55.0f); p->setScalep(4.0f, 5.0f); p->direction = -90; p->spread = 30; p->setSpeed(400.0f, 700.0f); p->start(); CGSoundManager * sm = App::GetInstance()->g_pSoundManager; sm->Play(2); this->parent->PopScene(this); return; } time += eTime; time2 += eTime; if (pos.y < 50) { pos.y += 150 * eTime; if (pos.y > 50) pos.y = 50; } if (time > 3.0f) { gs->PushEffect(this->pos.x+20, this->pos.y + 140); gs->PushArrow(this->pos.x - 65, this->pos.y + 170, D3DX_PI / 2); gs->PushArrow(this->pos.x - 65, this->pos.y + 170, D3DX_PI / 2 - 0.4); gs->PushArrow(this->pos.x - 65, this->pos.y + 170, D3DX_PI / 2 + 0.4); time = 0.f; } if (time2 > 7.0f) { pos.y += 700 * eTime; } if (pos.y > App::HEIGHT) { this->parent->PopScene(this); return; } }
///=========================================================================== void CParticleSystemShape::render(IDriver *drv, CTransformShape *trans, bool passOpaque) { H_AUTO ( NL3D_Particles_Render ); nlassert(drv); CParticleSystemModel *psm = NLMISC::safe_cast<CParticleSystemModel *>(trans); if (psm->_Invalidated) return; CParticleSystem *ps = psm->getPS(); /// has the system been triggered yet ? if (!ps) return; TAnimationTime delay = psm->getEllapsedTime(); nlassert(ps->getScene()); /////////////////////// // render particles // /////////////////////// /// if sharing is enabled, we should resetup the system matrix if (ps->isSharingEnabled()) { ps->setSysMat(&(psm->getWorldMatrix())); ps->setUserMatrix(&(psm->getUserMatrix())); } // Setup the matrix. /// drv->setupModelMatrix(trans->getWorldMatrix()); ps->setDriver(drv); // draw particle PARTICLES_CHECK_MEM; if (passOpaque) { PSLookAtRenderTime = 0; //NLMISC::TTicks start = NLMISC::CTime::getPerformanceTime(); ps->step(CParticleSystem::SolidRender, delay, *this, *psm); /*NLMISC::TTicks end = NLMISC::CTime::getPerformanceTime(); nlinfo("Solid render time time = %.2f", (float) (1000 * NLMISC::CTime::ticksToSecond(end - start))); nlinfo("LookAt Render time = %.2f", (float) (1000 * NLMISC::CTime::ticksToSecond(PSLookAtRenderTime))); */ } else { //PSLookAtRenderTime = 0; //NLMISC::TTicks start = NLMISC::CTime::getPerformanceTime(); ps->step(CParticleSystem::BlendRender, delay, *this, *psm); /*NLMISC::TTicks end = NLMISC::CTime::getPerformanceTime(); nlinfo("Blend render time time = %.2f", (float) (1000 * NLMISC::CTime::ticksToSecond(end - start))); nlinfo("LookAt Render time = %.2f", (float) (1000 * NLMISC::CTime::ticksToSecond(PSLookAtRenderTime))); */ } PARTICLES_CHECK_MEM; if (psm->isToolDisplayEnabled()) { ps->step(CParticleSystem::ToolRender, delay, *this, *psm); PARTICLES_CHECK_MEM; } }
void CGameScene::Update(float eTime) { IScene::Update(eTime); time += eTime; bulletTime += eTime; if (time >= delay) { delay = (float)(rand() % 1000) / 300.f; time = 0.f; //this->PushArrow(rand() % App::WIDTH, -200.0f); this->PushEnemy1(rand() % App::WIDTH, -200.0f); } //this->PushEffect(rand() % App::WIDTH, rand() % App::HEIGHT); for (auto iter = m_pBulletScene->children.begin(); iter != m_pBulletScene->children.end();iter++) { CBullet *bullet = (CBullet*)(*iter); RECT bulletRect; bulletRect.left = bullet->pos.x; bulletRect.top = bullet->pos.y; bulletRect.right = bullet->pos.x + bullet->sprite->width; bulletRect.bottom = bullet->pos.y + bullet->sprite->height; for (auto iter2 = m_pEnemyScene->children.begin(); iter2 != m_pEnemyScene->children.end();iter2++) { IEnemy *enemy = (IEnemy*)(*iter2); RECT enemyRect; enemyRect.left = enemy->pos.x; enemyRect.top = enemy->pos.y; enemyRect.right = enemy->pos.x + enemy->width; enemyRect.bottom = enemy->pos.y + enemy->height; RECT t; if (IntersectRect(&t, &bulletRect, &enemyRect) == true) { CParticleSystem *p = PushEffect(bullet->pos.x, bullet->pos.y); p->start(); bullet->available = false; enemy->hit(); break; } } } }
// tbh highly inefficent but we shouldn't have any large number of ps's, // and we won't be force removing very often so this won't be too bad void CParticleSystemManager::RemoveSystem( unsigned int iSystem ) { unsigned int i = 0; unsigned int iSystems = m_pParticleSystems.size(); CParticleSystem *pSystem = NULL; for (; i < iSystems; i++) { pSystem = m_pParticleSystems[i]; // i != the system id, as the server or the client can generate these if(pSystem && pSystem->SystemID() == iSystem) { delete pSystem; m_pParticleSystems.erase(m_pParticleSystems.begin() + i); i--; iSystems--; } } }
///=========================================================================== void CParticleSystemShape::buildFromPS(const CParticleSystem &ps) { // must be sure that we are writting in the stream if (_ParticleSystemProto.isReading()) { _ParticleSystemProto.invert(); } // to have const correctness in the prototype, we must do this... CParticleSystem *myPs = const_cast<CParticleSystem *>(&ps); nlassert(myPs); // build the prototype _ParticleSystemProto.serialPtr(myPs); // mirror some system values _MaxViewDist = myPs->getMaxViewDist(); _DestroyWhenOutOfFrustum = myPs->doesDestroyWhenOutOfFrustum(); _DestroyModelWhenOutOfRange = myPs->getDestroyModelWhenOutOfRange(); if (!myPs->getAutoComputeBBox()) { _UsePrecomputedBBox = true; myPs->computeBBox(_PrecomputedBBox); } else { _UsePrecomputedBBox = false; } _Sharing = myPs->isSharingEnabled(); }
void CParticleManager::RebuildSystemList (void) { #if 0 m_nUsed = m_nFree = -1; CParticleSystem *systemP = m_systems; for (int i = 0; i < MAX_PARTICLE_SYSTEMS; i++, systemP++) { if (systemP->HasEmitters ()) { systemP->SetNext (m_nUsed); m_nUsed = i; } else { systemP->Destroy (); systemP->SetNext (m_nFree); m_nFree = i; } } #endif }
//----------------------------------------------------------------------------- void CParticleManager::Update(long _lTime) { if (!listParticleSystem.size()) return; list<CParticleSystem *>::iterator i; i = listParticleSystem.begin(); while (i != listParticleSystem.end()) { CParticleSystem * p = *i; ++i; if (!p->IsAlive()) { delete p; listParticleSystem.remove(p); } else { p->Update(_lTime); } } }
void CParticleManager::Init (void) { #if OGL_VERTEX_BUFFERS GLfloat pf = colorBuffer; for (i = 0; i < VERT_BUFFER_SIZE; i++, pf++) { *pf++ = 1.0f; *pf++ = 1.0f; *pf++ = 1.0f; } #endif if (!m_objectSystems.Buffer ()) { if (!m_objectSystems.Create (LEVEL_OBJECTS)) { Shutdown (); extraGameInfo [0].bUseParticles = 0; return; } m_objectSystems.Clear (0xff); } if (!m_objExplTime.Buffer ()) { if (!m_objExplTime.Create (LEVEL_OBJECTS)) { Shutdown (); extraGameInfo [0].bUseParticles = 0; return; } m_objExplTime.Clear (0); } if (!m_systems.Create (MAX_PARTICLE_SYSTEMS)) { Shutdown (); extraGameInfo [0].bUseParticles = 0; return; } int i = 0; int nCurrent = m_systems.FreeList (); for (CParticleSystem* systemP = m_systems.GetFirst (nCurrent); systemP; systemP = GetNext (nCurrent)) systemP->Init (i++); }
void CGameScene::PushEffect(float x, float y) { CParticleSystem *p = new CParticleSystem("resource/particle/particle.png", 50); p->SetPosition(x, y); p->setScalep(1, 1); p->setColor1(400, 200, 220, 200); p->setLife(0.2, 0.3); m_pEffectScene->PushScene(p); p->start(); }
CEmpoweringCurse::CEmpoweringCurse(void) { duration = 0; ChatBubbleID = CSGD_TextureManager::GetInstance()->LoadTexture(_T("Resources/Graphics/ChatBubble.png")); for(unsigned int i = 0; i < CEnemy::GetInstance()->GetUnits().size(); i++) { CParticleSystem* power = new CParticleSystem; power->LoadEffect("Empower","Resources/XMLFiles/EmpoweringCurse.xml"); power->CreateEmitter("Empower"); power->GetEffect(0)->KillParticles(); pEmpower.push_back(power); } empowerID = CSGD_XAudio2::GetInstance()->SFXLoadSound(_T("Resources/Sounds/empowering_curse.wav")); CSGD_XAudio2::GetInstance()->SFXPlaySound(empowerID); pFont = CGame::GetInstance()->GetFont(); bChat = false; { int randNum = rand() % 100; if(randNum < 50) { bChat = true; phrase.push_back(_T("Kill the living!")); phrase.push_back(_T("MORE CHAOS!!!")); phrase.push_back(_T("Leave nothing!")); this->phraseToUse = rand() % 3; } } }
//----------------------------------------------------------------------------- // Purpose: Stick to an entity (using hierarchy if we can) // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CWeaponStriderBuster::StickToEntity( CBaseEntity *pOther ) { // Make sure the object is travelling fast enough to stick if ( m_flCollisionSpeedSqr > 50 && !m_bNoseDiving ) { // See if this is a valid strider bit if ( ShouldStickToEntity( pOther ) ) { // Attempt to constraint to it if ( CreateConstraintToObject( pOther ) ) { // Only works for striders, at the moment CBaseEntity *pFollowParent = pOther->GetOwnerEntity(); if ( pFollowParent == NULL ) return false; // Allows us to identify our constrained object later SetOwnerEntity( pFollowParent ); // Make a sound EmitSound( "Weapon_StriderBuster.StickToEntity" ); DispatchParticleEffect( "striderbuster_attach", GetAbsOrigin(), GetAbsAngles(), NULL ); if( striderbuster_use_particle_flare.GetBool() ) { // We don't have to save any pointers or handles to this because it's parented to the buster. // So it will die when the buster dies. Yay. CParticleSystem *pFlare = (CParticleSystem *) CreateEntityByName( "info_particle_system" ); if ( pFlare != NULL ) { pFlare->KeyValue( "start_active", "1" ); pFlare->KeyValue( "effect_name", "striderbuster_attached_pulse" ); pFlare->SetParent( this ); pFlare->SetLocalOrigin( vec3_origin ); DispatchSpawn( pFlare ); pFlare->Activate(); } } else { // Create a glow sprite m_hGlowSprite = CSprite::SpriteCreate( "sprites/orangeflare1.vmt", GetLocalOrigin(), false ); Assert( m_hGlowSprite ); if ( m_hGlowSprite != NULL ) { m_hGlowSprite->TurnOn(); m_hGlowSprite->SetTransparency( kRenderWorldGlow, 255, 255, 255, 255, kRenderFxNoDissipation ); m_hGlowSprite->SetAbsOrigin( GetAbsOrigin() ); m_hGlowSprite->SetScale( 5.0f ); m_hGlowSprite->m_nRenderFX = kRenderFxStrobeFaster; m_hGlowSprite->SetGlowProxySize( 16.0f ); m_hGlowSprite->SetParent( this ); } } // Stop touching things SetTouch( NULL ); // Must be a strider CNPC_Strider *pStrider = dynamic_cast<CNPC_Strider *>(pFollowParent); if ( pStrider == NULL ) return false; // Notify the strider we're attaching to him pStrider->StriderBusterAttached( this ); m_OnAttachToStrider.FireOutput( this, this ); // Start the ping sound. SetContextThink( &CWeaponStriderBuster::BusterPingThink, gpGlobals->curtime + BUSTER_PING_SOUND_FREQ, s_pBusterPingThinkContext ); // Don't autodelete this one! WeaponManager_RemoveManaged( this ); return true; } return false; } } return false; }
// updates all systems void CParticleSystemManager::UpdateSystems( void ) { CParticleSystem *pSystem = NULL; signed int i = 0; signed int iSystems = (signed)m_pParticleSystems.size(); // iterate through all the particle systems, drawing each for (; i < iSystems; i++) { pSystem = m_pParticleSystems[i]; // remove the system if the system requests it if( pSystem && pSystem->DrawSystem() == false) { delete pSystem; m_pParticleSystems.erase((m_pParticleSystems.begin() + i)); i--; iSystems--; } } // we couldn't return earlier as we need to have the sorting before the ps updating // however no sorting when we can't see the particles if(CheckDrawSystem() == false) return; int iParticles = m_pParticles.size(); if(iParticles > 1) { // calculate the fraction of a second between sorts float flTimeSinceLastSort = (gEngfuncs.GetClientTime() - m_flLastSort); // 1 / time between sorts will give us a number like 5 // if it is less than the particlesorts cvar then it is a small value // and therefore a long time since last sort if((((int)(1 / flTimeSinceLastSort)) < g_ParticleSorts->value)) { m_flLastSort = gEngfuncs.GetClientTime(); std::sort(m_pParticles.begin(), m_pParticles.end(), less_than); } } if(iParticles > 0) { // prepare opengl Particle_InitOpenGL(); float flTimeSinceLastDraw = TimeSinceLastDraw(); // loop through all particles drawing them // they have already been tested and updated in their pss' draw sys func // we've reversed the greater than order, so that oldest particles are at 0 // further away particles and recently added particles get drawn first CParticle *pParticle = NULL; for(i = 0; i < iParticles ; i++) { if(m_pParticles[i]) { pParticle = m_pParticles[i]; if(pParticle && pParticle->Test()) { pParticle->Update(flTimeSinceLastDraw); if(g_iUser1 != OBS_MAP_FREE && g_iUser1 != OBS_MAP_CHASE) { // unfortunately we have to prepare every particle now // as we can't prepare for a batch of the same type anymore pParticle->Prepare(); pParticle->Draw(); } } else { RemoveParticle(pParticle); i--; iParticles--; } } } Particle_FinishOpenGL(); } // print out how fast we've been drawing the systems in debug mode if (g_ParticleDebug->value != 0 && ((m_flLastSort + 0.5) <= gEngfuncs.GetClientTime())) { gEngfuncs.Con_Printf("%i Particles Drawn this pass in %i systems ", m_pParticles.size(), m_pParticleSystems.size()); gEngfuncs.Con_Printf("%i Textures in Cache\n\0", m_pTextures.size()); } m_flLastDraw = gEngfuncs.GetClientTime(); }
///=========================================================================== void CParticleSystemShape::flushTextures(IDriver &driver, uint selectedTexture) { // if textures are already flushed, no-op if (!_CachedTex.empty()) return; if (_SharedSystem) { _SharedSystem->enumTexs(_CachedTex, driver); } else { s_PSSMutex.enter(); // must create an instance just to flush the textures CParticleSystem *myInstance = NULL; #ifdef PS_FAST_ALLOC nlassert(PSBlockAllocator == NULL); NLMISC::CContiguousBlockAllocator blockAllocator; PSBlockAllocator = &blockAllocator; blockAllocator.init(300000); // we release memory just after, and we don't want to fragment the memory, so provide large enough mem #endif // serialize from the memory stream if (!_ParticleSystemProto.isReading()) // we must be sure that we are reading the stream { _ParticleSystemProto.invert(); } _ParticleSystemProto.resetPtrTable(); _ParticleSystemProto.seek(0, NLMISC::IStream::begin); _ParticleSystemProto.serialPtr(myInstance); // instanciate the system #ifdef PS_FAST_ALLOC _NumBytesWanted = blockAllocator.getNumAllocatedBytes(); // next allocation will be fast because we know how much memory to allocate #endif myInstance->enumTexs(_CachedTex, driver); // tmp /* #ifdef NL_DEBUG for(uint k = 0; k < myInstance->getNbProcess(); ++k) { CPSLocated *loc = (CPSLocated *) myInstance->getProcess(k); for(uint l = 0; l < loc->getNbBoundObjects(); ++l) { if (dynamic_cast<CPSCentralGravity *>(loc->getBoundObject(l))) { nlwarning("PS %s uses central gravity", myInstance->getName().c_str()); break; } } } #endif */ // sort the process inside the fx myInstance->getSortingByEmitterPrecedence(_ProcessOrder); delete myInstance; #ifdef PS_FAST_ALLOC PSBlockAllocator = NULL; #endif s_PSSMutex.leave(); } for(uint k = 0; k < _CachedTex.size(); ++k) { //nlinfo(_CachedTex[k]->getShareName().c_str()); if (_CachedTex[k]) { _CachedTex[k]->setTextureCategory(CPSTextureCategory::get()); driver.setupTexture(*_CachedTex[k]); } } }
///=========================================================================== CParticleSystem *CParticleSystemShape::instanciatePS(CScene &scene, NLMISC::CContiguousBlockAllocator *blockAllocator /*= NULL*/) { if (_Sharing && _SharedSystem != NULL) // is sharing enabled, and is a system already instanciated { return _SharedSystem; } // avoid prb with concurrent thread (may happen if an instance group containing ps is loaded in background) s_PSSMutex.enter(); #ifdef PS_FAST_ALLOC nlassert(PSBlockAllocator == NULL); if (blockAllocator) { // set new allocator for particle system memory PSBlockAllocator = blockAllocator; blockAllocator->init(_NumBytesWanted); // if size wanted is already known, set it } #endif //NLMISC::TTicks start = NLMISC::CTime::getPerformanceTime(); // copy the datas CParticleSystem *myInstance = NULL; // serialize from the memory stream if (!_ParticleSystemProto.isReading()) // we must be sure that we are reading the stream { _ParticleSystemProto.invert(); } _ParticleSystemProto.resetPtrTable(); _ParticleSystemProto.seek(0, NLMISC::IStream::begin); // NLMISC::TTicks start = NLMISC::CTime::getPerformanceTime(); _ParticleSystemProto.serialPtr(myInstance); // instanciate the system /* NLMISC::TTicks end = NLMISC::CTime::getPerformanceTime(); nlinfo("instanciation time = %.2f", (float) (1000 * NLMISC::CTime::ticksToSecond(end - start))); */ myInstance->setScene(&scene); if (_CachedTex.empty() && scene.getDriver()) { //nlinfo("flushing texs"); // load && cache textures myInstance->enumTexs(_CachedTex, *scene.getDriver()); for(uint k = 0; k < _CachedTex.size(); ++k) { if (_CachedTex[k]) { _CachedTex[k]->setTextureCategory(CPSTextureCategory::get()); scene.getDriver()->setupTexture (*(ITexture *)_CachedTex[k]); } } } else { /* for(uint k = 0; k < _CachedTex.size(); ++k) { nlinfo(_CachedTex[k]->getShareName().c_str()); } */ } // tmp if (_Sharing) { _SharedSystem = myInstance; // set this as the first shared instance } #ifdef PS_FAST_ALLOC if (blockAllocator) { _NumBytesWanted = blockAllocator->getNumAllocatedBytes(); // now we know the number of wanted bytes, subsequent alloc can be much faster PSBlockAllocator = NULL; } #endif s_PSSMutex.leave(); /*NLMISC::TTicks end = NLMISC::CTime::getPerformanceTime(); nlinfo("instanciation time = %.2f", (float) (1000 * NLMISC::CTime::ticksToSecond(end - start))); */ return myInstance; }
void UpdateScene(void) { particles.Spawn(); redraw(); }
//----------------------------------------------------------------------------- void LaunchPoisonExplosion(EERIE_3D * aePos) { // système de partoches pour l'explosion CParticleSystem * pPS = new CParticleSystem(); CParticleParams cp; cp.iNbMax = 80; cp.fLife = 1500; cp.fLifeRandom = 500; cp.p3Pos.x = 5; cp.p3Pos.y = 5; cp.p3Pos.z = 5; cp.p3Direction.x = 0; cp.p3Direction.y = 4; cp.p3Direction.z = 0; cp.fAngle = DEG2RAD(360); cp.fSpeed = 200; cp.fSpeedRandom = 0; cp.p3Gravity.x = 0; cp.p3Gravity.y = 17; cp.p3Gravity.z = 0; cp.fFlash = 0; cp.fRotation = 80; cp.bRotationRandomDirection = true; cp.bRotationRandomStart = true; cp.fStartSize = 5; cp.fStartSizeRandom = 3; cp.fStartColor[0] = 0; cp.fStartColor[1] = 76; cp.fStartColor[2] = 0; cp.fStartColor[3] = 0; cp.fStartColorRandom[0] = 0; cp.fStartColorRandom[1] = 0; cp.fStartColorRandom[2] = 0; cp.fStartColorRandom[3] = 150; cp.bStartLock = false; cp.fEndSize = 30; cp.fEndSizeRandom = 5; cp.fEndColor[0] = 0; cp.fEndColor[1] = 0; cp.fEndColor[2] = 0; cp.fEndColor[3] = 0; cp.fEndColorRandom[0] = 0; cp.fEndColorRandom[1] = 25; cp.fEndColorRandom[2] = 0; cp.fEndColorRandom[3] = 20; cp.bEndLock = false; cp.iBlendMode = 3; cp.iFreq = -1; cp.bTexInfo = FALSE; pPS->SetParams(cp); pPS->ulParticleSpawn = 0; pPS->SetTexture("graph\\particles\\big_greypouf.bmp", 0, 200); pPS->SetPos(*aePos); pPS->Update(0); pPS->iParticleNbMax = 0; list<CParticle *>::iterator i; for (i = pPS->listParticle.begin(); i != pPS->listParticle.end(); ++i) { CParticle * pP = *i; if (pP->isAlive()) { if (pP->p3Velocity.y >= 0.5f * 200) pP->p3Velocity.y = 0.5f * 200; if (pP->p3Velocity.y <= -0.5f * 200) pP->p3Velocity.y = -0.5f * 200; } } if (pParticleManager) { pParticleManager->AddSystem(pPS); } }
//----------------------------------------------------------------------------- void LaunchMagicMissileExplosion(EERIE_3D & _ePos, int t = 0, long spellinstance = -1) { // système de partoches pour l'explosion CParticleSystem * pPS = new CParticleSystem(); CParticleParams cp; cp.iNbMax = 100 + t * 50; cp.fLife = 1500; cp.fLifeRandom = 0; cp.p3Pos.x = 10; cp.p3Pos.y = 10; cp.p3Pos.z = 10; cp.p3Direction.x = 0; cp.p3Direction.y = -10; cp.p3Direction.z = 0; cp.fAngle = DEG2RAD(360); cp.fSpeed = 130; cp.fSpeedRandom = 100; cp.p3Gravity.x = 0; cp.p3Gravity.y = 10; cp.p3Gravity.z = 0; cp.fFlash = 0; cp.fRotation = 16; cp.fStartSize = 5; cp.fStartSizeRandom = 10; cp.fEndSize = 0; cp.fEndSizeRandom = 2; if ((spellinstance >= 0) && (spells[spellinstance].caster == 0) && (cur_mr == 3)) { cp.fStartSize = 20; cp.fSpeed = 13; cp.fSpeedRandom = 10; cp.fStartColorRandom[0] = 0; cp.fStartColorRandom[1] = 0; cp.fStartColorRandom[2] = 0; cp.fStartColorRandom[3] = 0; cp.fStartColor[0] = 0; cp.fStartColor[1] = 0; cp.fStartColor[2] = 0; cp.fStartColor[3] = 0; cp.fEndColor[0] = 255; cp.fEndColor[1] = 40; cp.fEndColor[2] = 120; cp.fEndColor[3] = 10;//55; pPS->SetTexture("graph\\particles\\(fx)_mr.bmp", 0, 500); } else { cp.fStartColorRandom[0] = 100; cp.fStartColorRandom[1] = 100; cp.fStartColorRandom[2] = 100; cp.fStartColorRandom[3] = 100; cp.fStartColor[0] = 110; cp.fStartColor[1] = 110; cp.fStartColor[2] = 110; cp.fStartColor[3] = 110; cp.fEndColor[0] = 0; cp.fEndColor[1] = 0; cp.fEndColor[2] = 120; cp.fEndColor[3] = 10; pPS->SetTexture("graph\\particles\\magicexplosion.bmp", 0, 500); } cp.fEndColorRandom[0] = 50; cp.fEndColorRandom[1] = 50; cp.fEndColorRandom[2] = 50; cp.fEndColorRandom[3] = 50; pPS->SetParams(cp); pPS->ulParticleSpawn = 0; EERIE_3D eP; eP.x = _ePos.x; eP.y = _ePos.y; eP.z = _ePos.z; pPS->SetPos(eP); pPS->Update(0); pPS->iParticleNbMax = 0; long id = GetFreeDynLight(); if (id != -1) { DynLight[id].exist = 1; DynLight[id].intensity = 2.3f; DynLight[id].fallstart = 250.f; DynLight[id].fallend = 420.f; if ((spellinstance >= 0) && (spells[spellinstance].caster == 0) && (cur_mr == 3)) { DynLight[id].rgb.r = 1.f; DynLight[id].rgb.g = 0.3f; DynLight[id].rgb.b = .8f; } else { DynLight[id].rgb.r = 0.f; DynLight[id].rgb.g = 0.f; DynLight[id].rgb.b = .8f; } DynLight[id].pos.x = eP.x; DynLight[id].pos.y = eP.y; DynLight[id].pos.z = eP.z; DynLight[id].duration = 1500; } if (pParticleManager) { pParticleManager->AddSystem(pPS); } ARX_SOUND_PlaySFX(SND_SPELL_MM_HIT, &_ePos); }