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

📄 particlestreamfx.cpp

📁 Blood 2全套源码
💻 CPP
字号:
// ----------------------------------------------------------------------- //
//
// MODULE  : ParticleStreamFX.cpp
//
// PURPOSE : Special FX class for streams of particles
//
// CREATED : 8/1/98
//
// ----------------------------------------------------------------------- //

#include "ParticleStreamFX.h"
#include "cpp_client_de.h"
#include "ClientUtilities.h"
#include "ClientServerShared.h"
#include "SoundTypes.h"

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CParticleStreamFX::Init
//
//	PURPOSE:	Init the stream
//
// ----------------------------------------------------------------------- //

DBOOL CParticleStreamFX::Init(SFXCREATESTRUCT* psfxCreateStruct)
{
	if (!CBaseParticleSystemFX::Init(psfxCreateStruct)) return DFALSE;

	PSTREAMCREATESTRUCT* pSS = (PSTREAMCREATESTRUCT*)psfxCreateStruct;

	m_fRadius			= pSS->fRadius;
	m_fPosRadius		= pSS->fPosRadius;
	m_fMinVel			= pSS->fMinVel;
	m_fMaxVel			= pSS->fMaxVel;
	m_nNumParticles		= pSS->nNumParticles;
	m_fSpread			= pSS->fSpread;
	VEC_COPY(m_vColor1, pSS->vColor1);
	VEC_COPY(m_vColor2, pSS->vColor2);
	m_fAlpha			= pSS->fAlpha;
	m_fMinLife			= pSS->fMinLife;
	m_fMaxLife			= pSS->fMaxLife;
	m_fRampTime			= pSS->fRampTime;
	m_fDelay			= pSS->fDelay;
	m_bState			= pSS->bOn ? 2 : 0;
	m_bRampFlags		= pSS->bRampFlags;
	m_fGravity			= pSS->fGravity;

	m_hstrSound1		= pSS->hstrSound1;
	m_hstrSound2		= pSS->hstrSound2;
	m_hstrSound3		= pSS->hstrSound3;

	m_hstrTexture		= pSS->hstrTexture;
	m_pTextureName		= "SpriteTextures\\drop32_1.dtx";
	return DTRUE;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CParticleStreamFX::CreateObject
//
//	PURPOSE:	Create object associated the particle system.
//
// ----------------------------------------------------------------------- //

DBOOL CParticleStreamFX::CreateObject(CClientDE *pClientDE)
{
	if(!pClientDE ) return DFALSE;

	if(m_hstrTexture)
		m_pTextureName = pClientDE->GetStringData(m_hstrTexture);
	
	DBOOL bRet = CBaseParticleSystemFX::CreateObject(pClientDE);

	if(m_hServerObject)
	{
		DVector		vPos;
		DRotation	rRot;

		m_pClientDE->GetObjectPos(m_hServerObject, &vPos);
		m_pClientDE->SetObjectPos(m_hObject, &vPos);

		m_pClientDE->GetObjectRotation(m_hServerObject, &rRot);
		m_pClientDE->GetRotationVectors(&rRot, &m_vU, &m_vR, &m_vDir);
	}
	else
		return DFALSE;

	if(bRet)
	{
		DFLOAT		r, g, b, a;
		m_pClientDE->GetObjectColor(m_hObject, &r, &g, &b, &a);
		m_pClientDE->SetObjectColor(m_hObject, r, g, b, m_fAlpha);
		if(m_bState)	AddParticles();
	}

	return bRet;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CParticleStreamFX::Update
//
//	PURPOSE:	Update the particles
//
// ----------------------------------------------------------------------- //

DBOOL CParticleStreamFX::Update()
{
	if(!m_hObject || !m_pClientDE) return DFALSE;

	// Update the position and direction of the particle stream based on the server object
	if(m_hServerObject)
	{
		DVector		vPos;
		DRotation	rRot;

		m_pClientDE->GetObjectPos(m_hServerObject, &vPos);
		m_pClientDE->SetObjectPos(m_hObject, &vPos);

		m_pClientDE->GetObjectRotation(m_hServerObject, &rRot);
		m_pClientDE->GetRotationVectors(&rRot, &m_vU, &m_vR, &m_vDir);
	}
	else
		return DFALSE;

	// Check to see if the server object is visible (determines on/off state of effect)
	DDWORD dwFlags;
	m_pClientDE->GetObjectUserFlags(m_hServerObject, &dwFlags);

	if(dwFlags & USRFLG_VISIBLE)
	{
		if((m_bState == 0) || (m_bState == 3))
		{
			m_fTriggerTime = m_pClientDE->GetTime();
			if(m_fRampTime)		m_bState = 1;
				else			m_bState = 2;
		}
	}
	else
	{
		if((m_bState == 1) || (m_bState == 2))
		{
			m_fTriggerTime = m_pClientDE->GetTime();
			if(m_fRampTime)		m_bState = 3;
				else			m_bState = 0;
		}
	}

	// Play the correct sound according to the current state
	switch(m_bState)
	{
		case	1:
			if(m_hstrSound1)
			{
				if(m_hsSound)	m_pClientDE->KillSound(m_hsSound);
				m_hsSound = PlaySoundFromObject(m_hObject, m_pClientDE->GetStringData(m_hstrSound1),
							m_fSoundRadius, SOUNDPRIORITY_MISC_MEDIUM, DFALSE, DTRUE);
			}
			break;

		case	2:
			if(m_hstrSound2 && !m_hsSound)
			{
				m_hsSound = PlaySoundFromObject(m_hObject, m_pClientDE->GetStringData(m_hstrSound2),
							m_fSoundRadius, SOUNDPRIORITY_MISC_MEDIUM, DTRUE, DTRUE);
			}
			break;

		case	3:
			if(m_hstrSound3)
			{
				if(m_hsSound)	m_pClientDE->KillSound(m_hsSound);
				m_hsSound = PlaySoundFromObject(m_hObject, m_pClientDE->GetStringData(m_hstrSound3),
							m_fSoundRadius, SOUNDPRIORITY_MISC_MEDIUM, DFALSE, DTRUE);
			}
			break;
	}

	// See if it's time to add more particles... and do so
	if(m_pClientDE->GetTime() > m_fLastAddTime + m_fDelay)
		AddParticles();

	return DTRUE;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CParticleStreamFX::AddParticles
//
//	PURPOSE:	Make the liquid drops
//
// ----------------------------------------------------------------------- //

DBOOL CParticleStreamFX::AddParticles()
{
	if(!m_hObject || !m_pClientDE) return DFALSE;

	DVector		minOffset, maxOffset;
	DFLOAT		minVel, maxVel;
	DFLOAT		minLife, maxLife;
	DFLOAT		spread;
	DFLOAT		ratio, time = m_pClientDE->GetTime();
	DDWORD		num;

	if(!m_bState)	return	DTRUE;

	num = m_nNumParticles;
	VEC_SET(minOffset, -m_fPosRadius, -m_fPosRadius, -m_fPosRadius);
	VEC_SET(maxOffset, m_fPosRadius, m_fPosRadius, m_fPosRadius);
	minVel = m_fMinVel;
	maxVel = m_fMaxVel;
	minLife = m_fMinLife;
	maxLife = m_fMaxLife;
	spread = m_fSpread;

	if((m_bState == 1) || (m_bState == 3))
	{
		// Set the ratio to ramp the values with
		if(m_bState == 1)
		{
			ratio = (time - m_fTriggerTime) / m_fRampTime;
			if(ratio >= 1.0f)
				{ ratio = 1.0f; m_bState = 2; }
		}
		else
		{
			ratio = 1.0f - ((time - m_fTriggerTime) / m_fRampTime);
			if(ratio <= 0.0f)
				{ ratio = 0.0f; m_bState = 0; return DTRUE; }
		}

		// Check which elements of the stream we should ramp... and calculate new values
		if(m_bRampFlags & PSTREAM_RAMP_NUM)
			num = (DDWORD)(num * ratio);

		if(m_bRampFlags & PSTREAM_RAMP_OFFSET)
		{
			VEC_MULSCALAR(minOffset, minOffset, ratio);
			VEC_MULSCALAR(maxOffset, maxOffset, ratio);
		}

		if(m_bRampFlags & PSTREAM_RAMP_VEL)
		{
			minVel *= ratio;
			maxVel *= ratio;
			spread *= ratio;
		}

		if(m_bRampFlags & PSTREAM_RAMP_LIFE)
		{
			minLife *= ratio;
			maxLife *= ratio;
		}
	}

	// Add the particles one by one... (instead of AddParticles... cause I wanted the spread)
	for(DDWORD i = 0; i < num; i++)
	{
		DVector		pos, vel, vSpread, color;
		DFLOAT		life = GetRandom(minLife, maxLife);

		VEC_SET(pos, GetRandom(minOffset.x, maxOffset.x), GetRandom(minOffset.y, maxOffset.y), GetRandom(minOffset.z, maxOffset.z));
		VEC_SET(vSpread, GetRandom(-spread, spread), GetRandom(-spread, spread), GetRandom(-spread, spread));
		VEC_MULSCALAR(vel, m_vDir, maxVel);
		VEC_ADD(vel, vel, vSpread);
		VEC_NORM(vel);
		VEC_MULSCALAR(vel, vel, GetRandom(minVel, maxVel));

		GetRandomColorInRange(color);

		m_pClientDE->AddParticle(m_hObject, &pos, &vel, &color, life);
	}

	// Make sure we know when the last batch of particles were added
	m_fLastAddTime = time;
	return DTRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -