📄 explosion.cpp
字号:
// ----------------------------------------------------------------------- //
//
// MODULE : Explosion.cpp
//
// PURPOSE : Explosion - Definition
//
// CREATED : 2/20/97
//
// ----------------------------------------------------------------------- //
#include "Explosion.h"
#include "cpp_server_de.h"
#include "generic_msg_de.h"
#include "ObjectUtilities.h"
#include "ModelObject.h"
#include "Impacts.h"
#include "ClientSmokeTrail.h"
#include <mbstring.h>
#include "SoundTypes.h"
static char *szDefExplosionModel = "Models\\Explosions\\Explosion_3.abc";
static char *szDefExplosionSkin = "Skins\\Explosions\\Explosion_1.dtx";
static char *szDefShockwaveSprite = "Sprites\\Shockring.spr";
#define EXPLOSION_UPDATE_DELTA 0.01f
#define EXPLOSION_DAMAGE_UPDATE_DELTA 0.1f
BEGIN_CLASS(Explosion)
ADD_STRINGPROP(Model, szDefExplosionModel)
ADD_STRINGPROP(Skin, szDefExplosionSkin)
ADD_STRINGPROP(Sound, "Sounds\\exp_tnt.wav")
ADD_REALPROP_FLAG(SoundRadius, 1000.0f, PF_RADIUS)
ADD_REALPROP_FLAG(DamageRadius, 200.0f, PF_RADIUS)
ADD_VECTORPROP(RotateSpeed)
ADD_REALPROP(MaxDamage, 50.0f)
ADD_REALPROP(MinScale, 0.1f)
ADD_REALPROP(MaxScale, 1.0f)
ADD_BOOLPROP(CreateLight, DTRUE)
ADD_COLORPROP(LightColor, 255, 255, 255)
ADD_BOOLPROP(CreateSmoke, DTRUE)
ADD_BOOLPROP(CreateShockwave, DFALSE)
ADD_STRINGPROP(ShockwaveFile, szDefShockwaveSprite)
ADD_VECTORPROP(ShockwaveScaleMin)
ADD_VECTORPROP(ShockwaveScaleMax)
ADD_REALPROP(ShockwaveDuration, 0.0f)
ADD_REALPROP(Delay, 0.0f)
END_CLASS_DEFAULT(Explosion, B2BaseClass, NULL, NULL)
// ----------------------------------------------------------------------- //
//
// ROUTINE: Explosion::Explosion()
//
// PURPOSE: Constructor
//
// ----------------------------------------------------------------------- //
Explosion::Explosion() : B2BaseClass()
{
m_hstrSkinName = DNULL;
m_hstrModelName = DNULL;
m_hstrSound = DNULL;
m_fSoundRadius = 1000.0f;
m_fDamageRadius = 200.0f;
m_fMaxDamage = 50.0f;
m_fMinScale = 0.1f;
m_fMaxScale = 1.0f;
m_fDuration = 1.5f;
m_bCreateSmoke = DTRUE;
m_hModel = DNULL;
m_fLastDamageTime = 0.0f;
m_bCreateLight = DTRUE;
m_hLight = DNULL;
m_hShockwave = DNULL;
m_fMinLightRadius = 100.0f;
m_fMaxLightRadius = 300.0f;
VEC_SET(m_vLightColor, 1.0f, 0.5f, 0.0f);
m_bCreateShockwave = DTRUE;
m_hstrShockwaveSprite = DNULL;
VEC_SET(m_vShockwaveScaleMin, 0.1f, 0.1f, 1.0f);
VEC_SET(m_vShockwaveScaleMax, 1.0f, 1.0f, 1.0f);
m_fShockwaveDuration = 0.0f;
m_bCreateMark = DFALSE;
m_bAddSparks = DFALSE;
m_fStartTime = 0.0f;
m_fDelay = 0.0f;
m_bFirstUpdate = DFALSE;
VEC_INIT(m_vRotation);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: Explosion::Setup()
//
// PURPOSE: Setup the Explosion data members (for non DEdit created
// explosions)
//
// ----------------------------------------------------------------------- //
void Explosion::Setup(char* pSound, DFLOAT fSoundRadius, DFLOAT fDuration,
char* pSkinName, DFLOAT fDamageRadius, DFLOAT fMaxDamage,
DFLOAT fMinScale, DFLOAT fMaxScale, DBOOL bCreateMark,
DBOOL bAddSparks, DBOOL bCreateSmoke)
{
if (!g_pServerDE) return;
if (pSound) m_hstrSound = g_pServerDE->CreateString(pSound);
if (pSkinName) m_hstrSkinName = g_pServerDE->CreateString(pSkinName);
m_fSoundRadius = fSoundRadius;
m_fDamageRadius = fDamageRadius;
m_fMaxDamage = fMaxDamage;
m_fMinScale = fMinScale;
m_fMaxScale = fMaxScale;
m_fDuration = fDuration;
m_bCreateSmoke = bCreateSmoke;
m_bCreateMark = bCreateMark;
m_bAddSparks = bAddSparks;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: Explosion::SetupLight()
//
// PURPOSE: Setup the Explosion data members (for non DEdit created
// explosions) if a light is desired
//
// ----------------------------------------------------------------------- //
void Explosion::SetupLight(DBOOL bCreateLight, DVector vLightColor,
DFLOAT fMinRadius, DFLOAT fMaxRadius)
{
m_bCreateLight = bCreateLight;
VEC_COPY(m_vLightColor, vLightColor);
m_fMinLightRadius = fMinRadius;
m_fMaxLightRadius = fMaxRadius;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: Explosion::SetupShockwave()
//
// PURPOSE: Setup the Explosion data members (for non DEdit created
// explosions) if a shockwave is desired
//
// ----------------------------------------------------------------------- //
void Explosion::SetupShockwave(char *pSprite, DVector vScaleMin, DVector vScaleMax,
DFLOAT fDuration)
{
if (!g_pServerDE || !pSprite) return;
if (pSprite) m_hstrShockwaveSprite = g_pServerDE->CreateString(pSprite);
else m_hstrShockwaveSprite = g_pServerDE->CreateString(szDefShockwaveSprite);
VEC_COPY(m_vShockwaveScaleMin, vScaleMin);
VEC_COPY(m_vShockwaveScaleMax, vScaleMax);
m_fShockwaveDuration = fDuration;
m_bCreateShockwave = DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: Explosion::~Explosion()
//
// PURPOSE: Deallocate object
//
// ----------------------------------------------------------------------- //
Explosion::~Explosion()
{
if (!g_pServerDE) return;
if ( m_hstrSound )
{
g_pServerDE->FreeString( m_hstrSound );
}
if ( m_hstrSkinName )
{
g_pServerDE->FreeString( m_hstrSkinName );
}
if ( m_hstrModelName )
{
g_pServerDE->FreeString( m_hstrModelName );
}
if ( m_hstrShockwaveSprite )
{
g_pServerDE->FreeString( m_hstrShockwaveSprite );
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: Explosion::ObjectMessageFn
//
// PURPOSE: Handle object-to-object messages
//
// ----------------------------------------------------------------------- //
DDWORD Explosion::ObjectMessageFn(HOBJECT hSender, DDWORD messageID, HMESSAGEREAD hRead)
{
switch(messageID)
{
case MID_TRIGGER:
{
HandleTrigger(hSender, hRead);
break;
}
default : break;
}
return B2BaseClass::ObjectMessageFn(hSender, messageID, hRead);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: Explosion::EngineMessageFn
//
// PURPOSE: Handle engine messages
//
// ----------------------------------------------------------------------- //
DDWORD Explosion::EngineMessageFn(DDWORD messageID, void *pData, DFLOAT fData)
{
switch(messageID)
{
case MID_UPDATE:
{
Update();
break;
}
case MID_INITIALUPDATE:
{
m_bFirstUpdate = DTRUE;
break;
}
case MID_PRECREATE:
{
if (fData == 1.0f)
ReadProp((ObjectCreateStruct* )pData);
break;
}
case MID_LINKBROKEN:
{
HOBJECT hObj = (HOBJECT)pData;
if (m_hShockwave == hObj)
{
m_hShockwave = DNULL;
}
}
break;
default : break;
}
return B2BaseClass::EngineMessageFn(messageID, pData, fData);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: Explosion::ReadProp()
//
// PURPOSE: Update Properties
//
// ----------------------------------------------------------------------- //
void Explosion::ReadProp(ObjectCreateStruct *pStruct)
{
CServerDE* pServerDE = GetServerDE();
if (!pServerDE || !pStruct) return;
char buf[MAX_CS_FILENAME_LEN];
buf[0] = '\0';
pServerDE->GetPropString("Skin", buf, MAX_CS_FILENAME_LEN);
if (buf[0]) m_hstrSkinName = pServerDE->CreateString(buf);
buf[0] = '\0';
pServerDE->GetPropString("Model", buf, MAX_CS_FILENAME_LEN);
if (buf[0]) m_hstrModelName = pServerDE->CreateString(buf);
buf[0] = '\0';
pServerDE->GetPropString("Sound", buf, MAX_CS_FILENAME_LEN);
if (buf[0]) m_hstrSound = pServerDE->CreateString(buf);
pServerDE->GetPropReal("SoundRadius", &m_fSoundRadius);
pServerDE->GetPropReal("DamageRadius", &m_fDamageRadius);
pServerDE->GetPropReal("MaxDamage", &m_fMaxDamage);
pServerDE->GetPropReal("MinScale", &m_fMinScale);
pServerDE->GetPropReal("MaxScale", &m_fMaxScale);
pServerDE->GetPropReal("Duration", &m_fMinScale);
pServerDE->GetPropBool("CreateLight", &m_bCreateLight);
pServerDE->GetPropVector("LightColor", &m_vLightColor);
VEC_DIVSCALAR(m_vLightColor, m_vLightColor, 255.0f);
pServerDE->GetPropBool("CreateSmoke", &m_bCreateSmoke);
pServerDE->GetPropBool("CreateShockwave", &m_bCreateShockwave);
buf[0] = '\0';
pServerDE->GetPropString("ShockwaveFile", buf, MAX_CS_FILENAME_LEN);
if (buf[0]) m_hstrShockwaveSprite = pServerDE->CreateString(buf);
pServerDE->GetPropVector("ShockwaveScaleMin", &m_vShockwaveScaleMin);
pServerDE->GetPropVector("ShockwaveScaleMax", &m_vShockwaveScaleMax);
pServerDE->GetPropReal("ShockwaveDuration", &m_fShockwaveDuration);
pServerDE->GetPropReal("Delay", &m_fDelay);
pServerDE->GetPropVector("RotateSpeed", &m_vRotation);
return;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: Explosion::CreateExplosion()
//
// PURPOSE: Create explosion
//
// ----------------------------------------------------------------------- //
void Explosion::CreateExplosion(DVector *pvPos)
{
if (!g_pServerDE) return;
ObjectCreateStruct ocStruct;
INIT_OBJECTCREATESTRUCT(ocStruct);
ocStruct.m_Flags = FLAG_VISIBLE;
VEC_COPY(ocStruct.m_Pos, *pvPos);
// DRotation rRot;
// g_pServerDE->GetObjectRotation(m_hObject, &rRot);
// ROT_COPY(ocStruct.m_Rotation, rRot);
DFLOAT fPitch = g_pServerDE->Random(-MATH_PI, MATH_PI);
DFLOAT fYaw = g_pServerDE->Random(-MATH_PI, MATH_PI);
DFLOAT fRoll = g_pServerDE->Random(-MATH_PI, MATH_PI);
g_pServerDE->SetupEuler(&ocStruct.m_Rotation, fPitch, fYaw, fRoll);
if (m_hstrModelName) _mbscpy((unsigned char*)ocStruct.m_Filename, (const unsigned char*)g_pServerDE->GetStringData(m_hstrModelName));
else _mbscpy((unsigned char*)ocStruct.m_Filename, (const unsigned char*)szDefExplosionModel );
if (m_hstrSkinName) _mbscpy((unsigned char*)ocStruct.m_SkinName, (const unsigned char*)g_pServerDE->GetStringData(m_hstrSkinName));
else _mbscpy((unsigned char*)ocStruct.m_SkinName, (const unsigned char*)szDefExplosionSkin );
// Create the explosion model
HCLASS hClass = g_pServerDE->GetClass("CModelObject");
if (!hClass) return;
CModelObject* pImpact = (CModelObject*)g_pServerDE->CreateObject(hClass, &ocStruct);
if (!pImpact) return;
// Initialize the object...
pImpact->Setup(m_fDuration, &m_vRotation, DFALSE, DTRUE);
m_hModel = pImpact->m_hObject;
// Gouraud shade and make full bright...
DDWORD dwFlags = g_pServerDE->GetObjectFlags(m_hModel);
g_pServerDE->SetObjectFlags(m_hModel, dwFlags | FLAG_MODELGOURAUDSHADE | FLAG_NOLIGHT);
g_pServerDE->SetObjectColor(m_hModel, 1.0f, 1.0f, 1.0f, 1.0f);
if (m_bCreateLight) CreateLight(pvPos);
if (m_bCreateShockwave) AddShockwave(pvPos);
if (m_bCreateMark) CreateMark(pvPos);
if (m_bCreateSmoke) CreateSmoke(pvPos);
// CreateFX(pvPos);
// Play sound
DVector vPos;
g_pServerDE->GetObjectPos(m_hObject, &vPos);
if ( m_hstrSound )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -