⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 explosion.cpp

📁 Blood 2全套源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ----------------------------------------------------------------------- //
//
// 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 + -