📄 particlestreamfx.cpp
字号:
// ----------------------------------------------------------------------- //
//
// MODULE : ParticleStreamFX.cpp
//
// PURPOSE : Special FX class for streams of particles
//
// CREATED : 8/1/98
//
// ----------------------------------------------------------------------- //
#include "ParticleStreamFX.h"
#include "cpp_client_de.h"
#include "ClientUtilities.h"
#include "ClientServerShared.h"
#include "SoundTypes.h"
// ----------------------------------------------------------------------- //
//
// ROUTINE: CParticleStreamFX::Init
//
// PURPOSE: Init the stream
//
// ----------------------------------------------------------------------- //
DBOOL CParticleStreamFX::Init(SFXCREATESTRUCT* psfxCreateStruct)
{
if (!CBaseParticleSystemFX::Init(psfxCreateStruct)) return DFALSE;
PSTREAMCREATESTRUCT* pSS = (PSTREAMCREATESTRUCT*)psfxCreateStruct;
m_fRadius = pSS->fRadius;
m_fPosRadius = pSS->fPosRadius;
m_fMinVel = pSS->fMinVel;
m_fMaxVel = pSS->fMaxVel;
m_nNumParticles = pSS->nNumParticles;
m_fSpread = pSS->fSpread;
VEC_COPY(m_vColor1, pSS->vColor1);
VEC_COPY(m_vColor2, pSS->vColor2);
m_fAlpha = pSS->fAlpha;
m_fMinLife = pSS->fMinLife;
m_fMaxLife = pSS->fMaxLife;
m_fRampTime = pSS->fRampTime;
m_fDelay = pSS->fDelay;
m_bState = pSS->bOn ? 2 : 0;
m_bRampFlags = pSS->bRampFlags;
m_fGravity = pSS->fGravity;
m_hstrSound1 = pSS->hstrSound1;
m_hstrSound2 = pSS->hstrSound2;
m_hstrSound3 = pSS->hstrSound3;
m_hstrTexture = pSS->hstrTexture;
m_pTextureName = "SpriteTextures\\drop32_1.dtx";
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CParticleStreamFX::CreateObject
//
// PURPOSE: Create object associated the particle system.
//
// ----------------------------------------------------------------------- //
DBOOL CParticleStreamFX::CreateObject(CClientDE *pClientDE)
{
if(!pClientDE ) return DFALSE;
if(m_hstrTexture)
m_pTextureName = pClientDE->GetStringData(m_hstrTexture);
DBOOL bRet = CBaseParticleSystemFX::CreateObject(pClientDE);
if(m_hServerObject)
{
DVector vPos;
DRotation rRot;
m_pClientDE->GetObjectPos(m_hServerObject, &vPos);
m_pClientDE->SetObjectPos(m_hObject, &vPos);
m_pClientDE->GetObjectRotation(m_hServerObject, &rRot);
m_pClientDE->GetRotationVectors(&rRot, &m_vU, &m_vR, &m_vDir);
}
else
return DFALSE;
if(bRet)
{
DFLOAT r, g, b, a;
m_pClientDE->GetObjectColor(m_hObject, &r, &g, &b, &a);
m_pClientDE->SetObjectColor(m_hObject, r, g, b, m_fAlpha);
if(m_bState) AddParticles();
}
return bRet;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CParticleStreamFX::Update
//
// PURPOSE: Update the particles
//
// ----------------------------------------------------------------------- //
DBOOL CParticleStreamFX::Update()
{
if(!m_hObject || !m_pClientDE) return DFALSE;
// Update the position and direction of the particle stream based on the server object
if(m_hServerObject)
{
DVector vPos;
DRotation rRot;
m_pClientDE->GetObjectPos(m_hServerObject, &vPos);
m_pClientDE->SetObjectPos(m_hObject, &vPos);
m_pClientDE->GetObjectRotation(m_hServerObject, &rRot);
m_pClientDE->GetRotationVectors(&rRot, &m_vU, &m_vR, &m_vDir);
}
else
return DFALSE;
// Check to see if the server object is visible (determines on/off state of effect)
DDWORD dwFlags;
m_pClientDE->GetObjectUserFlags(m_hServerObject, &dwFlags);
if(dwFlags & USRFLG_VISIBLE)
{
if((m_bState == 0) || (m_bState == 3))
{
m_fTriggerTime = m_pClientDE->GetTime();
if(m_fRampTime) m_bState = 1;
else m_bState = 2;
}
}
else
{
if((m_bState == 1) || (m_bState == 2))
{
m_fTriggerTime = m_pClientDE->GetTime();
if(m_fRampTime) m_bState = 3;
else m_bState = 0;
}
}
// Play the correct sound according to the current state
switch(m_bState)
{
case 1:
if(m_hstrSound1)
{
if(m_hsSound) m_pClientDE->KillSound(m_hsSound);
m_hsSound = PlaySoundFromObject(m_hObject, m_pClientDE->GetStringData(m_hstrSound1),
m_fSoundRadius, SOUNDPRIORITY_MISC_MEDIUM, DFALSE, DTRUE);
}
break;
case 2:
if(m_hstrSound2 && !m_hsSound)
{
m_hsSound = PlaySoundFromObject(m_hObject, m_pClientDE->GetStringData(m_hstrSound2),
m_fSoundRadius, SOUNDPRIORITY_MISC_MEDIUM, DTRUE, DTRUE);
}
break;
case 3:
if(m_hstrSound3)
{
if(m_hsSound) m_pClientDE->KillSound(m_hsSound);
m_hsSound = PlaySoundFromObject(m_hObject, m_pClientDE->GetStringData(m_hstrSound3),
m_fSoundRadius, SOUNDPRIORITY_MISC_MEDIUM, DFALSE, DTRUE);
}
break;
}
// See if it's time to add more particles... and do so
if(m_pClientDE->GetTime() > m_fLastAddTime + m_fDelay)
AddParticles();
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CParticleStreamFX::AddParticles
//
// PURPOSE: Make the liquid drops
//
// ----------------------------------------------------------------------- //
DBOOL CParticleStreamFX::AddParticles()
{
if(!m_hObject || !m_pClientDE) return DFALSE;
DVector minOffset, maxOffset;
DFLOAT minVel, maxVel;
DFLOAT minLife, maxLife;
DFLOAT spread;
DFLOAT ratio, time = m_pClientDE->GetTime();
DDWORD num;
if(!m_bState) return DTRUE;
num = m_nNumParticles;
VEC_SET(minOffset, -m_fPosRadius, -m_fPosRadius, -m_fPosRadius);
VEC_SET(maxOffset, m_fPosRadius, m_fPosRadius, m_fPosRadius);
minVel = m_fMinVel;
maxVel = m_fMaxVel;
minLife = m_fMinLife;
maxLife = m_fMaxLife;
spread = m_fSpread;
if((m_bState == 1) || (m_bState == 3))
{
// Set the ratio to ramp the values with
if(m_bState == 1)
{
ratio = (time - m_fTriggerTime) / m_fRampTime;
if(ratio >= 1.0f)
{ ratio = 1.0f; m_bState = 2; }
}
else
{
ratio = 1.0f - ((time - m_fTriggerTime) / m_fRampTime);
if(ratio <= 0.0f)
{ ratio = 0.0f; m_bState = 0; return DTRUE; }
}
// Check which elements of the stream we should ramp... and calculate new values
if(m_bRampFlags & PSTREAM_RAMP_NUM)
num = (DDWORD)(num * ratio);
if(m_bRampFlags & PSTREAM_RAMP_OFFSET)
{
VEC_MULSCALAR(minOffset, minOffset, ratio);
VEC_MULSCALAR(maxOffset, maxOffset, ratio);
}
if(m_bRampFlags & PSTREAM_RAMP_VEL)
{
minVel *= ratio;
maxVel *= ratio;
spread *= ratio;
}
if(m_bRampFlags & PSTREAM_RAMP_LIFE)
{
minLife *= ratio;
maxLife *= ratio;
}
}
// Add the particles one by one... (instead of AddParticles... cause I wanted the spread)
for(DDWORD i = 0; i < num; i++)
{
DVector pos, vel, vSpread, color;
DFLOAT life = GetRandom(minLife, maxLife);
VEC_SET(pos, GetRandom(minOffset.x, maxOffset.x), GetRandom(minOffset.y, maxOffset.y), GetRandom(minOffset.z, maxOffset.z));
VEC_SET(vSpread, GetRandom(-spread, spread), GetRandom(-spread, spread), GetRandom(-spread, spread));
VEC_MULSCALAR(vel, m_vDir, maxVel);
VEC_ADD(vel, vel, vSpread);
VEC_NORM(vel);
VEC_MULSCALAR(vel, vel, GetRandom(minVel, maxVel));
GetRandomColorInRange(color);
m_pClientDE->AddParticle(m_hObject, &pos, &vel, &color, life);
}
// Make sure we know when the last batch of particles were added
m_fLastAddTime = time;
return DTRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -