// ----------------------------------------------------------------------- //
//
// MODULE  : LOFWeaponFX.cpp
//
// PURPOSE : LOF Weapon special FX - Implementation
//
// CREATED : 18/12/98 - by Ewen Vowels for Anarchy-Arts
//
// ----------------------------------------------------------------------- //

#include "WeaponFX.h"
#include "cpp_client_de.h"
#include "ClientUtilities.h"
#include "WeaponFXTypes.h"
#include "RiotClientShell.h"
#include "MarkSFX.h"
#include "SparksFX.h"
#include "DynamicLightFX.h"
#include "BulletTrailFX.h"
#include "RiotMsgIDs.h"
#include "JuggernautFX.h"
#include "ShellCasingFX.h"
#include "ParticleExplosionFX.h"
#include "SpriteFX.h"
#include "ExplosionFX.h"
#include "DebrisFX.h"
#include "LineBallFX.h"
#include "CMoveMgr.h"

extern CRiotClientShell* g_pRiotClientShell;

#define	DEFAULT_WATER_IMPACT_SOUND_RADIUS	2000.0f
#define	DEFAULT_IMPACT_SOUND_RADIUS			500.0f

static DDWORD s_nNumShells = 0;

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CWeaponFX::CreateShochiFX
//
//	PURPOSE:	Create the Shochi fx
//
// ----------------------------------------------------------------------- //

void CWeaponFX::CreateShochiFX()
{
	if (!m_pClientDE || !g_pRiotClientShell) return;

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

	DFLOAT fFactor = m_eSize == MS_SMALL ? 0.2f : (m_eSize == MS_LARGE ? 5.0f : 1.0f);

	// Create model explosion...

	EXCREATESTRUCT ex;
	VEC_COPY(ex.vPos, m_vPos);

	DFLOAT fRadius = GetWeaponDamageRadius(m_nWeaponId, m_eSize) * 2.0f;

	VEC_SET(ex.vVel, 0.0f, 0.0f, 0.0f);
	VEC_SET(ex.vInitialScale, 50.0f, 50.0f, 50.0f);
	VEC_MULSCALAR(ex.vInitialScale, ex.vInitialScale, fFactor);
	VEC_SET(ex.vFinalScale, fRadius, fRadius, fRadius);
	VEC_SET(ex.vInitialColor, 1.0f, 1.0f, 1.0f);
	VEC_SET(ex.vFinalColor, 1.0f, 1.0f, 1.0f);
	ex.bUseUserColors = DTRUE;

	ex.dwFlags			= FLAG_VISIBLE | FLAG_MODELGOURAUDSHADE | FLAG_NOLIGHT;
	ex.fLifeTime		= 1.0f;
	ex.fInitialAlpha	= 0.3f;
	ex.fFinalAlpha		= 0.3f;
	ex.pFilename		= "Models\\PV_Weapons\\JuggernautExplosion.abc";
	ex.pSkin			= "SpecialFX\\Explosions\\juggernaut.dtx";

	CSpecialFX* pFX = psfxMgr->CreateSFX(SFX_EXPLOSION_ID, &ex);
	if (pFX) pFX->Update();


	// Create smoke bank...
/*
	SPRITECREATESTRUCT sc;

	DVector vPos;
	VEC_MULSCALAR(vPos, m_vDir, 10.0f);
	VEC_ADD(vPos, vPos, m_vPos);

	VEC_COPY(sc.vPos, vPos);
	VEC_SET(sc.vVel, 0.0f, 10.0f, 0.0f);

	VEC_SET(sc.vInitialScale, 0.5f, 0.5f, 1.0f);
	VEC_MULSCALAR(sc.vInitialScale, sc.vInitialScale, fFactor);
	VEC_SET(sc.vFinalScale, 4.0f, 4.0f, 1.0f);
	VEC_MULSCALAR(sc.vFinalScale, sc.vFinalScale, fFactor);

	sc.dwFlags			= FLAG_VISIBLE | FLAG_SPRITEBIAS | FLAG_NOLIGHT; 
	sc.fLifeTime		= 5.0f;
	sc.fInitialAlpha	= 1.0f;
	sc.fFinalAlpha		= 0.0f;
	sc.pFilename		= "Sprites\\SmokeTest.spr";

	pFX = psfxMgr->CreateSFX(SFX_SPRITE_ID, &sc);
	if (pFX) pFX->Update();

	DFLOAT fOffset = 30.0f * fFactor;

	sc.vPos.x += GetRandom(-fOffset, fOffset);
	sc.vPos.z += GetRandom(-fOffset, fOffset);
	VEC_SET(sc.vVel, 0.0f, fOffset/2.0f, 0.0f);
	VEC_SET(sc.vInitialScale, 0.75f, 0.75f, 1.0f);
	VEC_MULSCALAR(sc.vInitialScale, sc.vInitialScale, fFactor);
	VEC_SET(sc.vFinalScale, 4.0f, 4.0f, 1.0f);
	VEC_MULSCALAR(sc.vFinalScale, sc.vFinalScale, fFactor);
	sc.fLifeTime		= 6.0f;

	pFX = psfxMgr->CreateSFX(SFX_SPRITE_ID, &sc);
	if (pFX) pFX->Update();


	DVector vVelMin, vVelMax;
	VEC_SET(vVelMin, -200.0f, 200.0f, -200.0f)
	VEC_MULSCALAR(vVelMin, vVelMin, fFactor)
	VEC_SET(vVelMax, 200.0f, 400.0f, 200.0f)
	VEC_MULSCALAR(vVelMax, vVelMax, fFactor)

	// Create a particle explosion...

	PESCREATESTRUCT pe;

	pe.bCreateDebris	= DTRUE;
	pe.bRotateDebris	= DTRUE;
	ROT_COPY(pe.rSurfaceRot, m_rSurfaceRot);
	VEC_COPY(pe.vPos, m_vPos);
	VEC_SET(pe.vColor1, 200.0f, 200.0f, 200.0f);
	VEC_SET(pe.vColor2, 230.0f, 230.0f, 230.0f);
	VEC_COPY(pe.vMinVel, vVelMin);
	VEC_COPY(pe.vMaxVel, vVelMax);
	pe.bSmall			= DFALSE;
	pe.fLifeTime		= 2.5f;
	pe.fFadeTime		= 1.0f;
	pe.fOffsetTime		= 0.0f;
	pe.fRadius			= 4000.0f * fFactor;
	pe.fGravity			= 0.0f;
	pe.nNumPerPuff		= 1;
	pe.nNumEmmitters	= 4;
	pe.pFilename		= "Sprites\\SmokeTest.spr";

	if (IsLiquid(m_eCode))
	{
		GetLiquidColorRange(m_eCode, &pe.vColor1, &pe.vColor2);
		pe.pFilename = "SpecialFX\\ParticleTextures\\GreySphere_1.dtx";
	}

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

	VEC_MULSCALAR(pe.vMinVel, pe.vMinVel, 1.25f);
	VEC_MULSCALAR(pe.vMaxVel, pe.vMaxVel, 1.25f);
	pe.vPos.y += 20.0f * fFactor;
	pe.fLifeTime		= 2.0f;
	pe.fFadeTime		= 0.5f;
	pe.fRadius			= 3000.0f * fFactor;

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

	VEC_MULSCALAR(pe.vMinVel, pe.vMinVel, 1.2f);
	VEC_MULSCALAR(pe.vMaxVel, pe.vMaxVel, 1.2f);
	pe.vPos.y += 20.0f * fFactor;
	pe.fLifeTime		= 3.0f;
	pe.fFadeTime		= 1.5f;
	pe.fRadius			= 1500.0f;

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


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CWeaponFX::CreateMORTFX
//
//	PURPOSE:	Create the MORT fx
//
// ----------------------------------------------------------------------- //

void CWeaponFX::CreateMORTFX()
{
	if (!m_pClientDE || !g_pRiotClientShell) return;

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

	// Create model explosion...

	EXCREATESTRUCT ex;
	VEC_COPY(ex.vPos, m_vPos);

	DFLOAT fRadius = (DFLOAT)GetWeaponDamageRadius(m_nWeaponId, m_eSize);

	VEC_SET(ex.vVel, 0.0f, 0.0f, 0.0f);
	VEC_SET(ex.vInitialScale, fRadius/5.0f, fRadius/5.0f, fRadius/5.0f);
	VEC_SET(ex.vFinalScale, fRadius, fRadius, fRadius);
	VEC_SET(ex.vInitialColor, 1.0f, 1.0f, 1.0f);
	VEC_SET(ex.vFinalColor, 1.0f, 1.0f, 1.0f);
	ex.bUseUserColors = DTRUE;

	ex.dwFlags			= FLAG_VISIBLE | FLAG_MODELGOURAUDSHADE | FLAG_NOLIGHT;
	ex.fLifeTime		= 1.0f;
	ex.fInitialAlpha	= 0.6f;
	ex.fFinalAlpha		= 0.0f;
	ex.pFilename		= "Models\\PV_Weapons\\RedRiotExplosion.abc";
	ex.pSkin			= "SpriteTextures\\weapons\\Explosions\\BllgCore.dtx";

	CSpecialFX* pFX = psfxMgr->CreateSFX(SFX_EXPLOSION_ID, &ex);
	if (pFX) pFX->Update();

	if (g_pRiotClientShell->IsAnime()) return;


	// Create explosion sprite...

	SPRITECREATESTRUCT sc;

	DVector vPos;
	VEC_MULSCALAR(vPos, m_vDir, -20.0f);
	VEC_ADD(vPos, vPos, m_vPos);

	VEC_COPY(sc.vPos, vPos);
	VEC_SET(sc.vVel, 0.0f, 15.0f, 0.0f);

	//VEC_SET(sc.vInitialScale, 0.5f, 0.5f, 1.0f);
	//VEC_SET(sc.vFinalScale, 2.50f, 2.5f, 1.0f);
	VEC_SET(sc.vInitialScale, 0.5f, 0.5f, 1.0f);
	VEC_SET(sc.vFinalScale, 1.0f, 1.0f, 1.0f);

	sc.dwFlags			= FLAG_VISIBLE | FLAG_SPRITEBIAS | FLAG_NOLIGHT; 
	sc.fLifeTime		= 1.5f;
	sc.fInitialAlpha	= 1.0f;
	sc.fFinalAlpha		= 0.0f;
	sc.pFilename		= "Sprites\\weapons\\BllgtExp.spr";


	pFX = psfxMgr->CreateSFX(SFX_SPRITE_ID, &sc);
	if (pFX) pFX->Update();


	// Create smoke...

	VEC_MULSCALAR(vPos, m_vDir, 10.0f);
	VEC_ADD(sc.vPos, sc.vPos, vPos);
	VEC_SET(sc.vInitialScale, 0.25f, 0.25f, 0.0f);
	VEC_SET(sc.vFinalScale, 3.0f, 3.0f, 0.0f);
	VEC_SET(sc.vVel, 0.0f, 10.0f, 0.0f);
	sc.fLifeTime		= 5.0f;
	sc.pFilename		= "Sprites\\SmokeTest.spr";

	pFX = psfxMgr->CreateSFX(SFX_SPRITE_ID, &sc);
	if (pFX) pFX->Update();

	
	DVector vVelMin, vVelMax;
	VEC_SET(vVelMin, -400.0f, 400.0f, -400.0f)
	VEC_SET(vVelMax, 400.0f, 700.0f, 400.0f)

	// Create a particle explosion...

	PESCREATESTRUCT pe;

	pe.bCreateDebris	= DTRUE;
	pe.bRotateDebris	= DTRUE;
	VEC_COPY(pe.vPos, m_vPos);
	ROT_COPY(pe.rSurfaceRot, m_rSurfaceRot);
	VEC_SET(pe.vColor1, 200.0f, 200.0f, 200.0f);
	VEC_SET(pe.vColor2, 255.0f, 255.0f, 255.0f);
	VEC_COPY(pe.vMinVel, vVelMin);
	VEC_COPY(pe.vMaxVel, vVelMax);
	pe.bSmall			= DFALSE;
	pe.fLifeTime		= 1.75f;
	pe.fFadeTime		= 0.5f;
	pe.fOffsetTime		= 0.0f;
	pe.fRadius			= 1000.0f;
	pe.fGravity			= 0.0f;
	pe.nNumPerPuff		= 1;
	pe.nNumEmmitters	= 3;
	pe.pFilename		= "Sprites\\Fire.spr"; // "Sprites\\glow.spr";

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

	pe.vPos.y			+= 20.0f;
	pe.fRadius			= 2500.0f;
	pe.pFilename	    = "Sprites\\SmokeTest.spr";

	if (IsLiquid(m_eCode))
	{
		GetLiquidColorRange(m_eCode, &pe.vColor1, &pe.vColor2);
		pe.pFilename = "SpecialFX\\ParticleTextures\\GreySphere_1.dtx";
	}

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


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CWeaponFX::CreateHWARFX
//
//	PURPOSE:	Create the HWAR fx
//
// ----------------------------------------------------------------------- //
//#pragma optimize ( "", off)
void CWeaponFX::CreateHWARFX()
{
	if (!m_pClientDE || !g_pRiotClientShell) return;

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

	CSpecialFX* pFX;

	int		nNumRings = 2;
	DFLOAT	fLifeTime = 0.65f;


	// Create model explosion...

	EXCREATESTRUCT ex;
	ROT_COPY(ex.rRot, m_rDirRot);
	VEC_COPY(ex.vPos, m_vPos);

	DFLOAT fRadius = GetWeaponDamageRadius(m_nWeaponId, m_eSize) / 1.25f;

	VEC_SET(ex.vVel, 0.0f, 0.0f, 0.0f);
	VEC_SET(ex.vInitialColor, 1.0f, 1.0f, 1.0f);
	VEC_SET(ex.vFinalColor, 1.0f, 1.0f, 1.0f);
	ex.bUseUserColors = DTRUE;

	ex.dwFlags			= FLAG_VISIBLE | FLAG_MODELGOURAUDSHADE | FLAG_NOLIGHT;
	ex.fLifeTime		= fLifeTime;
	ex.pFilename		= "Models\\PV_Weapons\\RedRiotExplosion.abc";
	ex.pSkin			= "SpecialFX\\Explosions\\HWARCore.dtx";

	for (int i=0; i < nNumRings; i++)
	{
		if (i == 0) // the first model is an explosion
		{
			VEC_SET(ex.vInitialScale, 50.0f, 50.0f, 50.0f);
			VEC_SET(ex.vFinalScale, fRadius, fRadius, fRadius);
			ex.fInitialAlpha	= 0.4f;
			ex.fFinalAlpha		= 0.8f;
			ex.fDelayTime		= 0.35f;
		}
		else // the second model is an Implosion :)
		{
			VEC_SET(ex.vInitialScale, fRadius, fRadius, fRadius);
			VEC_SET(ex.vFinalScale, 50.0f, 50.0f, 50.0f);
			ex.fInitialAlpha	= 0.8f;
			ex.fFinalAlpha		= 0.0f;
			ex.fDelayTime		= 0.35f + fLifeTime;
			ex.fLifeTime		= fLifeTime - 0.1f;
		}
		pFX = psfxMgr->CreateSFX(SFX_EXPLOSION_ID, &ex);
		if (pFX) pFX->Update();
	}
	
	// Create mushroom cloud model explosion...

	VEC_SET(m_rDirRot.m_Vec, 0.0f, 1.0f, 0.0f);
	ROT_COPY(ex.rRot, m_rDirRot);
	VEC_COPY(ex.vPos, m_vPos);
	fRadius = GetWeaponDamageRadius(m_nWeaponId, m_eSize) / 2.0f;

	VEC_SET(ex.vVel, 0.0f, 0.0f, 0.0f);
	VEC_SET(ex.vInitialScale, 4.0f, 4.0f, 4.0f);
	VEC_SET(ex.vFinalScale, 8.0f, 8.0f, 8.0f);
	VEC_SET(ex.vInitialColor, 1.0f, 1.0f, 1.0f);
	VEC_SET(ex.vFinalColor, 1.0f, 1.0f, 1.0f);
	ex.bUseUserColors = DTRUE;

	ex.dwFlags			= FLAG_VISIBLE | FLAG_MODELGOURAUDSHADE | FLAG_NOLIGHT;
	ex.fLifeTime		= 3.0f;
	ex.fInitialAlpha	= 0.9f;
	ex.fFinalAlpha		= 0.0f;
	ex.pFilename		= "Models\\PV_Weapons\\HWARExplosion.abc";
	ex.pSkin			= "SpecialFX\\Explosions\\HWARExplosion.dtx";
	ex.fDelayTime		= 0.0f;
	pFX = psfxMgr->CreateSFX(SFX_EXPLOSION_ID, &ex);
	if (pFX) pFX->Update();


	// Create the line ball...

	if (g_pRiotClientShell->IsAnime())
	{
		LBCREATESTRUCT lb;

		ROT_COPY(lb.rRot, m_rDirRot);
		VEC_COPY(lb.vPos, m_vPos);
		VEC_SET(lb.vStartColor, 1.0f, 0.0f, 0.0f);
		VEC_SET(lb.vEndColor, 1.0f, 0.8f, 0.0f);
		VEC_SET(lb.vInitialScale, 0.25f, 0.25f, 0.25f);
		VEC_SET(lb.vFinalScale, 10.0f, 10.0f, 10.0f);
		lb.fSystemStartAlpha	= 0.5f;
		lb.fSystemEndAlpha		= 0.0f;
		lb.fStartAlpha			= 0.5f;
		lb.fEndAlpha			= 0.5f;
		lb.fOffset				= 20.0f;
		lb.fLifeTime			= 2.5f;
		lb.fLineLength			= 200;

		psfxMgr->CreateSFX(SFX_LINEBALL_ID, &lb);
	}

	
	// Create shockwave sprite...

	SPRITECREATESTRUCT sc;

	VEC_COPY(sc.vPos, m_vPos);
	m_pClientDE->SetupEuler(&(sc.rRot), MATH_HALFPI, 0.0f, 0.0f);
	VEC_SET(sc.vVel, 0.0f, 0.0f, 0.0f);
	VEC_SET(sc.vInitialScale, 1.0f, 1.0f, 1.0f);
	VEC_SET(sc.vFinalScale, 7.5f, 7.5f, 1.0f);

	sc.dwFlags			= FLAG_VISIBLE | FLAG_ROTATEABLESPRITE | FLAG_NOLIGHT; 
	sc.fLifeTime		= 1.0f;
	sc.fInitialAlpha	= 1.0f;
	sc.fFinalAlpha		= 0.0f;
	sc.pFilename		= "Sprites\\Weapons\\HWAR.spr";

	for (i=0; i < nNumRings; i++)
	{
		sc.fDelayTime = i*(fLifeTime/nNumRings);
		pFX = psfxMgr->CreateSFX(SFX_SPRITE_ID, &sc);
		if (pFX) pFX->Update();
	}


	// Create smoke bank...

	VEC_SET(sc.vVel, 0.0f, 10.0f, 0.0f);
	VEC_SET(sc.vInitialScale, 2.5f, 2.0f, 1.0f);
	VEC_SET(sc.vFinalScale, 18.0f, 18.0f, 1.0f);
	VEC_SET(sc.vInitialColor, 1.0f, 0.25f, 0.1f);
	VEC_SET(sc.vFinalColor,   0.1f, 0.0f, 0.0f);
	sc.bUseUserColors = DTRUE;
	sc.fDelayTime = 0.0f;

	sc.dwFlags			= FLAG_VISIBLE | FLAG_SPRITEBIAS | FLAG_NOLIGHT; 
	sc.fLifeTime		= 12.5f;
	sc.fInitialAlpha	= 1.0f;
	sc.fFinalAlpha		= 0.0f;
	sc.pFilename		= "Sprites\\SmokeTest.spr";

	pFX = psfxMgr->CreateSFX(SFX_SPRITE_ID, &sc);
	if (pFX) pFX->Update();

	sc.vPos.x += GetRandom(-50.0f, 50.0f);
	sc.vPos.z += GetRandom(-50.0f, 50.0f);
	VEC_SET(sc.vVel, 0.0f, 15.0f, 0.0f);
	sc.fLifeTime		= 10.0f;

	pFX = psfxMgr->CreateSFX(SFX_SPRITE_ID, &sc);
	if (pFX) pFX->Update();
}
//#pragma optimize ( "", on)
// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CWeaponFX::CreateEMSFX
//
//	PURPOSE:	Create the EMS fx
//
// ----------------------------------------------------------------------- //

void CWeaponFX::CreateEMSFX()
{
	// new ev - 4/12/98 copied from CreatePulseRifleFX
	if (!m_pClientDE || !g_pRiotClientShell) return;

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

	// Create impact sprite...

	SPRITECREATESTRUCT sc;

	VEC_COPY(sc.vPos, m_vPos);
	ROT_COPY(sc.rRot, m_rSurfaceRot);

	VEC_SET(sc.vVel, 0.0f, 0.0f, 0.0f);
	VEC_SET(sc.vInitialScale, 0.1f, 0.1f, 1.0f);
	VEC_SET(sc.vFinalScale, 0.75f, 0.75f, 1.0f); // new ev - changed was 1.0, 1.0, 1.0

	sc.dwFlags			= FLAG_VISIBLE | FLAG_ROTATEABLESPRITE | FLAG_NOLIGHT; 
	sc.fLifeTime		= 0.3f;
	sc.fInitialAlpha	= 1.0f;
	sc.fFinalAlpha		= 0.0f;
	sc.pFilename		= "Sprites\\PulseImpact.spr";


	CSpecialFX* pFX = psfxMgr->CreateSFX(SFX_SPRITE_ID, &sc);
	if (pFX) pFX->Update();


	// Rotate to be flat to direction fired...

	m_pClientDE->AlignRotation(&(sc.rRot), &m_vDir, DNULL);

	pFX = psfxMgr->CreateSFX(SFX_SPRITE_ID, &sc);
	if (pFX) pFX->Update();
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CWeaponFX::CreateRASGFX
//
//	PURPOSE:	Create the RASG fx
//
// ----------------------------------------------------------------------- //

void CWeaponFX::CreateRASGFX()
{
	if (!m_pClientDE || !g_pRiotClientShell) return;

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

	if (m_eSurfaceType == ST_LIQUID) return;

	DVector vVelMin, vVelMax;
	VEC_SET(vVelMin, -50.0f, 50.0f, -50.0f)
	VEC_SET(vVelMax, 50.0f, 100.0f, 50.0f)

	if (m_eSurfaceType == ST_FLESH || m_eSurfaceType == ST_ALIENFLESH)
	{
		VEC_SET(vVelMin, -10.0f, 200.0f, -10.0f)
		VEC_SET(vVelMax, 10.0f, 350.0f, 10.0f)
		DFLOAT fRange = 125.0f;

		CreateVectorBloodFX(vVelMin, vVelMax, fRange);
		return;
	}
	// Create a some debris...

	DEBRISCREATESTRUCT debris;

	if (m_eSurfaceType == ST_MECHA)
	{
		ROT_COPY(debris.rRot, m_rDirRot);
	}
	else
	{
		ROT_COPY(debris.rRot, m_rSurfaceRot);
	}

	VEC_COPY(debris.vPos, m_vPos);
	VEC_COPY(debris.vMinVel, vVelMin);
	VEC_COPY(debris.vMaxVel, vVelMax);
	debris.fLifeTime		= GetRandom(0.5f, 1.5f);
	debris.fFadeTime		= 1.0f;
	debris.nNumDebris		= 1;
	debris.bRotate			= DTRUE;
	debris.fMinScale		= 2.0f;
	debris.fMaxScale		= 4.0f;
	debris.nDebrisType		= GetVectorDebrisType(m_eSurfaceType);
	debris.bForceRemove		= DTRUE;

	CSpecialFX* pFX = psfxMgr->CreateSFX(SFX_DEBRIS_ID, &debris);
	if (pFX) pFX->Update();
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CWeaponFX::CreateAgumaFX
//
//	PURPOSE:	Create the Aguma fx
//
// ----------------------------------------------------------------------- //

void CWeaponFX::CreateAgumaFX()
{
	if (!m_pClientDE || !g_pRiotClientShell) return;

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

	if (m_eSurfaceType == ST_LIQUID) return;

	DVector vVelMin, vVelMax;
	VEC_SET(vVelMin, -100.0f, 150.0f, -100.0f)
	VEC_SET(vVelMax, 100.0f, 200.0f, 100.0f)

	if (m_eSurfaceType == ST_FLESH || m_eSurfaceType == ST_ALIENFLESH)
	{
		VEC_SET(vVelMin, -10.0f, 200.0f, -10.0f)
		VEC_SET(vVelMax, 10.0f, 350.0f, 10.0f)
		DFLOAT fRange = 75.0f;

		CreateVectorBloodFX(vVelMin, vVelMax, fRange);
		return;
	}
	// Create a some debris...

	DEBRISCREATESTRUCT debris;

	if (m_eSurfaceType == ST_MECHA)
	{
		ROT_COPY(debris.rRot, m_rDirRot);
	}
	else
	{
		ROT_COPY(debris.rRot, m_rSurfaceRot);
	}

	VEC_COPY(debris.vPos, m_vPos);
	VEC_COPY(debris.vMinVel, vVelMin);
	VEC_COPY(debris.vMaxVel, vVelMax);
	debris.fLifeTime		= GetRandom(0.5f, 1.5f);
	debris.fFadeTime		= 1.0f;
	debris.nNumDebris		= 1;
	debris.bRotate			= DTRUE;
	debris.fMinScale		= 1.0f;
	debris.fMaxScale		= 2.0f;
	debris.nDebrisType		= GetVectorDebrisType(m_eSurfaceType);
	debris.bForceRemove		= DTRUE;

	CSpecialFX* pFX = psfxMgr->CreateSFX(SFX_DEBRIS_ID, &debris);
	if (pFX) pFX->Update();

}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CWeaponFX::CreateMinigunFX
//
//	PURPOSE:	Create the Minigun fx
//
// ----------------------------------------------------------------------- //

void CWeaponFX::CreateMinigunFX()
{
	if (!m_pClientDE || !g_pRiotClientShell) return;

	if (m_eSurfaceType == ST_LIQUID) return;

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

	DVector vVelMin, vVelMax;
	VEC_SET(vVelMin, -50.0f, 50.0f, -50.0f)
	VEC_SET(vVelMax, 50.0f, 100.0f, 50.0f)

	if (m_eSurfaceType == ST_FLESH || m_eSurfaceType == ST_ALIENFLESH)
	{
		VEC_SET(vVelMin, -10.0f, 200.0f, -10.0f)
		VEC_SET(vVelMax, 10.0f, 400.0f, 10.0f)
		DFLOAT fRange = 150.0f;

		CreateVectorBloodFX(vVelMin, vVelMax, fRange);
		return;
	}
	// Create a some debris...

	DEBRISCREATESTRUCT debris;

	if (m_eSurfaceType == ST_MECHA)
	{
		ROT_COPY(debris.rRot, m_rDirRot);
	}
	else
	{
		ROT_COPY(debris.rRot, m_rSurfaceRot);
	}

	VEC_COPY(debris.vPos, m_vPos);
	VEC_COPY(debris.vMinVel, vVelMin);
	VEC_COPY(debris.vMaxVel, vVelMax);
	debris.fLifeTime		= GetRandom(0.5f, 1.5f);
	debris.fFadeTime		= 1.0f;
	debris.nNumDebris		= 1;
	debris.bRotate			= DTRUE;
	debris.fMinScale		= 1.0f;
	debris.fMaxScale		= 4.0f;
	debris.nDebrisType		= GetVectorDebrisType(m_eSurfaceType);
	debris.bForceRemove		= DTRUE;

	CSpecialFX* pFX = psfxMgr->CreateSFX(SFX_DEBRIS_ID, &debris);
	if (pFX) pFX->Update();
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CWeaponFX::CreateProximityMineFX
//
//	PURPOSE:	Create the proximity mine fx
//
// ----------------------------------------------------------------------- //

void CWeaponFX::CreateProximityMineFX()
{
	if (!m_pClientDE || !g_pRiotClientShell) return;

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

	int nNumFireballs = 2;

	// Create model explosion...

	EXCREATESTRUCT ex;
	VEC_COPY(ex.vPos, m_vPos);

	DFLOAT fRadius = (DFLOAT)GetWeaponDamageRadius(m_nWeaponId, m_eSize);

	VEC_SET(ex.vVel, 0.0f, 0.0f, 0.0f);
	VEC_SET(ex.vInitialScale, fRadius, fRadius, fRadius);
	VEC_SET(ex.vFinalScale, fRadius, fRadius, fRadius);
	VEC_SET(ex.vInitialColor, 1.0f, 1.0f, 1.0f);
	VEC_SET(ex.vFinalColor, 1.0f, 1.0f, 1.0f);
	ex.bUseUserColors = DTRUE;

	ex.dwFlags			= FLAG_VISIBLE | FLAG_MODELGOURAUDSHADE | FLAG_NOLIGHT;
	ex.fLifeTime		= 1.0f;
	ex.fInitialAlpha	= 1.0f;
	ex.fFinalAlpha		= 0.0f;
	ex.pFilename		= "Models\\PV_Weapons\\SpiderExplosionCore.abc";
	ex.pSkin			= "SpecialFX\\Explosions\\SpiderCore.dtx";
	ex.bLoop			= DTRUE;

	CSpecialFX* pFX = psfxMgr->CreateSFX(SFX_EXPLOSION_ID, &ex);
	if (pFX) pFX->Update();

	// Create shockwave sprite...

	SPRITECREATESTRUCT sc;

	VEC_COPY(sc.vPos, m_vPos);
	m_pClientDE->SetupEuler(&(sc.rRot), MATH_HALFPI, 0.0f, 0.0f);
	VEC_SET(sc.vVel, 0.0f, 0.0f, 0.0f);
	VEC_SET(sc.vInitialScale, 0.5f, 0.5f, 1.0f);
	VEC_SET(sc.vFinalScale, 4.0f, 4.0f, 1.0f);

	sc.dwFlags			= FLAG_VISIBLE | FLAG_ROTATEABLESPRITE | FLAG_NOLIGHT; 
	sc.fLifeTime		= 0.7f;
	sc.fInitialAlpha	= 1.0f;
	sc.fFinalAlpha		= 0.0f;
	sc.pFilename		= "Sprites\\Weapons\\RedRiot.spr";

	int nNumRings = 1;
	for (int i=0; i < nNumRings; i++)
	{
		sc.fDelayTime = i*(sc.fLifeTime/nNumRings);
		pFX = psfxMgr->CreateSFX(SFX_SPRITE_ID, &sc);
		if (pFX) pFX->Update();
	}

#ifdef SHEYOT

	// Create explosion sprite...

	SPRITECREATESTRUCT sc;

	VEC_COPY(sc.vPos, m_vPos);
	VEC_SET(sc.vVel, 0.0f, 0.0f, 0.0f);
	VEC_SET(sc.vInitialScale, 0.5f, 0.5f, 1.0f);
	VEC_SET(sc.vFinalScale, 1.0f, 1.0f, 1.0f);

	sc.dwFlags			= FLAG_VISIBLE | FLAG_SPRITEBIAS | FLAG_NOLIGHT; 
	sc.fLifeTime		= 1.0f;
	sc.fInitialAlpha	= 1.0f;
	sc.fFinalAlpha		= 0.0f;
	sc.pFilename		= "Sprites\\weapons\\UtlltyLnchrExp.spr";


	// Create smoke...

	SPRITECREATESTRUCT sc2;

	DVector vPos;
	VEC_SET(sc2.vInitialScale, 1.25f, 1.25f, 0.0f);
	VEC_SET(sc2.vFinalScale, 4.0f, 4.0f, 0.0f);
	VEC_SET(sc2.vVel, 0.0f, 15.0f, 0.0f);
	sc2.fLifeTime		= 8.0f;
	sc2.fInitialAlpha	= 1.0f;
	sc2.fFinalAlpha		= 0.0f;
	sc2.pFilename		= "Sprites\\SmokeTest.spr";


	for (int i=0; i < nNumFireballs; i++)
	{
		VEC_MULSCALAR(vPos, m_vDir, -50.0f*i);
		VEC_ADD(sc.vPos, ex.vPos, vPos);

#define USING_SPRITES
#ifdef USING_SPRITES
		sc.vFinalScale.x -= i*1.5f;
		sc.vFinalScale.y -= i*1.5f;

		pFX = psfxMgr->CreateSFX(SFX_SPRITE_ID, &sc);
		if (pFX) pFX->Update();
#endif

		sc2.vFinalScale.x -= i*.5f;
		sc2.vFinalScale.y -= i*.5f;
		sc2.vVel.y += GetRandom(-10.0f, 10.0f);
		sc2.vVel.x += GetRandom(-10.0f, 10.0f);
		sc2.vVel.z += GetRandom(-10.0f, 10.0f);
		VEC_MULSCALAR(vPos, m_vDir, -10.0f);
		VEC_ADD(sc2.vPos, sc.vPos, vPos);
		pFX = psfxMgr->CreateSFX(SFX_SPRITE_ID, &sc2);
		if (pFX) pFX->Update();
	}
#endif
}
