//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // //=============================================================================// #include "cbase.h" #include "hud.h" #include "hudelement.h" #include "hud_macros.h" #include "hud_numericdisplay.h" #include "iclientmode.h" #include "iclientvehicle.h" #include #include #include "ihudlcd.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" //----------------------------------------------------------------------------- // Purpose: Displays current ammunition level //----------------------------------------------------------------------------- class CHudAmmo : public CHudNumericDisplay, public CHudElement { DECLARE_CLASS_SIMPLE( CHudAmmo, CHudNumericDisplay ); public: CHudAmmo( const char *pElementName ); void Init( void ); void VidInit( void ); void Reset(); void SetAmmo(int ammo, bool playAnimation); void SetAmmo2(int ammo2, bool playAnimation); protected: virtual void OnThink(); void UpdateAmmoDisplays(); void UpdatePlayerAmmo( C_BasePlayer *player ); private: CHandle< C_BaseCombatWeapon > m_hCurrentActiveWeapon; CHandle< C_BaseEntity > m_hCurrentVehicle; int m_iAmmo; int m_iAmmo2; }; DECLARE_HUDELEMENT( CHudAmmo ); //----------------------------------------------------------------------------- // Purpose: Constructor //----------------------------------------------------------------------------- CHudAmmo::CHudAmmo( const char *pElementName ) : BaseClass(NULL, "HudAmmo"), CHudElement( pElementName ) { SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT | HIDEHUD_WEAPONSELECTION ); hudlcd->SetGlobalStat( "(ammo_primary)", "0" ); hudlcd->SetGlobalStat( "(ammo_secondary)", "0" ); hudlcd->SetGlobalStat( "(weapon_print_name)", "" ); hudlcd->SetGlobalStat( "(weapon_name)", "" ); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CHudAmmo::Init( void ) { m_iAmmo = -1; m_iAmmo2 = -1; wchar_t *tempString = g_pVGuiLocalize->Find("#Valve_Hud_AMMO"); if (tempString) { SetLabelText(tempString); } else { SetLabelText(L"AMMO"); } } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CHudAmmo::VidInit( void ) { } //----------------------------------------------------------------------------- // Purpose: Resets hud after save/restore //----------------------------------------------------------------------------- void CHudAmmo::Reset() { BaseClass::Reset(); m_hCurrentActiveWeapon = NULL; m_hCurrentVehicle = NULL; m_iAmmo = 0; m_iAmmo2 = 0; UpdateAmmoDisplays(); } //----------------------------------------------------------------------------- // Purpose: called every frame to get ammo info from the weapon //----------------------------------------------------------------------------- void CHudAmmo::UpdatePlayerAmmo( C_BasePlayer *player ) { // Clear out the vehicle entity m_hCurrentVehicle = NULL; C_BaseCombatWeapon *wpn = GetActiveWeapon(); hudlcd->SetGlobalStat( "(weapon_print_name)", wpn ? wpn->GetPrintName() : " " ); hudlcd->SetGlobalStat( "(weapon_name)", wpn ? wpn->GetName() : " " ); if ( !wpn || !player || !wpn->UsesPrimaryAmmo() ) { hudlcd->SetGlobalStat( "(ammo_primary)", "n/a" ); hudlcd->SetGlobalStat( "(ammo_secondary)", "n/a" ); SetPaintEnabled(false); SetPaintBackgroundEnabled(false); return; } SetPaintEnabled(true); SetPaintBackgroundEnabled(true); // get the ammo in our clip int ammo1 = wpn->Clip1(); int ammo2; if (ammo1 < 0) { // we don't use clip ammo, just use the total ammo count ammo1 = player->GetAmmoCount(wpn->GetPrimaryAmmoType()); ammo2 = 0; } else { // we use clip ammo, so the second ammo is the total ammo ammo2 = player->GetAmmoCount(wpn->GetPrimaryAmmoType()); } hudlcd->SetGlobalStat( "(ammo_primary)", VarArgs( "%d", ammo1 ) ); hudlcd->SetGlobalStat( "(ammo_secondary)", VarArgs( "%d", ammo2 ) ); if (wpn == m_hCurrentActiveWeapon) { // same weapon, just update counts SetAmmo(ammo1, true); SetAmmo2(ammo2, true); } else { // diferent weapon, change without triggering SetAmmo(ammo1, false); SetAmmo2(ammo2, false); // update whether or not we show the total ammo display if (wpn->UsesClipsForAmmo1()) { SetShouldDisplaySecondaryValue(true); g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponUsesClips"); } else { g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponDoesNotUseClips"); SetShouldDisplaySecondaryValue(false); } g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponChanged"); m_hCurrentActiveWeapon = wpn; } } /* void CHudAmmo::UpdateVehicleAmmo( C_BasePlayer *player, IClientVehicle *pVehicle ) { m_hCurrentActiveWeapon = NULL; CBaseEntity *pVehicleEnt = pVehicle->GetVehicleEnt(); if ( !pVehicleEnt || pVehicle->GetPrimaryAmmoType() < 0 ) { SetPaintEnabled(false); SetPaintBackgroundEnabled(false); return; } SetPaintEnabled(true); SetPaintBackgroundEnabled(true); // get the ammo in our clip int ammo1 = pVehicle->GetPrimaryAmmoClip(); int ammo2; if (ammo1 < 0) { // we don't use clip ammo, just use the total ammo count ammo1 = pVehicle->GetPrimaryAmmoCount(); ammo2 = 0; } else { // we use clip ammo, so the second ammo is the total ammo ammo2 = pVehicle->GetPrimaryAmmoCount(); } if (pVehicleEnt == m_hCurrentVehicle) { // same weapon, just update counts SetAmmo(ammo1, true); SetAmmo2(ammo2, true); } else { // diferent weapon, change without triggering SetAmmo(ammo1, false); SetAmmo2(ammo2, false); // update whether or not we show the total ammo display if (pVehicle->PrimaryAmmoUsesClips()) { SetShouldDisplaySecondaryValue(true); g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponUsesClips"); } else { g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponDoesNotUseClips"); SetShouldDisplaySecondaryValue(false); } g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponChanged"); m_hCurrentVehicle = pVehicleEnt; } } */ //----------------------------------------------------------------------------- // Purpose: called every frame to get ammo info from the weapon //----------------------------------------------------------------------------- void CHudAmmo::OnThink() { UpdateAmmoDisplays(); } //----------------------------------------------------------------------------- // Purpose: updates the ammo display counts //----------------------------------------------------------------------------- void CHudAmmo::UpdateAmmoDisplays() { C_BasePlayer *player = C_BasePlayer::GetLocalPlayer(); UpdatePlayerAmmo( player ); } //----------------------------------------------------------------------------- // Purpose: Updates ammo display //----------------------------------------------------------------------------- void CHudAmmo::SetAmmo(int ammo, bool playAnimation) { if (ammo != m_iAmmo) { if (ammo == 0) { g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("AmmoEmpty"); } else if (ammo < m_iAmmo) { // ammo has decreased g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("AmmoDecreased"); } else { // ammunition has increased g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("AmmoIncreased"); } m_iAmmo = ammo; } SetDisplayValue(ammo); } //----------------------------------------------------------------------------- // Purpose: Updates 2nd ammo display //----------------------------------------------------------------------------- void CHudAmmo::SetAmmo2(int ammo2, bool playAnimation) { if (ammo2 != m_iAmmo2) { if (ammo2 == 0) { g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("Ammo2Empty"); } else if (ammo2 < m_iAmmo2) { // ammo has decreased g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("Ammo2Decreased"); } else { // ammunition has increased g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("Ammo2Increased"); } m_iAmmo2 = ammo2; } SetSecondaryValue(ammo2); } //----------------------------------------------------------------------------- // Purpose: Displays the secondary ammunition level //----------------------------------------------------------------------------- class CHudSecondaryAmmo : public CHudNumericDisplay, public CHudElement { DECLARE_CLASS_SIMPLE( CHudSecondaryAmmo, CHudNumericDisplay ); public: CHudSecondaryAmmo( const char *pElementName ) : BaseClass( NULL, "HudAmmoSecondary" ), CHudElement( pElementName ) { m_iAmmo = -1; SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_WEAPONSELECTION | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT ); } void Init( void ) { } void VidInit( void ) { } void SetAmmo( int ammo ) { if (ammo != m_iAmmo) { if (ammo == 0) { g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("AmmoSecondaryEmpty"); } else if (ammo < m_iAmmo) { // ammo has decreased g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("AmmoSecondaryDecreased"); } else { // ammunition has increased g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("AmmoSecondaryIncreased"); } m_iAmmo = ammo; } SetDisplayValue( ammo ); } void Reset() { // hud reset, update ammo state BaseClass::Reset(); m_iAmmo = 0; m_hCurrentActiveWeapon = NULL; SetAlpha( 0 ); UpdateAmmoState(); } protected: virtual void OnThink() { // set whether or not the panel draws based on if we have a weapon that supports secondary ammo C_BaseCombatWeapon *wpn = GetActiveWeapon(); C_BasePlayer *player = C_BasePlayer::GetLocalPlayer(); IClientVehicle *pVehicle = player ? player->GetVehicle() : NULL; if (!wpn || !player || pVehicle) { m_hCurrentActiveWeapon = NULL; SetPaintEnabled(false); SetPaintBackgroundEnabled(false); return; } else { SetPaintEnabled(true); SetPaintBackgroundEnabled(true); } UpdateAmmoState(); } void UpdateAmmoState() { C_BaseCombatWeapon *wpn = GetActiveWeapon(); C_BasePlayer *player = C_BasePlayer::GetLocalPlayer(); if (player && wpn && wpn->UsesSecondaryAmmo()) { SetAmmo(player->GetAmmoCount(wpn->GetSecondaryAmmoType())); } if ( m_hCurrentActiveWeapon != wpn ) { if ( wpn->UsesSecondaryAmmo() ) { // we've changed to a weapon that uses secondary ammo g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponUsesSecondaryAmmo"); } else { // we've changed away from a weapon that uses secondary ammo g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponDoesNotUseSecondaryAmmo"); } m_hCurrentActiveWeapon = wpn; } } private: CHandle< C_BaseCombatWeapon > m_hCurrentActiveWeapon; int m_iAmmo; }; DECLARE_HUDELEMENT( CHudSecondaryAmmo );