You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
777 lines
17 KiB
777 lines
17 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
// |
|
//=============================================================================// |
|
/* |
|
|
|
===== h_battery.cpp ======================================================== |
|
|
|
battery-related code |
|
|
|
*/ |
|
|
|
#include "cbase.h" |
|
#include "gamerules.h" |
|
#include "player.h" |
|
#include "engine/IEngineSound.h" |
|
#include "in_buttons.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
static ConVar sk_suitcharger( "sk_suitcharger","0" ); |
|
static ConVar sk_suitcharger_citadel( "sk_suitcharger_citadel","0" ); |
|
static ConVar sk_suitcharger_citadel_maxarmor( "sk_suitcharger_citadel_maxarmor","0" ); |
|
|
|
#define SF_CITADEL_RECHARGER 0x2000 |
|
#define SF_KLEINER_RECHARGER 0x4000 // Gives only 25 health |
|
|
|
class CRecharge : public CBaseToggle |
|
{ |
|
public: |
|
DECLARE_CLASS( CRecharge, CBaseToggle ); |
|
|
|
void Spawn( ); |
|
bool CreateVPhysics(); |
|
int DrawDebugTextOverlays(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() | FCAP_CONTINUOUS_USE); } |
|
|
|
private: |
|
void InputRecharge( inputdata_t &inputdata ); |
|
|
|
float MaxJuice() const; |
|
void UpdateJuice( int newJuice ); |
|
|
|
DECLARE_DATADESC(); |
|
|
|
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; |
|
|
|
COutputFloat m_OutRemainingCharge; |
|
COutputEvent m_OnHalfEmpty; |
|
COutputEvent m_OnEmpty; |
|
COutputEvent m_OnFull; |
|
COutputEvent m_OnPlayerUse; |
|
}; |
|
|
|
BEGIN_DATADESC( CRecharge ) |
|
|
|
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 ), |
|
|
|
// Function Pointers |
|
DEFINE_FUNCTION( Off ), |
|
DEFINE_FUNCTION( Recharge ), |
|
|
|
DEFINE_OUTPUT(m_OutRemainingCharge, "OutRemainingCharge"), |
|
DEFINE_OUTPUT(m_OnHalfEmpty, "OnHalfEmpty" ), |
|
DEFINE_OUTPUT(m_OnEmpty, "OnEmpty" ), |
|
DEFINE_OUTPUT(m_OnFull, "OnFull" ), |
|
DEFINE_OUTPUT(m_OnPlayerUse, "OnPlayerUse" ), |
|
|
|
DEFINE_INPUTFUNC( FIELD_VOID, "Recharge", InputRecharge ), |
|
|
|
END_DATADESC() |
|
|
|
|
|
LINK_ENTITY_TO_CLASS(func_recharge, CRecharge); |
|
|
|
|
|
bool CRecharge::KeyValue( const char *szKeyName, const char *szValue ) |
|
{ |
|
if ( FStrEq(szKeyName, "style") || |
|
FStrEq(szKeyName, "height") || |
|
FStrEq(szKeyName, "value1") || |
|
FStrEq(szKeyName, "value2") || |
|
FStrEq(szKeyName, "value3")) |
|
{ |
|
} |
|
else if (FStrEq(szKeyName, "dmdelay")) |
|
{ |
|
m_iReactivate = atoi(szValue); |
|
} |
|
else |
|
{ |
|
return BaseClass::KeyValue( szKeyName, szValue ); |
|
} |
|
|
|
return true; |
|
} |
|
|
|
void CRecharge::Spawn() |
|
{ |
|
Precache( ); |
|
|
|
SetSolid( SOLID_BSP ); |
|
SetMoveType( MOVETYPE_PUSH ); |
|
|
|
SetModel( STRING( GetModelName() ) ); |
|
|
|
UpdateJuice( MaxJuice() ); |
|
|
|
m_nState = 0; |
|
|
|
CreateVPhysics(); |
|
} |
|
|
|
bool CRecharge::CreateVPhysics() |
|
{ |
|
VPhysicsInitStatic(); |
|
return true; |
|
} |
|
|
|
int CRecharge::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; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Max juice for recharger |
|
//----------------------------------------------------------------------------- |
|
float CRecharge::MaxJuice() const |
|
{ |
|
if ( HasSpawnFlags( SF_CITADEL_RECHARGER ) ) |
|
{ |
|
return sk_suitcharger_citadel.GetFloat(); |
|
} |
|
|
|
return sk_suitcharger.GetFloat(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : newJuice - |
|
//----------------------------------------------------------------------------- |
|
void CRecharge::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 CRecharge::InputRecharge( inputdata_t &inputdata ) |
|
{ |
|
Recharge(); |
|
} |
|
|
|
void CRecharge::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) |
|
{ |
|
// if it's not a player, ignore |
|
if ( !pActivator || !pActivator->IsPlayer() ) |
|
return; |
|
|
|
// Only usable if you have the HEV suit on |
|
if ( !((CBasePlayer *)pActivator)->IsSuitEquipped() ) |
|
{ |
|
if (m_flSoundTime <= gpGlobals->curtime) |
|
{ |
|
m_flSoundTime = gpGlobals->curtime + 0.62; |
|
EmitSound( "SuitRecharge.Deny" ); |
|
} |
|
return; |
|
} |
|
|
|
// 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 |
|
if ( m_iJuice <= 0 ) |
|
{ |
|
if (m_flSoundTime <= gpGlobals->curtime) |
|
{ |
|
m_flSoundTime = gpGlobals->curtime + 0.62; |
|
EmitSound( "SuitRecharge.Deny" ); |
|
} |
|
return; |
|
} |
|
|
|
SetNextThink( gpGlobals->curtime + 0.25 ); |
|
SetThink(&CRecharge::Off); |
|
|
|
// Time to recharge yet? |
|
if (m_flNextCharge >= gpGlobals->curtime) |
|
return; |
|
|
|
// Make sure that we have a caller |
|
if (!pActivator) |
|
return; |
|
|
|
m_hActivator = pActivator; |
|
|
|
//only recharge the player |
|
|
|
if (!m_hActivator->IsPlayer() ) |
|
return; |
|
|
|
// Play the on sound or the looping charging sound |
|
if (!m_iOn) |
|
{ |
|
m_iOn++; |
|
EmitSound( "SuitRecharge.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, "SuitRecharge.ChargingLoop" ); |
|
filter.MakeReliable(); |
|
EmitSound( filter, entindex(), "SuitRecharge.ChargingLoop" ); |
|
} |
|
|
|
CBasePlayer *pl = (CBasePlayer *) m_hActivator.Get(); |
|
|
|
// charge the player |
|
int nMaxArmor = 100; |
|
int nIncrementArmor = 1; |
|
if ( HasSpawnFlags( SF_CITADEL_RECHARGER ) ) |
|
{ |
|
nMaxArmor = sk_suitcharger_citadel_maxarmor.GetInt(); |
|
nIncrementArmor = 10; |
|
|
|
// Also give health for the citadel version. |
|
if( pActivator->GetHealth() < pActivator->GetMaxHealth() ) |
|
{ |
|
pActivator->TakeHealth( 5, DMG_GENERIC ); |
|
} |
|
} |
|
|
|
if (pl->ArmorValue() < nMaxArmor) |
|
{ |
|
UpdateJuice( m_iJuice - nIncrementArmor ); |
|
pl->IncrementArmorValue( nIncrementArmor, nMaxArmor ); |
|
} |
|
|
|
// Send the output. |
|
float flRemaining = m_iJuice / MaxJuice(); |
|
m_OutRemainingCharge.Set(flRemaining, pActivator, this); |
|
|
|
// govern the rate of charge |
|
m_flNextCharge = gpGlobals->curtime + 0.1; |
|
} |
|
|
|
void CRecharge::Recharge(void) |
|
{ |
|
UpdateJuice( MaxJuice() ); |
|
m_nState = 0; |
|
SetThink( &CRecharge::SUB_DoNothing ); |
|
} |
|
|
|
void CRecharge::Off(void) |
|
{ |
|
// Stop looping sound. |
|
if (m_iOn > 1) |
|
{ |
|
StopSound( "SuitRecharge.ChargingLoop" ); |
|
} |
|
|
|
m_iOn = 0; |
|
|
|
if ((!m_iJuice) && ( ( m_iReactivate = g_pGameRules->FlHEVChargerRechargeTime() ) > 0) ) |
|
{ |
|
SetNextThink( gpGlobals->curtime + m_iReactivate ); |
|
SetThink(&CRecharge::Recharge); |
|
} |
|
else |
|
{ |
|
SetThink( NULL ); |
|
} |
|
} |
|
|
|
|
|
//NEW |
|
class CNewRecharge : public CBaseAnimating |
|
{ |
|
public: |
|
DECLARE_CLASS( CNewRecharge, CBaseAnimating ); |
|
|
|
void Spawn( ); |
|
bool CreateVPhysics(); |
|
int DrawDebugTextOverlays(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 ); } |
|
|
|
void SetInitialCharge( void ); |
|
|
|
private: |
|
void InputRecharge( inputdata_t &inputdata ); |
|
void InputSetCharge( inputdata_t &inputdata ); |
|
float MaxJuice() const; |
|
void UpdateJuice( int newJuice ); |
|
void Precache( void ); |
|
|
|
DECLARE_DATADESC(); |
|
|
|
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; |
|
int m_iMaxJuice; |
|
|
|
COutputFloat m_OutRemainingCharge; |
|
COutputEvent m_OnHalfEmpty; |
|
COutputEvent m_OnEmpty; |
|
COutputEvent m_OnFull; |
|
COutputEvent m_OnPlayerUse; |
|
|
|
virtual void StudioFrameAdvance ( void ); |
|
float m_flJuice; |
|
}; |
|
|
|
BEGIN_DATADESC( CNewRecharge ) |
|
|
|
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 ), |
|
DEFINE_FIELD( m_iMaxJuice, FIELD_INTEGER ), |
|
|
|
// Function Pointers |
|
DEFINE_FUNCTION( Off ), |
|
DEFINE_FUNCTION( Recharge ), |
|
|
|
DEFINE_OUTPUT(m_OutRemainingCharge, "OutRemainingCharge"), |
|
DEFINE_OUTPUT(m_OnHalfEmpty, "OnHalfEmpty" ), |
|
DEFINE_OUTPUT(m_OnEmpty, "OnEmpty" ), |
|
DEFINE_OUTPUT(m_OnFull, "OnFull" ), |
|
DEFINE_OUTPUT(m_OnPlayerUse, "OnPlayerUse" ), |
|
DEFINE_FIELD( m_flJuice, FIELD_FLOAT ), |
|
|
|
DEFINE_INPUTFUNC( FIELD_VOID, "Recharge", InputRecharge ), |
|
DEFINE_INPUTFUNC( FIELD_INTEGER, "SetCharge", InputSetCharge ), |
|
|
|
END_DATADESC() |
|
|
|
|
|
LINK_ENTITY_TO_CLASS( item_suitcharger, CNewRecharge); |
|
|
|
#define HEALTH_CHARGER_MODEL_NAME "models/props_combine/suit_charger001.mdl" |
|
#define CHARGE_RATE 0.25f |
|
#define CHARGES_PER_SECOND 1 / CHARGE_RATE |
|
#define CITADEL_CHARGES_PER_SECOND 10 / CHARGE_RATE |
|
#define CALLS_PER_SECOND 7.0f * CHARGES_PER_SECOND |
|
|
|
|
|
bool CNewRecharge::KeyValue( const char *szKeyName, const char *szValue ) |
|
{ |
|
if ( FStrEq(szKeyName, "style") || |
|
FStrEq(szKeyName, "height") || |
|
FStrEq(szKeyName, "value1") || |
|
FStrEq(szKeyName, "value2") || |
|
FStrEq(szKeyName, "value3")) |
|
{ |
|
} |
|
else if (FStrEq(szKeyName, "dmdelay")) |
|
{ |
|
m_iReactivate = atoi(szValue); |
|
} |
|
else |
|
{ |
|
return BaseClass::KeyValue( szKeyName, szValue ); |
|
} |
|
|
|
return true; |
|
} |
|
|
|
void CNewRecharge::Precache( void ) |
|
{ |
|
PrecacheModel( HEALTH_CHARGER_MODEL_NAME ); |
|
|
|
PrecacheScriptSound( "SuitRecharge.Deny" ); |
|
PrecacheScriptSound( "SuitRecharge.Start" ); |
|
PrecacheScriptSound( "SuitRecharge.ChargingLoop" ); |
|
|
|
} |
|
|
|
void CNewRecharge::SetInitialCharge( void ) |
|
{ |
|
if ( HasSpawnFlags( SF_KLEINER_RECHARGER ) ) |
|
{ |
|
// The charger in Kleiner's lab. |
|
m_iMaxJuice = 25.0f; |
|
return; |
|
} |
|
|
|
if ( HasSpawnFlags( SF_CITADEL_RECHARGER ) ) |
|
{ |
|
m_iMaxJuice = sk_suitcharger_citadel.GetFloat(); |
|
return; |
|
} |
|
|
|
m_iMaxJuice = sk_suitcharger.GetFloat(); |
|
} |
|
|
|
void CNewRecharge::Spawn() |
|
{ |
|
Precache( ); |
|
|
|
SetMoveType( MOVETYPE_NONE ); |
|
SetSolid( SOLID_VPHYSICS ); |
|
CreateVPhysics(); |
|
|
|
SetModel( HEALTH_CHARGER_MODEL_NAME ); |
|
AddEffects( EF_NOSHADOW ); |
|
|
|
ResetSequence( LookupSequence( "idle" ) ); |
|
|
|
SetInitialCharge(); |
|
|
|
UpdateJuice( MaxJuice() ); |
|
|
|
m_nState = 0; |
|
m_iCaps = FCAP_CONTINUOUS_USE; |
|
|
|
CreateVPhysics(); |
|
|
|
m_flJuice = m_iJuice; |
|
|
|
m_iReactivate = 0; |
|
|
|
SetCycle( 1.0f - ( m_flJuice / MaxJuice() ) ); |
|
} |
|
|
|
bool CNewRecharge::CreateVPhysics() |
|
{ |
|
VPhysicsInitStatic(); |
|
return true; |
|
} |
|
|
|
int CNewRecharge::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; |
|
} |
|
|
|
void CNewRecharge::StudioFrameAdvance( void ) |
|
{ |
|
m_flPlaybackRate = 0; |
|
|
|
float flMaxJuice = MaxJuice() + 0.1f; |
|
float flNewJuice = 1.0f - (float)( m_flJuice / flMaxJuice ); |
|
|
|
SetCycle( flNewJuice ); |
|
// 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; |
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Max juice for recharger |
|
//----------------------------------------------------------------------------- |
|
float CNewRecharge::MaxJuice() const |
|
{ |
|
return m_iMaxJuice; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : newJuice - |
|
//----------------------------------------------------------------------------- |
|
void CNewRecharge::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 CNewRecharge::InputRecharge( inputdata_t &inputdata ) |
|
{ |
|
Recharge(); |
|
} |
|
|
|
void CNewRecharge::InputSetCharge( inputdata_t &inputdata ) |
|
{ |
|
ResetSequence( LookupSequence( "idle" ) ); |
|
|
|
int iJuice = inputdata.value.Int(); |
|
|
|
m_flJuice = m_iMaxJuice = m_iJuice = iJuice; |
|
StudioFrameAdvance(); |
|
} |
|
|
|
void CNewRecharge::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) |
|
{ |
|
// if it's not a player, ignore |
|
if ( !pActivator || !pActivator->IsPlayer() ) |
|
return; |
|
|
|
CBasePlayer *pPlayer = static_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; |
|
|
|
if ( HasSpawnFlags( SF_CITADEL_RECHARGER ) ) |
|
flCharges = CITADEL_CHARGES_PER_SECOND; |
|
|
|
m_flJuice -= flCharges / flCalls; |
|
StudioFrameAdvance(); |
|
} |
|
|
|
// Only usable if you have the HEV suit on |
|
if ( !pPlayer->IsSuitEquipped() ) |
|
{ |
|
if (m_flSoundTime <= gpGlobals->curtime) |
|
{ |
|
m_flSoundTime = gpGlobals->curtime + 0.62; |
|
EmitSound( "SuitRecharge.Deny" ); |
|
} |
|
return; |
|
} |
|
|
|
// if there is no juice left, turn it off |
|
if ( m_iJuice <= 0 ) |
|
{ |
|
// Start our deny animation over again |
|
ResetSequence( LookupSequence( "emptyclick" ) ); |
|
|
|
m_nState = 1; |
|
|
|
// Shut off |
|
Off(); |
|
|
|
// Play a deny sound |
|
if ( m_flSoundTime <= gpGlobals->curtime ) |
|
{ |
|
m_flSoundTime = gpGlobals->curtime + 0.62; |
|
EmitSound( "SuitRecharge.Deny" ); |
|
} |
|
|
|
return; |
|
} |
|
|
|
// Get our maximum armor value |
|
int nMaxArmor = 100; |
|
if ( HasSpawnFlags( SF_CITADEL_RECHARGER ) ) |
|
{ |
|
nMaxArmor = sk_suitcharger_citadel_maxarmor.GetInt(); |
|
} |
|
|
|
int nIncrementArmor = 1; |
|
|
|
// The citadel charger gives more per charge and also gives health |
|
if ( HasSpawnFlags( SF_CITADEL_RECHARGER ) ) |
|
{ |
|
nIncrementArmor = 10; |
|
|
|
#ifdef HL2MP |
|
nIncrementArmor = 2; |
|
#endif |
|
|
|
// Also give health for the citadel version. |
|
if ( pActivator->GetHealth() < pActivator->GetMaxHealth() && m_flNextCharge < gpGlobals->curtime ) |
|
{ |
|
pActivator->TakeHealth( 5, DMG_GENERIC ); |
|
} |
|
} |
|
|
|
// If we're over our limit, debounce our keys |
|
if ( pPlayer->ArmorValue() >= nMaxArmor) |
|
{ |
|
// Citadel charger must also be at max health |
|
if ( !HasSpawnFlags(SF_CITADEL_RECHARGER) || ( HasSpawnFlags( SF_CITADEL_RECHARGER ) && pActivator->GetHealth() >= pActivator->GetMaxHealth() ) ) |
|
{ |
|
// Make the user re-use me to get started drawing health. |
|
pPlayer->m_afButtonPressed &= ~IN_USE; |
|
m_iCaps = FCAP_IMPULSE_USE; |
|
|
|
EmitSound( "SuitRecharge.Deny" ); |
|
return; |
|
} |
|
} |
|
|
|
// This is bumped out if used within the time period |
|
SetNextThink( gpGlobals->curtime + CHARGE_RATE ); |
|
SetThink( &CNewRecharge::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( "SuitRecharge.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, "SuitRecharge.ChargingLoop" ); |
|
filter.MakeReliable(); |
|
EmitSound( filter, entindex(), "SuitRecharge.ChargingLoop" ); |
|
} |
|
|
|
// Give armor if we need it |
|
if ( pPlayer->ArmorValue() < nMaxArmor ) |
|
{ |
|
UpdateJuice( m_iJuice - nIncrementArmor ); |
|
pPlayer->IncrementArmorValue( nIncrementArmor, nMaxArmor ); |
|
} |
|
|
|
// Send the output. |
|
float flRemaining = m_iJuice / MaxJuice(); |
|
m_OutRemainingCharge.Set(flRemaining, pActivator, this); |
|
|
|
// govern the rate of charge |
|
m_flNextCharge = gpGlobals->curtime + 0.1; |
|
} |
|
|
|
void CNewRecharge::Recharge(void) |
|
{ |
|
EmitSound( "SuitRecharge.Start" ); |
|
ResetSequence( LookupSequence( "idle" ) ); |
|
|
|
UpdateJuice( MaxJuice() ); |
|
|
|
m_nState = 0; |
|
m_flJuice = m_iJuice; |
|
m_iReactivate = 0; |
|
StudioFrameAdvance(); |
|
|
|
SetThink( &CNewRecharge::SUB_DoNothing ); |
|
} |
|
|
|
void CNewRecharge::Off(void) |
|
{ |
|
// Stop looping sound. |
|
if (m_iOn > 1) |
|
{ |
|
StopSound( "SuitRecharge.ChargingLoop" ); |
|
} |
|
|
|
if ( m_nState == 1 ) |
|
{ |
|
SetCycle( 1.0f ); |
|
} |
|
|
|
m_iOn = 0; |
|
m_flJuice = m_iJuice; |
|
|
|
if ( m_iReactivate == 0 ) |
|
{ |
|
if ((!m_iJuice) && g_pGameRules->FlHEVChargerRechargeTime() > 0 ) |
|
{ |
|
if ( HasSpawnFlags( SF_CITADEL_RECHARGER ) ) |
|
{ |
|
m_iReactivate = g_pGameRules->FlHEVChargerRechargeTime() * 2; |
|
} |
|
else |
|
{ |
|
m_iReactivate = g_pGameRules->FlHEVChargerRechargeTime(); |
|
} |
|
SetNextThink( gpGlobals->curtime + m_iReactivate ); |
|
SetThink(&CNewRecharge::Recharge); |
|
} |
|
else |
|
{ |
|
SetThink( NULL ); |
|
} |
|
} |
|
}
|
|
|