sqwarmed/sdk_src/game/shared/swarm/asw_alien_goo_shared.cpp

691 lines
19 KiB
C++

#include "cbase.h"
#ifdef CLIENT_DLL
#define CBaseFlex C_BaseFlex
#define CASW_Alien_Goo C_ASW_Alien_Goo
#define CASW_Grub_Sac C_ASW_Grub_Sac
#include "c_asw_generic_emitter_entity.h"
#include "c_asw_fx.h"
#include "baseparticleentity.h"
#include "asw_util_shared.h"
#else
#include "EntityFlame.h"
#include "asw_grub.h"
#include "asw_simple_grub.h"
#include "asw_marine.h"
#include "asw_player.h"
#include "asw_fx_shared.h"
#include "asw_util_shared.h"
#include "asw_gamerules.h"
#include "asw_mission_manager.h"
#include "asw_entity_dissolve.h"
#include "asw_marine_speech.h"
#include "asw_burning.h"
#include "te_effect_dispatch.h"
#include "cvisibilitymonitor.h"
#endif
#include "asw_alien_goo_shared.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#define ASW_GRUB_SAC_BURST_DISTANCE 180.0f
#define ACID_BURN_INTERVAL 1.0f
#define ASW_ACID_DAMAGE 10.0f
IMPLEMENT_NETWORKCLASS_ALIASED( ASW_Alien_Goo, DT_ASW_Alien_Goo )
BEGIN_NETWORK_TABLE( CASW_Alien_Goo, DT_ASW_Alien_Goo )
#ifdef CLIENT_DLL
// recvprops
RecvPropFloat (RECVINFO(m_fPulseStrength)),
RecvPropFloat (RECVINFO(m_fPulseSpeed)),
RecvPropBool(RECVINFO(m_bOnFire)),
#else
// sendprops
SendPropExclude( "DT_BaseFlex", "m_flexWeight" ), // don't send the weights from the server, we'll animate them clientside
SendPropFloat (SENDINFO(m_fPulseStrength), 10, SPROP_UNSIGNED ),
SendPropFloat (SENDINFO(m_fPulseSpeed), 10, SPROP_UNSIGNED ),
SendPropBool(SENDINFO(m_bOnFire)),
#endif
END_NETWORK_TABLE()
#ifdef GAME_DLL
ConVar asw_goo_volume("asw_goo_volume", "1.0f", FCVAR_CHEAT, "Volume of the alien goo looping sound");
LINK_ENTITY_TO_CLASS( asw_alien_goo, CASW_Alien_Goo );
PRECACHE_WEAPON_REGISTER(asw_alien_goo);
#endif
#ifndef CLIENT_DLL
//---------------------------------------------------------
// Save/Restore
//---------------------------------------------------------
BEGIN_DATADESC( CASW_Alien_Goo )
DEFINE_KEYFIELD( m_fPulseStrength, FIELD_FLOAT, "PulseStrength" ),
DEFINE_KEYFIELD( m_fPulseSpeed, FIELD_FLOAT, "PulseSpeed" ),
DEFINE_KEYFIELD( m_BurningLinkName, FIELD_STRING, "BurningLinkName" ),
DEFINE_KEYFIELD( m_fGrubSpawnAngle, FIELD_FLOAT, "GrubSpawnAngle" ),
DEFINE_KEYFIELD( m_bHasAmbientSound, FIELD_BOOLEAN, "HasAmbientSound" ),
DEFINE_KEYFIELD( m_bRequiredByObjective, FIELD_BOOLEAN, "RequiredByObjective" ),
DEFINE_FIELD( m_bSpawnedGrubs, FIELD_BOOLEAN ),
DEFINE_FIELD( m_bHasGrubs, FIELD_BOOLEAN ),
DEFINE_FIELD( m_bOnFire, FIELD_BOOLEAN ),
DEFINE_THINKFUNC(BurningLinkThink),
DEFINE_THINKFUNC(InitThink),
DEFINE_THINKFUNC(GrubSacThink),
DEFINE_FUNCTION( GooTouch ),
DEFINE_FUNCTION( GooAcidTouch ),
DEFINE_INPUTFUNC( FIELD_VOID, "Burst", InputBurst ),
DEFINE_OUTPUT( m_OnGooDestroyed, "OnGooDestroyed" ),
END_DATADESC()
float CASW_Alien_Goo::s_fNextSpottedChatterTime = 0;
CUtlVector<CASW_Alien_Goo*> g_AlienGoo;
#endif // not client
CASW_Alien_Goo::CASW_Alien_Goo()
{
#ifdef CLIENT_DLL
m_fPulseCycle = 0;
m_bClientOnFire = false;
m_pBurningEffect = NULL;
#else
m_bPlayingAmbientSound = false;
m_bPlayingGooScream = false;
m_fNextAcidBurnTime = 0;
#endif
m_fPulseStrength = 1.0f;
m_fPulseSpeed = 1.0f;
#ifndef CLIENT_DLL
g_AlienGoo.AddToTail( this );
#endif
}
CASW_Alien_Goo::~CASW_Alien_Goo()
{
#ifdef CLIENT_DLL
m_bOnFire = false;
UpdateFireEmitters();
#endif
#ifndef CLIENT_DLL
g_AlienGoo.FindAndRemove( this );
#endif
}
#ifndef CLIENT_DLL
void CASW_Alien_Goo::Spawn()
{
BaseClass::Spawn();
char *szModel = (char *)STRING( GetModelName() );
if (!szModel || !*szModel)
{
Warning( "%s at %.0f %.0f %0.f missing modelname\n", GetClassname(), GetAbsOrigin().x, GetAbsOrigin().y, GetAbsOrigin().z );
UTIL_Remove( this );
return;
}
if (FClassnameIs(this, "asw_grub_sac"))
{
m_bHasGrubs = true;
m_fPulseStrength = 1.0f;
m_fPulseSpeed = random->RandomFloat(1.5f, 3.0f);
SetBlocksLOS(false);
}
PrecacheModel( szModel );
Precache();
SetModel( szModel );
SetMoveType( MOVETYPE_NONE );
SetSolid(SOLID_VPHYSICS);
SetCollisionGroup( COLLISION_GROUP_NONE ); //COLLISION_GROUP_DEBRIS );
m_takedamage = DAMAGE_YES;
m_iHealth = 100;
m_iMaxHealth = m_iHealth;
AddFlag( FL_STATICPROP );
VPhysicsInitStatic();
SetThink( &CASW_Alien_Goo::InitThink );
SetNextThink( gpGlobals->curtime + random->RandomFloat(5.0f, 10.0f));
if ( m_bRequiredByObjective )
{
VisibilityMonitor_AddEntity( this, asw_visrange_generic.GetFloat() * 0.9f, NULL, NULL );
}
}
void CASW_Alien_Goo::InitThink()
{
if (m_bHasAmbientSound && !m_bPlayingAmbientSound)
{
if (!UTIL_ASW_MissionHasBriefing(STRING(gpGlobals->mapname)))
{
StartGooSound();
}
}
// if spawns grubs
if (m_bHasGrubs)
{
SetTouch( &CASW_Alien_Goo::GooTouch );
}
else
{
SetTouch( &CASW_Alien_Goo::GooAcidTouch );
}
// all goo needs to think periodically, so marines can shout about it
// check if we need to burst open thanks to nearby marines
SetThink( &CASW_Alien_Goo::GrubSacThink );
SetNextThink( gpGlobals->curtime + 1.0f );
}
void CASW_Alien_Goo::Event_Killed( const CTakeDamageInfo &info )
{
m_OnGooDestroyed.FireOutput( this, this );
if (!m_bHasGrubs)
{
if (ASWGameRules() && ASWGameRules()->GetMissionManager())
ASWGameRules()->GetMissionManager()->GooKilled(this);
}
StopGooSound();
BaseClass::Event_Killed(info);
}
void CASW_Alien_Goo::Precache()
{
PrecacheModel( "models/aliens/biomass/biomasshelix.mdl" );
PrecacheModel( "models/aliens/biomass/biomassl.mdl" );
PrecacheModel( "models/aliens/biomass/biomasss.mdl" );
PrecacheModel( "models/aliens/biomass/biomassu.mdl" );
PrecacheScriptSound("ASWGoo.GooLoop");
PrecacheScriptSound("ASWGoo.GooScream");
PrecacheScriptSound("ASWGoo.GooDissolve");
PrecacheScriptSound("ASWFire.AcidBurn");
PrecacheParticleSystem( "biomass_dissolve" );
PrecacheParticleSystem( "acid_touch" );
PrecacheParticleSystem( "grubsack_death" );
UTIL_PrecacheOther( "asw_grub" );
BaseClass::Precache();
}
int CASW_Alien_Goo::OnTakeDamage( const CTakeDamageInfo &info )
{
CASW_Marine* pMarine = dynamic_cast<CASW_Marine*>(info.GetAttacker());
// if has grubs
if ( m_bHasGrubs && HasSpawnFlags( ASW_SF_BURST_WHEN_DAMAGED ) )
{
SpawnGrubs();
if ( pMarine)
pMarine->HurtAlien(this, info);
}
// goo is only damaged by fire!
if ( !( info.GetDamageType() & DMG_BURN ) && !( info.GetDamageType() & DMG_ENERGYBEAM ) )
return 0;
// notify the marine that he's hurting this, so his accuracy doesn't drop
if (info.GetAttacker() && info.GetAttacker()->Classify() == CLASS_ASW_MARINE)
{
if ( pMarine )
{
pMarine->HurtJunkItem( this, info );
}
}
// if this damage would make us close to dying, then make us dissolve instead
if ( m_iHealth - info.GetDamage() < 10.0f )
{
if ( !IsDissolving() )
{
//bool bRagdollCreated =
Dissolve( NULL, gpGlobals->curtime, false, ENTITY_DISSOLVE_NORMAL );
//Msg("Dissolved = %d\n", bRagdollCreated);
return 0;
}
else if ( info.GetDamage() != 10000.0 ) // when dissolving, only the dissolve damage will kill us
{
return 0;
}
}
int result = BaseClass::OnTakeDamage( info );
if ( result > 0 )
{
if ( info.GetDamageType() & DMG_BURN )
{
Ignite( 30.0f );
CASW_Player *pPlayerAttacer = NULL;
if ( pMarine )
{
pPlayerAttacer = pMarine->GetCommander();
}
IGameEvent * event = gameeventmanager->CreateEvent( "alien_ignited" );
if ( event )
{
event->SetInt( "userid", ( pPlayerAttacer ? pPlayerAttacer->GetUserID() : 0 ) );
event->SetInt( "entindex", entindex() );
gameeventmanager->FireEventClientSide( event );
}
}
}
return result;
}
void CASW_Alien_Goo::Ignite( float flFlameLifetime, bool bNPCOnly, float flSize, bool bCalledByLevelDesigner )
{
if ( IsOnFire() || m_bHasGrubs )
{
return;
}
AddFlag( FL_ONFIRE );
m_bOnFire = true;
if ( ASWBurning() )
{
ASWBurning()->BurnEntity(this, NULL, flFlameLifetime, 0.4f, 5.0f * 0.4f); // 5 dps, applied every 0.4 seconds
}
m_OnIgnite.FireOutput( this, this );
// wail
StartScreaming();
// set up a delay to burn our linked entities
SetThink( &CASW_Alien_Goo::BurningLinkThink );
SetNextThink( gpGlobals->curtime + 2.0f );
}
void CASW_Alien_Goo::Extinguish()
{
m_bOnFire = false;
if (ASWBurning())
ASWBurning()->Extinguish(this);
RemoveFlag( FL_ONFIRE );
}
// periodically find the nearest marine and check if we should burst open
void CASW_Alien_Goo::GrubSacThink()
{
if (m_bHasAmbientSound && !m_bPlayingAmbientSound)
{
if (UTIL_ASW_MissionHasBriefing(STRING(gpGlobals->mapname)) && ASWGameRules() && ASWGameRules()->GetGameState() == ASW_GS_INGAME)
StartGooSound();
}
if (m_bHasGrubs)
{
float marine_distance = -1;
if (UTIL_ASW_NearestMarine(GetAbsOrigin(), marine_distance )) // returns the nearest marine to this point
{
if (m_bHasGrubs && HasSpawnFlags(ASW_SF_BURST_WHEN_NEAR))
{
if (marine_distance <= ASW_GRUB_SAC_BURST_DISTANCE)
{
SpawnGrubs();
return;
}
}
// NOTE: Marines chattering about alien good disabled, as it sounded bad
/*
else if (marine_distance < 300 && gpGlobals->curtime > s_fNextSpottedChatterTime)
{
CASW_Marine *pSpottedMarine = UTIL_ASW_Marine_Can_Chatter_Spot(this, 300);
if (pSpottedMarine)
{
pSpottedMarine->GetMarineSpeech()->Chatter(CHATTER_BIOMASS);
s_fNextSpottedChatterTime = gpGlobals->curtime + 30.0f;
}
else
s_fNextSpottedChatterTime = gpGlobals->curtime + 1.0f;
}*/
}
// rethink interval based on how near the marines are
if (marine_distance == -1 || marine_distance > 4096)
{
SetNextThink( gpGlobals->curtime + 5.0f );
}
else if (marine_distance > 1024)
{
SetNextThink( gpGlobals->curtime + 2.0f );
}
else
{
SetNextThink( gpGlobals->curtime + 1.0f );
}
}
else
{
if (m_bHasAmbientSound && !m_bPlayingAmbientSound)
{
SetNextThink( gpGlobals->curtime + random->RandomFloat(2.0f, 5.0f) );
}
}
}
void CASW_Alien_Goo::BurningLinkThink()
{
CBaseEntity *ent = NULL;
while ( (ent = gEntList.NextEnt(ent)) != NULL )
{
CASW_Alien_Goo *pGoo = dynamic_cast<CASW_Alien_Goo*>(ent);
if (pGoo)
{
if ( (pGoo->GetBurningLinkName() != NULL_STRING && FStrEq(STRING(m_BurningLinkName), STRING(pGoo->GetBurningLinkName()))) &&
(ent->GetClassname()!=NULL &&
(FStrEq("asw_alien_goo", ent->GetClassname()) || FStrEq("asw_grub_sac", ent->GetClassname())
)))
{
pGoo->Ignite(30.0f);
}
}
}
}
void CASW_Alien_Goo::GooAcidTouch(CBaseEntity* pOther)
{
// if touched by a marine, acid burn him!
if (pOther && pOther->Classify() == CLASS_ASW_MARINE)
{
if (m_fNextAcidBurnTime == 0 || gpGlobals->curtime > m_fNextAcidBurnTime)
{
m_fNextAcidBurnTime = gpGlobals->curtime + ACID_BURN_INTERVAL;
CTakeDamageInfo info( this, this, ASW_ACID_DAMAGE, DMG_ACID );
Vector killDir = pOther->GetAbsOrigin() - GetAbsOrigin();
VectorNormalize( killDir );
info.SetDamageForce( killDir );
Vector vecDamagePos = pOther->GetAbsOrigin() -killDir * 32.0f;
info.SetDamagePosition( vecDamagePos );
pOther->TakeDamage(info);
EmitSound("ASWFire.AcidBurn");
CEffectData data;
data.m_vOrigin = vecDamagePos;
data.m_nOtherEntIndex = pOther->entindex();
DispatchEffect( "ASWAcidBurn", data );
}
}
}
void CASW_Alien_Goo::GooTouch(CBaseEntity* pOther)
{
// egg will open if touched by a marine
CASW_Marine* pMarine = CASW_Marine::AsMarine( pOther );
if (pMarine && m_bHasGrubs && HasSpawnFlags(ASW_SF_BURST_WHEN_TOUCHED))
{
SetTouch( NULL );
SpawnGrubs();
}
}
bool CASW_Alien_Goo::RoomToSpawnGrub(const Vector& pos)
{
// Check to see if there's enough room to spawn
trace_t tr;
UTIL_TraceHull( pos, pos, Vector(-12,-12,0),Vector(12,12,0), MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );
if ( tr.m_pEnt || tr.startsolid )
{
return false;
}
return true;
}
// makes this bit of goo burst and spawn some grubs
void CASW_Alien_Goo::SpawnGrubs()
{
if (m_bSpawnedGrubs)
return;
m_bSpawnedGrubs = true;
AddSolidFlags( FSOLID_NOT_SOLID );
int num_grubs = random->RandomInt(4,5);
if (m_fGrubSpawnAngle <= 0)
m_fGrubSpawnAngle = 180.0f;
//Vector mins = WorldAlignMins() + GetAbsOrigin();
//Vector maxs = WorldAlignMaxs() + GetAbsOrigin();
if (!CollisionProp())
return;
// for some reason if we calculate these inside the loop, the random numbers all come out the same. Worrying.
QAngle angGrubFacing[5];
angGrubFacing[0] = GetAbsAngles(); angGrubFacing[0].y += RandomFloat(-m_fGrubSpawnAngle, m_fGrubSpawnAngle);
angGrubFacing[1] = GetAbsAngles(); angGrubFacing[1].y += RandomFloat(-m_fGrubSpawnAngle, m_fGrubSpawnAngle);
angGrubFacing[2] = GetAbsAngles(); angGrubFacing[2].y += RandomFloat(-m_fGrubSpawnAngle, m_fGrubSpawnAngle);
angGrubFacing[3] = GetAbsAngles(); angGrubFacing[3].y += RandomFloat(-m_fGrubSpawnAngle, m_fGrubSpawnAngle);
angGrubFacing[4] = GetAbsAngles(); angGrubFacing[4].y += RandomFloat(-m_fGrubSpawnAngle, m_fGrubSpawnAngle);
Vector vecSpawnPos[5];
CollisionProp()->RandomPointInBounds( Vector(0.1f, 0.1f, 0.1f), Vector( 0.9f, 0.9f, 0.9f ), &vecSpawnPos[0] );
CollisionProp()->RandomPointInBounds( Vector(0.1f, 0.1f, 0.1f), Vector( 0.9f, 0.9f, 0.9f ), &vecSpawnPos[1] );
CollisionProp()->RandomPointInBounds( Vector(0.1f, 0.1f, 0.1f), Vector( 0.9f, 0.9f, 0.9f ), &vecSpawnPos[2] );
CollisionProp()->RandomPointInBounds( Vector(0.1f, 0.1f, 0.1f), Vector( 0.9f, 0.9f, 0.9f ), &vecSpawnPos[3] );
CollisionProp()->RandomPointInBounds( Vector(0.1f, 0.1f, 0.1f), Vector( 0.9f, 0.9f, 0.9f ), &vecSpawnPos[4] );
Vector mins, maxs;
CollisionProp()->WorldSpaceAABB( &mins, &mins );
for (int i=0;i<num_grubs;i++)
{
angGrubFacing[i].x = 0;
vecSpawnPos[i].z += 1.0f;
int count = 0;
while (!RoomToSpawnGrub(vecSpawnPos[i]) && count < 5)
{
CollisionProp()->RandomPointInBounds( Vector(0.1f, 0.1f, 0.1f), Vector( 0.9f, 0.9f, 0.9f ), &vecSpawnPos[i] );
count++;
}
if (count >= 5)
continue;
UTIL_ASW_DroneBleed( vecSpawnPos[i], Vector(0,0,1), 4 );
CASW_Simple_Grub* pGrub = dynamic_cast<CASW_Simple_Grub*>(CreateNoSpawn("asw_grub", vecSpawnPos[i], angGrubFacing[i], this));
if (pGrub)
{
ASWGameRules()->GrubSpawned(pGrub);
pGrub->AddSpawnFlags(SF_NPC_FALL_TO_GROUND); // stop it teleporting to the ground
pGrub->Spawn();
pGrub->m_fFallSpeed = 250;
pGrub->PlayFallingAnimation();
}
}
EmitSound("ASW_Parasite.EggBurst");
UTIL_ASW_EggGibs( WorldSpaceCenter(), EGG_FLAG_GRUBSACK_DIE, entindex() );
trace_t ptr;
Vector vecDir( 0, 0, -1.0f );
ptr.endpos = GetLocalOrigin();
ptr.endpos[2] += 8.0f;
// make blood decal on the floor
trace_t Bloodtr;
Vector vecTraceDir;
int k;
for ( k = 0 ; k < 4 ; k++ )
{
vecTraceDir = vecDir;
vecTraceDir.x += random->RandomFloat( -0.8f, 0.8f );
vecTraceDir.y += random->RandomFloat( -0.8f, 0.8f );
vecTraceDir.z += random->RandomFloat( -0.8f, 0.8f );
AI_TraceLine( ptr.endpos, ptr.endpos + vecTraceDir * 172, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &Bloodtr);
if ( Bloodtr.fraction != 1.0 )
{
UTIL_BloodDecalTrace( &Bloodtr, BLOOD_COLOR_BRIGHTGREEN );
}
}
UTIL_Remove( this );
}
// make this goo sac burst open and spit out grubs
void CASW_Alien_Goo::InputBurst( inputdata_t &inputdata )
{
if (m_bHasGrubs && HasSpawnFlags(ASW_SF_BURST_ON_INPUT))
SpawnGrubs();
}
void CASW_Alien_Goo::StartGooSound()
{
m_bPlayingAmbientSound = true;
UTIL_EmitAmbientSound(GetSoundSourceIndex(), GetAbsOrigin(), "ASWGoo.GooLoop",
random->RandomFloat(0.9f, 1.0f) * asw_goo_volume.GetFloat(), SNDLVL_85dB, SND_CHANGE_VOL, random->RandomInt( 95, 105 ));
}
void CASW_Alien_Goo::StartScreaming()
{
if (!m_bPlayingGooScream)
{
StopGooSound();
m_bPlayingGooScream = true;
UTIL_EmitAmbientSound(GetSoundSourceIndex(), GetAbsOrigin(), "ASWGoo.GooScream",
random->RandomFloat(0.9f, 1.0f) * asw_goo_volume.GetFloat(), SNDLVL_95dB, SND_CHANGE_VOL, random->RandomInt( 95, 105 ));
}
}
void CASW_Alien_Goo::StopLoopingSounds()
{
StopGooSound();
}
void CASW_Alien_Goo::StopGooSound()
{
if (m_bPlayingGooScream)
UTIL_EmitAmbientSound(GetSoundSourceIndex(), GetAbsOrigin(), "ASWGoo.GooLoop",
0, SNDLVL_NONE, SND_STOP, 0);
else
UTIL_EmitAmbientSound(GetSoundSourceIndex(), GetAbsOrigin(), "ASWGoo.GooLoop",
0, SNDLVL_NONE, SND_STOP, 0);
}
bool CASW_Alien_Goo::Dissolve( const char *pMaterialName, float flStartTime, bool bNPCOnly, int nDissolveType )
{
// Right now this prevents stuff we don't want to catch on fire from catching on fire.
if( bNPCOnly && !(GetFlags() & FL_NPC) )
return false;
// Can't dissolve twice
if ( IsDissolving() )
return false;
bool bRagdollCreated = false;
CASW_Entity_Dissolve *pDissolve = CASW_Entity_Dissolve::Create( this, pMaterialName, flStartTime, nDissolveType, &bRagdollCreated );
if (pDissolve)
{
SetEffectEntity( pDissolve );
AddFlag( FL_DISSOLVING );
// m_flDissolveStartTime = flStartTime;
EmitSound( "ASWGoo.GooDissolve" );
}
return bRagdollCreated;
}
#else
// make all our flex controllers sine in and out, each one time offset a bit to
// create a rippling pulse in the mesh
void CASW_Alien_Goo::SetupWeights( const matrix3x4_t *pBoneToWorld, int nFlexWeightCount, float *pFlexWeights, float *pFlexDelayedWeights )
{
m_fPulseCycle += gpGlobals->frametime * m_fPulseSpeed;
float interval = 1.5f / nFlexWeightCount;
for (int i = 0; i < nFlexWeightCount; i++)
{
pFlexWeights[i] = sin(m_fPulseCycle + i * interval);
if (pFlexWeights[i] < 0)
pFlexWeights[i] = -pFlexWeights[i];
pFlexWeights[i] *= m_fPulseStrength;
}
if ( pFlexDelayedWeights )
{
memset( pFlexDelayedWeights, 0, nFlexWeightCount * sizeof(float) );
}
}
void CASW_Alien_Goo::OnDataChanged( DataUpdateType_t type )
{
BaseClass::OnDataChanged( type );
UpdateFireEmitters();
}
void CASW_Alien_Goo::UpdateFireEmitters()
{
bool bOnFire = (m_bOnFire && !IsEffectActive(EF_NODRAW));
if (bOnFire != m_bClientOnFire)
{
m_bClientOnFire = bOnFire;
if (m_bClientOnFire)
{
if ( !m_pBurningEffect )
{
m_pBurningEffect = UTIL_ASW_CreateFireEffect( this );
}
EmitSound( "ASWFire.BurningFlesh" );
}
else
{
if ( m_pBurningEffect )
{
ParticleProp()->StopEmission( m_pBurningEffect );
m_pBurningEffect = NULL;
}
StopSound("ASWFire.BurningFlesh");
if ( C_BaseEntity::IsAbsQueriesValid() )
EmitSound("ASWFire.StopBurning");
}
}
}
void CASW_Alien_Goo::UpdateOnRemove()
{
BaseClass::UpdateOnRemove();
m_bOnFire = false;
UpdateFireEmitters();
}
#endif // not client
/// ========================== grub sac version =======================
#ifndef CLIENT_DLL
LINK_ENTITY_TO_CLASS( asw_grub_sac, CASW_Grub_Sac );
#endif
IMPLEMENT_NETWORKCLASS_ALIASED( ASW_Grub_Sac, DT_ASW_Grub_Sac )
BEGIN_NETWORK_TABLE( CASW_Grub_Sac, DT_ASW_Grub_Sac )
#ifdef CLIENT_DLL
// recvprops
#else
// sendprops
#endif
END_NETWORK_TABLE()
CASW_Grub_Sac::CASW_Grub_Sac()
{
}
CASW_Grub_Sac::~CASW_Grub_Sac()
{
}