mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-23 06:36:54 +00:00
503 lines
13 KiB
C++
503 lines
13 KiB
C++
//========= 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 <vgui_controls/AnimationController.h>
|
|
#include <vgui/ILocalize.h>
|
|
#include <vgui/ISurface.h>
|
|
#include "ihudlcd.h"
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
using namespace vgui;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// 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);
|
|
virtual void Paint( void );
|
|
|
|
protected:
|
|
virtual void OnThink();
|
|
|
|
void UpdateAmmoDisplays();
|
|
void UpdatePlayerAmmo( C_BasePlayer *player );
|
|
void UpdateVehicleAmmo( C_BasePlayer *player, IClientVehicle *pVehicle );
|
|
|
|
private:
|
|
CHandle< C_BaseCombatWeapon > m_hCurrentActiveWeapon;
|
|
CHandle< C_BaseEntity > m_hCurrentVehicle;
|
|
int m_iAmmo;
|
|
int m_iAmmo2;
|
|
CHudTexture *m_iconPrimaryAmmo;
|
|
};
|
|
|
|
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;
|
|
|
|
m_iconPrimaryAmmo = NULL;
|
|
|
|
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 our icons for the ammo types
|
|
m_iconPrimaryAmmo = gWR.GetAmmoIconFromWeapon( wpn->GetPrimaryAmmoType() );
|
|
|
|
// 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();
|
|
IClientVehicle *pVehicle = player ? player->GetVehicle() : NULL;
|
|
|
|
if ( !pVehicle )
|
|
{
|
|
UpdatePlayerAmmo( player );
|
|
}
|
|
else
|
|
{
|
|
UpdateVehicleAmmo( player, pVehicle );
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// 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: We add an icon into the
|
|
//-----------------------------------------------------------------------------
|
|
void CHudAmmo::Paint( void )
|
|
{
|
|
BaseClass::Paint();
|
|
|
|
#ifndef HL2MP
|
|
if ( m_hCurrentVehicle == NULL && m_iconPrimaryAmmo )
|
|
{
|
|
int nLabelHeight;
|
|
int nLabelWidth;
|
|
surface()->GetTextSize( m_hTextFont, m_LabelText, nLabelWidth, nLabelHeight );
|
|
|
|
// Figure out where we're going to put this
|
|
int x = text_xpos + ( nLabelWidth - m_iconPrimaryAmmo->Width() ) / 2;
|
|
int y = text_ypos - ( nLabelHeight + ( m_iconPrimaryAmmo->Height() / 2 ) );
|
|
|
|
m_iconPrimaryAmmo->DrawSelf( x, y, GetFgColor() );
|
|
}
|
|
#endif // HL2MP
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// 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 )
|
|
{
|
|
#ifndef HL2MP
|
|
wchar_t *tempString = g_pVGuiLocalize->Find("#Valve_Hud_AMMO_ALT");
|
|
if (tempString)
|
|
{
|
|
SetLabelText(tempString);
|
|
}
|
|
else
|
|
{
|
|
SetLabelText(L"ALT");
|
|
}
|
|
#endif // HL2MP
|
|
}
|
|
|
|
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();
|
|
}
|
|
|
|
virtual void Paint( void )
|
|
{
|
|
BaseClass::Paint();
|
|
|
|
#ifndef HL2MP
|
|
if ( m_iconSecondaryAmmo )
|
|
{
|
|
int nLabelHeight;
|
|
int nLabelWidth;
|
|
surface()->GetTextSize( m_hTextFont, m_LabelText, nLabelWidth, nLabelHeight );
|
|
|
|
// Figure out where we're going to put this
|
|
int x = text_xpos + ( nLabelWidth - m_iconSecondaryAmmo->Width() ) / 2;
|
|
int y = text_ypos - ( nLabelHeight + ( m_iconSecondaryAmmo->Height() / 2 ) );
|
|
|
|
m_iconSecondaryAmmo->DrawSelf( x, y, GetFgColor() );
|
|
}
|
|
#endif // HL2MP
|
|
}
|
|
|
|
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;
|
|
|
|
// Get the icon we should be displaying
|
|
m_iconSecondaryAmmo = gWR.GetAmmoIconFromWeapon( m_hCurrentActiveWeapon->GetSecondaryAmmoType() );
|
|
}
|
|
}
|
|
|
|
private:
|
|
CHandle< C_BaseCombatWeapon > m_hCurrentActiveWeapon;
|
|
CHudTexture *m_iconSecondaryAmmo;
|
|
int m_iAmmo;
|
|
};
|
|
|
|
DECLARE_HUDELEMENT( CHudSecondaryAmmo );
|
|
|