📄 explosionfx.cpp
字号:
m_fStartTime = pClientDE->GetTime();
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CExplosionLightFX::Update
//
// PURPOSE: Update the particles
//
// ----------------------------------------------------------------------- //
DBOOL CExplosionLightFX::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)
{
m_pClientDE->SetLightRadius(m_hObject, m_fRadius1);
m_fStartTime = m_pClientDE->GetTime();
m_fDelay = 0.0f;
}
return DTRUE;
}
if(m_bChangeColor)
{
DVector vColor;
VEC_SUB(vColor, m_vColor2, m_vColor1);
VEC_MULSCALAR(vColor, vColor, fRatio);
VEC_ADD(vColor, vColor, m_vColor1);
m_pClientDE->SetLightColor(m_hObject, vColor.x, vColor.y, vColor.z);
}
if(m_bScale)
{
DFLOAT radius;
radius = m_fRadius1 + ((m_fRadius2 - m_fRadius1) * fRatio);
m_pClientDE->SetLightRadius(m_hObject, radius);
}
return (fTime < m_fDuration);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CExplosionFragFX::Init
//
// PURPOSE: Init the fragment
//
// ----------------------------------------------------------------------- //
DBOOL CExplosionFragFX::Init(SFXCREATESTRUCT* psfxCreateStruct)
{
if (!psfxCreateStruct) return DFALSE;
CSpecialFX::Init(psfxCreateStruct);
EXPLOSIONFRAGCS* pEFCS = (EXPLOSIONFRAGCS*)psfxCreateStruct;
VEC_COPY(m_vPos, pEFCS->vPos);
VEC_COPY(m_vLastPos, pEFCS->vPos);
VEC_COPY(m_vNormal, pEFCS->vNormal);
VEC_COPY(m_vScale, pEFCS->vScale);
VEC_COPY(m_vRotateMax, pEFCS->vRotateMax);
m_fSpread = pEFCS->fSpread;
m_fDuration = pEFCS->fDuration;
m_fVelocity = pEFCS->fVelocity;
m_fBounceMod = pEFCS->fBounceMod;
m_fGravity = pEFCS->fGravity;
m_fFadeTime = pEFCS->fFadeTime;
m_fInitAlpha = pEFCS->fInitAlpha;
m_bRandDir = pEFCS->bRandDir;
m_bSpawnExp = pEFCS->bSpawnExp;
m_nSpawnType = pEFCS->nSpawnType;
m_nTrailType = pEFCS->nTrailType;
if( m_szModel )
g_pClientDE->FreeString( m_szModel );
m_szModel = g_pClientDE->CopyString( pEFCS->szModel );
if( m_szSkin )
g_pClientDE->FreeString( m_szSkin );
m_szSkin = g_pClientDE->CopyString( pEFCS->szSkin );
if(m_vRotateMax.x || m_vRotateMax.y || m_vRotateMax.z)
m_bRotate = 1;
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CExplosionFragFX::CreateObject
//
// PURPOSE: Create object associated the particle system.
//
// ----------------------------------------------------------------------- //
DBOOL CExplosionFragFX::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_bRandDir)
{
DVector vDir;
VEC_SET(vDir, GetRandom(-10.0f, 10.0f), GetRandom(-10.0f, 10.0f), GetRandom(-10.0f, 10.0f));
VEC_NORM(vDir);
VEC_MULSCALAR(m_vVelocity, vDir, m_fVelocity);
}
else
{
DVector vUp, vU, vR, vF;
DRotation rRot;
VEC_SET(vUp, 0.0f, 1.0f, 0.0f);
pClientDE->AlignRotation(&rRot, &m_vNormal, &vUp);
pClientDE->RotateAroundAxis(&rRot, &m_vNormal, GetRandom(-MATH_PI, MATH_PI));
pClientDE->GetRotationVectors(&rRot, &vU, &vR, &vF);
VEC_MULSCALAR(m_vVelocity, m_vNormal, m_fVelocity);
VEC_MULSCALAR(vR, vR, m_fSpread);
VEC_ADD(m_vVelocity, m_vVelocity, vR);
VEC_NORM(m_vVelocity);
VEC_MULSCALAR(m_vVelocity, m_vVelocity, m_fVelocity);
}
VEC_SET(m_vGravity, 0.0f, -1.0f, 0.0f);
VEC_MULSCALAR(m_vGravity, m_vGravity, m_fGravity);
if(m_bRotate)
{
fPitch = GetRandom(-m_vRotateMax.x, m_vRotateMax.x);
fYaw = GetRandom(-m_vRotateMax.y, m_vRotateMax.y);
fRoll = GetRandom(-m_vRotateMax.z, m_vRotateMax.z);
}
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);
DDWORD dwFlags = pClientDE->GetObjectFlags(m_hObject);
pClientDE->SetObjectFlags(m_hObject, dwFlags | FLAG_MODELGOURAUDSHADE | FLAG_NOLIGHT);
pClientDE->SetObjectScale(m_hObject, &m_vScale);
DFLOAT r, g, b, a;
pClientDE->GetObjectColor(m_hObject, &r, &g, &b, &a);
pClientDE->SetObjectColor(m_hObject, r, g, b, m_fInitAlpha);
//**************************************************************//
if(m_nTrailType)
{
CBloodClientShell *pShell = (CBloodClientShell*)pClientDE->GetClientShell();
if (!pClientDE || !pShell) return DFALSE;
CSFXMgr* psfxMgr = pShell->GetSFXMgr();
if (!psfxMgr) return DFALSE;
OBJECTFXCS ops;
ops.hObj = m_hObject;
VEC_SET(ops.vOffset, 0.0f, 0.0f, 0.0f);
ops.fScale = 0.0f;
ops.nScaleFlags = 0;
ops.nFXType = m_nTrailType;
ops.nFXFlags = 0;
psfxMgr->CreateSFX(SFX_OBJECTFX_ID, &ops, DFALSE, this);
}
//**************************************************************//
m_fStartTime = pClientDE->GetTime();
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CExplosionFragFX::Update
//
// PURPOSE: Update the particles
//
// ----------------------------------------------------------------------- //
DBOOL CExplosionFragFX::Update()
{
if(!m_hObject || !m_pClientDE) return DFALSE;
DFLOAT fTime = m_pClientDE->GetTime() - m_fStartTime;
DBOOL bMove = 1;
if((VEC_MAG(m_vVelocity) < 1.0f) && (m_vLastNormal.y > 0.9f))
bMove = 0;
// Rotate the object if it has a rotation flag and is moving
if(m_bRotate && bMove)
{
DRotation rRot;
m_fPitch += fPitch;
m_fYaw += fYaw;
m_fRoll += fRoll;
m_pClientDE->SetupEuler(&rRot, m_fPitch, m_fYaw, m_fRoll);
m_pClientDE->SetObjectRotation(m_hObject, &rRot);
}
// Fade out at the end of the duration if there is a fade out time
if((fTime > m_fDuration - m_fFadeTime) && (fTime < m_fDuration))
{
DFLOAT alpha = m_fInitAlpha - ((fTime - (m_fDuration - m_fFadeTime)) / m_fFadeTime);
DFLOAT r, g, b, a;
m_pClientDE->GetObjectColor(m_hObject, &r, &g, &b, &a);
m_pClientDE->SetObjectColor(m_hObject, r, g, b, alpha);
}
// If the object is moving, check for collisions and set the position and velocity
if(bMove)
{
// Adjust the last and current position data
VEC_COPY(m_vLastPos, m_vPos);
VEC_ADD(m_vVelocity, m_vVelocity, m_vGravity);
VEC_ADD(m_vPos, m_vPos, m_vVelocity);
// Setup the data to test for a collision
ClientIntersectQuery iq;
ClientIntersectInfo ii;
iq.m_Flags = INTERSECT_OBJECTS | IGNORE_NONSOLID | INTERSECT_HPOLY;
VEC_COPY(iq.m_From, m_vLastPos);
VEC_MULSCALAR(iq.m_To, m_vVelocity, 1.1f);
VEC_ADD(iq.m_To, iq.m_To, iq.m_From);
if(m_pClientDE->IntersectSegment(&iq, &ii))
{
DVector vLift, vVel, vNorm;
DFLOAT r = VEC_MAG(m_vVelocity);
DFLOAT dot;
// Make some temporary vectors for calculations
VEC_COPY(vVel, m_vVelocity);
VEC_COPY(vNorm, ii.m_Plane.m_Normal);
VEC_COPY(m_vLastNormal, vNorm);
VEC_NORM(vNorm);
VEC_NORM(vVel);
// Calculate a reflection vector
dot = VEC_DOT(vNorm, vVel);
VEC_MULSCALAR(vLift, vNorm, 2.0f * -dot);
VEC_ADD(vLift, vVel, vLift);
// Set the velocity of the reflection and decrease it a little
VEC_MULSCALAR(m_vVelocity, vLift, r * m_fBounceMod);
// Place the object at the collision point... a little off the surface
VEC_ADD(m_vPos, ii.m_Point, vNorm);
// Spawn and new explosion
if(m_bSpawnExp >= 2)
{
CBloodClientShell *pShell = (CBloodClientShell*)m_pClientDE->GetClientShell();
if (!pShell) return DFALSE;
CSFXMgr* psfxMgr = pShell->GetSFXMgr();
if (!psfxMgr) return DFALSE;
EXPLOSIONFXCS expCS;
expCS.hServerObj = 0;
VEC_COPY(expCS.vPos, m_vPos);
VEC_COPY(expCS.vNormal, m_vLastNormal);
expCS.nType = m_nSpawnType;
psfxMgr->CreateSFX(SFX_EXPLOSIONFX_ID, &expCS, DFALSE, this);
if(m_bSpawnExp == 2) return DFALSE;
}
// Slow the rotation for every impact
fPitch *= 0.5f;
fYaw *= 0.5f;
fRoll *= 0.5f;
}
m_pClientDE->SetObjectPos(m_hObject, &m_vPos);
}
// Check to see if the object should continue to exist...
if(fTime < m_fDuration)
return DTRUE;
else
{
if((m_bSpawnExp == 1) || (m_bSpawnExp == 4))
{
CBloodClientShell *pShell = (CBloodClientShell*)m_pClientDE->GetClientShell();
if (!pShell) return DFALSE;
CSFXMgr* psfxMgr = pShell->GetSFXMgr();
if (!psfxMgr) return DFALSE;
EXPLOSIONFXCS expCS;
expCS.hServerObj = 0;
VEC_COPY(expCS.vPos, m_vPos);
VEC_COPY(expCS.vNormal, m_vLastNormal);
expCS.nType = m_nSpawnType;
psfxMgr->CreateSFX(SFX_EXPLOSIONFX_ID, &expCS, DFALSE, this);
}
return DFALSE;
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CExplosionFX::Init
//
// PURPOSE: Init the FX location and type
//
// ----------------------------------------------------------------------- //
DBOOL CExplosionFX::Init(SFXCREATESTRUCT* psfxCreateStruct)
{
if (!psfxCreateStruct) return DFALSE;
CSpecialFX::Init(psfxCreateStruct);
EXPLOSIONFXCS* pEFXCS = (EXPLOSIONFXCS*)psfxCreateStruct;
VEC_COPY(m_vPos, pEFXCS->vPos);
VEC_COPY(m_vNormal, pEFXCS->vNormal);
VEC_NORM(m_vNormal);
m_nExpID = pEFXCS->nType;
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CExplosionFX::CreateObject
//
// PURPOSE: Create object associated the particle system.
//
// ----------------------------------------------------------------------- //
DBOOL CExplosionFX::CreateObject(CClientDE *pClientDE)
{
CBloodClientShell *pShell = (CBloodClientShell*)pClientDE->GetClientShell();
if (!pClientDE || !pShell) return DFALSE;
CSFXMgr* psfxMgr = pShell->GetSFXMgr();
if (!psfxMgr) return DFALSE;
HCONSOLEVAR hVar = pClientDE->GetConsoleVar("ExplosionsDetail");
DBYTE detail = (DBYTE)pClientDE->GetVarValueFloat(hVar);
if(detail >= 2)
{
switch(m_nExpID)
{
case EXP_DEFAULT_SMALL:
{
EXPLOSIONMODELCS emCS;
EXPLOSIONSPRITECS esCS;
EXPLOSIONRINGCS erCS, erCS2;
EXPLOSIONLIGHTCS elCS;
DVector temp;
// Model
VEC_COPY(emCS.vNormal, m_vNormal);
VEC_COPY(emCS.vPos, m_vPos);
VEC_MULSCALAR(temp, m_vNormal, 10.0f);
VEC_ADD(emCS.vPos, m_vPos, temp);
VEC_SET(emCS.vScale1, 25.0f, 25.0f, 25.0f);
VEC_SET(emCS.vScale2, 200.0f, 200.0f, 200.0f);
emCS.fDuration = 0.5f;
emCS.fAlpha = 0.75f;
emCS.bWaveForm = GetRandom(0,2);
emCS.bFadeType = 1;
emCS.bRandomRot = 1;
emCS.szModel = 0;
emCS.szSkin = 0;
psfxMgr->CreateSFX(SFX_EXPLOSION_ID, &emCS, DFALSE, this);
// Sprite
VEC_COPY(esCS.vNormal, m_vNormal);
VEC_MULSCALAR(temp, m_vNormal, 25.0f);
VEC_ADD(esCS.vPos, m_vPos, temp);
VEC_SET(esCS.vScale1, 0.25f, 0.25f, 0.0f);
VEC_SET(esCS.vScale2, 0.25f, 0.25f, 0.0f);
esCS.fDuration = 1.5f;
esCS.fAlpha = 1.0f;
esCS.bWaveForm = 0;
esCS.bFadeType = 1;
esCS.bAlign = 0;
esCS.szSprite = pClientDE->CreateString("Sprites\\fireball2.spr");
psfxMgr->CreateSFX(SFX_EXPLOSIONSPRITE_ID, &esCS, DFALSE, this);
g_pClientDE->FreeString( esCS.szSprite );
esCS.szSprite = DNULL;
// Ring
VEC_COPY(erCS.vNormal, m_vNormal);
VEC_MULSCALAR(temp, m_vNormal, 25.0f);
VEC_ADD(erCS.vPos, m_vPos, temp);
VEC_SET(erCS.vColor, 1.0f, 1.0f, 1.0f);
erCS.fRadius = 4000.0f;
erCS.fPosRadius = 10.0f;
erCS.fVelocity = 400.0f;
erCS.fGravity = 0.0f;
erCS.nParticles = 32;
erCS.fDuration = 0.5f;
erCS.fAlpha = 1.0f;
erCS.fDelay = 0.0f;
erCS.bFadeType = 1;
erCS.bAlign = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -