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

📄 explosionfx.cpp

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