//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //============================================================================= #include "cbase.h" #include "hud.h" #include "hudelement.h" #include "c_tf_player.h" #include "iclientmode.h" #include "ienginevgui.h" #include #include #include #include #include #include "tf_spectatorgui.h" #include "hud_macros.h" #include "c_playerresource.h" #include "view.h" #include "player_vs_environment/c_tf_upgrades.h" #include "tf_hud_inspectpanel.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" DECLARE_HUDELEMENT( CHudInspectPanel ); static float s_flLastInspectDownTime = 0.f; void InspectDown() { C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer(); if ( pLocalPlayer == NULL ) { return; } s_flLastInspectDownTime = gpGlobals->curtime; KeyValues *kv = new KeyValues( "+inspect_server" ); engine->ServerCmdKeyValues( kv ); pLocalPlayer->SetInspectTime( gpGlobals->curtime ); } static ConCommand s_inspect_down_cmd( "+inspect", InspectDown, "", FCVAR_SERVER_CAN_EXECUTE ); void InspectUp() { C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer(); if ( pLocalPlayer == NULL ) { return; } // quick tap on the inspect button, try to inspect players if ( gpGlobals->curtime - s_flLastInspectDownTime <= 0.2f ) { CHudElement *pElement = gHUD.FindElement( "CHudInspectPanel" ); if ( pElement ) { ((CHudInspectPanel *)pElement)->UserCmd_InspectTarget(); } } KeyValues *kv = new KeyValues( "-inspect_server" ); engine->ServerCmdKeyValues( kv ); pLocalPlayer->SetInspectTime( 0.f ); } static ConCommand s_inspect_up_cmd( "-inspect", InspectUp, "", FCVAR_SERVER_CAN_EXECUTE ); //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- CHudInspectPanel::CHudInspectPanel( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudInspectPanel" ) { Panel *pParent = g_pClientMode->GetViewport(); SetParent( pParent ); SetHiddenBits( HIDEHUD_MISCSTATUS ); m_pItemPanel = new CItemModelPanel( this, "itempanel" ) ; m_iTargetItemIterator = 0; RegisterForRenderGroup( "mid" ); RegisterForRenderGroup( "commentary" ); RegisterForRenderGroup( "arena_target_id" ); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CHudInspectPanel::ApplySchemeSettings( IScheme *pScheme ) { // load control settings... LoadControlSettings( "resource/UI/HudInspectPanel.res" ); BaseClass::ApplySchemeSettings( pScheme ); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CHudInspectPanel::LockInspectRenderGroup( bool bLock ) { int iIndex = gHUD.LookupRenderGroupIndexByName( "inspect_panel" ); if ( bLock ) { gHUD.LockRenderGroup( iIndex ); } else { gHUD.UnlockRenderGroup( iIndex ); } } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- bool CHudInspectPanel::ShouldDraw( void ) { C_TFPlayer *pLocalTFPlayer = C_TFPlayer::GetLocalTFPlayer(); if ( !CHudElement::ShouldDraw() || !pLocalTFPlayer || !pLocalTFPlayer->IsAlive() ) { m_hTarget = NULL; SetPanelVisible( false ); return false; } return ( m_hTarget != NULL ); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CHudInspectPanel::UserCmd_InspectTarget( void ) { // If we're in observer mode, we cycle items on the current observer target C_TFPlayer *pLocalTFPlayer = C_TFPlayer::GetLocalTFPlayer(); if ( !pLocalTFPlayer ) return; C_TFPlayer *pTargetPlayer = GetInspectTarget( pLocalTFPlayer ); bool bVisible = false; if ( pLocalTFPlayer->IsObserver() ) { CTFSpectatorGUI *pPanel = (CTFSpectatorGUI*)gViewPortInterface->FindPanelByName( PANEL_SPECGUI ); if ( pPanel ) { pPanel->ForceItemPanelCycle(); } } // In MvM, display player upgrades else if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() ) { CHudUpgradePanel *pUpgradePanel = GET_HUDELEMENT( CHudUpgradePanel ); if ( pUpgradePanel ) { // Close if open if ( pUpgradePanel->IsVisible() ) { pUpgradePanel->OnCommand( "cancel" ); } // Inspect a player else if ( pTargetPlayer && ( pTargetPlayer->GetTeamNumber() != TF_TEAM_PVE_INVADERS ) ) { pUpgradePanel->InspectUpgradesForPlayer( pTargetPlayer ); } // Inspect self else if ( !pTargetPlayer && pLocalTFPlayer ) { pUpgradePanel->InspectUpgradesForPlayer( pLocalTFPlayer ); } } } else { if ( pTargetPlayer && !pTargetPlayer->IsEnemyPlayer() ) { m_hTarget = pTargetPlayer; CEconItemView *pItem = m_hTarget->GetInspectItem( &m_iTargetItemIterator ); if ( pItem && pItem->IsValid() ) { m_pItemPanel->SetDialogVariable( "killername", g_PR->GetPlayerName( m_hTarget->entindex() ) ); m_pItemPanel->SetItem( pItem ); // force update description to get the correct panel size m_pItemPanel->UpdateDescription(); bVisible = true; int x,y; GetPos( x, y ); SetPos( x, ScreenHeight() - YRES( 12 ) - m_pItemPanel->GetTall() ); } } else { m_iTargetItemIterator = 0; } } SetPanelVisible( bVisible ); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- C_TFPlayer *CHudInspectPanel::GetInspectTarget( C_TFPlayer *pLocalTFPlayer ) { if ( !pLocalTFPlayer ) return NULL; C_TFPlayer *pTargetPlayer = NULL; trace_t tr; Vector vecStart, vecEnd; VectorMA( MainViewOrigin(), MAX_TRACE_LENGTH, MainViewForward(), vecEnd ); VectorMA( MainViewOrigin(), 10, MainViewForward(), vecStart ); UTIL_TraceLine( vecStart, vecEnd, MASK_SOLID, pLocalTFPlayer, COLLISION_GROUP_NONE, &tr ); if ( !tr.startsolid && tr.DidHitNonWorldEntity() ) { C_BaseEntity *pEntity = tr.m_pEnt; if ( pEntity && ( pEntity != pLocalTFPlayer ) && pEntity->IsPlayer() ) { // Get the player under our crosshair pTargetPlayer = ToTFPlayer( pEntity ); // Fix up if it's a spy disguised as my team if ( pLocalTFPlayer->m_Shared.IsSpyDisguisedAsMyTeam( pTargetPlayer ) ) { // Get the player that the spy is disguised as C_TFPlayer *pDisguiseTarget = ToTFPlayer( pTargetPlayer->m_Shared.GetDisguiseTarget().Get() ); if ( pDisguiseTarget && pDisguiseTarget->GetPlayerClass()->GetClassIndex() == pTargetPlayer->m_Shared.GetDisguiseClass() ) { // The spy is disguised as the same class as the target, so inspect the disguise target instead pTargetPlayer = pDisguiseTarget; } } } } return pTargetPlayer; } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CHudInspectPanel::SetPanelVisible( bool bVisible ) { if ( m_pItemPanel->IsVisible() != bVisible ) { LockInspectRenderGroup( bVisible ); m_pItemPanel->SetVisible( bVisible ); } } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- int CHudInspectPanel::HudElementKeyInput( int down, ButtonCode_t keynum, const char *pszCurrentBinding ) { if ( IsVisible() && pszCurrentBinding && pszCurrentBinding[0] ) { if ( FStrEq( pszCurrentBinding, "+attack" ) ) { CBasePlayer *pLocalPlayer = CBasePlayer::GetLocalPlayer(); if ( pLocalPlayer && ( pLocalPlayer->GetTeamNumber() >= FIRST_GAME_TEAM ) && pLocalPlayer->IsAlive() ) { SetPanelVisible( false ); } } } return 1; // intentionally not handling the key }