📄 explosion.cpp
字号:
{
char* pSound = g_pServerDE->GetStringData(m_hstrSound);
if (pSound) PlaySoundFromPos(&vPos, pSound, m_fSoundRadius, SOUNDPRIORITY_MISC_HIGH );
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: Explosion::CreateLight()
//
// PURPOSE: Create light
//
// ----------------------------------------------------------------------- //
void Explosion::CreateLight( DVector *pvPos )
{
ObjectCreateStruct ocStruct;
INIT_OBJECTCREATESTRUCT(ocStruct);
if (m_hLight)
{
g_pServerDE->RemoveObject(m_hLight);
m_hLight = DNULL;
}
ocStruct.m_Flags = FLAG_VISIBLE;
ocStruct.m_ObjectType = OT_LIGHT;
VEC_COPY(ocStruct.m_Pos, *pvPos);
HCLASS hClass = g_pServerDE->GetClass("BaseClass");
if (!hClass) return;
LPBASECLASS pLight = g_pServerDE->CreateObject(hClass, &ocStruct);
if (!pLight) return;
m_hLight = pLight->m_hObject;
g_pServerDE->SetLightRadius(m_hLight, m_fMinLightRadius);
g_pServerDE->SetLightColor(m_hLight, m_vLightColor.x, m_vLightColor.y, m_vLightColor.z);
g_pServerDE->SetObjectColor(m_hModel, m_vLightColor.x, m_vLightColor.y, m_vLightColor.z, 1.0f);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CExplosion::CreateImpact()
//
// PURPOSE: Create an impact object.
//
// ----------------------------------------------------------------------- //
CImpact* Explosion::CreateImpact(ObjectCreateStruct & ocStruct, HSTRING hstrFile)
{
if (!g_pServerDE) return DNULL;
CImpact* pRet = DNULL;
if (g_pServerDE && hstrFile)
{
HCLASS hClass = g_pServerDE->GetClass("CImpact");
_mbscpy((unsigned char*)ocStruct.m_Filename, (const unsigned char*)g_pServerDE->GetStringData( hstrFile ));
if (hClass)
{
pRet = (CImpact*)g_pServerDE->CreateObject(hClass, &ocStruct);
}
}
return pRet;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CWeapon::CreateFX
//
// PURPOSE: Create the weaponFX
//
// ----------------------------------------------------------------------- //
//void CWeapon::CreateFX(DBYTE nFX, DVector vPos, DVector vFire, DVector vNormal, DFLOAT fDamage, HOBJECT hObject, SurfaceType eType)
void Explosion::CreateFX(DVector *vPos)
{
/* CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return;
if (eType == SURFTYPE_STONE || eType == SURFTYPE_METAL ||
eType == SURFTYPE_WOOD || eType == SURFTYPE_GLASS)
{
nFX |= WFX_MARK;
}
ObjectCreateStruct theStruct;
INIT_OBJECTCREATESTRUCT(theStruct);
// Offset a bit so the sprite doesn't clip into the wall
DVector vTmp;
VEC_MULSCALAR(vTmp, vNormal, 0.5f);
VEC_COPY(theStruct.m_Pos, vPos);
VEC_ADD(theStruct.m_Pos, theStruct.m_Pos, vTmp);
// VEC_COPY(theStruct.m_Pos, vPos);
ROT_COPY(theStruct.m_Rotation, m_Rotation);
HCLASS hClass = pServerDE->GetClass("CClientWeaponSFX");
CClientWeaponSFX *pWeaponFX = DNULL;
if (hClass)
{
pWeaponFX = (CClientWeaponSFX *)pServerDE->CreateObject(hClass, &theStruct);
}
if (pWeaponFX)
{
DRotation rRot;
pServerDE->AlignRotation(&rRot, &vNormal, DNULL);
DBOOL bAltFire = (m_eState == WS_ALT_FIRING);
pWeaponFX->Setup(hObject, m_nType, GetAmmoType(bAltFire), eType, nFX, m_fDamage, &rRot, &m_Position);
}
*/}
// ----------------------------------------------------------------------- //
//
// ROUTINE: Explosion::HandleTrigger
//
// PURPOSE: Handle trigger message.
//
// ----------------------------------------------------------------------- //
void Explosion::HandleTrigger(HOBJECT hSender, HMESSAGEREAD hRead)
{
HSTRING hMsg = g_pServerDE->ReadFromMessageHString(hRead);
if (!hMsg) return;
// See if we should make big boom...
HSTRING hstr = g_pServerDE->CreateString("TRIGGER");
if (g_pServerDE->CompareStringsUpper(hMsg, hstr))
{
Explode(m_fDelay);
}
g_pServerDE->FreeString(hMsg);
g_pServerDE->FreeString(hstr);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: Explosion::Explode
//
// PURPOSE: Creates a triggered explosion
//
// ----------------------------------------------------------------------- //
void Explosion::Explode(DFLOAT fDelay)
{
if (!g_pServerDE) return;
// DVector vPos;
// g_pServerDE->GetObjectPos(m_hObject, &vPos);
// CreateExplosion(&vPos);
// g_pServerDE->SetNextUpdate(m_hObject, EXPLOSION_UPDATE_DELTA);
if (fDelay == 0.0f)
fDelay = 0.01f;
g_pServerDE->SetNextUpdate(m_hObject, fDelay);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: Explosion::AddShockwave()
//
// PURPOSE: Add a shockwave
//
// ----------------------------------------------------------------------- //
void Explosion::AddShockwave(DVector *pvPoint)
{
if (!g_pServerDE) return;
ObjectCreateStruct ocStruct;
INIT_OBJECTCREATESTRUCT(ocStruct);
DRotation rRot;
ROT_INIT(rRot);
g_pServerDE->SetupEuler(&rRot, MATH_HALFPI, 0.0f, 0.0f);
ROT_COPY(ocStruct.m_Rotation, rRot);
VEC_COPY(ocStruct.m_Pos, *pvPoint);
ocStruct.m_Flags = FLAG_VISIBLE | FLAG_ROTATEABLESPRITE;
CImpact* pShockwave = CreateImpact(ocStruct, m_hstrShockwaveSprite);
if (!pShockwave) return;
if (pShockwave)
{
DVector vNormal;
VEC_SET(vNormal, 0.0f, 1.0f, 0.0f);
pShockwave->Setup(vNormal, m_vShockwaveScaleMin, m_vShockwaveScaleMax,
DNULL, 0, m_fShockwaveDuration, DTRUE, DFALSE);
m_hShockwave = g_pServerDE->ObjectToHandle(pShockwave);
g_pServerDE->CreateInterObjectLink(m_hObject, m_hShockwave);
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: Explosion::Update()
//
// PURPOSE: Update the explosion
//
// ----------------------------------------------------------------------- //
void Explosion::Update()
{
if (!g_pServerDE) return;
g_pServerDE->SetNextUpdate(m_hObject, 0.01f);
// Init
if (m_bFirstUpdate)
{
m_bFirstUpdate = DFALSE;
m_fStartTime = g_pServerDE->GetTime();
DVector vPos;
g_pServerDE->GetObjectPos(m_hObject, &vPos);
CreateExplosion(&vPos);
return;
}
DFLOAT fTime = g_pServerDE->GetTime() - m_fStartTime;
// Remove everything if we're done.
if (fTime > m_fDuration)
{
if (m_hLight) g_pServerDE->RemoveObject(m_hLight);
if (m_hModel) g_pServerDE->RemoveObject(m_hModel);
g_pServerDE->RemoveObject(m_hObject);
return;
}
DFLOAT fMul = (fTime / m_fDuration);
// Square it to give a curve to the rise
fMul = (DFLOAT)pow(fMul, 0.4);
// Scale the model
if (m_hModel)
{
DVector vScale, vDims;
vScale.x = m_fMinScale + (fMul * (m_fMaxScale - m_fMinScale));
vScale.y = vScale.z = vScale.x;
g_pServerDE->GetObjectDims( m_hModel, &vDims );
VEC_MUL( vDims, vDims, vScale);
// g_pServerDE->SetObjectDims( m_hModel, &vDims );
g_pServerDE->ScaleObject(m_hModel, &vScale);
}
DFLOAT fScaleUDur = m_fDuration*0.75f;
DFLOAT fScaleDDur = m_fDuration*0.25f;
// Scale light
if (m_hLight)
{
if (m_fDuration <= 0) return;
DFLOAT fRange = m_fMaxLightRadius - m_fMinLightRadius;
DFLOAT fRadius = 0.0f;
DFLOAT fModelAlpha = 1.0f;
if (fTime <= fScaleUDur)
{
fRadius = m_fMinLightRadius + (fTime * fRange / fScaleUDur);
}
else
{
DFLOAT fNewDeltaTime = fTime - fScaleUDur;
fRadius = m_fMaxLightRadius - (fNewDeltaTime * fRange / fScaleDDur);
fModelAlpha = 1.0f - (fNewDeltaTime / fScaleDDur);
if (fModelAlpha < 0.0f) fModelAlpha = 0.0f;
}
fModelAlpha *= 0.4f;
g_pServerDE->SetLightRadius(m_hLight, fRadius);
// Adjust alpha on model...
if (m_hModel)
{
g_pServerDE->SetObjectColor(m_hModel, m_vLightColor.x*fModelAlpha, m_vLightColor.y*fModelAlpha, m_vLightColor.z*fModelAlpha, fModelAlpha);
}
// and on the shockwave
if (m_hShockwave)
{
g_pServerDE->SetObjectColor(m_hShockwave, m_vLightColor.x*fModelAlpha, m_vLightColor.y*fModelAlpha, m_vLightColor.z*fModelAlpha, fModelAlpha);
}
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: Explosion::CreateMark()
//
// PURPOSE: Create a scorch mark at the impact point
//
// ----------------------------------------------------------------------- //
void Explosion::CreateMark(DVector *pvPos)
{
// Create the outer dark area
CreateScorchMark(pvPos, m_fMinLightRadius/3.0f, m_fMaxLightRadius/3.0f,
m_fDuration *0.2f,
60.0f,
0.0f,
30.0f,
50.0f, 50.0f, 50.0f);
// Create the glowing red center
CreateScorchMark(pvPos, m_fMinLightRadius/10.0f, m_fMaxLightRadius/10.0f,
m_fDuration * 0.2f,
2.0f,
0.0f,
2.0f,
255.0f, 100.0f, 0.0f);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: Explosion::CreateSmoke()
//
// PURPOSE: Creates a smoke trail from the impact point
//
// ----------------------------------------------------------------------- //
void Explosion::CreateSmoke(DVector *pvPos)
{
if (!g_pServerDE) return;
// DVector vPos;
//
// ObjectCreateStruct theStruct;
// INIT_OBJECTCREATESTRUCT(theStruct);
//
// g_pServerDE->GetObjectPos(m_hObject, &vPos);
// vPos.y = vPos.y + 5;
//
// VEC_COPY(theStruct.m_Pos, vPos);
// HCLASS hClass = g_pServerDE->GetClass("CClientSmokeTrail");
//
// CClientSmokeTrail* pTrail = DNULL;
//
// if (hClass)
// {
// pTrail = (CClientSmokeTrail*)g_pServerDE->CreateObject(hClass, &theStruct);
// }
//
// if (pTrail)
// {
// DVector vVel;
// g_pServerDE->GetVelocity(m_hObject, &vVel);
// pTrail->Setup(vVel, DFALSE);
//// m_hSmokeTrail[x] = pTrail->m_hObject;
// }
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -