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

📄 weaponfx.cpp

📁 Blood 2全套源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// ----------------------------------------------------------------------- //
//
// MODULE  : WeaponFX.cpp
//
// PURPOSE : Weapon special effects - adapted from Riot
//
// CREATED : 4/30/98
//
// ----------------------------------------------------------------------- //

#include "WeaponFX.h"
#include "cpp_client_de.h"
#include "ClientUtilities.h"
#include "BloodClientShell.h"
#include "MarkSFX.h"
#include "SparksFX.h"
#include "ClientServerShared.h"
#include "SFXMsgIds.h"
#include "SmokeFX.h"
#include "SmokeImpactFX.h"
#include "SurfaceFragmentFX.h"
#include "bloodsplatfx.h"
#include "ParticleExplosionFX.h"
#include "ShellCasingFX.h"
#include "ExplosionFX.h"
#include "SplashFX.h"
#include "RippleFX.h"
#include "SoundTypes.h"

extern CBloodClientShell* g_pBloodClientShell;

char* 	szSmokeParticles[6] = {"SpriteTextures\\smoke64_1.dtx",
							   "SpriteTextures\\smoke64_2.dtx",
							   "SpriteTextures\\smoke64_3.dtx",
							   "SpriteTextures\\smoke64_4.dtx",
							   "SpriteTextures\\smoke64_5.dtx",
							   "SpriteTextures\\smoke64_6.dtx",};

char* 	szSmokeSprites[6] = {"Sprites\\smokepuff1.spr",
							 "Sprites\\smokepuff2.spr",
							 "Sprites\\smokepuff3.spr",
							 "Sprites\\smokepuff4.spr",
							 "Sprites\\smokepuff5.spr",
							 "Sprites\\smokepuff6.spr",};

#define	DEFAULT_WATER_IMPACT_SOUND_RADIUS	2000.0f
#define	DEFAULT_IMPACT_SOUND_RADIUS			500.0f

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CWeaponFX::Init
//
//	PURPOSE:	Init the weapon fx
//
// ----------------------------------------------------------------------- //

DBOOL CWeaponFX::Init(SFXCREATESTRUCT* psfxCreateStruct)
{
	if (!CSpecialFX::Init(psfxCreateStruct)) return DFALSE;

	WFXCREATESTRUCT* pCS = (WFXCREATESTRUCT*)psfxCreateStruct;

	VEC_COPY(m_vSourcePos, pCS->vSourcePos);
	VEC_COPY(m_vDestPos, pCS->vDestPos);
	VEC_COPY(m_vForward, pCS->vForward);
	VEC_COPY(m_vNormal, pCS->vNormal);

	m_nFXFlags			= pCS->nFXFlags;
	m_nExtraData		= pCS->nExtraData;

	m_nAmmoType			= pCS->nAmmoType;
	m_eSurfaceType		= (SurfaceType)pCS->nSurfaceType;
	m_nExplosionType	= pCS->nExplosionType;

	m_fDamage			= pCS->fDamage;
	m_fDensity			= pCS->fDensity;

	VEC_COPY(m_vColor1, pCS->vColor1);
	VEC_COPY(m_vColor2, pCS->vColor2);
	VEC_COPY(m_vLightColor1, pCS->vLightColor1);
	VEC_COPY(m_vLightColor2, pCS->vLightColor2);

	m_eSourceCode	= CC_NOTHING;
	m_eDestCode		= CC_NOTHING;

	return DTRUE;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CWeaponFX::CreateObject
//
//	PURPOSE:	Create the various fx
//
// ----------------------------------------------------------------------- //

DBOOL CWeaponFX::CreateObject(CClientDE* pClientDE)
{
	CBloodClientShell *pShell = (CBloodClientShell*)g_pClientDE->GetClientShell();
	if (!CSpecialFX::CreateObject(pClientDE) || !pShell) return DFALSE;

	// Calculate the direction vector
	VEC_SUB(m_vDir, m_vDestPos, m_vSourcePos);

	VEC_NORM(m_vDir);
	VEC_NORM(m_vForward);
	VEC_NORM(m_vNormal);

	// Get the rotation
	m_pClientDE->AlignRotation(&m_rRotation, &m_vNormal, DNULL);

	// Determine what container the source location is in...
	HLOCALOBJ objList[1];
	DDWORD dwNum = m_pClientDE->GetPointContainers(&m_vSourcePos, objList, 1);

	if(dwNum > 0 && objList[0])
	{
		DDWORD dwUserFlags;
		m_pClientDE->GetObjectUserFlags(objList[0], &dwUserFlags);

		if(dwUserFlags & USRFLG_VISIBLE)
		{
			D_WORD dwCode;
			if (m_pClientDE->GetContainerCode(objList[0], &dwCode))
				m_eSourceCode = (ContainerCode)dwCode;
		}
	}

	// Determine what container the destination location is in...
	dwNum = m_pClientDE->GetPointContainers(&m_vDestPos, objList, 1);

	if (dwNum > 0 && objList[0])
	{
		DDWORD dwUserFlags;
		m_pClientDE->GetObjectUserFlags(objList[0], &dwUserFlags);

		if (dwUserFlags & USRFLG_VISIBLE)
		{
			D_WORD dwCode;
			if (m_pClientDE->GetContainerCode(objList[0], &dwCode))
				m_eDestCode = (ContainerCode)dwCode;
		}
	}

	// Create the FX from the muzzle to the destination
	if(m_nFXFlags & WFX_MUZZLESMOKE)		CreateMuzzleSmoke();
	if(m_nFXFlags & WFX_MUZZLELIGHT)		CreateMuzzleLight();
	if(m_nFXFlags & WFX_EJECTSHELL)
		{ CreateShellCasing(); if(m_nAmmoType == AMMO_SHELL) CreateShellCasing(); }
	if(m_nFXFlags & WFX_TRACER)				CreateTracer();
	if(m_nFXFlags & WFX_PARTICLETRAIL)		CreateParticleTrail();

	// Create the FX at the destination
	if(m_nFXFlags & WFX_MARK)				CreateMark();
	if(m_nFXFlags & WFX_FLASH)				CreateFlash();
	if(m_nFXFlags & WFX_SPARKS)				CreateSparks();
	if(m_nFXFlags & WFX_SPLASH)				CreateSplash();
	if(m_nFXFlags & WFX_SMOKE)				CreateSmoke();
	if(m_nFXFlags & WFX_SOUND)				PlayImpactSound();
	if(m_nFXFlags & WFX_BLOODSPLAT)			CreateBloodSplat();
	if(m_nFXFlags & WFX_BLOODSPURT)			CreateBloodSpurt();
	if(m_nFXFlags & WFX_EXPLOSION)			CreateExplosion();
	if(m_nFXFlags & WFX_FRAGMENTS)			CreateFragments();
	if(m_nFXFlags & WFX_IMPACTLIGHT)		CreateImpactLight();
	if(m_nFXFlags & WFX_SCREENSHAKE)		CreateShakeNFlash();

	return DTRUE;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CWeaponFX::Update
//
//	PURPOSE:	Update the weapon fx
//
// ----------------------------------------------------------------------- //

DBOOL CWeaponFX::Update()
{
	return DFALSE;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CWeaponFX::CreateMark
//
//	PURPOSE:	Create a mark fx
//
// ----------------------------------------------------------------------- //

void CWeaponFX::CreateMark()
{
	CBloodClientShell *pShell = (CBloodClientShell*)g_pClientDE->GetClientShell();
	if (!pShell) return;

	CSFXMgr* psfxMgr = pShell->GetSFXMgr();
	if (!psfxMgr) return;

	char* pMarkSprite = GetMarkSprite(m_eSurfaceType);
	if (!pMarkSprite) return;

	MARKCREATESTRUCT mark;

	mark.hServerObj = DNULL;
	VEC_COPY(mark.m_Pos, m_vDestPos);
	ROT_COPY(mark.m_Rotation, m_rRotation);
	mark.m_fScale = (m_nAmmoType == AMMO_BULLET) ? 0.05f : 0.035f;
	mark.m_hstrSprite = m_pClientDE->CreateString(pMarkSprite);
	mark.m_bServerObj = DFALSE;

	psfxMgr->CreateSFX(SFX_MARK_ID, &mark, DFALSE, this);
	g_pClientDE->FreeString( mark.m_hstrSprite );
}

// ----------------------------------------------------------------------- //
// ROUTINE		: CWeaponFX::CreateBloodSplat
// DESCRIPTION	: Create a blood splat on surface
// RETURN TYPE	: void 
// ----------------------------------------------------------------------- //

void CWeaponFX::CreateBloodSplat()
{
	CBloodClientShell *pShell = (CBloodClientShell*)g_pClientDE->GetClientShell();
	if (!pShell) return;

	CSFXMgr* psfxMgr = pShell->GetSFXMgr();
	if (!psfxMgr) return;

	char* pSplatSprite = DNULL;

	switch(GetRandom(1,3))
	{
		case 1:		pSplatSprite = "sprites\\bloodsplat1.spr";	break;
		case 2:		pSplatSprite = "sprites\\bloodsplat2.spr";	break;
		case 3:		pSplatSprite = "sprites\\bloodsplat3.spr";	break;
		default:	pSplatSprite = "sprites\\bloodsplat1.spr";	break;
	}

	BSCREATESTRUCT splat;

	splat.hServerObj = DNULL;
	VEC_COPY(splat.m_Pos, m_vDestPos);
	ROT_COPY(splat.m_Rotation, m_rRotation);
	splat.m_fScale = 0.1f + GetRandom(-0.05f,0.05f);
	splat.m_hstrSprite = m_pClientDE->CreateString(pSplatSprite);
	splat.m_fGrowScale = 0;

	psfxMgr->CreateSFX(SFX_BLOODSPLAT_ID, &splat, DFALSE, this);
	g_pClientDE->FreeString( splat.m_hstrSprite );
}

// ----------------------------------------------------------------------- //
// ROUTINE		: CWeaponFX::CreateBloodSpurt
// DESCRIPTION	: Create a blood splat on surface
// RETURN TYPE	: void 
// ----------------------------------------------------------------------- //

void CWeaponFX::CreateBloodSpurt()
{
	CBloodClientShell *pShell = (CBloodClientShell*)g_pClientDE->GetClientShell();
	if (!pShell) return;
	CSFXMgr* psfxMgr = pShell->GetSFXMgr();
	if (!psfxMgr) return;

	char* szBlood[4] = { "spritetextures\\particles\\blooddrop_1.dtx", 
						 "spritetextures\\particles\\blooddrop_2.dtx",
						 "spritetextures\\particles\\blooddrop_3.dtx",
						 "spritetextures\\particles\\blooddrop_4.dtx"};


	PESCREATESTRUCT pe;

//	VEC_SET(pe.vVelMin, -50.0f, 0.0f, -50.0f)
//	VEC_SET(pe.vVelMax, 50.0f, 50.0f, 50.0f)
	VEC_MULSCALAR(pe.vMinVel, m_vNormal, 30.0f);
	VEC_MULSCALAR(pe.vMaxVel, m_vNormal, 50.0f);
	pe.vMinVel.y = 40.0f;
	pe.vMaxVel.y = 50.0f;
	pe.vMinVel.x -= 20.0f;
	pe.vMinVel.z -= 20.0f;
	pe.vMaxVel.x += 20.0f;
	pe.vMaxVel.z += 20.0f;

	VEC_COPY(pe.vPos, m_vDestPos);
	ROT_COPY(pe.rSurfaceRot, m_rRotation);
//	VEC_SET(pe.vColor1, 255.0f, 255.0f, 255.0f);
//	VEC_SET(pe.vColor2, 255.0f, 255.0f, 255.0f);
	VEC_SET(pe.vColor1, 128.0f, 128.0f, 128.0f);
	VEC_SET(pe.vColor2, 128.0f, 128.0f, 128.0f);
//	VEC_COPY(pe.vMinVel, vVelMin);
//	VEC_COPY(pe.vMaxVel, vVelMax);
	VEC_SET(pe.vMinDriftOffset, 0.0f, -10.0f, 0.0f);
	VEC_SET(pe.vMaxDriftOffset, 0.0f, -5.0f, 0.0f);
	pe.bSmall			= DFALSE;
	pe.fLifeTime		= 1.0f;
	pe.fFadeTime		= 0.5f;
	pe.fOffsetTime		= 0.0f;
	pe.fRadius			= 200.0f;
	pe.fGravity			= -100.0f;
	pe.nNumPerPuff		= 2;
	pe.nNumEmitters		= 1; //GetRandom(1,4);
	pe.nEmitterFlags	= MO_HALFGRAVITY;
	pe.bIgnoreWind		= DTRUE;
	
	int nMaxSZBlood = NRES(4) - 1;
	pe.pFilename		= szBlood[GetRandom(0,nMaxSZBlood)];
	pe.nSurfaceType		= SURFTYPE_FLESH;
	pe.nNumSteps		= 6;
	pe.bBounce			= DFALSE;


	CSpecialFX* pFX = psfxMgr->CreateSFX(SFX_PARTICLEEXPLOSION_ID, &pe, DFALSE, this);
	if (pFX) 
	{
		CBaseParticleSystemFX* pBasePS = (CBaseParticleSystemFX*)pFX;
		pBasePS->m_bSetSoftwareColor = DFALSE;

		pFX->Update();
		m_pClientDE->SetSoftwarePSColor(pFX->GetObject(), 1.0f, 0.0f, 0.0f);
	}

	// Create a pass-through spurt scaled by damage
	VEC_MULSCALAR(pe.vMinVel, m_vNormal, -2.5f * m_fDamage);
	VEC_MULSCALAR(pe.vMaxVel, m_vNormal, -3.0f * m_fDamage);
	pe.vMinVel.y += 30.0f;
	pe.vMaxVel.y += 40.0f;
	pe.vMinVel.x -= 20.0f;
	pe.vMinVel.z -= 20.0f;
	pe.vMaxVel.x += 20.0f;
	pe.vMaxVel.z += 20.0f;
	pe.fLifeTime		= 1.2f;
	pe.fFadeTime		= 0.8f;

	pFX = psfxMgr->CreateSFX(SFX_PARTICLEEXPLOSION_ID, &pe, DFALSE, this);
	if (pFX) pFX->Update();
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CWeaponFX::CreateSparks
//
//	PURPOSE:	Create sparks fx
//
// ----------------------------------------------------------------------- //

void CWeaponFX::CreateSparks()
{
	CBloodClientShell *pShell = (CBloodClientShell*)g_pClientDE->GetClientShell();
	if (!pShell) return;

	CSFXMgr* psfxMgr = pShell->GetSFXMgr();
	if (!psfxMgr) return;

	SCREATESTRUCT sp;
	DBOOL	big = DFALSE;
	char	str[128];

	// General variables for the sparks
	sp.hServerObj = DNULL;
	VEC_COPY(sp.vPos, m_vDestPos);
	sp.bFadeColors = DFALSE;

	switch(m_eSurfaceType)
	{
		// Specific variable values just for metal surfaces
		case	SURFTYPE_METAL:
			big = GetRandom(0,19) ? DFALSE : DTRUE;

			VEC_MULSCALAR(sp.vDir, m_vNormal, 75.0f);
			VEC_SET(sp.vColor1, 255.0f, 255.0f, 0.0f);
			VEC_SET(sp.vColor2, 255.0f, 255.0f, 255.0f);

			sp.hstrTexture		= m_pClientDE->CreateString("spriteTextures\\particles\\particle2.dtx");
			sp.fEmissionRadius	= 0.3f;
			sp.fRadius			= 175.0f;
			sp.fGravity			= -150;

			if(big)
			{
				sp.nSparks			= (m_fDamage < 50.0f) ? (DBYTE)(m_fDamage * 5.0f): 250;

⌨️ 快捷键说明

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