//----------------------------------------------------------------------------- // Purpose: Returns the magnitude of the entity's angular velocity. //----------------------------------------------------------------------------- void CPointVelocitySensor::SampleVelocity( void ) { if ( m_hTargetEntity == NULL ) return; Vector vecVelocity; if ( m_hTargetEntity->GetMoveType() == MOVETYPE_VPHYSICS ) { IPhysicsObject *pPhys = m_hTargetEntity->VPhysicsGetObject(); if ( pPhys != NULL ) { pPhys->GetVelocity( &vecVelocity, NULL ); } } else { vecVelocity = m_hTargetEntity->GetAbsVelocity(); } /* float flSpeed = VectorNormalize( vecVelocity ); float flDot = ( m_vecAxis != vec3_origin ) ? DotProduct( vecVelocity, m_vecAxis ) : 1.0f; */ // We want the component of the velocity vector in the direction of the axis, which since the // axis is normalized is simply their dot product (eg V . A = |V|*|A|*cos(theta) ) m_fPrevVelocity = ( m_vecAxis != vec3_origin ) ? DotProduct( vecVelocity, m_vecAxis ) : 1.0f; // if it's changed since the last frame, poke the output if ( m_fPrevVelocity != m_Velocity.Get() ) { m_Velocity.Set( m_fPrevVelocity, NULL, NULL ); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CGameUI::Deactivate( CBaseEntity *pActivator ) { CBasePlayer *pPlayer = m_player; AssertMsg(pPlayer, "CGameUI deactivated without a player!"); if (pPlayer) { // Re-enable player motion if ( FBitSet( m_spawnflags, SF_GAMEUI_FREEZE_PLAYER ) ) { m_player->RemoveFlag( FL_ATCONTROLS ); } // Restore weapons if ( FBitSet( m_spawnflags, SF_GAMEUI_HIDE_WEAPON ) ) { // Turn the hud back on pPlayer->m_Local.m_iHideHUD &= ~HIDEHUD_WEAPONSELECTION; if ( m_hSaveWeapon.Get() ) { m_player->Weapon_Switch( m_hSaveWeapon.Get() ); m_hSaveWeapon = NULL; } if ( pPlayer->GetActiveWeapon() ) { pPlayer->GetActiveWeapon()->Deploy(); } } // Announce that the player is no longer controlling through us m_playerOff.FireOutput( pPlayer, this, 0 ); // Clear out the axis controls m_xaxis.Set( 0, pPlayer, this ); m_yaxis.Set( 0, pPlayer, this ); m_attackaxis.Set( 0, pPlayer, this ); m_attack2axis.Set( 0, pPlayer, this ); m_nLastButtonState = 0; m_player = NULL; } else { Warning("%s Deactivate(): I have no player when called by %s!\n", GetEntityName().ToCStr(), pActivator->GetEntityName().ToCStr()); } // Stop thinking SetNextThink( TICK_NEVER_THINK ); }
//----------------------------------------------------------------------------- // Purpose: Compares the given entity's angular velocity to the threshold velocity. // Input : pEntity - Entity whose angular velocity is being measured. // flThreshold - // Output : Returns -1 if less than, 0 if equal to, or 1 if greater than the threshold. //----------------------------------------------------------------------------- int CPointAngularVelocitySensor::CompareToThreshold(CBaseEntity *pEntity, float flThreshold, bool bFireVelocityOutput) { if (pEntity == NULL) { return 0; } float flAngVelocity = SampleAngularVelocity(pEntity); if ( g_debug_angularsensor.GetBool() ) { DrawDebugLines(); } if (bFireVelocityOutput && (flAngVelocity != m_flLastAngVelocity)) { m_AngularVelocity.Set(flAngVelocity, pEntity, this); m_flLastAngVelocity = flAngVelocity; } if (flAngVelocity > flThreshold) { return 1; } if (flAngVelocity == flThreshold) { return 0; } return -1; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CGameUI::Deactivate( CBaseEntity *pActivator ) { CBasePlayer *pPlayer = m_player; // If deactivated by the player using me if ( pPlayer == pActivator ) { // Re-enable player motion if (FBitSet(m_spawnflags, SF_GAMEUI_FREEZE_PLAYER)) { m_player->RemoveFlag( FL_ATCONTROLS ); } // Restore weapons if (FBitSet(m_spawnflags, SF_GAMEUI_HIDE_WEAPON)) { // Turn the hud back on pPlayer->m_Local.m_iHideHUD &= ~HIDEHUD_WEAPONS; if (m_hSaveWeapon.Get()) { m_player->Weapon_Switch( m_hSaveWeapon.Get() ); m_hSaveWeapon = NULL; } if ( pPlayer->GetActiveWeapon() ) { pPlayer->GetActiveWeapon()->Deploy(); } } m_playerOff.FireOutput( pPlayer, this, 0 ); // clear out the axis controls m_xaxis.Set( 0, pPlayer, this ); m_yaxis.Set( 0, pPlayer, this ); m_attackaxis.Set( 0, pPlayer, this ); m_attack2axis.Set( 0, pPlayer, this ); m_player = NULL; SetNextThink( TICK_NEVER_THINK ); } }
//----------------------------------------------------------------------------- // Purpose: Called every frame. //----------------------------------------------------------------------------- void CPointAngleSensor::Think(void) { if (m_hTargetEntity != NULL) { Vector forward; m_hTargetEntity->GetVectors(&forward, NULL, NULL); m_TargetDir.Set(forward, this, this); if (m_hLookAtEntity != NULL) { // // Check to see if the measure entity's forward vector has been within // given tolerance of the target entity for the given period of time. // float flDot; if (IsFacingWithinTolerance(m_hTargetEntity, m_hLookAtEntity, m_flDotTolerance, &flDot )) { if (!m_bFired) { if (!m_flFacingTime) { m_flFacingTime = gpGlobals->curtime; } if (gpGlobals->curtime >= m_flFacingTime + m_flDuration) { m_OnFacingLookat.FireOutput(this, this); m_bFired = true; } } } else { // Reset the fired state if ( m_bFired ) { m_bFired = false; } // Always reset the time when we've lost our facing m_flFacingTime = 0; } // Output the angle range we're in float flPerc = RemapValClamped( flDot, 1.0f, m_flDotTolerance, 1.0f, 0.0f ); m_FacingPercentage.Set( flPerc, this, this ); } SetNextThink( gpGlobals->curtime ); } }
//----------------------------------------------------------------------------- // Purpose: Called every frame //----------------------------------------------------------------------------- void CPointProximitySensor::Think( void ) { if ( m_hTargetEntity != NULL ) { Vector vecTestDir = ( m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin() ); float flDist = VectorNormalize( vecTestDir ); // If we're only interested in the distance along a vector, modify the length the accomodate that if ( HasSpawnFlags( SF_PROXIMITY_TEST_AGAINST_AXIS ) ) { Vector vecDir; GetVectors( &vecDir, NULL, NULL ); float flDot = DotProduct( vecTestDir, vecDir ); flDist *= fabs( flDot ); } m_Distance.Set( flDist, this, this ); SetNextThink( gpGlobals->curtime ); } }
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 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::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { // if it's not a player, ignore if ( !pActivator->IsPlayer() ) return; // if there is no juice left, turn it off if (m_iJuice <= 0) { SetTextureFrameIndex( 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(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; } 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 if (pl->ArmorValue() < 100) { m_iJuice--; pl->IncrementArmorValue( 1, 100 ); } // Send the output. float flRemaining = m_iJuice / sk_suitcharger.GetFloat(); m_OutRemainingCharge.Set(flRemaining, pActivator, this); // govern the rate of charge m_flNextCharge = gpGlobals->curtime + 0.1; }
//------------------------------------------------------------------------------ // Purpose: Samples the player's inputs and fires outputs based on what buttons // are currently held down. //------------------------------------------------------------------------------ void CGameUI::Think( void ) { CBasePlayer *pPlayer = m_player; // If player is gone, stop thinking if (pPlayer == NULL) { SetNextThink( TICK_NEVER_THINK ); return; } // If we're forcing an update, state with a clean button state if ( m_bForceUpdate ) { m_nLastButtonState = pPlayer->m_nButtons; } // ------------------------------------------------ // Check that toucher is facing the UI within // the field of view tolerance. If not disconnect // ------------------------------------------------ if (m_flFieldOfView > -1) { Vector vPlayerFacing; pPlayer->EyeVectors( &vPlayerFacing ); Vector vPlayerToUI = GetAbsOrigin() - pPlayer->WorldSpaceCenter(); VectorNormalize(vPlayerToUI); float flDotPr = DotProduct(vPlayerFacing,vPlayerToUI); if (flDotPr < m_flFieldOfView) { Deactivate( pPlayer ); return; } } pPlayer->AddFlag( FL_ONTRAIN ); SetNextThink( gpGlobals->curtime ); // Deactivate if they jump or press +use. // FIXME: prevent the use from going through in player.cpp if ((( pPlayer->m_afButtonPressed & IN_USE ) && ( m_spawnflags & SF_GAMEUI_USE_DEACTIVATES )) || (( pPlayer->m_afButtonPressed & IN_JUMP ) && ( m_spawnflags & SF_GAMEUI_JUMP_DEACTIVATES ))) { Deactivate( pPlayer ); return; } // Determine what's different int nButtonsChanged = ( pPlayer->m_nButtons ^ m_nLastButtonState ); // // Handle all our possible input triggers // if ( nButtonsChanged & IN_MOVERIGHT ) { if ( m_nLastButtonState & IN_MOVERIGHT ) { m_unpressedMoveRight.FireOutput( pPlayer, this, 0 ); } else { m_pressedMoveRight.FireOutput( pPlayer, this, 0 ); } } if ( nButtonsChanged & IN_MOVELEFT ) { if ( m_nLastButtonState & IN_MOVELEFT ) { m_unpressedMoveLeft.FireOutput( pPlayer, this, 0 ); } else { m_pressedMoveLeft.FireOutput( pPlayer, this, 0 ); } } if ( nButtonsChanged & IN_FORWARD ) { if ( m_nLastButtonState & IN_FORWARD ) { m_unpressedForward.FireOutput( pPlayer, this, 0 ); } else { m_pressedForward.FireOutput( pPlayer, this, 0 ); } } if ( nButtonsChanged & IN_BACK ) { if ( m_nLastButtonState & IN_BACK ) { m_unpressedBack.FireOutput( pPlayer, this, 0 ); } else { m_pressedBack.FireOutput( pPlayer, this, 0 ); } } if ( nButtonsChanged & IN_ATTACK ) { if ( m_nLastButtonState & IN_ATTACK ) { m_unpressedAttack.FireOutput( pPlayer, this, 0 ); } else { m_pressedAttack.FireOutput( pPlayer, this, 0 ); } } if ( nButtonsChanged & IN_ATTACK2 ) { if ( m_nLastButtonState & IN_ATTACK2 ) { m_unpressedAttack2.FireOutput( pPlayer, this, 0 ); } else { m_pressedAttack2.FireOutput( pPlayer, this, 0 ); } } // Setup for the next frame m_nLastButtonState = pPlayer->m_nButtons; float x = 0, y = 0, attack = 0, attack2 = 0; if ( pPlayer->m_nButtons & IN_MOVERIGHT ) { x = 1; } else if ( pPlayer->m_nButtons & IN_MOVELEFT ) { x = -1; } if ( pPlayer->m_nButtons & IN_FORWARD ) { y = 1; } else if ( pPlayer->m_nButtons & IN_BACK ) { y = -1; } if ( pPlayer->m_nButtons & IN_ATTACK ) { attack = 1; } if ( pPlayer->m_nButtons & IN_ATTACK2 ) { attack2 = 1; } // // Fire the analog outputs if they changed. // if ( m_bForceUpdate || ( m_xaxis.Get() != x ) ) { m_xaxis.Set( x, pPlayer, this ); } if ( m_bForceUpdate || ( m_yaxis.Get() != y ) ) { m_yaxis.Set( y, pPlayer, this ); } if ( m_bForceUpdate || ( m_attackaxis.Get() != attack ) ) { m_attackaxis.Set( attack, pPlayer, this ); } if ( m_bForceUpdate || ( m_attack2axis.Get() != attack2 ) ) { m_attack2axis.Set( attack2, pPlayer, this ); } m_bForceUpdate = false; }
//----------------------------------------------------------------------------- // 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; 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 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; }
void CRecharge::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 ); if ( pPlayer == NULL ) return; // 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) { SetTextureFrameIndex( 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; } // If we're over our limit, debounce our keys if ( pPlayer->ArmorValue() >= HL1_MAX_ARMOR) { // 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; } SetNextThink( gpGlobals->curtime + 0.25 ); SetThink(&CRecharge::Off); // Time to recharge yet? if (m_flNextCharge >= gpGlobals->curtime) return; m_hActivator = pActivator; // Play the on sound or the looping charging sound if (!m_iOn) { m_iOn++; EmitSound( "SuitRecharge.Start" ); m_flSoundTime = 0.56 + gpGlobals->curtime; } 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 if (pl->ArmorValue() < HL1_MAX_ARMOR) { m_iJuice--; pl->IncrementArmorValue( 1, HL1_MAX_ARMOR ); } // Send the output. float flRemaining = m_iJuice / sk_suitcharger.GetFloat(); m_OutRemainingCharge.Set(flRemaining, pActivator, this); // govern the rate of charge m_flNextCharge = gpGlobals->curtime + 0.1; }