📄 explosionfx.cpp
字号:
// ----------------------------------------------------------------------- //
//
// MODULE : ExplosionFX.cpp
//
// PURPOSE : Explosion special FX - Implementation
//
// CREATED : 7/1/98
//
// ----------------------------------------------------------------------- //
#include "ExplosionFX.h"
#include "SFXMsgIds.h"
#include "cpp_client_de.h"
#include "ClientUtilities.h"
#include "BloodClientShell.h"
#include "ObjectFX.h"
#include <mbstring.h>
// ----------------------------------------------------------------------- //
//
// ROUTINE: CExplosionModelFX::Init
//
// PURPOSE: Init the splash
//
// ----------------------------------------------------------------------- //
DBOOL CExplosionModelFX::Init(SFXCREATESTRUCT* psfxCreateStruct)
{
if (!psfxCreateStruct) return DFALSE;
CSpecialFX::Init(psfxCreateStruct);
EXPLOSIONMODELCS* pEMCS = (EXPLOSIONMODELCS*)psfxCreateStruct;
VEC_COPY(m_vPos, pEMCS->vPos);
VEC_COPY(m_vNormal, pEMCS->vNormal);
VEC_COPY(m_vScale1, pEMCS->vScale1);
VEC_COPY(m_vScale2, pEMCS->vScale2);
VEC_COPY(m_vRotations, pEMCS->vRotations);
m_fDuration = pEMCS->fDuration;
m_fInitAlpha = pEMCS->fAlpha;
m_bWaveForm = pEMCS->bWaveForm;
m_bFadeType = pEMCS->bFadeType;
m_bRandomRot = pEMCS->bRandomRot;
if( m_szModel )
g_pClientDE->FreeString( m_szModel );
m_szModel = g_pClientDE->CopyString( pEMCS->szModel );
if( m_szSkin )
g_pClientDE->FreeString( m_szSkin );
m_szSkin = g_pClientDE->CopyString( pEMCS->szSkin );
if((m_vScale1.x != m_vScale2.x) || (m_vScale1.y != m_vScale2.y) || (m_vScale1.z != m_vScale2.z))
m_bScale = 1;
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CExplosionModelFX::CreateObject
//
// PURPOSE: Create object associated the particle system.
//
// ----------------------------------------------------------------------- //
DBOOL CExplosionModelFX::CreateObject(CClientDE *pClientDE)
{
if (!pClientDE ) return DFALSE;
m_pClientDE = pClientDE;
ObjectCreateStruct ocStruct;
INIT_OBJECTCREATESTRUCT(ocStruct);
ocStruct.m_ObjectType = OT_MODEL;
ocStruct.m_Flags = FLAG_VISIBLE;
VEC_COPY(ocStruct.m_Pos, m_vPos);
if(m_bRandomRot == 1)
{
DFLOAT fPitch, fYaw, fRoll;
fPitch = GetRandom(-MATH_PI, MATH_PI);
fYaw = GetRandom(-MATH_PI, MATH_PI);
fRoll = GetRandom(-MATH_PI, MATH_PI);
pClientDE->SetupEuler(&ocStruct.m_Rotation, fPitch, fYaw, fRoll);
}
else if(m_bRandomRot == 2)
{
DVector u, r, f;
VEC_SET(u, 0.0f, 1.0f, 0.0f);
//pClientDE->CPrint("Normal: %f %f %f", m_vNormal.x, m_vNormal.y, m_vNormal.z);
pClientDE->AlignRotation(&ocStruct.m_Rotation, &m_vNormal, &u);
pClientDE->GetRotationVectors(&ocStruct.m_Rotation, &u, &r, &f);
pClientDE->RotateAroundAxis(&ocStruct.m_Rotation, &f, GetRandom(0.0f, MATH_PI));
}
if(m_szModel) _mbscpy((unsigned char*)ocStruct.m_Filename, (const unsigned char*)pClientDE->GetStringData(m_szModel));
else _mbscpy((unsigned char*)ocStruct.m_Filename, (const unsigned char*)"Models\\Explosions\\exp_sphere.abc");
if(m_szSkin) _mbscpy((unsigned char*)ocStruct.m_SkinName, (const unsigned char*)pClientDE->GetStringData(m_szSkin));
else _mbscpy((unsigned char*)ocStruct.m_SkinName, (const unsigned char*)"Skins\\Explosions\\Explosion_1.dtx");
m_hObject = pClientDE->CreateObject(&ocStruct);
// Gouraud shade and make full bright...
DDWORD dwFlags = pClientDE->GetObjectFlags(m_hObject);
pClientDE->SetObjectFlags(m_hObject, dwFlags | FLAG_MODELGOURAUDSHADE | FLAG_NOLIGHT);
pClientDE->SetObjectColor(m_hObject, 1.0f, 1.0f, 1.0f, m_fInitAlpha);
pClientDE->SetObjectScale(m_hObject, &m_vScale1);
m_fStartTime = pClientDE->GetTime();
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CExplosionModelFX::Update
//
// PURPOSE: Update the particles
//
// ----------------------------------------------------------------------- //
DBOOL CExplosionModelFX::Update()
{
if(!m_hObject || !m_pClientDE) return DFALSE;
DFLOAT fTime = m_pClientDE->GetTime() - m_fStartTime;
DFLOAT fRatio = fTime / m_fDuration;
if(m_bScale)
{
DFLOAT fTemp = fRatio;
DVector vScale;
VEC_SUB(vScale, m_vScale2, m_vScale1);
switch(m_bWaveForm)
{
case 1: fTemp = (DFLOAT)pow(fRatio, 0.5); break;
case 2: fTemp = (DFLOAT)pow(fRatio, 2.0); break;
case 3: if(fTime < (m_fDuration / 2))
fTemp = fRatio * 2.0f;
else
fTemp = (1.0f - fRatio) * 2.0f;
break;
case 4: if(fTime < (m_fDuration / 2))
fTemp = (DFLOAT)pow(fRatio * 2.0f, 0.5);
else
fTemp = (DFLOAT)pow((1.0f - fRatio) * 2.0f, 0.5);
break;
case 5: if(fTime < (m_fDuration / 2))
fTemp = (DFLOAT)pow(fRatio * 2.0f, 2.0);
else
fTemp = (DFLOAT)pow((1.0f - fRatio) * 2.0f, 2.0);
break;
}
VEC_MULSCALAR(vScale, vScale, fTemp);
VEC_ADD(vScale, vScale, m_vScale1);
m_pClientDE->SetObjectScale(m_hObject, &vScale);
}
if(m_vRotations.x || m_vRotations.y || m_vRotations.z)
{
DRotation rot;
DVector u, r, f;
m_pClientDE->GetObjectRotation(m_hObject, &rot);
m_pClientDE->GetRotationVectors(&rot, &u, &r, &f);
m_pClientDE->RotateAroundAxis(&rot, &u, m_vRotations.x);
m_pClientDE->RotateAroundAxis(&rot, &r, m_vRotations.y);
m_pClientDE->RotateAroundAxis(&rot, &f, m_vRotations.z);
m_pClientDE->SetObjectRotation(m_hObject, &rot);
}
if(m_bFadeType)
{
DFLOAT alpha;
switch(m_bFadeType)
{
case 1: alpha = m_fInitAlpha * (1.0f - fRatio); break; // InitAlpha to zero
case 2: alpha = 1.0f - ((1.0f - m_fInitAlpha) * fRatio); break; // Solid to InitAlpha
case 3: alpha = m_fInitAlpha * fRatio; break; // Zero to InitAlpha
case 4: alpha = m_fInitAlpha + ((1.0f - m_fInitAlpha) * fRatio);break; // InitAlpha to Solid
case 5: if(fTime < (m_fDuration / 2))
alpha = m_fInitAlpha * fRatio * 2.0f;
else
alpha = m_fInitAlpha * 2.0f * (1.0f - fRatio); break;
}
m_pClientDE->SetObjectColor(m_hObject, 1.0f, 1.0f, 1.0f, alpha);
}
return (fTime < m_fDuration);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CExplosionSpriteFX::Init
//
// PURPOSE: Init the splash
//
// ----------------------------------------------------------------------- //
DBOOL CExplosionSpriteFX::Init(SFXCREATESTRUCT* psfxCreateStruct)
{
if (!psfxCreateStruct) return DFALSE;
CSpecialFX::Init(psfxCreateStruct);
EXPLOSIONSPRITECS* pESCS = (EXPLOSIONSPRITECS*)psfxCreateStruct;
VEC_COPY(m_vPos, pESCS->vPos);
VEC_COPY(m_vNormal, pESCS->vNormal);
VEC_COPY(m_vScale1, pESCS->vScale1);
VEC_COPY(m_vScale2, pESCS->vScale2);
m_fDuration = pESCS->fDuration;
m_fInitAlpha = pESCS->fAlpha;
m_bWaveForm = pESCS->bWaveForm;
m_bFadeType = pESCS->bFadeType;
m_bAlign = pESCS->bAlign;
if( m_szSprite )
g_pClientDE->FreeString( m_szSprite );
m_szSprite = g_pClientDE->CopyString( pESCS->szSprite );
if((m_vScale1.x != m_vScale2.x) || (m_vScale1.y != m_vScale2.y) || (m_vScale1.z != m_vScale2.z))
m_bScale = 1;
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CExplosionSpriteFX::CreateObject
//
// PURPOSE: Create object associated the particle system.
//
// ----------------------------------------------------------------------- //
DBOOL CExplosionSpriteFX::CreateObject(CClientDE *pClientDE)
{
if (!pClientDE ) return DFALSE;
m_pClientDE = pClientDE;
ObjectCreateStruct ocStruct;
INIT_OBJECTCREATESTRUCT(ocStruct);
ocStruct.m_ObjectType = OT_SPRITE;
ocStruct.m_Flags = FLAG_VISIBLE | FLAG_SPRITECHROMAKEY;
VEC_COPY(ocStruct.m_Pos, m_vPos);
if(m_bAlign)
{
DVector vUp;
VEC_SET(vUp, 0.0f, 1.0f, 0.0f);
m_pClientDE->AlignRotation(&(ocStruct.m_Rotation), &m_vNormal, &vUp);
ocStruct.m_Flags |= FLAG_ROTATEABLESPRITE;
if(m_bAlign == 2)
m_pClientDE->RotateAroundAxis(&(ocStruct.m_Rotation), &m_vNormal, GetRandom(0.0f, 2 * MATH_PI));
}
if(m_szSprite)
_mbscpy((unsigned char*)ocStruct.m_Filename, (const unsigned char*)pClientDE->GetStringData(m_szSprite));
else
_mbscpy((unsigned char*)ocStruct.m_Filename, (const unsigned char*)"Sprites\\Explosn.spr");
m_hObject = pClientDE->CreateObject(&ocStruct);
pClientDE->SetObjectColor(m_hObject, 1.0f, 1.0f, 1.0f, m_fInitAlpha);
pClientDE->SetObjectScale(m_hObject, &m_vScale1);
m_fStartTime = pClientDE->GetTime();
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CExplosionSpriteFX::Update
//
// PURPOSE: Update the particles
//
// ----------------------------------------------------------------------- //
DBOOL CExplosionSpriteFX::Update()
{
if(!m_hObject || !m_pClientDE) return DFALSE;
DFLOAT fTime = m_pClientDE->GetTime() - m_fStartTime;
DFLOAT fRatio = fTime / m_fDuration;
if(m_bScale)
{
DFLOAT fTemp = fRatio;
DVector vScale;
VEC_SUB(vScale, m_vScale2, m_vScale1);
if(m_bWaveForm == 1) fTemp = (DFLOAT)pow(fRatio, 0.5);
else if(m_bWaveForm == 2) fTemp = (DFLOAT)pow(fRatio, 2.0);
VEC_MULSCALAR(vScale, vScale, fTemp);
VEC_ADD(vScale, vScale, m_vScale1);
m_pClientDE->SetObjectScale(m_hObject, &vScale);
}
if(m_bFadeType)
{
DFLOAT alpha;
switch(m_bFadeType)
{
case 1: alpha = m_fInitAlpha * (1.0f - fRatio); break; // InitAlpha to zero
case 2: alpha = 1.0f - ((1.0f - m_fInitAlpha) * fRatio); break; // Solid to InitAlpha
case 3: alpha = m_fInitAlpha * fRatio; break; // Zero to InitAlpha
case 4: alpha = m_fInitAlpha + ((1.0f - m_fInitAlpha) * fRatio);break; // InitAlpha to Solid
case 5: if(fTime < (m_fDuration / 2))
alpha = m_fInitAlpha * fRatio * 2.0f;
else
alpha = m_fInitAlpha * 2.0f * (1.0f - fRatio); break;
}
m_pClientDE->SetObjectColor(m_hObject, 1.0f, 1.0f, 1.0f, alpha);
}
return (fTime < m_fDuration);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CExplosionRingFX::Init
//
// PURPOSE: Init the splash
//
// ----------------------------------------------------------------------- //
DBOOL CExplosionRingFX::Init(SFXCREATESTRUCT* psfxCreateStruct)
{
if (!psfxCreateStruct) return DFALSE;
CBaseParticleSystemFX::Init(psfxCreateStruct);
EXPLOSIONRINGCS* pERCS = (EXPLOSIONRINGCS*)psfxCreateStruct;
VEC_COPY(m_vPos, pERCS->vPos);
VEC_COPY(m_vNormal, pERCS->vNormal);
VEC_COPY(m_vColor, pERCS->vColor);
m_fRadius = pERCS->fRadius;
m_fPosRadius = pERCS->fPosRadius;
m_fVelocity = pERCS->fVelocity;
m_fGravity = pERCS->fGravity;
m_nParticles = pERCS->nParticles;
m_fDuration = pERCS->fDuration;
m_fRotation = pERCS->fRotation;
m_fInitAlpha = pERCS->fAlpha;
m_fDelay = pERCS->fDelay;
m_bFadeType = pERCS->bFadeType;
m_bRotateType = pERCS->bRotateType;
m_bAlign = pERCS->bAlign;
if( m_szParticle )
g_pClientDE->FreeString( m_szParticle );
m_szParticle = g_pClientDE->CopyString( pERCS->szParticle );
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CExplosionRingFX::CreateObject
//
// PURPOSE: Create object associated the particle system.
//
// ----------------------------------------------------------------------- //
DBOOL CExplosionRingFX::CreateObject(CClientDE *pClientDE)
{
if(!pClientDE ) return DFALSE;
if(m_szParticle)
m_pTextureName = pClientDE->GetStringData(m_szParticle);
else
m_pTextureName = "SpriteTextures\\smoke64_2.dtx";
DBOOL bRet = CBaseParticleSystemFX::CreateObject(pClientDE);
if(bRet)
{
if(m_fDelay)
pClientDE->SetObjectColor(m_hObject, m_vColor.x, m_vColor.y, m_vColor.z, 0.0f);
else
{
pClientDE->SetObjectColor(m_hObject, m_vColor.x, m_vColor.y, m_vColor.z, m_fInitAlpha);
AddParticles();
}
m_fStartTime = m_pClientDE->GetTime();
}
return bRet;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CExplosionRingFX::Update
//
// PURPOSE: Update the particles
//
// ----------------------------------------------------------------------- //
DBOOL CExplosionRingFX::Update()
{
if(!m_hObject || !m_pClientDE) return DFALSE;
DFLOAT fTime = m_pClientDE->GetTime() - m_fStartTime;
DFLOAT fRatio = fTime / m_fDuration;
if(m_fDelay)
{
if(fTime >= m_fDelay)
{
if(!m_bFadeType)
m_pClientDE->SetObjectColor(m_hObject, m_vColor.x, m_vColor.y, m_vColor.z, m_fInitAlpha);
m_fStartTime = m_pClientDE->GetTime();
m_fDelay = 0.0f;
AddParticles();
}
return DTRUE;
}
if(m_bRotateType)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -