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.
1157 lines
39 KiB
1157 lines
39 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//=============================================================================// |
|
|
|
#include "cbase.h" |
|
#include "hudelement.h" |
|
#include "iclientmode.h" |
|
#include <KeyValues.h> |
|
#include <vgui/IScheme.h> |
|
#include <vgui/ISurface.h> |
|
#include <vgui/ISystem.h> |
|
#include <vgui_controls/AnimationController.h> |
|
#include <vgui_controls/EditablePanel.h> |
|
#include <vgui/ISurface.h> |
|
#include <vgui/IImage.h> |
|
#include <vgui_controls/Label.h> |
|
|
|
#include "c_tf_playerresource.h" |
|
#include "tf_playermodelpanel.h" |
|
#include "econ_item_description.h" |
|
|
|
#include "hud_numericdisplay.h" |
|
#include "c_team.h" |
|
#include "c_tf_player.h" |
|
#include "tf_shareddefs.h" |
|
#include "tf_hud_playerstatus.h" |
|
#include "tf_gamerules.h" |
|
#include "tf_logic_halloween_2014.h" |
|
#include "tf_logic_player_destruction.h" |
|
|
|
#include "tf_wheel_of_doom.h" |
|
|
|
#include "confirm_dialog.h" |
|
|
|
using namespace vgui; |
|
|
|
ConVar cl_hud_playerclass_use_playermodel( "cl_hud_playerclass_use_playermodel", "1", FCVAR_ARCHIVE, "Use player model in player class HUD." ); |
|
|
|
#ifdef STAGING_ONLY |
|
ConVar cl_hud_playerclass_playermodel_lod( "cl_hud_playerclass_playermodel_lod", "0", FCVAR_ARCHIVE, "Adjust lod on player model in the player class HUD." ); |
|
#endif // STAGING_ONLY |
|
|
|
ConVar cl_hud_playerclass_playermodel_showed_confirm_dialog( "cl_hud_playerclass_playermodel_showed_confirm_dialog", "0", FCVAR_ARCHIVE | FCVAR_HIDDEN ); |
|
|
|
extern ConVar tf_max_health_boost; |
|
|
|
|
|
static const char *g_szBlueClassImages[] = |
|
{ |
|
"", |
|
"../hud/class_scoutblue", |
|
"../hud/class_sniperblue", |
|
"../hud/class_soldierblue", |
|
"../hud/class_demoblue", |
|
"../hud/class_medicblue", |
|
"../hud/class_heavyblue", |
|
"../hud/class_pyroblue", |
|
"../hud/class_spyblue", |
|
"../hud/class_engiblue", |
|
"../hud/class_scoutblue", |
|
}; |
|
|
|
static const char *g_szRedClassImages[] = |
|
{ |
|
"", |
|
"../hud/class_scoutred", |
|
"../hud/class_sniperred", |
|
"../hud/class_soldierred", |
|
"../hud/class_demored", |
|
"../hud/class_medicred", |
|
"../hud/class_heavyred", |
|
"../hud/class_pyrored", |
|
"../hud/class_spyred", |
|
"../hud/class_engired", |
|
"../hud/class_scoutred", |
|
}; |
|
|
|
enum |
|
{ |
|
HUD_HEALTH_NO_ANIM = 0, |
|
HUD_HEALTH_BONUS_ANIM, |
|
HUD_HEALTH_DYING_ANIM, |
|
}; |
|
|
|
DECLARE_BUILD_FACTORY( CTFClassImage ); |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CTFHudPlayerClass::CTFHudPlayerClass( Panel *parent, const char *name ) : EditablePanel( parent, name ) |
|
{ |
|
m_pClassImage = NULL; |
|
m_pClassImageBG = NULL; |
|
m_pSpyImage = NULL; |
|
m_pSpyOutlineImage = NULL; |
|
m_pPlayerModelPanel = NULL; |
|
m_pPlayerModelPanelBG = NULL; |
|
m_pCarryingWeaponPanel = NULL; |
|
m_pCarryingLabel = NULL; |
|
m_pCarryingOwnerLabel = NULL; |
|
m_pCarryingBG = NULL; |
|
|
|
m_nTeam = TEAM_UNASSIGNED; |
|
m_nClass = TF_CLASS_UNDEFINED; |
|
m_nDisguiseTeam = TEAM_UNASSIGNED; |
|
m_nDisguiseClass = TF_CLASS_UNDEFINED; |
|
m_hDisguiseWeapon = NULL; |
|
m_flNextThink = 0.0f; |
|
m_nKillStreak = 0; |
|
#ifdef STAGING_ONLY |
|
m_nLOD = -1; |
|
#endif // STAGING_ONLY |
|
|
|
m_bUsePlayerModel = cl_hud_playerclass_use_playermodel.GetBool(); |
|
|
|
ListenForGameEvent( "localplayer_changedisguise" ); |
|
ListenForGameEvent( "post_inventory_application" ); |
|
ListenForGameEvent( "localplayer_pickup_weapon" ); |
|
|
|
for ( int i = 0; i < TF_CLASS_COUNT_ALL; i++ ) |
|
{ |
|
// The materials are given to vgui via the SetImage() function, which prepends |
|
// the "vgui/", so we need to precache them with the same. |
|
if ( g_szBlueClassImages[i] && g_szBlueClassImages[i][0] ) |
|
{ |
|
PrecacheMaterial( VarArgs( "vgui/%s", g_szBlueClassImages[i] ) ); |
|
PrecacheMaterial( VarArgs( "vgui/%s_cloak", g_szBlueClassImages[i] ) ); |
|
PrecacheMaterial( VarArgs( "vgui/%s_halfcloak", g_szBlueClassImages[i] ) ); |
|
} |
|
if ( g_szRedClassImages[i] && g_szRedClassImages[i][0] ) |
|
{ |
|
PrecacheMaterial( VarArgs( "vgui/%s", g_szRedClassImages[i] ) ); |
|
PrecacheMaterial( VarArgs( "vgui/%s_cloak", g_szRedClassImages[i] ) ); |
|
PrecacheMaterial( VarArgs( "vgui/%s_halfcloak", g_szRedClassImages[i] ) ); |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFHudPlayerClass::Reset() |
|
{ |
|
m_flNextThink = gpGlobals->curtime + 0.05f; |
|
|
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HudSpyDisguiseHide" ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFHudPlayerClass::ApplySchemeSettings( IScheme *pScheme ) |
|
{ |
|
// load control settings... |
|
LoadControlSettings( "resource/UI/HudPlayerClass.res" ); |
|
|
|
m_nTeam = TEAM_UNASSIGNED; |
|
m_nClass = TF_CLASS_UNDEFINED; |
|
m_nDisguiseTeam = TEAM_UNASSIGNED; |
|
m_nDisguiseClass = TF_CLASS_UNDEFINED; |
|
m_hDisguiseWeapon = NULL; |
|
m_flNextThink = 0.0f; |
|
m_nCloakLevel = 0; |
|
m_nLoadoutPosition = LOADOUT_POSITION_PRIMARY; |
|
|
|
m_pClassImage = FindControl<CTFClassImage>( "PlayerStatusClassImage", false ); |
|
m_pClassImageBG = FindControl<CTFImagePanel>( "PlayerStatusClassImageBG", false ); |
|
m_pSpyImage = FindControl<CTFImagePanel>( "PlayerStatusSpyImage", false ); |
|
m_pSpyOutlineImage = FindControl<CTFImagePanel>( "PlayerStatusSpyOutlineImage", false ); |
|
|
|
m_pPlayerModelPanel = FindControl<CTFPlayerModelPanel>( "classmodelpanel", false ); |
|
m_pPlayerModelPanelBG = FindControl<CTFImagePanel>( "classmodelpanelBG", false ); |
|
|
|
m_pCarryingWeaponPanel = FindControl< EditablePanel >( "CarryingWeapon", false ); |
|
if ( m_pCarryingWeaponPanel ) |
|
{ |
|
m_pCarryingLabel = m_pCarryingWeaponPanel->FindControl< CExLabel >( "CarryingLabel" ); |
|
m_pCarryingOwnerLabel = m_pCarryingWeaponPanel->FindControl< Label >( "OwnerLabel" ); |
|
m_pCarryingBG = m_pCarryingWeaponPanel->FindControl< CTFImagePanel >( "CarryingBackground" ); |
|
} |
|
|
|
BaseClass::ApplySchemeSettings( pScheme ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFHudPlayerClass::OnThink() |
|
{ |
|
if ( m_flNextThink > gpGlobals->curtime ) |
|
return; |
|
|
|
m_flNextThink = gpGlobals->curtime + 0.5f; |
|
C_TFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer(); |
|
if ( !pPlayer ) |
|
return; |
|
|
|
bool bTeamChange = false; |
|
// set our background colors |
|
if ( m_nTeam != pPlayer->GetTeamNumber() ) |
|
{ |
|
bTeamChange = true; |
|
m_nTeam = pPlayer->GetTeamNumber(); |
|
} |
|
|
|
int nCloakLevel = 0; |
|
bool bCloakChange = false; |
|
float flInvis = pPlayer->GetPercentInvisible(); |
|
|
|
if ( flInvis > 0.9 ) |
|
{ |
|
nCloakLevel = 2; |
|
} |
|
else if ( flInvis > 0.1 ) |
|
{ |
|
nCloakLevel = 1; |
|
} |
|
|
|
if ( nCloakLevel != m_nCloakLevel ) |
|
{ |
|
m_nCloakLevel = nCloakLevel; |
|
bCloakChange = true; |
|
} |
|
|
|
bool bLoadoutPositionChange = false; |
|
int nLoadoutSlot = pPlayer->GetActiveTFWeapon() ? pPlayer->GetActiveTFWeapon()->GetAttributeContainer()->GetItem()->GetStaticData()->GetLoadoutSlot( m_nClass ) : LOADOUT_POSITION_PRIMARY; |
|
if ( m_nLoadoutPosition != nLoadoutSlot ) |
|
{ |
|
m_nLoadoutPosition = nLoadoutSlot; |
|
bLoadoutPositionChange = true; |
|
} |
|
|
|
bool bPlayerClassModeChange = false; |
|
if ( m_bUsePlayerModel != cl_hud_playerclass_use_playermodel.GetBool() ) |
|
{ |
|
m_bUsePlayerModel = cl_hud_playerclass_use_playermodel.GetBool(); |
|
bPlayerClassModeChange = true; |
|
} |
|
|
|
#ifdef STAGING_ONLY |
|
if ( m_nLOD != cl_hud_playerclass_playermodel_lod.GetInt() && m_pPlayerModelPanel ) |
|
{ |
|
m_nLOD = cl_hud_playerclass_playermodel_lod.GetInt(); |
|
m_pPlayerModelPanel->SetLOD( m_nLOD ); |
|
} |
|
#endif // STAGING_ONLY |
|
|
|
bool bForceEyeUpdate = false; |
|
// set our class image |
|
if ( m_nClass != pPlayer->GetPlayerClass()->GetClassIndex() || bTeamChange || bCloakChange || bLoadoutPositionChange || bPlayerClassModeChange || |
|
( |
|
m_nClass == TF_CLASS_SPY && |
|
( |
|
m_nDisguiseClass != pPlayer->m_Shared.GetDisguiseClass() || |
|
m_nDisguiseTeam != pPlayer->m_Shared.GetDisguiseTeam() || |
|
m_hDisguiseWeapon != pPlayer->m_Shared.GetDisguiseWeapon() |
|
) |
|
) |
|
) |
|
{ |
|
bForceEyeUpdate = true; |
|
m_nClass = pPlayer->GetPlayerClass()->GetClassIndex(); |
|
|
|
if ( m_nClass == TF_CLASS_SPY && pPlayer->m_Shared.InCond( TF_COND_DISGUISED ) ) |
|
{ |
|
if ( !pPlayer->m_Shared.InCond( TF_COND_DISGUISING ) ) |
|
{ |
|
m_nDisguiseTeam = pPlayer->m_Shared.GetDisguiseTeam(); |
|
m_nDisguiseClass = pPlayer->m_Shared.GetDisguiseClass(); |
|
m_hDisguiseWeapon = pPlayer->m_Shared.GetDisguiseWeapon(); |
|
} |
|
} |
|
else |
|
{ |
|
m_nDisguiseTeam = TEAM_UNASSIGNED; |
|
m_nDisguiseClass = TF_CLASS_UNDEFINED; |
|
m_hDisguiseWeapon = NULL; |
|
} |
|
|
|
if ( m_bUsePlayerModel && m_pPlayerModelPanel && m_pPlayerModelPanelBG ) |
|
{ |
|
m_pPlayerModelPanel->SetVisible( true ); |
|
m_pPlayerModelPanelBG->SetVisible( true ); |
|
|
|
UpdateModelPanel(); |
|
} |
|
else if ( m_pClassImage && m_pSpyImage ) |
|
{ |
|
if ( m_pPlayerModelPanel ) |
|
m_pPlayerModelPanel->SetVisible( false ); |
|
if ( m_pPlayerModelPanelBG ) |
|
m_pPlayerModelPanelBG->SetVisible( false ); |
|
|
|
m_pClassImage->SetVisible( true ); |
|
m_pClassImageBG->SetVisible( true ); |
|
|
|
int iCloakState = 0; |
|
if ( pPlayer->IsPlayerClass( TF_CLASS_SPY ) ) |
|
{ |
|
iCloakState = m_nCloakLevel; |
|
} |
|
|
|
if ( m_nDisguiseTeam != TEAM_UNASSIGNED || m_nDisguiseClass != TF_CLASS_UNDEFINED ) |
|
{ |
|
m_pSpyImage->SetVisible( true ); |
|
m_pClassImage->SetClass( m_nDisguiseTeam, m_nDisguiseClass, iCloakState ); |
|
} |
|
else |
|
{ |
|
m_pSpyImage->SetVisible( false ); |
|
m_pClassImage->SetClass( m_nTeam, m_nClass, iCloakState ); |
|
} |
|
} |
|
} |
|
|
|
if ( m_pCarryingWeaponPanel ) |
|
{ |
|
// Don't show if we're disguised (the panels overlap) |
|
bool bShowCarryingWeaponPanel = m_nDisguiseClass == TF_CLASS_UNDEFINED; |
|
|
|
if ( pPlayer->GetActiveTFWeapon() && pPlayer->GetActiveTFWeapon()->GetAttributeContainer() ) |
|
{ |
|
CEconItemView* pItem = pPlayer->GetActiveTFWeapon()->GetAttributeContainer()->GetItem(); |
|
if ( pItem ) |
|
{ |
|
CSteamID playerSteamID; |
|
pPlayer->GetSteamID( &playerSteamID ); |
|
// We're holding a weapon we dont own! |
|
if ( playerSteamID.GetAccountID() != pItem->GetAccountID() && m_pCarryingLabel ) |
|
{ |
|
locchar_t wszLocString [128]; |
|
|
|
// Construct and set the weapon's name |
|
g_pVGuiLocalize->ConstructString_safe( wszLocString, L"%s1", 1, CEconItemLocalizedFullNameGenerator( GLocalizationProvider(), pItem->GetItemDefinition(), pItem->GetItemQuality() ).GetFullName() ); |
|
m_pCarryingWeaponPanel->SetDialogVariable( "carrying", wszLocString ); |
|
|
|
// Get and set the rarity color of the weapon |
|
const char* pszColorName = GetItemSchema()->GetRarityColor( pItem->GetItemDefinition()->GetRarity() ); |
|
pszColorName = pszColorName ? pszColorName : "TanLight"; |
|
if ( pszColorName ) |
|
{ |
|
m_pCarryingLabel->SetColorStr( pszColorName ); |
|
} |
|
|
|
bool bHasOwner = false; |
|
locchar_t wszPlayerName [128]; |
|
CBasePlayer *pOwner = GetPlayerByAccountID( pItem->GetAccountID() ); |
|
// Bots will not work here, so don't fill this out if there's no owner |
|
if ( pOwner ) |
|
{ |
|
// Fill out the actual owner's name |
|
locchar_t wszStolenString[128]; |
|
g_pVGuiLocalize->ConvertANSIToUnicode( pOwner->GetPlayerName(), wszPlayerName, sizeof(wszPlayerName) ); |
|
g_pVGuiLocalize->ConstructString_safe( wszStolenString, g_pVGuiLocalize->Find( "TF_WhoDropped" ), 1, wszPlayerName ); |
|
m_pCarryingOwnerLabel->SetText( wszStolenString ); |
|
bHasOwner = true; |
|
} |
|
else |
|
{ |
|
m_pCarryingOwnerLabel->SetText( "" ); |
|
} |
|
|
|
int nMaxWide = 0, nMaxTall = 0; |
|
// Resize the panel to just be the width of whichever label is longer |
|
int nTall, nWide; |
|
m_pCarryingLabel->SizeToContents(); |
|
m_pCarryingLabel->GetContentSize( nWide, nTall ); |
|
nMaxWide = Max( nMaxWide, nWide ); |
|
nMaxTall = Max( nMaxTall, nTall ); |
|
|
|
m_pCarryingOwnerLabel->SizeToContents(); |
|
m_pCarryingOwnerLabel->GetContentSize( nWide, nTall ); |
|
nMaxWide = Max( nMaxWide, nWide ); |
|
nMaxTall = Max( nMaxTall, nTall ); |
|
|
|
m_pCarryingBG->SetWide( nMaxWide + ( m_pCarryingLabel->GetXPos() * 2 ) ); |
|
m_pCarryingBG->SetTall( bHasOwner ? m_pCarryingOwnerLabel->GetYPos() + m_pCarryingOwnerLabel->GetTall() + YRES( 2 ) |
|
: m_pCarryingLabel->GetYPos() + m_pCarryingLabel->GetTall() + YRES( 2 ) ); |
|
} |
|
else |
|
{ |
|
bShowCarryingWeaponPanel = false; |
|
} |
|
} |
|
} |
|
else |
|
{ |
|
bShowCarryingWeaponPanel = false; |
|
} |
|
|
|
if ( CTFPlayerDestructionLogic::GetRobotDestructionLogic() && ( CTFPlayerDestructionLogic::GetRobotDestructionLogic()->GetType() == CTFPlayerDestructionLogic::TYPE_PLAYER_DESTRUCTION ) ) |
|
{ |
|
if ( pPlayer->HasTheFlag() ) |
|
{ |
|
bShowCarryingWeaponPanel = false; |
|
} |
|
} |
|
|
|
m_pCarryingWeaponPanel->SetVisible( bShowCarryingWeaponPanel ); |
|
} |
|
|
|
if ( m_bUsePlayerModel && m_pPlayerModelPanel ) |
|
{ |
|
bool bPlaySparks = false; |
|
int iKillStreak = pPlayer->m_Shared.GetStreak( CTFPlayerShared::kTFStreak_Kills ); |
|
if ( iKillStreak != m_nKillStreak && iKillStreak > 0 ) |
|
{ |
|
bPlaySparks = true; |
|
} |
|
m_nKillStreak = iKillStreak; |
|
m_pPlayerModelPanel->SetEyeGlowEffect( pPlayer->GetEyeGlowEffect(), pPlayer->GetEyeGlowColor( false ), pPlayer->GetEyeGlowColor( true ), bForceEyeUpdate, bPlaySparks ); |
|
} |
|
} |
|
|
|
static void HudPlayerClassUsePlayerModelDialogCallback( bool bConfirmed, void *pContext ) |
|
{ |
|
cl_hud_playerclass_use_playermodel.SetValue( bConfirmed ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFHudPlayerClass::UpdateModelPanel() |
|
{ |
|
if ( !m_bUsePlayerModel ) |
|
{ |
|
return; |
|
} |
|
|
|
C_TFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer(); |
|
if ( !pPlayer || !pPlayer->IsAlive() ) |
|
{ |
|
return; |
|
} |
|
|
|
if ( !cl_hud_playerclass_playermodel_showed_confirm_dialog.GetBool() ) |
|
{ |
|
// only show this message one time |
|
ShowConfirmDialog( "#GameUI_HudPlayerClassUsePlayerModelDialogTitle", |
|
"#GameUI_HudPlayerClassUsePlayerModelDialogMessage", |
|
"#GameUI_HudPlayerClassUsePlayerModelDialogConfirm", |
|
"#GameUI_HudPlayerClassUsePlayerModelDialogCancel", |
|
&HudPlayerClassUsePlayerModelDialogCallback ); |
|
cl_hud_playerclass_playermodel_showed_confirm_dialog.SetValue( true ); |
|
} |
|
|
|
// hide old UI |
|
if ( m_pSpyImage ) |
|
m_pSpyImage->SetVisible( false ); |
|
if ( m_pClassImage ) |
|
m_pClassImage->SetVisible( false ); |
|
if ( m_pClassImageBG ) |
|
m_pClassImageBG->SetVisible( false ); |
|
|
|
if ( m_pPlayerModelPanel && m_pPlayerModelPanel->IsVisible() ) |
|
{ |
|
int nClass; |
|
int nTeam; |
|
int nItemSlot = m_nLoadoutPosition; |
|
CEconItemView *pWeapon = NULL; |
|
|
|
bool bDisguised = pPlayer->m_Shared.InCond( TF_COND_DISGUISED ); |
|
if ( bDisguised ) |
|
{ |
|
nClass = pPlayer->m_Shared.GetDisguiseClass(); |
|
nTeam = pPlayer->m_Shared.GetDisguiseTeam(); |
|
|
|
if ( pPlayer->m_Shared.GetDisguiseWeapon() ) |
|
{ |
|
CAttributeContainer *pCont = pPlayer->m_Shared.GetDisguiseWeapon()->GetAttributeContainer(); |
|
pWeapon = pCont ? pCont->GetItem() : NULL; |
|
if ( pWeapon ) |
|
{ |
|
nItemSlot = pWeapon->GetStaticData()->GetLoadoutSlot( nClass ); |
|
} |
|
} |
|
} |
|
else |
|
{ |
|
nClass = pPlayer->GetPlayerClass()->GetClassIndex(); |
|
nTeam = pPlayer->GetTeamNumber(); |
|
|
|
CTFWeaponBase *pEnt = dynamic_cast< CTFWeaponBase* >( pPlayer->GetEntityForLoadoutSlot( nItemSlot ) ); |
|
if ( pEnt ) |
|
{ |
|
pWeapon = pEnt->GetAttributeContainer()->GetItem(); |
|
} |
|
} |
|
|
|
bool bIsRobot = false; |
|
int iRobot = 0; |
|
CALL_ATTRIB_HOOK_INT_ON_OTHER( pPlayer, iRobot, appear_as_mvm_robot ); |
|
bIsRobot = iRobot ? true : false; |
|
|
|
m_pPlayerModelPanel->ClearCarriedItems(); |
|
m_pPlayerModelPanel->SetToPlayerClass( nClass, bIsRobot ); |
|
m_pPlayerModelPanel->SetTeam( nTeam ); |
|
|
|
if ( pWeapon ) |
|
{ |
|
m_pPlayerModelPanel->AddCarriedItem( pWeapon ); |
|
} |
|
|
|
for ( int wbl = pPlayer->GetNumWearables()-1; wbl >= 0; wbl-- ) |
|
{ |
|
C_TFWearable *pItem = dynamic_cast<C_TFWearable*>( pPlayer->GetWearable( wbl ) ); |
|
if ( !pItem ) |
|
continue; |
|
|
|
if ( pItem->IsViewModelWearable() ) |
|
continue; |
|
|
|
if ( pItem->IsDisguiseWearable() && !bDisguised ) |
|
continue; |
|
|
|
if ( !pItem->IsDisguiseWearable() && bDisguised ) |
|
continue; |
|
|
|
CAttributeContainer *pCont = pItem->GetAttributeContainer(); |
|
CEconItemView *pEconItemView = pCont ? pCont->GetItem() : NULL; |
|
|
|
if ( pEconItemView && pEconItemView->IsValid() ) |
|
{ |
|
m_pPlayerModelPanel->AddCarriedItem( pEconItemView ); |
|
} |
|
} |
|
|
|
m_pPlayerModelPanel->HoldItemInSlot( nItemSlot ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFHudPlayerClass::FireGameEvent( IGameEvent * event ) |
|
{ |
|
const char* pszEventName = event->GetName(); |
|
|
|
if ( FStrEq( "localplayer_changedisguise", pszEventName ) ) |
|
{ |
|
if ( m_pSpyImage && m_pSpyOutlineImage ) |
|
{ |
|
bool bFadeIn = event->GetBool( "disguised", false ); |
|
|
|
if ( bFadeIn ) |
|
{ |
|
m_pSpyImage->SetAlpha( 0 ); |
|
} |
|
else |
|
{ |
|
m_pSpyImage->SetAlpha( 255 ); |
|
} |
|
|
|
m_pSpyOutlineImage->SetAlpha( 0 ); |
|
|
|
m_pSpyImage->SetVisible( true ); |
|
m_pSpyOutlineImage->SetVisible( true ); |
|
|
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( bFadeIn ? "HudSpyDisguiseFadeIn" : "HudSpyDisguiseFadeOut" ); |
|
} |
|
|
|
UpdateModelPanel(); |
|
} |
|
else if ( FStrEq( "post_inventory_application", pszEventName ) ) |
|
{ |
|
// Force a refresh. if this is for the local player |
|
int iUserID = event->GetInt( "userid" ); |
|
C_TFPlayer* pPlayer = ToTFPlayer( C_TFPlayer::GetLocalPlayer() ); |
|
if ( pPlayer && pPlayer->GetUserID() == iUserID ) |
|
{ |
|
UpdateModelPanel(); |
|
} |
|
} |
|
else if ( FStrEq( "localplayer_pickup_weapon", pszEventName ) ) |
|
{ |
|
UpdateModelPanel(); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CTFHealthPanel::CTFHealthPanel( Panel *parent, const char *name ) : vgui::Panel( parent, name ) |
|
{ |
|
m_flHealth = 1.0f; |
|
|
|
m_iMaterialIndex = surface()->DrawGetTextureId( "hud/health_color" ); |
|
if ( m_iMaterialIndex == -1 ) // we didn't find it, so create a new one |
|
{ |
|
m_iMaterialIndex = surface()->CreateNewTextureID(); |
|
surface()->DrawSetTextureFile( m_iMaterialIndex, "hud/health_color", true, false ); |
|
} |
|
|
|
m_iDeadMaterialIndex = surface()->DrawGetTextureId( "hud/health_dead" ); |
|
if ( m_iDeadMaterialIndex == -1 ) // we didn't find it, so create a new one |
|
{ |
|
m_iDeadMaterialIndex = surface()->CreateNewTextureID(); |
|
surface()->DrawSetTextureFile( m_iDeadMaterialIndex, "hud/health_dead", true, false ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFHealthPanel::Paint() |
|
{ |
|
BaseClass::Paint(); |
|
|
|
int x, y, w, h; |
|
GetBounds( x, y, w, h ); |
|
|
|
Vertex_t vert[4]; |
|
float uv1 = 0.0f; |
|
float uv2 = 1.0f; |
|
int xpos = 0, ypos = 0; |
|
|
|
if ( m_flHealth <= 0 ) |
|
{ |
|
// Draw the dead material |
|
surface()->DrawSetTexture( m_iDeadMaterialIndex ); |
|
|
|
vert[0].Init( Vector2D( xpos, ypos ), Vector2D( uv1, uv1 ) ); |
|
vert[1].Init( Vector2D( xpos + w, ypos ), Vector2D( uv2, uv1 ) ); |
|
vert[2].Init( Vector2D( xpos + w, ypos + h ), Vector2D( uv2, uv2 ) ); |
|
vert[3].Init( Vector2D( xpos, ypos + h ), Vector2D( uv1, uv2 ) ); |
|
|
|
surface()->DrawSetColor( Color(255,255,255,255) ); |
|
} |
|
else |
|
{ |
|
float flDamageY = h * ( 1.0f - m_flHealth ); |
|
|
|
// blend in the red "damage" part |
|
surface()->DrawSetTexture( m_iMaterialIndex ); |
|
|
|
Vector2D uv11( uv1, uv2 - m_flHealth ); |
|
Vector2D uv21( uv2, uv2 - m_flHealth ); |
|
Vector2D uv22( uv2, uv2 ); |
|
Vector2D uv12( uv1, uv2 ); |
|
|
|
vert[0].Init( Vector2D( xpos, flDamageY ), uv11 ); |
|
vert[1].Init( Vector2D( xpos + w, flDamageY ), uv21 ); |
|
vert[2].Init( Vector2D( xpos + w, ypos + h ), uv22 ); |
|
vert[3].Init( Vector2D( xpos, ypos + h ), uv12 ); |
|
|
|
surface()->DrawSetColor( GetFgColor() ); |
|
} |
|
|
|
surface()->DrawTexturedPolygon( 4, vert ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CTFHudPlayerHealth::CTFHudPlayerHealth( Panel *parent, const char *name ) : EditablePanel( parent, name ) |
|
{ |
|
m_pHealthImage = new CTFHealthPanel( this, "PlayerStatusHealthImage" ); |
|
m_pHealthImageBG = new ImagePanel( this, "PlayerStatusHealthImageBG" ); |
|
m_pHealthBonusImage = new ImagePanel( this, "PlayerStatusHealthBonusImage" ); |
|
m_pBuildingHealthImageBG = new ImagePanel( this, "BuildingStatusHealthImageBG" ); |
|
m_pBleedImage = new ImagePanel( this, "PlayerStatusBleedImage" ); |
|
m_pHookBleedImage = new ImagePanel( this, "PlayerStatusHookBleedImage" ); |
|
m_pMarkedForDeathImage = new ImagePanel( this, "PlayerStatusMarkedForDeathImage" ); |
|
m_pMarkedForDeathImageSilent = new ImagePanel( this, "PlayerStatusMarkedForDeathSilentImage" ); |
|
m_pMilkImage = new ImagePanel( this, "PlayerStatusMilkImage" ); |
|
|
|
m_pWheelOfDoomImage = new ImagePanel( this, "PlayerStatus_WheelOfDoom" ); |
|
|
|
m_flNextThink = 0.0f; |
|
|
|
m_nBonusHealthOrigX = -1; |
|
m_nBonusHealthOrigY = -1; |
|
m_nBonusHealthOrigW = -1; |
|
m_nBonusHealthOrigH = -1; |
|
|
|
// Vaccinator |
|
m_vecBuffInfo.AddToTail( new CTFBuffInfo( TF_COND_MEDIGUN_UBER_BULLET_RESIST, BUFF_CLASS_BULLET_RESIST, new ImagePanel( this, "PlayerStatus_MedicUberBulletResistImage" ), "../HUD/defense_buff_bullet_blue", "../HUD/defense_buff_bullet_red" ) ); |
|
m_vecBuffInfo.AddToTail( new CTFBuffInfo( TF_COND_MEDIGUN_UBER_BLAST_RESIST, BUFF_CLASS_BLAST_RESIST, new ImagePanel( this, "PlayerStatus_MedicUberBlastResistImage" ), "../HUD/defense_buff_explosion_blue", "../HUD/defense_buff_explosion_red" ) ); |
|
m_vecBuffInfo.AddToTail( new CTFBuffInfo( TF_COND_MEDIGUN_UBER_FIRE_RESIST, BUFF_CLASS_FIRE_RESIST, new ImagePanel( this, "PlayerStatus_MedicUberFireResistImage" ), "../HUD/defense_buff_fire_blue", "../HUD/defense_buff_fire_red" ) ); |
|
m_vecBuffInfo.AddToTail( new CTFBuffInfo( TF_COND_MEDIGUN_SMALL_BULLET_RESIST, BUFF_CLASS_BULLET_RESIST, new ImagePanel( this, "PlayerStatus_MedicSmallBulletResistImage" ), "../HUD/defense_buff_bullet_blue", "../HUD/defense_buff_bullet_red" ) ); |
|
m_vecBuffInfo.AddToTail( new CTFBuffInfo( TF_COND_MEDIGUN_SMALL_BLAST_RESIST, BUFF_CLASS_BLAST_RESIST, new ImagePanel( this, "PlayerStatus_MedicSmallBlastResistImage" ), "../HUD/defense_buff_explosion_blue", "../HUD/defense_buff_explosion_red" ) ); |
|
m_vecBuffInfo.AddToTail( new CTFBuffInfo( TF_COND_MEDIGUN_SMALL_FIRE_RESIST, BUFF_CLASS_FIRE_RESIST, new ImagePanel( this, "PlayerStatus_MedicSmallFireResistImage" ), "../HUD/defense_buff_fire_blue", "../HUD/defense_buff_fire_red" ) ); |
|
// Soldier buffs |
|
m_vecBuffInfo.AddToTail( new CTFBuffInfo( TF_COND_OFFENSEBUFF, BUFF_CLASS_SOLDIER_OFFENSE, new ImagePanel( this, "PlayerStatus_SoldierOffenseBuff" ), "../Effects/soldier_buff_offense_blue", "../Effects/soldier_buff_offense_red" ) ); |
|
m_vecBuffInfo.AddToTail( new CTFBuffInfo( TF_COND_DEFENSEBUFF, BUFF_CLASS_SOLDIER_DEFENSE, new ImagePanel( this, "PlayerStatus_SoldierDefenseBuff" ), "../Effects/soldier_buff_defense_blue", "../Effects/soldier_buff_defense_red" ) ); |
|
m_vecBuffInfo.AddToTail( new CTFBuffInfo( TF_COND_REGENONDAMAGEBUFF, BUFF_CLASS_SOLDIER_HEALTHONHIT, new ImagePanel( this, "PlayerStatus_SoldierHealOnHitBuff" ), "../Effects/soldier_buff_healonhit_blue", "../Effects/soldier_buff_healonhit_red" ) ); |
|
// Powerup Rune status |
|
m_vecBuffInfo.AddToTail( new CTFBuffInfo( TF_COND_RUNE_STRENGTH, RUNE_CLASS_STRENGTH, new ImagePanel( this, "PlayerStatus_RuneStrength" ), "../Effects/powerup_strength_hud", "../Effects/powerup_strength_hud" ) ); |
|
m_vecBuffInfo.AddToTail( new CTFBuffInfo( TF_COND_RUNE_HASTE, RUNE_CLASS_HASTE, new ImagePanel( this, "PlayerStatus_RuneHaste" ), "../Effects/powerup_haste_hud", "../Effects/powerup_haste_hud" ) ); |
|
m_vecBuffInfo.AddToTail( new CTFBuffInfo( TF_COND_RUNE_REGEN, RUNE_CLASS_REGEN, new ImagePanel( this, "PlayerStatus_RuneRegen" ), "../Effects/powerup_regen_hud", "../Effects/powerup_regen_hud" ) ); |
|
m_vecBuffInfo.AddToTail( new CTFBuffInfo( TF_COND_RUNE_RESIST, RUNE_CLASS_RESIST, new ImagePanel( this, "PlayerStatus_RuneResist" ), "../Effects/powerup_resist_hud", "../Effects/powerup_resist_hud" ) ); |
|
m_vecBuffInfo.AddToTail( new CTFBuffInfo( TF_COND_RUNE_VAMPIRE, RUNE_CLASS_VAMPIRE, new ImagePanel( this, "PlayerStatus_RuneVampire" ), "../Effects/powerup_vampire_hud", "../Effects/powerup_vampire_hud" ) ); |
|
m_vecBuffInfo.AddToTail( new CTFBuffInfo( TF_COND_RUNE_REFLECT, RUNE_CLASS_REFLECT, new ImagePanel( this, "PlayerStatus_RuneReflect" ), "../Effects/powerup_reflect_hud", "../Effects/powerup_reflect_hud" ) ); |
|
m_vecBuffInfo.AddToTail( new CTFBuffInfo( TF_COND_RUNE_PRECISION, RUNE_CLASS_PRECISION, new ImagePanel( this, "PlayerStatus_RunePrecision" ), "../Effects/powerup_precision_hud", "../Effects/powerup_precision_hud" ) ); |
|
m_vecBuffInfo.AddToTail( new CTFBuffInfo( TF_COND_RUNE_AGILITY, RUNE_CLASS_AGILITY, new ImagePanel( this, "PlayerStatus_RuneAgility" ), "../Effects/powerup_agility_hud", "../Effects/powerup_agility_hud" ) ); |
|
m_vecBuffInfo.AddToTail( new CTFBuffInfo( TF_COND_RUNE_KNOCKOUT, RUNE_CLASS_KNOCKOUT, new ImagePanel( this, "PlayerStatus_RuneKnockout" ), "../Effects/powerup_knockout_hud", "../Effects/powerup_knockout_hud" ) ); |
|
m_vecBuffInfo.AddToTail( new CTFBuffInfo( TF_COND_RUNE_KING, RUNE_CLASS_KING, new ImagePanel( this, "PlayerStatus_RuneKing" ), "../Effects/powerup_king_hud", "../Effects/powerup_king_hud" ) ); |
|
m_vecBuffInfo.AddToTail( new CTFBuffInfo( TF_COND_RUNE_PLAGUE, RUNE_CLASS_PLAGUE, new ImagePanel( this, "PlayerStatus_RunePlague" ), "../Effects/powerup_plague_hud", "../Effects/powerup_plague_hud" ) ); |
|
m_vecBuffInfo.AddToTail( new CTFBuffInfo( TF_COND_RUNE_SUPERNOVA, RUNE_CLASS_SUPERNOVA, new ImagePanel( this, "PlayerStatus_RuneSupernova" ), "../Effects/powerup_supernova_hud", "../Effects/powerup_supernova_hud" ) ); |
|
#ifdef STAGING_ONLY |
|
// Spy Mark |
|
m_vecBuffInfo.AddToTail( new CTFBuffInfo( TF_COND_TRANQ_MARKED, DEBUFF_CLASS_SPY_MARKED, new ImagePanel( this, "PlayerStatus_SpyMarked" ), "../Effects/tranq_debuff", "../Effects/tranq_debuff" ) ); |
|
#endif // STAGING_ONLY |
|
|
|
// Parachute |
|
m_vecBuffInfo.AddToTail( new CTFBuffInfo( TF_COND_PARACHUTE_DEPLOYED, BUFF_CLASS_PARACHUTE, new ImagePanel( this, "PlayerStatus_Parachute" ), "../HUD/hud_parachute_active", "../HUD/hud_parachute_active" ) ); |
|
|
|
m_iAnimState = HUD_HEALTH_NO_ANIM; |
|
m_bAnimate = true; |
|
} |
|
|
|
CTFHudPlayerHealth::~CTFHudPlayerHealth() |
|
{ |
|
m_vecBuffInfo.PurgeAndDeleteElements(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFHudPlayerHealth::Reset() |
|
{ |
|
m_flNextThink = gpGlobals->curtime + 0.05f; |
|
m_nHealth = -1; |
|
m_bBuilding = false; |
|
|
|
m_iAnimState = HUD_HEALTH_NO_ANIM; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFHudPlayerHealth::ApplySchemeSettings( IScheme *pScheme ) |
|
{ |
|
// load control settings... |
|
LoadControlSettings( GetResFilename() ); |
|
|
|
if ( m_pHealthBonusImage ) |
|
{ |
|
m_pHealthBonusImage->GetBounds( m_nBonusHealthOrigX, m_nBonusHealthOrigY, m_nBonusHealthOrigW, m_nBonusHealthOrigH ); |
|
} |
|
|
|
m_flNextThink = 0.0f; |
|
|
|
BaseClass::ApplySchemeSettings( pScheme ); |
|
|
|
m_pBuildingHealthImageBG->SetVisible( m_bBuilding ); |
|
|
|
m_pPlayerLevelLabel = dynamic_cast<CExLabel*>( FindChildByName( "PlayerStatusPlayerLevel" ) ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFHudPlayerHealth::SetHealth( int iNewHealth, int iMaxHealth, int iMaxBuffedHealth ) |
|
{ |
|
// set our health |
|
m_nHealth = iNewHealth; |
|
m_nMaxHealth = iMaxHealth; |
|
m_pHealthImage->SetHealth( (float)(m_nHealth) / (float)(m_nMaxHealth) ); |
|
|
|
if ( m_pHealthImage ) |
|
{ |
|
m_pHealthImage->SetFgColor( Color( 255, 255, 255, 255 ) ); |
|
} |
|
|
|
if ( m_nHealth <= 0 ) |
|
{ |
|
if ( m_pHealthImageBG->IsVisible() ) |
|
{ |
|
m_pHealthImageBG->SetVisible( false ); |
|
} |
|
if ( m_pBuildingHealthImageBG->IsVisible() ) |
|
{ |
|
m_pBuildingHealthImageBG->SetVisible( false ); |
|
} |
|
HideHealthBonusImage(); |
|
} |
|
else |
|
{ |
|
if ( !m_pHealthImageBG->IsVisible() ) |
|
{ |
|
m_pHealthImageBG->SetVisible( true ); |
|
} |
|
m_pBuildingHealthImageBG->SetVisible( m_bBuilding ); |
|
|
|
// are we getting a health bonus? |
|
if ( m_nHealth > m_nMaxHealth ) |
|
{ |
|
if ( m_pHealthBonusImage && m_nBonusHealthOrigW != -1 ) |
|
{ |
|
if ( !m_pHealthBonusImage->IsVisible() ) |
|
{ |
|
m_pHealthBonusImage->SetVisible( true ); |
|
} |
|
|
|
if ( m_bAnimate && m_iAnimState != HUD_HEALTH_BONUS_ANIM ) |
|
{ |
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, "HudHealthDyingPulseStop" ); |
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, "HudHealthBonusPulse" ); |
|
|
|
m_iAnimState = HUD_HEALTH_BONUS_ANIM; |
|
} |
|
|
|
m_pHealthBonusImage->SetDrawColor( Color( 255, 255, 255, 255 ) ); |
|
|
|
// scale the flashing image based on how much health bonus we currently have |
|
float flBoostMaxAmount = ( iMaxBuffedHealth ) - m_nMaxHealth; |
|
float flPercent = MIN( ( m_nHealth - m_nMaxHealth ) / flBoostMaxAmount, 1.0f ); |
|
|
|
int nPosAdj = RoundFloatToInt( flPercent * m_nHealthBonusPosAdj ); |
|
int nSizeAdj = 2 * nPosAdj; |
|
|
|
m_pHealthBonusImage->SetBounds( m_nBonusHealthOrigX - nPosAdj, |
|
m_nBonusHealthOrigY - nPosAdj, |
|
m_nBonusHealthOrigW + nSizeAdj, |
|
m_nBonusHealthOrigH + nSizeAdj ); |
|
} |
|
} |
|
// are we close to dying? |
|
else if ( m_nHealth < m_nMaxHealth * m_flHealthDeathWarning ) |
|
{ |
|
if ( m_pHealthBonusImage && m_nBonusHealthOrigW != -1 ) |
|
{ |
|
if ( !m_pHealthBonusImage->IsVisible() ) |
|
{ |
|
m_pHealthBonusImage->SetVisible( true ); |
|
} |
|
|
|
if ( m_bAnimate && m_iAnimState != HUD_HEALTH_DYING_ANIM ) |
|
{ |
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, "HudHealthBonusPulseStop" ); |
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, "HudHealthDyingPulse" ); |
|
|
|
m_iAnimState = HUD_HEALTH_DYING_ANIM; |
|
} |
|
|
|
m_pHealthBonusImage->SetDrawColor( m_clrHealthDeathWarningColor ); |
|
|
|
// scale the flashing image based on how much health bonus we currently have |
|
float flBoostMaxAmount = m_nMaxHealth * m_flHealthDeathWarning; |
|
float flPercent = ( flBoostMaxAmount - m_nHealth ) / flBoostMaxAmount; |
|
|
|
int nPosAdj = RoundFloatToInt( flPercent * m_nHealthBonusPosAdj ); |
|
int nSizeAdj = 2 * nPosAdj; |
|
|
|
m_pHealthBonusImage->SetBounds( m_nBonusHealthOrigX - nPosAdj, |
|
m_nBonusHealthOrigY - nPosAdj, |
|
m_nBonusHealthOrigW + nSizeAdj, |
|
m_nBonusHealthOrigH + nSizeAdj ); |
|
} |
|
|
|
if ( m_pHealthImage ) |
|
{ |
|
m_pHealthImage->SetFgColor( m_clrHealthDeathWarningColor ); |
|
} |
|
} |
|
// turn it off |
|
else |
|
{ |
|
HideHealthBonusImage(); |
|
} |
|
} |
|
|
|
// set our health display value |
|
if ( m_nHealth > 0 ) |
|
{ |
|
SetDialogVariable( "Health", m_nHealth ); |
|
} |
|
else |
|
{ |
|
SetDialogVariable( "Health", "" ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFHudPlayerHealth::SetLevel( int nLevel ) |
|
{ |
|
if ( m_pPlayerLevelLabel ) |
|
{ |
|
bool bVisible = ( nLevel >= 0 ) ? true : false; |
|
if ( bVisible ) |
|
{ |
|
m_pPlayerLevelLabel->SetText( CFmtStr( "%d", nLevel ) ); |
|
} |
|
|
|
if ( m_pPlayerLevelLabel->IsVisible() != bVisible ) |
|
{ |
|
m_pPlayerLevelLabel->SetVisible( bVisible ); |
|
} |
|
} |
|
}; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFHudPlayerHealth::HideHealthBonusImage( void ) |
|
{ |
|
if ( m_pHealthBonusImage && m_pHealthBonusImage->IsVisible() ) |
|
{ |
|
if ( m_nBonusHealthOrigW != -1 ) |
|
{ |
|
m_pHealthBonusImage->SetBounds( m_nBonusHealthOrigX, m_nBonusHealthOrigY, m_nBonusHealthOrigW, m_nBonusHealthOrigH ); |
|
} |
|
m_pHealthBonusImage->SetVisible( false ); |
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, "HudHealthBonusPulseStop" ); |
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, "HudHealthDyingPulseStop" ); |
|
|
|
m_iAnimState = HUD_HEALTH_NO_ANIM; |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
static void SetPlayerHealthImagePanelVisibility( CTFPlayer *pPlayer, ETFCond eCond, vgui::ImagePanel *pImagePanel, int& nXOffset, const Color& colorIfVisible ) |
|
{ |
|
Assert( pImagePanel != NULL ); |
|
|
|
if ( pPlayer->m_Shared.InCond( eCond ) && !pImagePanel->IsVisible() ) |
|
{ |
|
pImagePanel->SetVisible( true ); |
|
pImagePanel->SetDrawColor( colorIfVisible ); |
|
|
|
// Reposition ourselves and increase the offset if we are active |
|
int x,y; |
|
pImagePanel->GetPos( x, y ); |
|
pImagePanel->SetPos( nXOffset, y ); |
|
nXOffset += 100.f; |
|
} |
|
} |
|
|
|
void CTFBuffInfo::Update( CTFPlayer *pPlayer ) |
|
{ |
|
Assert( m_pImagePanel != NULL && pPlayer != NULL ); |
|
|
|
if ( pPlayer->m_Shared.InCond( m_eCond ) ) |
|
{ |
|
if( m_pzsBlueImage && m_pzsBlueImage[0] && m_pzsRedImage && m_pzsRedImage[0] ) |
|
{ |
|
if( pPlayer->GetTeamNumber() == TF_TEAM_BLUE ) |
|
m_pImagePanel->SetImage( m_pzsBlueImage ); |
|
else |
|
m_pImagePanel->SetImage( m_pzsRedImage ); |
|
} |
|
} |
|
} |
|
|
|
void CTFHudPlayerHealth::OnThink() |
|
{ |
|
if ( m_flNextThink < gpGlobals->curtime ) |
|
{ |
|
C_TFPlayer *pPlayer = ToTFPlayer( C_BasePlayer::GetLocalPlayer() ); |
|
|
|
if ( pPlayer ) |
|
{ |
|
SetHealth( pPlayer->GetHealth(), pPlayer->GetMaxHealth(), pPlayer->m_Shared.GetMaxBuffedHealth() ); |
|
|
|
int color_offset = ((int)(gpGlobals->realtime*10)) % 5; |
|
int color_fade = 160 + (color_offset*10); |
|
|
|
// Find our starting point, just above the health '+' |
|
int nXOffset,y; |
|
m_pHealthImage->GetPos( nXOffset, y ); |
|
// Nudge over a bit to get centered |
|
nXOffset += 25; |
|
|
|
// Turn all the panels off, and below conditionally turn them on |
|
FOR_EACH_VEC( m_vecBuffInfo, i ) |
|
{ |
|
m_vecBuffInfo[ i ]->m_pImagePanel->SetVisible( false ); |
|
} |
|
|
|
CUtlVector<BuffClass_t> m_vecActiveClasses; |
|
// Cycle through all the buffs and update them |
|
FOR_EACH_VEC( m_vecBuffInfo, i ) |
|
{ |
|
// Skip if this class of buff is already being drawn |
|
if( m_vecActiveClasses.Find( m_vecBuffInfo[i]->m_eClass ) != m_vecActiveClasses.InvalidIndex() ) |
|
continue; |
|
|
|
m_vecBuffInfo[i]->Update( pPlayer ); |
|
SetPlayerHealthImagePanelVisibility( pPlayer, m_vecBuffInfo[i]->m_eCond, m_vecBuffInfo[i]->m_pImagePanel, nXOffset, Color( 255, 255, 255, color_fade ) ); |
|
|
|
// This class of buff is now active. |
|
if( m_vecBuffInfo[i]->m_pImagePanel->IsVisible() ) |
|
{ |
|
m_vecActiveClasses.AddToTail( m_vecBuffInfo[i]->m_eClass ); |
|
} |
|
} |
|
|
|
// Turn all the panels off, and below conditionally turn them on |
|
m_pBleedImage->SetVisible( false ); |
|
m_pHookBleedImage->SetVisible( false ); |
|
m_pMilkImage->SetVisible( false ); |
|
m_pMarkedForDeathImage->SetVisible( false ); |
|
m_pMarkedForDeathImageSilent->SetVisible( false ); |
|
|
|
// Old method for goofy color manipulation |
|
int nBloodX = nXOffset; |
|
SetPlayerHealthImagePanelVisibility( pPlayer, TF_COND_BLEEDING, m_pBleedImage, nXOffset, Color( color_fade, 0, 0, 255 ) ); |
|
SetPlayerHealthImagePanelVisibility( pPlayer, TF_COND_GRAPPLINGHOOK_BLEEDING, m_pHookBleedImage, nBloodX, Color( 255, 255, 255, 255 ) ); // draw this on top of bleeding |
|
SetPlayerHealthImagePanelVisibility( pPlayer, TF_COND_MAD_MILK, m_pMilkImage, nXOffset, Color( color_fade, color_fade, color_fade, 255 ) ); |
|
SetPlayerHealthImagePanelVisibility( pPlayer, TF_COND_MARKEDFORDEATH, m_pMarkedForDeathImage, nXOffset, Color( 255 - color_fade, 245 - color_fade, 245 - color_fade, 255 ) ); |
|
SetPlayerHealthImagePanelVisibility( pPlayer, TF_COND_MARKEDFORDEATH_SILENT, m_pMarkedForDeathImageSilent, nXOffset, Color( 125 - color_fade, 255 - color_fade, 255 - color_fade, 255 ) ); |
|
SetPlayerHealthImagePanelVisibility( pPlayer, TF_COND_PASSTIME_PENALTY_DEBUFF, m_pMarkedForDeathImageSilent, nXOffset, Color( 125 - color_fade, 255 - color_fade, 255 - color_fade, 255 ) ); |
|
|
|
UpdateHalloweenStatus(); |
|
} |
|
|
|
m_flNextThink = gpGlobals->curtime + 0.05f; |
|
} |
|
} |
|
|
|
|
|
void CTFHudPlayerHealth::UpdateHalloweenStatus( void ) |
|
{ |
|
if ( TFGameRules()->IsHalloweenEffectStatusActive() ) |
|
{ |
|
int status = TFGameRules()->GetHalloweenEffectStatus(); |
|
|
|
if ( status == EFFECT_WHAMMY ) |
|
{ |
|
m_pWheelOfDoomImage->SetImage( "..\\HUD\\death_wheel_whammy" ); |
|
} |
|
else |
|
{ |
|
m_pWheelOfDoomImage->SetImage( VarArgs( "..\\HUD\\death_wheel_%d", status - 1 ) ); |
|
|
|
} |
|
|
|
float timeLeft = TFGameRules()->GetHalloweenEffectTimeLeft(); |
|
|
|
const float warnExpireTime = 3.0f; |
|
const float blinkInterval = 0.25f; |
|
|
|
if ( timeLeft < warnExpireTime ) |
|
{ |
|
int blink = (int)( timeLeft / blinkInterval ); |
|
|
|
m_pWheelOfDoomImage->SetVisible( blink & 0x1 ); |
|
} |
|
else |
|
{ |
|
m_pWheelOfDoomImage->SetVisible( true ); |
|
} |
|
} |
|
else |
|
{ |
|
m_pWheelOfDoomImage->SetVisible( false ); |
|
} |
|
} |
|
|
|
|
|
DECLARE_HUDELEMENT( CTFHudPlayerStatus ); |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CTFHudPlayerStatus::CTFHudPlayerStatus( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudPlayerStatus" ) |
|
{ |
|
Panel *pParent = g_pClientMode->GetViewport(); |
|
SetParent( pParent ); |
|
|
|
m_pHudPlayerClass = new CTFHudPlayerClass( this, "HudPlayerClass" ); |
|
m_pHudPlayerHealth = new CTFHudPlayerHealth( this, "HudPlayerHealth" ); |
|
|
|
SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFHudPlayerStatus::ApplySchemeSettings( IScheme *pScheme ) |
|
{ |
|
BaseClass::ApplySchemeSettings( pScheme ); |
|
|
|
// HACK: Work around the scheme application order failing |
|
// to reload the player class hud element's scheme in minmode. |
|
static ConVarRef cl_hud_minmode( "cl_hud_minmode", true ); |
|
if ( cl_hud_minmode.IsValid() && cl_hud_minmode.GetBool() ) |
|
{ |
|
m_pHudPlayerClass->InvalidateLayout( false, true ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
bool CTFHudPlayerStatus::ShouldDraw( void ) |
|
{ |
|
CTFPlayer *pTFPlayer = CTFPlayer::GetLocalTFPlayer(); |
|
if ( pTFPlayer && pTFPlayer->m_Shared.InCond( TF_COND_HALLOWEEN_GHOST_MODE ) ) |
|
return false; |
|
|
|
if ( CTFMinigameLogic::GetMinigameLogic() && CTFMinigameLogic::GetMinigameLogic()->GetActiveMinigame() ) |
|
return false; |
|
|
|
if ( TFGameRules() && TFGameRules()->ShowMatchSummary() ) |
|
return false; |
|
|
|
return CHudElement::ShouldDraw(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFHudPlayerStatus::Reset() |
|
{ |
|
if ( m_pHudPlayerClass ) |
|
{ |
|
m_pHudPlayerClass->Reset(); |
|
} |
|
|
|
if ( m_pHudPlayerHealth ) |
|
{ |
|
m_pHudPlayerHealth->Reset(); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFClassImage::SetClass( int iTeam, int iClass, int iCloakstate ) |
|
{ |
|
char szImage[128]; |
|
szImage[0] = '\0'; |
|
|
|
if ( iTeam == TF_TEAM_BLUE ) |
|
{ |
|
Q_strncpy( szImage, g_szBlueClassImages[ iClass ], sizeof(szImage) ); |
|
} |
|
else |
|
{ |
|
Q_strncpy( szImage, g_szRedClassImages[ iClass ], sizeof(szImage) ); |
|
} |
|
|
|
switch( iCloakstate ) |
|
{ |
|
case 2: |
|
Q_strncat( szImage, "_cloak", sizeof(szImage), COPY_ALL_CHARACTERS ); |
|
break; |
|
case 1: |
|
Q_strncat( szImage, "_halfcloak", sizeof(szImage), COPY_ALL_CHARACTERS ); |
|
break; |
|
default: |
|
break; |
|
} |
|
|
|
if ( Q_strlen( szImage ) > 0 ) |
|
{ |
|
SetImage( szImage ); |
|
} |
|
}
|
|
|