mirror of
https://github.com/Gigaslav/HL2Overcharged.git
synced 2026-01-02 17:48:11 +03:00
647 lines
16 KiB
C++
647 lines
16 KiB
C++
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose: env_flare from hl2 (original)
|
|
//
|
|
// $NoKeywords: $
|
|
//=============================================================================//
|
|
|
|
#include "cbase.h"
|
|
#include "player.h"
|
|
#include "gamerules.h"
|
|
#include "basehlcombatweapon.h"
|
|
#include "decals.h"
|
|
#include "in_buttons.h"
|
|
#include "soundenvelope.h"
|
|
#include "IEffects.h"
|
|
#include "engine/IEngineSound.h"
|
|
#include "overcharged/env_flare.h"
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
#define FLARE_LAUNCH_SPEED 1500
|
|
|
|
LINK_ENTITY_TO_CLASS(env_flare, CFlare);
|
|
|
|
BEGIN_DATADESC(CFlare)
|
|
|
|
DEFINE_FIELD(m_pOwner, FIELD_CLASSPTR),
|
|
DEFINE_FIELD(m_nBounces, FIELD_INTEGER),
|
|
DEFINE_FIELD(m_flTimeBurnOut, FIELD_TIME),
|
|
DEFINE_KEYFIELD(m_flScale, FIELD_FLOAT, "scale"),
|
|
DEFINE_KEYFIELD(m_flDuration, FIELD_FLOAT, "duration"),
|
|
DEFINE_FIELD(m_flNextDamage, FIELD_TIME),
|
|
DEFINE_SOUNDPATCH(m_pBurnSound),
|
|
DEFINE_FIELD(m_bFading, FIELD_BOOLEAN),
|
|
DEFINE_FIELD(m_bLight, FIELD_BOOLEAN),
|
|
DEFINE_FIELD(m_bSmoke, FIELD_BOOLEAN),
|
|
DEFINE_FIELD(m_bPropFlare, FIELD_BOOLEAN),
|
|
DEFINE_FIELD(m_bInActiveList, FIELD_BOOLEAN),
|
|
DEFINE_FIELD(m_pNextFlare, FIELD_CLASSPTR),
|
|
|
|
//Input functions
|
|
DEFINE_INPUTFUNC(FIELD_FLOAT, "Start", InputStart),
|
|
DEFINE_INPUTFUNC(FIELD_FLOAT, "Die", InputDie),
|
|
DEFINE_INPUTFUNC(FIELD_FLOAT, "Launch", InputLaunch),
|
|
|
|
// Function Pointers
|
|
DEFINE_FUNCTION(FlareTouch),
|
|
DEFINE_FUNCTION(FlareBurnTouch),
|
|
DEFINE_FUNCTION(FlareThink),
|
|
|
|
END_DATADESC()
|
|
|
|
//Data-tables
|
|
IMPLEMENT_SERVERCLASS_ST(CFlare, DT_Flare)
|
|
SendPropFloat(SENDINFO(m_flTimeBurnOut), 0, SPROP_NOSCALE),
|
|
SendPropFloat(SENDINFO(m_flScale), 0, SPROP_NOSCALE),
|
|
SendPropInt(SENDINFO(m_bLight), 1, SPROP_UNSIGNED),
|
|
SendPropInt(SENDINFO(m_bSmoke), 1, SPROP_UNSIGNED),
|
|
SendPropInt(SENDINFO(m_bPropFlare), 1, SPROP_UNSIGNED),
|
|
END_SEND_TABLE()
|
|
|
|
CFlare *CFlare::activeFlares = NULL;
|
|
|
|
CFlare *CFlare::GetActiveFlares(void)
|
|
{
|
|
return CFlare::activeFlares;
|
|
}
|
|
|
|
Class_T CFlare::Classify(void)
|
|
{
|
|
return CLASS_FLARE;
|
|
}
|
|
|
|
CBaseEntity *CreateFlare(Vector vOrigin, QAngle Angles, CBaseEntity *pOwner, float flDuration)
|
|
{
|
|
CFlare *pFlare = CFlare::Create(vOrigin, Angles, pOwner, flDuration);
|
|
|
|
if (pFlare)
|
|
{
|
|
pFlare->m_bPropFlare = true;
|
|
}
|
|
|
|
return pFlare;
|
|
}
|
|
|
|
void KillFlare(CBaseEntity *pOwnerEntity, CBaseEntity *pEntity, float flKillTime)
|
|
{
|
|
CFlare *pFlare = dynamic_cast< CFlare *>(pEntity);
|
|
|
|
if (pFlare)
|
|
{
|
|
float flDieTime = (pFlare->m_flTimeBurnOut - gpGlobals->curtime) - flKillTime;
|
|
|
|
if (flDieTime > 1.0f)
|
|
{
|
|
pFlare->Die(flDieTime);
|
|
pOwnerEntity->SetNextThink(gpGlobals->curtime + flDieTime + 3.0f);
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
CFlare::CFlare(void)
|
|
{
|
|
m_flScale = 4.0f;
|
|
m_nBounces = 0;
|
|
m_bFading = false;
|
|
m_bLight = true;
|
|
m_bSmoke = true;
|
|
m_flNextDamage = gpGlobals->curtime;
|
|
m_lifeState = LIFE_ALIVE;
|
|
m_iHealth = 100;
|
|
m_bPropFlare = false;
|
|
m_bInActiveList = false;
|
|
m_pNextFlare = NULL;
|
|
}
|
|
|
|
CFlare::~CFlare()
|
|
{
|
|
CSoundEnvelopeController::GetController().SoundDestroy(m_pBurnSound);
|
|
m_pBurnSound = NULL;
|
|
|
|
RemoveFromActiveFlares();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CFlare::Precache(void)
|
|
{
|
|
PrecacheModel("models/weapons/flare.mdl");
|
|
|
|
PrecacheScriptSound("Weapon_FlareGun.Burn");
|
|
|
|
// FIXME: needed to precache the fire model. Shouldn't have to do this.
|
|
UTIL_PrecacheOther("_firesmoke");
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : &restore -
|
|
// Output : int
|
|
//-----------------------------------------------------------------------------
|
|
int CFlare::Restore(IRestore &restore)
|
|
{
|
|
int result = BaseClass::Restore(restore);
|
|
|
|
if (m_spawnflags & SF_FLARE_NO_DLIGHT)
|
|
{
|
|
m_bLight = false;
|
|
}
|
|
|
|
if (m_spawnflags & SF_FLARE_NO_SMOKE)
|
|
{
|
|
m_bSmoke = false;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CFlare::Spawn(void)
|
|
{
|
|
Precache();
|
|
|
|
SetModel("models/weapons/flare.mdl");
|
|
|
|
UTIL_SetSize(this, Vector(-2, -2, -2), Vector(2, 2, 2));
|
|
|
|
SetSolid(SOLID_BBOX);
|
|
AddSolidFlags(FSOLID_NOT_SOLID);
|
|
|
|
SetMoveType(MOVETYPE_NONE);
|
|
SetFriction(0.6f);
|
|
SetGravity(UTIL_ScaleForGravity(400));
|
|
m_flTimeBurnOut = gpGlobals->curtime + 30;
|
|
|
|
AddEffects(EF_NOSHADOW | EF_NORECEIVESHADOW);
|
|
|
|
if (m_spawnflags & SF_FLARE_NO_DLIGHT)
|
|
{
|
|
m_bLight = false;
|
|
}
|
|
|
|
if (m_spawnflags & SF_FLARE_NO_SMOKE)
|
|
{
|
|
m_bSmoke = false;
|
|
}
|
|
|
|
if (m_spawnflags & SF_FLARE_INFINITE)
|
|
{
|
|
m_flTimeBurnOut = -1.0f;
|
|
}
|
|
|
|
if (m_spawnflags & SF_FLARE_START_OFF)
|
|
{
|
|
AddEffects(EF_NODRAW);
|
|
}
|
|
|
|
AddFlag(FL_OBJECT);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CFlare::Activate(void)
|
|
{
|
|
BaseClass::Activate();
|
|
|
|
// Start the burning sound if we're already on
|
|
if ((m_spawnflags & SF_FLARE_START_OFF) == false)
|
|
{
|
|
StartBurnSound();
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CFlare::StartBurnSound(void)
|
|
{
|
|
if (m_pBurnSound == NULL)
|
|
{
|
|
CPASAttenuationFilter filter(this);
|
|
m_pBurnSound = CSoundEnvelopeController::GetController().SoundCreate(
|
|
filter, entindex(), CHAN_WEAPON, "Weapon_FlareGun.Burn", 3.0f);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : vecOrigin -
|
|
// vecAngles -
|
|
// *pOwner -
|
|
// Output : CFlare
|
|
//-----------------------------------------------------------------------------
|
|
CFlare *CFlare::Create(Vector vecOrigin, QAngle vecAngles, CBaseEntity *pOwner, float lifetime)
|
|
{
|
|
CFlare *pFlare = (CFlare *)CreateEntityByName("env_flare");
|
|
|
|
if (pFlare == NULL)
|
|
return NULL;
|
|
|
|
UTIL_SetOrigin(pFlare, vecOrigin);
|
|
|
|
pFlare->SetLocalAngles(vecAngles);
|
|
pFlare->Spawn();
|
|
pFlare->SetTouch(&CFlare::FlareTouch);
|
|
pFlare->SetThink(&CFlare::FlareThink);
|
|
|
|
//Start up the flare
|
|
pFlare->Start(lifetime);
|
|
|
|
//Don't start sparking immediately
|
|
pFlare->SetNextThink(gpGlobals->curtime + 0.5f);
|
|
|
|
//Burn out time
|
|
pFlare->m_flTimeBurnOut = gpGlobals->curtime + lifetime;
|
|
|
|
pFlare->RemoveSolidFlags(FSOLID_NOT_SOLID);
|
|
pFlare->AddSolidFlags(FSOLID_NOT_STANDABLE);
|
|
|
|
pFlare->SetMoveType(MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE);
|
|
|
|
pFlare->SetOwnerEntity(pOwner);
|
|
pFlare->m_pOwner = pOwner;
|
|
|
|
return pFlare;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
unsigned int CFlare::PhysicsSolidMaskForEntity(void) const
|
|
{
|
|
return MASK_NPCSOLID;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CFlare::FlareThink(void)
|
|
{
|
|
float deltaTime = (m_flTimeBurnOut - gpGlobals->curtime);
|
|
|
|
if (!m_bInActiveList && ((deltaTime > FLARE_BLIND_TIME) || (m_flTimeBurnOut == -1.0f)))
|
|
{
|
|
AddToActiveFlares();
|
|
}
|
|
|
|
if (m_flTimeBurnOut != -1.0f)
|
|
{
|
|
//Fading away
|
|
if ((deltaTime <= FLARE_DECAY_TIME) && (m_bFading == false))
|
|
{
|
|
m_bFading = true;
|
|
CSoundEnvelopeController::GetController().SoundChangePitch(m_pBurnSound, 60, deltaTime);
|
|
CSoundEnvelopeController::GetController().SoundFadeOut(m_pBurnSound, deltaTime);
|
|
}
|
|
|
|
// if flare is no longer bright, remove it from active flare list
|
|
if (m_bInActiveList && (deltaTime <= FLARE_BLIND_TIME))
|
|
{
|
|
RemoveFromActiveFlares();
|
|
}
|
|
|
|
//Burned out
|
|
if (m_flTimeBurnOut < gpGlobals->curtime)
|
|
{
|
|
UTIL_Remove(this);
|
|
return;
|
|
}
|
|
}
|
|
|
|
//Act differently underwater
|
|
if (GetWaterLevel() > 1)
|
|
{
|
|
UTIL_Bubbles(GetAbsOrigin() + Vector(-2, -2, -2), GetAbsOrigin() + Vector(2, 2, 2), 1);
|
|
m_bSmoke = false;
|
|
}
|
|
else
|
|
{
|
|
//Shoot sparks
|
|
if (random->RandomInt(0, 8) == 1)
|
|
{
|
|
g_pEffects->Sparks(GetAbsOrigin());
|
|
}
|
|
}
|
|
|
|
//Next update
|
|
SetNextThink(gpGlobals->curtime + 0.1f);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : *pOther -
|
|
//-----------------------------------------------------------------------------
|
|
void CFlare::FlareBurnTouch(CBaseEntity *pOther)
|
|
{
|
|
if (pOther && pOther->m_takedamage && (m_flNextDamage < gpGlobals->curtime) && (!FClassnameIs(pOther, "prop_vehicle_jeep") && !FClassnameIs(pOther, "prop_vehicle_apc") && !FClassnameIs(pOther, "prop_vehicle_airboat")))
|
|
{
|
|
pOther->TakeDamage(CTakeDamageInfo(this, m_pOwner, 1, (DMG_BULLET | DMG_BURN)));
|
|
m_flNextDamage = gpGlobals->curtime + 1.0f;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : *pOther -
|
|
//-----------------------------------------------------------------------------
|
|
void CFlare::FlareTouch(CBaseEntity *pOther)
|
|
{
|
|
Assert(pOther);
|
|
if (!pOther->IsSolid() || FClassnameIs(pOther, "prop_vehicle_jeep") || FClassnameIs(pOther, "prop_vehicle_apc") || FClassnameIs(pOther, "prop_vehicle_airboat"))
|
|
return;
|
|
|
|
//if (!pOther->IsSolid() || pOther->IsSolidFlagSet(FSOLID_VOLUME_CONTENTS))
|
|
//return;
|
|
|
|
//if (pOther->IsSolidFlagSet(FSOLID_TRIGGER | FSOLID_VOLUME_CONTENTS)) // BriJee TEST
|
|
//return;
|
|
|
|
/*if (pOther->IsSolidFlagSet(FSOLID_VOLUME_CONTENTS | FSOLID_TRIGGER)) //test
|
|
{
|
|
// Some NPCs are triggers that can take damage (like antlion grubs). We should hit them.
|
|
if ((pOther->m_takedamage == DAMAGE_NO) || (pOther->m_takedamage == DAMAGE_EVENTS_ONLY))
|
|
return;
|
|
}*/
|
|
|
|
if ((m_nBounces < 10) && (GetWaterLevel() < 1))
|
|
{
|
|
// Throw some real chunks here
|
|
g_pEffects->Sparks(GetAbsOrigin());
|
|
}
|
|
|
|
//If the flare hit a person or NPC, do damage here.
|
|
if (pOther && pOther->m_takedamage)
|
|
{
|
|
|
|
//The Flare is the iRifle round right now. No damage, just ignite. (sjb)
|
|
/*//Damage is a function of how fast the flare is flying.
|
|
int iDamage = GetAbsVelocity().Length() / 50.0f;
|
|
//if ( iDamage < 12 ) //5
|
|
//{
|
|
//Clamp minimum damage
|
|
iDamage = 12; //5
|
|
//}
|
|
//Use m_pOwner, not GetOwnerEntity()
|
|
pOther->TakeDamage( CTakeDamageInfo( this, m_pOwner, iDamage, (DMG_BULLET|DMG_BURN) ) );
|
|
m_flNextDamage = gpGlobals->curtime + 1.0f;*/
|
|
|
|
CBaseAnimating *pAnim;
|
|
|
|
pAnim = dynamic_cast<CBaseAnimating*>(pOther);
|
|
if (pAnim)
|
|
{
|
|
pAnim->Ignite(30.0f);
|
|
}
|
|
|
|
Vector vecNewVelocity = GetAbsVelocity();
|
|
vecNewVelocity *= 0.1f;
|
|
SetAbsVelocity(vecNewVelocity);
|
|
|
|
SetMoveType(MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE);
|
|
SetGravity(1.0f);
|
|
|
|
|
|
Die(0.5);
|
|
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
// hit the world, check the material type here, see if the flare should stick.
|
|
trace_t tr;
|
|
tr = CBaseEntity::GetTouchTrace();
|
|
|
|
//Only do this on the first bounce
|
|
if (m_nBounces == 0)
|
|
{
|
|
const surfacedata_t *pdata = physprops->GetSurfaceData(tr.surface.surfaceProps);
|
|
|
|
if (pdata != NULL)
|
|
{
|
|
//Only embed into concrete and wood (jdw: too obscure for players?)
|
|
//if ( ( pdata->gameMaterial == 'C' ) || ( pdata->gameMaterial == 'W' ) )
|
|
{
|
|
Vector impactDir = (tr.endpos - tr.startpos);
|
|
VectorNormalize(impactDir);
|
|
|
|
float surfDot = tr.plane.normal.Dot(impactDir);
|
|
|
|
//Do not stick to ceilings or on shallow impacts
|
|
if ((tr.plane.normal.z > -0.5f) && (surfDot < -0.9f))
|
|
{
|
|
RemoveSolidFlags(FSOLID_NOT_SOLID);
|
|
AddSolidFlags(FSOLID_TRIGGER);
|
|
UTIL_SetOrigin(this, tr.endpos + (tr.plane.normal * 2.0f));
|
|
SetAbsVelocity(vec3_origin);
|
|
SetMoveType(MOVETYPE_NONE);
|
|
|
|
SetTouch(&CFlare::FlareBurnTouch);
|
|
|
|
int index = decalsystem->GetDecalIndexForName("SmallScorch");
|
|
if (index >= 0)
|
|
{
|
|
CBroadcastRecipientFilter filter;
|
|
te->Decal(filter, 0.0, &tr.endpos, &tr.startpos, ENTINDEX(tr.m_pEnt), tr.hitbox, index);
|
|
}
|
|
|
|
CPASAttenuationFilter filter2(this, "Flare.Touch");
|
|
EmitSound(filter2, entindex(), "Flare.Touch");
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//Scorch decal
|
|
if (GetAbsVelocity().LengthSqr() > (250 * 250))
|
|
{
|
|
int index = decalsystem->GetDecalIndexForName("FadingScorch");
|
|
if (index >= 0)
|
|
{
|
|
CBroadcastRecipientFilter filter;
|
|
te->Decal(filter, 0.0, &tr.endpos, &tr.startpos, ENTINDEX(tr.m_pEnt), tr.hitbox, index);
|
|
}
|
|
}
|
|
|
|
// Change our flight characteristics
|
|
SetMoveType(MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE);
|
|
SetGravity(UTIL_ScaleForGravity(640));
|
|
|
|
m_nBounces++;
|
|
|
|
//After the first bounce, smacking into whoever fired the flare is fair game
|
|
//SetOwnerEntity(this);
|
|
|
|
// Slow down
|
|
Vector vecNewVelocity = GetAbsVelocity();
|
|
vecNewVelocity.x *= 0.8f;
|
|
vecNewVelocity.y *= 0.8f;
|
|
SetAbsVelocity(vecNewVelocity);
|
|
|
|
//Stopped?
|
|
if (GetAbsVelocity().Length() < 64.0f)
|
|
{
|
|
SetAbsVelocity(vec3_origin);
|
|
SetMoveType(MOVETYPE_NONE);
|
|
RemoveSolidFlags(FSOLID_NOT_SOLID);
|
|
AddSolidFlags(FSOLID_TRIGGER);
|
|
SetTouch(&CFlare::FlareBurnTouch);
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CFlare::Start(float lifeTime)
|
|
{
|
|
StartBurnSound();
|
|
|
|
if (m_pBurnSound != NULL)
|
|
{
|
|
CSoundEnvelopeController::GetController().Play(m_pBurnSound, 0.0f, 60);
|
|
CSoundEnvelopeController::GetController().SoundChangeVolume(m_pBurnSound, 0.8f, 2.0f);
|
|
CSoundEnvelopeController::GetController().SoundChangePitch(m_pBurnSound, 100, 2.0f);
|
|
}
|
|
|
|
if (lifeTime > 0)
|
|
{
|
|
m_flTimeBurnOut = gpGlobals->curtime + lifeTime;
|
|
}
|
|
else
|
|
{
|
|
m_flTimeBurnOut = -1.0f;
|
|
}
|
|
|
|
RemoveEffects(EF_NODRAW);
|
|
|
|
SetThink(&CFlare::FlareThink);
|
|
SetNextThink(gpGlobals->curtime + 0.1f);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CFlare::Die(float fadeTime)
|
|
{
|
|
m_flTimeBurnOut = gpGlobals->curtime + fadeTime;
|
|
|
|
SetThink(&CFlare::FlareThink);
|
|
SetNextThink(gpGlobals->curtime + 0.1f);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CFlare::Launch(const Vector &direction, float speed)
|
|
{
|
|
// Make sure we're visible
|
|
if (m_spawnflags & SF_FLARE_INFINITE)
|
|
{
|
|
Start(-1);
|
|
}
|
|
else
|
|
{
|
|
Start(8.0f);
|
|
}
|
|
|
|
SetMoveType(MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE);
|
|
|
|
// Punch our velocity towards our facing
|
|
SetAbsVelocity(direction * speed);
|
|
|
|
SetGravity(1.0f);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : &inputdata -
|
|
//-----------------------------------------------------------------------------
|
|
void CFlare::InputStart(inputdata_t &inputdata)
|
|
{
|
|
Start(inputdata.value.Float());
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : &inputdata -
|
|
//-----------------------------------------------------------------------------
|
|
void CFlare::InputDie(inputdata_t &inputdata)
|
|
{
|
|
Die(inputdata.value.Float());
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : &inputdata -
|
|
//-----------------------------------------------------------------------------
|
|
void CFlare::InputLaunch(inputdata_t &inputdata)
|
|
{
|
|
Vector direction;
|
|
AngleVectors(GetAbsAngles(), &direction);
|
|
|
|
float speed = inputdata.value.Float();
|
|
|
|
if (speed == 0)
|
|
{
|
|
speed = FLARE_LAUNCH_SPEED;
|
|
}
|
|
|
|
Launch(direction, speed);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Removes flare from active flare list
|
|
//-----------------------------------------------------------------------------
|
|
void CFlare::RemoveFromActiveFlares(void)
|
|
{
|
|
CFlare *pFlare;
|
|
CFlare *pPrevFlare;
|
|
|
|
if (!m_bInActiveList)
|
|
return;
|
|
|
|
pPrevFlare = NULL;
|
|
for (pFlare = CFlare::activeFlares; pFlare != NULL; pFlare = pFlare->m_pNextFlare)
|
|
{
|
|
if (pFlare == this)
|
|
{
|
|
if (pPrevFlare)
|
|
{
|
|
pPrevFlare->m_pNextFlare = m_pNextFlare;
|
|
}
|
|
else
|
|
{
|
|
activeFlares = m_pNextFlare;
|
|
}
|
|
break;
|
|
}
|
|
pPrevFlare = pFlare;
|
|
}
|
|
|
|
m_pNextFlare = NULL;
|
|
m_bInActiveList = false;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Adds flare to active flare list
|
|
//-----------------------------------------------------------------------------
|
|
void CFlare::AddToActiveFlares(void)
|
|
{
|
|
if (!m_bInActiveList)
|
|
{
|
|
m_pNextFlare = CFlare::activeFlares;
|
|
CFlare::activeFlares = this;
|
|
m_bInActiveList = true;
|
|
}
|
|
} |