Blixibon b8611071c5 Mapbase v2.1
- Fixed parallax corrected cubemaps not working when cubemaps are disabled
- Fixed a crash with some new script_intro code
- Fixed item_health/suitcharger not emptying or using correct animation with keyvalue charge
- Added a new "Always touchable" spawnflag for weapons and items that should disregard obstructions
- Added "OnFoundNPC" output on scripted_sequence for when a NPC starts moving to play the script
- Fixed npc_snipers not working when parented or not working when attacking parented targets
- Changed "ai_nographrebuildmessage" to "ai_norebuildgraphmessage" to reduce confusion and increase visibility (it is assumed nobody was using it before, at least not in a compatibility-breaking way)
- Added damage bit modification to filter_damage_mod
- Added Add/RemoveSolidFlags input to all entities + added "Collide with owner" solid flag from the VDC
- Added custom model support to item_health/suitcharger
2019-12-18 00:15:59 +00:00

919 lines
22 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Implements health kits and wall mounted health chargers.
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "gamerules.h"
#include "player.h"
#include "items.h"
#include "in_buttons.h"
#include "engine/IEngineSound.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
ConVar sk_healthkit( "sk_healthkit","0" );
ConVar sk_healthvial( "sk_healthvial","0" );
ConVar sk_healthcharger( "sk_healthcharger","0" );
//-----------------------------------------------------------------------------
// Small health kit. Heals the player when picked up.
//-----------------------------------------------------------------------------
class CHealthKit : public CItem
{
public:
DECLARE_CLASS( CHealthKit, CItem );
void Spawn( void );
void Precache( void );
bool MyTouch( CBasePlayer *pPlayer );
};
LINK_ENTITY_TO_CLASS( item_healthkit, CHealthKit );
PRECACHE_REGISTER(item_healthkit);
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHealthKit::Spawn( void )
{
Precache();
SetModel( "models/items/healthkit.mdl" );
BaseClass::Spawn();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHealthKit::Precache( void )
{
PrecacheModel("models/items/healthkit.mdl");
PrecacheScriptSound( "HealthKit.Touch" );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pPlayer -
// Output :
//-----------------------------------------------------------------------------
bool CHealthKit::MyTouch( CBasePlayer *pPlayer )
{
if ( pPlayer->TakeHealth( sk_healthkit.GetFloat(), DMG_GENERIC ) )
{
CSingleUserRecipientFilter user( pPlayer );
user.MakeReliable();
UserMessageBegin( user, "ItemPickup" );
WRITE_STRING( GetClassname() );
MessageEnd();
CPASAttenuationFilter filter( pPlayer, "HealthKit.Touch" );
EmitSound( filter, pPlayer->entindex(), "HealthKit.Touch" );
if ( g_pGameRules->ItemShouldRespawn( this ) )
{
Respawn();
}
else
{
UTIL_Remove(this);
}
return true;
}
return false;
}
//-----------------------------------------------------------------------------
// Small dynamically dropped health kit
//-----------------------------------------------------------------------------
class CHealthVial : public CItem
{
public:
DECLARE_CLASS( CHealthVial, CItem );
void Spawn( void )
{
Precache();
SetModel( "models/healthvial.mdl" );
BaseClass::Spawn();
}
void Precache( void )
{
PrecacheModel("models/healthvial.mdl");
PrecacheScriptSound( "HealthVial.Touch" );
}
bool MyTouch( CBasePlayer *pPlayer )
{
if ( pPlayer->TakeHealth( sk_healthvial.GetFloat(), DMG_GENERIC ) )
{
CSingleUserRecipientFilter user( pPlayer );
user.MakeReliable();
UserMessageBegin( user, "ItemPickup" );
WRITE_STRING( GetClassname() );
MessageEnd();
CPASAttenuationFilter filter( pPlayer, "HealthVial.Touch" );
EmitSound( filter, pPlayer->entindex(), "HealthVial.Touch" );
if ( g_pGameRules->ItemShouldRespawn( this ) )
{
Respawn();
}
else
{
UTIL_Remove(this);
}
return true;
}
return false;
}
};
LINK_ENTITY_TO_CLASS( item_healthvial, CHealthVial );
PRECACHE_REGISTER( item_healthvial );
//-----------------------------------------------------------------------------
// Wall mounted health kit. Heals the player when used.
//-----------------------------------------------------------------------------
class CWallHealth : public CBaseToggle
{
public:
DECLARE_CLASS( CWallHealth, CBaseToggle );
void Spawn( );
void Precache( void );
int DrawDebugTextOverlays(void);
bool CreateVPhysics(void);
void Off(void);
void Recharge(void);
bool KeyValue( const char *szKeyName, const char *szValue );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
virtual int ObjectCaps( void ) { return BaseClass::ObjectCaps() | m_iCaps; }
float m_flNextCharge;
int m_iReactivate ; // DeathMatch Delay until reactvated
int m_iJuice;
int m_iOn; // 0 = off, 1 = startup, 2 = going
float m_flSoundTime;
int m_nState;
int m_iCaps;
COutputFloat m_OutRemainingHealth;
COutputEvent m_OnPlayerUse;
DECLARE_DATADESC();
};
LINK_ENTITY_TO_CLASS(func_healthcharger, CWallHealth);
BEGIN_DATADESC( CWallHealth )
DEFINE_FIELD( m_flNextCharge, FIELD_TIME),
DEFINE_FIELD( m_iReactivate, FIELD_INTEGER),
DEFINE_FIELD( m_iJuice, FIELD_INTEGER),
DEFINE_FIELD( m_iOn, FIELD_INTEGER),
DEFINE_FIELD( m_flSoundTime, FIELD_TIME),
DEFINE_FIELD( m_nState, FIELD_INTEGER ),
DEFINE_FIELD( m_iCaps, FIELD_INTEGER ),
// Function Pointers
DEFINE_FUNCTION( Off ),
DEFINE_FUNCTION( Recharge ),
DEFINE_OUTPUT( m_OnPlayerUse, "OnPlayerUse" ),
DEFINE_OUTPUT( m_OutRemainingHealth, "OutRemainingHealth"),
END_DATADESC()
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pkvd -
//-----------------------------------------------------------------------------
bool CWallHealth::KeyValue( const char *szKeyName, const char *szValue )
{
if (FStrEq(szKeyName, "style") ||
FStrEq(szKeyName, "height") ||
FStrEq(szKeyName, "value1") ||
FStrEq(szKeyName, "value2") ||
FStrEq(szKeyName, "value3"))
{
return(true);
}
else if (FStrEq(szKeyName, "dmdelay"))
{
m_iReactivate = atoi(szValue);
return(true);
}
return(BaseClass::KeyValue( szKeyName, szValue ));
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWallHealth::Spawn(void)
{
Precache( );
SetSolid( SOLID_BSP );
SetMoveType( MOVETYPE_PUSH );
SetModel( STRING( GetModelName() ) );
m_iJuice = sk_healthcharger.GetFloat();
m_nState = 0;
m_iCaps = FCAP_CONTINUOUS_USE;
CreateVPhysics();
}
int CWallHealth::DrawDebugTextOverlays(void)
{
int text_offset = BaseClass::DrawDebugTextOverlays();
if (m_debugOverlays & OVERLAY_TEXT_BIT)
{
char tempstr[512];
Q_snprintf(tempstr,sizeof(tempstr),"Charge left: %i", m_iJuice );
EntityText(text_offset,tempstr,0);
text_offset++;
}
return text_offset;
}
//-----------------------------------------------------------------------------
bool CWallHealth::CreateVPhysics(void)
{
VPhysicsInitStatic();
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWallHealth::Precache(void)
{
PrecacheScriptSound( "WallHealth.Deny" );
PrecacheScriptSound( "WallHealth.Start" );
PrecacheScriptSound( "WallHealth.LoopingContinueCharge" );
PrecacheScriptSound( "WallHealth.Recharge" );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pActivator -
// *pCaller -
// useType -
// value -
//-----------------------------------------------------------------------------
void CWallHealth::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
// Make sure that we have a caller
if (!pActivator)
return;
// if it's not a player, ignore
if ( !pActivator->IsPlayer() )
return;
CBasePlayer *pPlayer = dynamic_cast<CBasePlayer *>(pActivator);
// Reset to a state of continuous use.
m_iCaps = FCAP_CONTINUOUS_USE;
// if there is no juice left, turn it off
if (m_iJuice <= 0)
{
m_nState = 1;
Off();
}
// if the player doesn't have the suit, or there is no juice left, make the deny noise.
// disabled HEV suit dependency for now.
//if ((m_iJuice <= 0) || (!(pActivator->m_bWearingSuit)))
if (m_iJuice <= 0)
{
if (m_flSoundTime <= gpGlobals->curtime)
{
m_flSoundTime = gpGlobals->curtime + 0.62;
EmitSound( "WallHealth.Deny" );
}
return;
}
if( pActivator->GetHealth() >= pActivator->GetMaxHealth() )
{
if( pPlayer )
{
pPlayer->m_afButtonPressed &= ~IN_USE;
}
// Make the user re-use me to get started drawing health.
m_iCaps = FCAP_IMPULSE_USE;
return;
}
SetNextThink( gpGlobals->curtime + 0.25f );
SetThink(&CWallHealth::Off);
// Time to recharge yet?
if (m_flNextCharge >= gpGlobals->curtime)
return;
// Play the on sound or the looping charging sound
if (!m_iOn)
{
m_iOn++;
EmitSound( "WallHealth.Start" );
m_flSoundTime = 0.56 + gpGlobals->curtime;
m_OnPlayerUse.FireOutput( pActivator, this );
}
if ((m_iOn == 1) && (m_flSoundTime <= gpGlobals->curtime))
{
m_iOn++;
CPASAttenuationFilter filter( this, "WallHealth.LoopingContinueCharge" );
filter.MakeReliable();
EmitSound( filter, entindex(), "WallHealth.LoopingContinueCharge" );
}
// charge the player
if ( pActivator->TakeHealth( 1, DMG_GENERIC ) )
{
m_iJuice--;
}
// Send the output.
float flRemaining = m_iJuice / sk_healthcharger.GetFloat();
m_OutRemainingHealth.Set(flRemaining, pActivator, this);
// govern the rate of charge
m_flNextCharge = gpGlobals->curtime + 0.1;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWallHealth::Recharge(void)
{
EmitSound( "WallHealth.Recharge" );
m_iJuice = sk_healthcharger.GetFloat();
m_nState = 0;
SetThink( NULL );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWallHealth::Off(void)
{
// Stop looping sound.
if (m_iOn > 1)
StopSound( "WallHealth.LoopingContinueCharge" );
m_iOn = 0;
if ((!m_iJuice) && ( ( m_iReactivate = g_pGameRules->FlHealthChargerRechargeTime() ) > 0) )
{
SetNextThink( gpGlobals->curtime + m_iReactivate );
SetThink(&CWallHealth::Recharge);
}
else
SetThink( NULL );
}
//-----------------------------------------------------------------------------
// Wall mounted health kit. Heals the player when used.
//-----------------------------------------------------------------------------
class CNewWallHealth : public CBaseAnimating
{
public:
DECLARE_CLASS( CNewWallHealth, CBaseAnimating );
void Spawn( );
void Precache( void );
int DrawDebugTextOverlays(void);
bool CreateVPhysics(void);
void Off(void);
void Recharge(void);
bool KeyValue( const char *szKeyName, const char *szValue );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
virtual int ObjectCaps( void ) { return BaseClass::ObjectCaps() | m_iCaps; }
#ifdef MAPBASE
void InputRecharge( inputdata_t &inputdata );
void InputSetCharge( inputdata_t &inputdata );
void InputSetChargeNoMax( inputdata_t &inputdata );
void UpdateJuice( int newJuice );
float MaxJuice() const;
void SetInitialCharge( void );
int m_iMaxJuice;
int m_iIncrementValue;
#endif
float m_flNextCharge;
int m_iReactivate ; // DeathMatch Delay until reactvated
int m_iJuice;
int m_iOn; // 0 = off, 1 = startup, 2 = going
float m_flSoundTime;
int m_nState;
int m_iCaps;
COutputFloat m_OutRemainingHealth;
#ifdef MAPBASE
COutputEvent m_OnHalfEmpty;
COutputEvent m_OnEmpty;
COutputEvent m_OnFull;
#endif
COutputEvent m_OnPlayerUse;
void StudioFrameAdvance ( void );
float m_flJuice;
DECLARE_DATADESC();
};
LINK_ENTITY_TO_CLASS( item_healthcharger, CNewWallHealth);
BEGIN_DATADESC( CNewWallHealth )
DEFINE_FIELD( m_flNextCharge, FIELD_TIME),
DEFINE_FIELD( m_iReactivate, FIELD_INTEGER),
#ifdef MAPBASE
DEFINE_KEYFIELD( m_iJuice, FIELD_INTEGER, "Charge" ),
#else
DEFINE_FIELD( m_iJuice, FIELD_INTEGER),
#endif
DEFINE_FIELD( m_iOn, FIELD_INTEGER),
DEFINE_FIELD( m_flSoundTime, FIELD_TIME),
DEFINE_FIELD( m_nState, FIELD_INTEGER ),
DEFINE_FIELD( m_iCaps, FIELD_INTEGER ),
DEFINE_FIELD( m_flJuice, FIELD_FLOAT ),
#ifdef MAPBASE
DEFINE_KEYFIELD( m_iMaxJuice, FIELD_INTEGER, "MaxCharge" ),
DEFINE_INPUT( m_iIncrementValue, FIELD_INTEGER, "SetIncrementValue" ),
#endif
// Function Pointers
DEFINE_FUNCTION( Off ),
DEFINE_FUNCTION( Recharge ),
DEFINE_OUTPUT( m_OnPlayerUse, "OnPlayerUse" ),
DEFINE_OUTPUT( m_OutRemainingHealth, "OutRemainingHealth"),
#ifdef MAPBASE
DEFINE_OUTPUT(m_OnHalfEmpty, "OnHalfEmpty" ),
DEFINE_OUTPUT(m_OnEmpty, "OnEmpty" ),
DEFINE_OUTPUT(m_OnFull, "OnFull" ),
DEFINE_INPUTFUNC( FIELD_VOID, "Recharge", InputRecharge ),
DEFINE_INPUTFUNC( FIELD_INTEGER, "SetCharge", InputSetCharge ),
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetChargeNoMax", InputSetChargeNoMax ),
#endif
END_DATADESC()
#define HEALTH_CHARGER_MODEL_NAME "models/props_combine/health_charger001.mdl"
#define CHARGE_RATE 0.25f
#define CHARGES_PER_SECOND 1.0f / CHARGE_RATE
#define CALLS_PER_SECOND 7.0f * CHARGES_PER_SECOND
#ifdef MAPBASE
#define CUSTOM_CHARGES_PER_SECOND(inc) inc / CHARGE_RATE
#endif
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pkvd -
//-----------------------------------------------------------------------------
bool CNewWallHealth::KeyValue( const char *szKeyName, const char *szValue )
{
if (FStrEq(szKeyName, "style") ||
FStrEq(szKeyName, "height") ||
FStrEq(szKeyName, "value1") ||
FStrEq(szKeyName, "value2") ||
FStrEq(szKeyName, "value3"))
{
return(true);
}
else if (FStrEq(szKeyName, "dmdelay"))
{
m_iReactivate = atoi(szValue);
return(true);
}
return(BaseClass::KeyValue( szKeyName, szValue ));
}
#ifdef MAPBASE
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CNewWallHealth::SetInitialCharge( void )
{
if ( m_iMaxJuice != 0 )
{
// It must've been overridden by the mapper
return;
}
m_iMaxJuice = sk_healthcharger.GetFloat();
}
//-----------------------------------------------------------------------------
// Max juice for recharger
//-----------------------------------------------------------------------------
float CNewWallHealth::MaxJuice() const
{
return m_iMaxJuice;
}
#endif
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CNewWallHealth::Spawn(void)
{
Precache( );
SetMoveType( MOVETYPE_NONE );
SetSolid( SOLID_VPHYSICS );
CreateVPhysics();
#ifdef MAPBASE
SetModel( STRING(GetModelName()) );
#else
SetModel( HEALTH_CHARGER_MODEL_NAME );
#endif
AddEffects( EF_NOSHADOW );
ResetSequence( LookupSequence( "idle" ) );
#ifdef MAPBASE
if (m_iIncrementValue == 0)
m_iIncrementValue = 1;
SetInitialCharge();
// In case the juice was overridden
if (m_iJuice == 0)
UpdateJuice( MaxJuice() );
else if (m_iJuice == -1)
{
UpdateJuice( 0 );
ResetSequence( LookupSequence( "empty" ) );
}
else
UpdateJuice( m_iJuice );
#else
m_iJuice = sk_healthcharger.GetFloat();
#endif
m_nState = 0;
m_iReactivate = 0;
m_iCaps = FCAP_CONTINUOUS_USE;
CreateVPhysics();
m_flJuice = m_iJuice;
#ifdef MAPBASE
SetCycle( 1.0f - ( m_flJuice / MaxJuice() ) );
#else
SetCycle( 1.0f - ( m_flJuice / sk_healthcharger.GetFloat() ) );
#endif
}
int CNewWallHealth::DrawDebugTextOverlays(void)
{
int text_offset = BaseClass::DrawDebugTextOverlays();
if (m_debugOverlays & OVERLAY_TEXT_BIT)
{
char tempstr[512];
Q_snprintf(tempstr,sizeof(tempstr),"Charge left: %i", m_iJuice );
EntityText(text_offset,tempstr,0);
text_offset++;
}
return text_offset;
}
//-----------------------------------------------------------------------------
bool CNewWallHealth::CreateVPhysics(void)
{
VPhysicsInitStatic();
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CNewWallHealth::Precache(void)
{
#ifdef MAPBASE
if ( GetModelName() == NULL_STRING )
SetModelName( AllocPooledString(HEALTH_CHARGER_MODEL_NAME) );
PrecacheModel( STRING(GetModelName()) );
#else
PrecacheModel( HEALTH_CHARGER_MODEL_NAME );
#endif
PrecacheScriptSound( "WallHealth.Deny" );
PrecacheScriptSound( "WallHealth.Start" );
PrecacheScriptSound( "WallHealth.LoopingContinueCharge" );
PrecacheScriptSound( "WallHealth.Recharge" );
}
void CNewWallHealth::StudioFrameAdvance( void )
{
m_flPlaybackRate = 0;
#ifdef MAPBASE
float flMaxJuice = MaxJuice() + 0.1f;
#else
float flMaxJuice = sk_healthcharger.GetFloat();
#endif
SetCycle( 1.0f - (float)( m_flJuice / flMaxJuice ) );
// Msg( "Cycle: %f - Juice: %d - m_flJuice :%f - Interval: %f\n", (float)GetCycle(), (int)m_iJuice, (float)m_flJuice, GetAnimTimeInterval() );
if ( !m_flPrevAnimTime )
{
m_flPrevAnimTime = gpGlobals->curtime;
}
// Latch prev
m_flPrevAnimTime = m_flAnimTime;
// Set current
m_flAnimTime = gpGlobals->curtime;
}
#ifdef MAPBASE
//-----------------------------------------------------------------------------
// Purpose:
// Input : newJuice -
//-----------------------------------------------------------------------------
void CNewWallHealth::UpdateJuice( int newJuice )
{
bool reduced = newJuice < m_iJuice;
if ( reduced )
{
// Fire 1/2 way output and/or empyt output
int oneHalfJuice = (int)(MaxJuice() * 0.5f);
if ( newJuice <= oneHalfJuice && m_iJuice > oneHalfJuice )
{
m_OnHalfEmpty.FireOutput( this, this );
}
if ( newJuice <= 0 )
{
m_OnEmpty.FireOutput( this, this );
}
}
else if ( newJuice != m_iJuice &&
newJuice == (int)MaxJuice() )
{
m_OnFull.FireOutput( this, this );
}
m_iJuice = newJuice;
}
void CNewWallHealth::InputRecharge( inputdata_t &inputdata )
{
Recharge();
}
void CNewWallHealth::InputSetCharge( inputdata_t &inputdata )
{
int iJuice = inputdata.value.Int();
m_flJuice = m_iMaxJuice = m_iJuice = iJuice;
ResetSequence( m_iJuice > 0 ? LookupSequence( "idle" ) : LookupSequence( "empty" ) );
StudioFrameAdvance();
}
void CNewWallHealth::InputSetChargeNoMax( inputdata_t &inputdata )
{
m_flJuice = inputdata.value.Float();
UpdateJuice(m_flJuice);
ResetSequence( m_iJuice > 0 ? LookupSequence( "idle" ) : LookupSequence( "empty" ) );
StudioFrameAdvance();
}
#endif
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pActivator -
// *pCaller -
// useType -
// value -
//-----------------------------------------------------------------------------
void CNewWallHealth::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
// Make sure that we have a caller
if (!pActivator)
return;
// if it's not a player, ignore
if ( !pActivator->IsPlayer() )
return;
CBasePlayer *pPlayer = dynamic_cast<CBasePlayer *>(pActivator);
// Reset to a state of continuous use.
m_iCaps = FCAP_CONTINUOUS_USE;
if ( m_iOn )
{
float flCharges = CHARGES_PER_SECOND;
float flCalls = CALLS_PER_SECOND;
#ifdef MAPBASE
if ( m_iIncrementValue != 0 )
flCharges = CUSTOM_CHARGES_PER_SECOND(m_iIncrementValue);
#endif
m_flJuice -= flCharges / flCalls;
StudioFrameAdvance();
}
// if there is no juice left, turn it off
if (m_iJuice <= 0)
{
ResetSequence( LookupSequence( "emptyclick" ) );
m_nState = 1;
Off();
}
// if the player doesn't have the suit, or there is no juice left, make the deny noise.
// disabled HEV suit dependency for now.
//if ((m_iJuice <= 0) || (!(pActivator->m_bWearingSuit)))
if (m_iJuice <= 0)
{
if (m_flSoundTime <= gpGlobals->curtime)
{
m_flSoundTime = gpGlobals->curtime + 0.62;
EmitSound( "WallHealth.Deny" );
}
return;
}
if( pActivator->GetHealth() >= pActivator->GetMaxHealth() )
{
if( pPlayer )
{
pPlayer->m_afButtonPressed &= ~IN_USE;
}
// Make the user re-use me to get started drawing health.
m_iCaps = FCAP_IMPULSE_USE;
EmitSound( "WallHealth.Deny" );
return;
}
SetNextThink( gpGlobals->curtime + CHARGE_RATE );
SetThink( &CNewWallHealth::Off );
// Time to recharge yet?
if (m_flNextCharge >= gpGlobals->curtime)
return;
// Play the on sound or the looping charging sound
if (!m_iOn)
{
m_iOn++;
EmitSound( "WallHealth.Start" );
m_flSoundTime = 0.56 + gpGlobals->curtime;
m_OnPlayerUse.FireOutput( pActivator, this );
}
if ((m_iOn == 1) && (m_flSoundTime <= gpGlobals->curtime))
{
m_iOn++;
CPASAttenuationFilter filter( this, "WallHealth.LoopingContinueCharge" );
filter.MakeReliable();
EmitSound( filter, entindex(), "WallHealth.LoopingContinueCharge" );
}
// charge the player
#ifdef MAPBASE
if ( pActivator->TakeHealth( m_iIncrementValue, DMG_GENERIC ) )
{
UpdateJuice(m_iJuice - m_iIncrementValue);
}
#else
if ( pActivator->TakeHealth( 1, DMG_GENERIC ) )
{
m_iJuice--;
}
#endif
// Send the output.
#ifdef MAPBASE
float flRemaining = m_iJuice / MaxJuice();
#else
float flRemaining = m_iJuice / sk_healthcharger.GetFloat();
#endif
m_OutRemainingHealth.Set(flRemaining, pActivator, this);
// govern the rate of charge
m_flNextCharge = gpGlobals->curtime + 0.1;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CNewWallHealth::Recharge(void)
{
EmitSound( "WallHealth.Recharge" );
#ifdef MAPBASE
UpdateJuice(MaxJuice());
m_flJuice = m_iJuice;
#else
m_flJuice = m_iJuice = sk_healthcharger.GetFloat();
#endif
m_nState = 0;
ResetSequence( LookupSequence( "idle" ) );
StudioFrameAdvance();
m_iReactivate = 0;
SetThink( NULL );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CNewWallHealth::Off(void)
{
// Stop looping sound.
if (m_iOn > 1)
StopSound( "WallHealth.LoopingContinueCharge" );
if ( m_nState == 1 )
{
SetCycle( 1.0f );
}
m_iOn = 0;
m_flJuice = m_iJuice;
if ( m_iReactivate == 0 )
{
if ((!m_iJuice) && g_pGameRules->FlHealthChargerRechargeTime() > 0 )
{
m_iReactivate = g_pGameRules->FlHealthChargerRechargeTime();
SetNextThink( gpGlobals->curtime + m_iReactivate );
SetThink(&CNewWallHealth::Recharge);
}
else
SetThink( NULL );
}
}