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

📄 smoketrailsegmentfx.cpp

📁 Blood 2全套源码
💻 CPP
字号:
// ----------------------------------------------------------------------- //
//
// MODULE  : SmokeTrailSegmentFX.cpp
//
// PURPOSE : SmokeTrail segment special FX - Implementation
//
// CREATED : 3/1/98
//
// ----------------------------------------------------------------------- //

#include "SmokeTrailSegmentFX.h"
#include "cpp_client_de.h"
#include "ClientUtilities.h"
#include "ContainerCodes.h"

DVector g_vWorldWindVel;

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CSmokeTrailSegmentFX::Init
//
//	PURPOSE:	Init the smoke trail segment
//
// ----------------------------------------------------------------------- //

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

	STSCREATESTRUCT* pSTS = (STSCREATESTRUCT*)psfxCreateStruct;
	VEC_COPY(m_vVel, pSTS->vVel);
	VEC_COPY(m_vColor1, pSTS->vColor1);
	VEC_COPY(m_vColor2, pSTS->vColor2);
	m_bSmall		= pSTS->bSmall;
	m_fLifeTime		= pSTS->fLifeTime;
	m_fFadeTime		= pSTS->fFadeTime;
	m_fOffsetTime	= pSTS->fOffsetTime;
	m_fRadius		= pSTS->fRadius;
	m_fGravity		= pSTS->fGravity;
	m_nNumPerPuff	= pSTS->nNumPerPuff;

	m_bIgnoreWind	= DFALSE;

	if (m_bSmall)
	{
		m_fRadius /= 2.0f;
	}

	return DTRUE;
}

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

DBOOL CSmokeTrailSegmentFX::CreateObject(CClientDE *pClientDE)
{
	if(!pClientDE || !m_hServerObject) return DFALSE;

	m_pTextureName	= "SpriteTextures\\smoke32_2.dtx";

	// Determine if we are in a liquid...
	DVector vPos;
	pClientDE->GetObjectPos(m_hServerObject, &vPos);

	HLOCALOBJ objList[1];
	DDWORD dwNum = pClientDE->GetPointContainers(&vPos, objList, 1);

	if(dwNum > 0 && objList[0])
	{
		D_WORD dwCode;
		if(pClientDE->GetContainerCode(objList[0], &dwCode))
		{
			if(IsLiquid((ContainerCode)dwCode))
			{
				m_pTextureName = "SpriteTextures\\ParticleTextures\\particlebubble.dtx";
				m_fRadius *= 0.25f;
				m_fGravity = 5.0f;
				m_nNumPerPuff *= 3;
				m_bIgnoreWind = DTRUE;
			}
		}
	}

	int ret = CBaseParticleSystemFX::CreateObject(pClientDE);

	if(ret)
	{
		DFLOAT r, g, b, a;
		m_pClientDE->GetObjectColor(m_hObject, &r, &g, &b, &a);
		m_pClientDE->SetObjectColor(m_hObject, r, g, b, 0.5f);
	}

	return ret;
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CSmokeTrailSegmentFX::Update
//
//	PURPOSE:	Update the smoke trail (add smoke)
//
// ----------------------------------------------------------------------- //

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

	DFLOAT fTime = m_pClientDE->GetTime();

	if (m_bFirstUpdate)
	{
		if (!m_hServerObject) return DFALSE;

		m_bFirstUpdate = DFALSE;
		m_fStartTime   = fTime;
		m_fLastTime	   = fTime;

		// Where is the server (moving) object...
		DVector vPos, vTemp;
		m_pClientDE->GetObjectPos(m_hServerObject, &vPos);
		
		// Current position is relative to the particle system's postion (i.e., 
		// each puff of smoke is some distance away from the particle system's 
		/// position)...
		m_pClientDE->GetObjectPos(m_hObject, &vTemp);
		VEC_SUB(vPos, vPos, vTemp);

		VEC_COPY(m_vLastPos, vPos);
	}


	// Check to see if we should just wait for last smoke puff to go away...
	if (m_bWantRemove || (fTime > m_fStartTime + m_fFadeTime))
	{
		if (fTime > m_fLastTime + m_fLifeTime)
		{
			return DFALSE;
		}

		DFLOAT fScale = (m_fLifeTime - (fTime - m_fLastTime)) / m_fLifeTime;

		// Adjust the alpha
		DFLOAT r, g, b, a;
		m_pClientDE->GetObjectColor(m_hObject, &r, &g, &b, &a);
		m_pClientDE->SetObjectColor(m_hObject, r, g, b, fScale);

		return DTRUE;
	}

	// See if it is time to create a new smoke puff...
	if ((fTime > m_fLastTime + m_fOffsetTime) && m_hServerObject)
	{
		DVector vCurPos, vPos, vDelta, vTemp, vDriftVel, vColor;

		// Calculate smoke puff position...

		// Where is the server (moving) object...
		m_pClientDE->GetObjectPos(m_hServerObject, &vCurPos);
		
		// Current position is relative to the particle system's postion (i.e., 
		// each puff of smoke is some distance away from the particle system's 
		/// position)...
		m_pClientDE->GetObjectPos(m_hObject, &vTemp);
		VEC_SUB(vCurPos, vCurPos, vTemp);

		// How long has it been since the last smoke puff?
		DFLOAT fTimeOffset = fTime - m_fLastTime;

		// What is the range of colors?
		DFLOAT fRange = m_vColor2.x - m_vColor1.x;

		// Fill the distance between the last projectile position, and it's 
		// current position with smoke puffs...
		int nNumSteps = (m_fLastTime > 0) ? 8 : 1;

		VEC_SUB(vTemp, vCurPos, m_vLastPos);
		VEC_MULSCALAR(vDelta, vTemp, 1.0f/float(nNumSteps));

		VEC_COPY(vPos, m_vLastPos);

		DFLOAT fCurLifeTime    = 10.0f; //  m_fLifeTime - fTimeOffset;
		DFLOAT fLifeTimeOffset = fTimeOffset / float(nNumSteps);

		DFLOAT fOffset = 0.5f;
		DVector vDriftOffset;
		VEC_SET(vDriftOffset, 4.0f, 5.5f, 0.5f);

		if (m_bSmall)
		{
			VEC_SET(vDriftOffset, 5.0f, 50.0f, 5.0f);
		}
		else
		{
			VEC_SET(vDriftOffset, 10.0f, 50.0f, 10.0f);
		}

		for (int i=0; i < nNumSteps; i++)
		{
			// Build the individual smoke puffs...

			for (int j=0; j < m_nNumPerPuff; j++)
			{
				VEC_COPY(vTemp, vPos);

				if (m_bIgnoreWind)
				{
					VEC_SET(vDriftVel, GetRandom(-vDriftOffset.x, vDriftOffset.x), 
									   GetRandom(5.0f, 6.0f), 
									   GetRandom(-vDriftOffset.z, vDriftOffset.z));
				}
				else
				{
					VEC_SET(vDriftVel, g_vWorldWindVel.x + GetRandom(-vDriftOffset.x, vDriftOffset.x), 
									   g_vWorldWindVel.y + GetRandom(5.0f, 6.0f), 
									   g_vWorldWindVel.z + GetRandom(-vDriftOffset.z, vDriftOffset.z));
				}

				vTemp.x += GetRandom(-fOffset, fOffset);
				vTemp.y += GetRandom(-fOffset, fOffset);
				vTemp.z += GetRandom(-fOffset, fOffset);

				DFLOAT fOffset  = GetRandom(m_vColor1.x, m_vColor2.x);
				DFLOAT fPercent = 1.0f;

				if (fRange > 0.01)
				{
					fPercent = fOffset / fRange;
				}

				vColor.x = m_vColor1.x + fOffset;

				fOffset = fPercent * (m_vColor2.y - m_vColor1.y);
				vColor.y = m_vColor1.y + fOffset;

				fOffset = fPercent * (m_vColor2.z - m_vColor1.z);
				vColor.z = m_vColor1.z + fOffset;

				m_pClientDE->AddParticle(m_hObject, &vTemp, &vDriftVel, &vColor, fCurLifeTime);

			}
			VEC_ADD(vPos, vPos, vDelta);
			fCurLifeTime += fLifeTimeOffset;
		}

		m_fLastTime = fTime;

		VEC_COPY(m_vLastPos, vCurPos);
	}

	return DTRUE;
}

⌨️ 快捷键说明

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