summaryrefslogtreecommitdiff
path: root/game/client/tf2/c_tf_hints.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/tf2/c_tf_hints.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'game/client/tf2/c_tf_hints.cpp')
-rw-r--r--game/client/tf2/c_tf_hints.cpp1468
1 files changed, 1468 insertions, 0 deletions
diff --git a/game/client/tf2/c_tf_hints.cpp b/game/client/tf2/c_tf_hints.cpp
new file mode 100644
index 0000000..b12ff20
--- /dev/null
+++ b/game/client/tf2/c_tf_hints.cpp
@@ -0,0 +1,1468 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "c_tf_basehint.h"
+#include "tf_hints.h"
+#include "hintitemorderbase.h"
+#include "iclientmode.h"
+#include "clientmode_commander.h"
+#include "hud_technologytreedoc.h"
+#include "paneleffect.h"
+#include "techtree.h"
+#include "hintitemobjectbase.h"
+#include "c_order.h"
+#include "c_basetfplayer.h"
+#include "weapon_selection.h"
+#include <KeyValues.h>
+#include "c_weapon_builder.h"
+#include "VGuiMatSurface/IMatSystemSurface.h"
+#include "c_tf_hints.h"
+#include "c_hint_events.h"
+#include "c_tf_hintmanager.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+
+// Class Hierarchy
+// CHintItemBase -- base class for hint items
+// CHintItemOrderBase -- base class for hints derived from orders ( know how to draw
+// a white line from the hint to the order panel )
+// CHintItemObjectBase -- base class for hints that care about another object ( stores the object type name )
+// CHintGotoObject -- Contains logic that relates to the other object
+// CHintWaitBuilding
+// CHintChangeToCommander -- first level hint, doesn't rely on object, but does rely on UI manipulation
+// CHintChooseAnyTechnology -- doesn't try to draw line to order since it's in tactical view?
+//
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Change to commander view hint
+//-----------------------------------------------------------------------------
+class CHintChangeToCommander : public CHintItemOrderBase
+{
+ DECLARE_CLASS( CHintChangeToCommander, CHintItemOrderBase );
+
+public:
+ CHintChangeToCommander( vgui::Panel *parent, const char *panelName );
+ virtual void Think( void );
+};
+
+DECLARE_HINTITEMFACTORY( CHintChangeToCommander )
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *parent -
+// *panelName -
+// *text -
+// itemwidth -
+//-----------------------------------------------------------------------------
+CHintChangeToCommander::CHintChangeToCommander( vgui::Panel *parent, const char *panelName )
+: BaseClass( parent, panelName )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Set completed flag if we've made it to commander mode
+// Output : virtual void
+//-----------------------------------------------------------------------------
+void CHintChangeToCommander::Think( void )
+{
+ BaseClass::Think();
+
+ if ( g_pClientMode == ClientModeCommander() )
+ {
+ m_bCompleted = true;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class CHintGotoObject : public CHintItemObjectBase
+{
+ DECLARE_CLASS( CHintGotoObject, CHintItemObjectBase );
+
+public:
+ CHintGotoObject( vgui::Panel *parent, const char *panelName );
+ virtual void Think( void );
+
+private:
+ enum
+ {
+ MAX_OBJECT_TYPE = 128,
+ };
+
+ EFFECT_HANDLE m_ArrowEffect;
+
+ float m_flNextDistanceCheck;
+ IClientMode *m_pPreviousMode;
+};
+
+DECLARE_HINTITEMFACTORY( CHintGotoObject )
+
+#define ZONE_DISTANCE_CHECK_INTERVAL 0.5f
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *parent -
+// *panelName -
+//-----------------------------------------------------------------------------
+CHintGotoObject::CHintGotoObject( vgui::Panel *parent, const char *panelName )
+ : BaseClass( parent, panelName )
+{
+ m_ArrowEffect = CreateArrowEffect( this, parent, NULL );
+
+ m_flNextDistanceCheck = 0.0f;
+
+ m_pPreviousMode = NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHintGotoObject::Think( void )
+{
+ BaseClass::Think();
+
+ ClientModeTFBase *basemode = ( ClientModeTFBase * )g_pClientMode;
+ CMinimapPanel *minimap = basemode->GetMinimap();
+
+ CPanelEffect *e = g_pTF2RootPanel->FindEffect( m_ArrowEffect );
+ if ( e && minimap )
+ {
+ e->SetPanelOther( minimap );
+ }
+
+ // Check right away if we switch modes
+ if ( g_pClientMode != m_pPreviousMode )
+ {
+ m_flNextDistanceCheck = 0.0f;
+ m_pPreviousMode = g_pClientMode;
+ }
+
+ if ( gpGlobals->curtime < m_flNextDistanceCheck )
+ {
+ return;
+ }
+
+ m_flNextDistanceCheck = gpGlobals->curtime + ZONE_DISTANCE_CHECK_INTERVAL;
+
+ // The order contains the resource zone target
+ C_TFBaseHint *hint = static_cast< C_TFBaseHint * >( GetParent() );
+ if ( hint )
+ {
+ C_Order *order = dynamic_cast< C_Order * >( ClientEntityList().GetEnt( hint->GetEntity() ) );
+ if ( order )
+ {
+ C_BaseEntity *pTarget = ClientEntityList().GetEnt( order->GetTarget() );
+ if ( IsObjectOfType( pTarget ) )
+ {
+ Vector zonecenter = pTarget->WorldSpaceCenter( );
+
+ if ( e && minimap )
+ {
+ float mapx, mapy;
+
+ // Convert target center to map position
+ CMinimapPanel::MinimapPanel()->WorldToMinimap( MINIMAP_CLIP, zonecenter, mapx, mapy );
+
+ e->SetUsingOffset( true, (int)mapx, (int)mapy );
+ }
+
+ Vector delta;
+
+ C_BaseTFPlayer *local = C_BaseTFPlayer::GetLocalPlayer();
+ if ( local )
+ {
+ delta = local->GetAbsOrigin() - zonecenter;
+ if ( delta.Length() < 256.0f )
+ {
+ m_bCompleted = true;
+ }
+ }
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class CHintDeployWeapon : public CHintItemOrderBase
+{
+ DECLARE_CLASS( CHintDeployWeapon, CHintItemOrderBase );
+
+public:
+ CHintDeployWeapon( vgui::Panel *parent, const char *panelName );
+
+ virtual void Think( void );
+
+ virtual void SetWeaponType( const char *type );
+ virtual char const *GetWeaponType( void );
+
+ virtual char const *GetKeyName( void );
+
+ virtual void SetPrintName( const char *name );
+ virtual char const *GetPrintName( void );
+
+ virtual void ParseItem( KeyValues *pKeyValues );
+
+ virtual bool CheckKeyAndValue( const char *instring, int* keylength, const char **ppOutstring );
+
+private:
+ enum
+ {
+ MAX_WEAPON_TYPE = 128,
+ MAX_WEAPON_NAME = 128,
+ };
+
+ char m_szWeaponType[ MAX_WEAPON_TYPE ];
+ char m_szPrintName[ MAX_WEAPON_NAME ];
+};
+
+DECLARE_HINTITEMFACTORY( CHintDeployWeapon )
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *parent -
+// *panelName -
+//-----------------------------------------------------------------------------
+CHintDeployWeapon::CHintDeployWeapon( vgui::Panel *parent, const char *panelName )
+: BaseClass( parent, panelName )
+{
+ SetWeaponType( "" );
+ SetPrintName( "" );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *instring -
+// keylength -
+// **ppOutstring -
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CHintDeployWeapon::CheckKeyAndValue( const char *instring, int* keylength, const char **ppOutstring )
+{
+ if ( !Q_strnicmp( instring, "keyname", strlen( "keyname" ) ) )
+ {
+ *keylength = strlen( "keyname" );
+ *ppOutstring = GetKeyName();
+ return true;
+ }
+ else if ( !Q_strnicmp( instring, "printname", strlen( "printname" ) ) )
+ {
+ *keylength = strlen( "printname" );
+ *ppOutstring = GetPrintName();
+ return true;
+ }
+
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *type -
+//-----------------------------------------------------------------------------
+void CHintDeployWeapon::SetWeaponType( const char *type )
+{
+ Q_strncpy( m_szWeaponType, type, MAX_WEAPON_TYPE );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : char const
+//-----------------------------------------------------------------------------
+const char *CHintDeployWeapon::GetWeaponType( void )
+{
+ return m_szWeaponType;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *name -
+//-----------------------------------------------------------------------------
+void CHintDeployWeapon::SetPrintName( const char *name )
+{
+ Q_strncpy( m_szPrintName, name, MAX_WEAPON_NAME );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : char const
+//-----------------------------------------------------------------------------
+const char *CHintDeployWeapon::GetPrintName( void )
+{
+ return m_szPrintName;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : char const
+//-----------------------------------------------------------------------------
+const char *CHintDeployWeapon::GetKeyName( void )
+{
+ static char keyname[ 128 ];
+
+ keyname[ 0 ] = 0;
+
+ CBaseHudWeaponSelection *pHudSelection = GetHudWeaponSelection();
+ if ( pHudSelection )
+ {
+ C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
+ if ( player )
+ {
+ for ( int slot = 0; slot < MAX_WEAPON_SLOTS; slot++ )
+ {
+ C_BaseCombatWeapon *weapon = pHudSelection->GetFirstPos( slot );
+ if ( !weapon )
+ continue;
+
+ if ( !stricmp( weapon->GetName(), GetWeaponType() ) )
+ {
+ Q_snprintf( keyname, sizeof( keyname ), GetKeyNameForBinding( VarArgs( "slot%i", slot + 1 ) ) );
+ break;
+ }
+ }
+ }
+ }
+
+ return keyname;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *pKeyValues -
+//-----------------------------------------------------------------------------
+void CHintDeployWeapon::ParseItem( KeyValues *pKeyValues )
+{
+ BaseClass::ParseItem( pKeyValues );
+
+ const char *type = pKeyValues->GetString( "weapon", "" );
+ if ( type )
+ {
+ SetWeaponType( type );
+ }
+
+ const char *printname = pKeyValues->GetString( "printname", "" );
+ if ( printname )
+ {
+ SetPrintName( printname );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHintDeployWeapon::Think( void )
+{
+ BaseClass::Think();
+
+ C_BaseTFPlayer *player = C_BaseTFPlayer::GetLocalPlayer();
+ if ( !player )
+ return;
+
+ // Get the weapon selection Hud Element
+ CBaseHudWeaponSelection *pHudSelection = GetHudWeaponSelection();
+ // Make sure it's not still active
+ if ( pHudSelection->IsActive() )
+ return;
+
+ C_BaseCombatWeapon *weapon = GetActiveWeapon();
+ if ( !weapon )
+ return;
+
+ if ( !stricmp( weapon->GetClientClass()->m_pNetworkName, "CWeaponBuilder" ) )
+ {
+ m_bCompleted = true;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class CHintStartPlacing : public CHintItemOrderBase
+{
+ DECLARE_CLASS( CHintStartPlacing, CHintItemOrderBase );
+
+public:
+ CHintStartPlacing( vgui::Panel *parent, const char *panelName );
+
+ virtual void Think( void );
+private:
+};
+
+DECLARE_HINTITEMFACTORY( CHintStartPlacing )
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *parent -
+// *panelName -
+//-----------------------------------------------------------------------------
+CHintStartPlacing::CHintStartPlacing( vgui::Panel *parent, const char *panelName )
+: BaseClass( parent, panelName )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHintStartPlacing::Think( void )
+{
+ BaseClass::Think();
+
+ C_WeaponBuilder *builder = dynamic_cast< C_WeaponBuilder * >( GetActiveWeapon() );
+ if ( builder && builder->IsPlacingObject() )
+ {
+ m_bCompleted = true;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class CHintStartBuilding : public CHintItemOrderBase
+{
+ DECLARE_CLASS( CHintStartBuilding, CHintItemOrderBase );
+
+public:
+ CHintStartBuilding( vgui::Panel *parent, const char *panelName );
+
+ virtual void Think( void );
+private:
+};
+
+DECLARE_HINTITEMFACTORY( CHintStartBuilding )
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *parent -
+// *panelName -
+//-----------------------------------------------------------------------------
+CHintStartBuilding::CHintStartBuilding( vgui::Panel *parent, const char *panelName )
+ : BaseClass( parent, panelName )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHintStartBuilding::Think( void )
+{
+ BaseClass::Think();
+
+ C_WeaponBuilder *builder = dynamic_cast< C_WeaponBuilder * >( GetActiveWeapon() );
+ if ( builder && builder->IsBuildingObject() )
+ {
+ m_bCompleted = true;
+ }
+}
+
+#define CHECK_FOR_BUILDING_INTERVAL 1.0f
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class CHintWaitBuilding : public CHintItemObjectBase
+{
+ DECLARE_CLASS( CHintWaitBuilding, CHintItemObjectBase );
+
+public:
+ CHintWaitBuilding( vgui::Panel *parent, const char *panelName );
+
+ virtual void Think( void );
+private:
+
+ float m_flNextCheck;
+};
+
+
+DECLARE_HINTITEMFACTORY( CHintWaitBuilding )
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *parent -
+// *panelName -
+//-----------------------------------------------------------------------------
+CHintWaitBuilding::CHintWaitBuilding( vgui::Panel *parent, const char *panelName )
+ : BaseClass( parent, panelName )
+{
+ m_flNextCheck = 0.0f;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHintWaitBuilding::Think( void )
+{
+ BaseClass::Think();
+
+ if ( !GetActive() )
+ return;
+
+ C_BaseTFPlayer *player = C_BaseTFPlayer::GetLocalPlayer();
+ if ( !player )
+ return;
+
+ if ( gpGlobals->curtime < m_flNextCheck )
+ return;
+
+ m_flNextCheck = gpGlobals->curtime + CHECK_FOR_BUILDING_INTERVAL;
+
+ // Find resource zone
+ ClientEntityHandle_t e = ClientEntityList().FirstHandle();
+ for ( ; e != ClientEntityList().InvalidHandle(); e = ClientEntityList().NextHandle( e ) )
+ {
+ C_BaseEntity *ent = C_BaseEntity::Instance( e );
+ if ( !ent )
+ continue;
+
+ if ( IsObjectOfType( ent ) )
+ {
+ C_BaseObject *obj = static_cast< C_BaseObject * >( ent );
+
+ Assert( obj );
+
+ if ( obj->GetTeamNumber() == player->GetTeamNumber() && obj->IsOwnedByLocalPlayer() )
+ {
+ m_bCompleted = true;
+ break;
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class CHintBuilderSelection : public CHintItemOrderBase
+{
+ DECLARE_CLASS( CHintBuilderSelection, CHintItemOrderBase );
+
+public:
+ CHintBuilderSelection( vgui::Panel *parent, const char *panelName );
+
+ virtual void Think( void );
+ virtual void SetSelection( const char *type );
+ virtual char const *GetSelection( void );
+
+ virtual void ParseItem( KeyValues *pKeyValues );
+
+ virtual bool CheckKeyAndValue( const char *instring, int* keylength, const char **ppOutstring );
+
+private:
+ enum
+ {
+ MAX_SELECTION_NAME = 128,
+ };
+
+ char m_szSelection[ MAX_SELECTION_NAME ];
+};
+
+DECLARE_HINTITEMFACTORY( CHintBuilderSelection )
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *parent -
+// *panelName -
+//-----------------------------------------------------------------------------
+CHintBuilderSelection::CHintBuilderSelection( vgui::Panel *parent, const char *panelName )
+ : BaseClass( parent, panelName )
+{
+ SetSelection( "" );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *instring -
+// keylength -
+// **ppOutstring -
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CHintBuilderSelection::CheckKeyAndValue( const char *instring, int* keylength, const char **ppOutstring )
+{
+ if ( !Q_strnicmp( instring, "selection", strlen( "selection" ) ) )
+ {
+ *keylength = strlen( "selection" );
+ *ppOutstring = GetSelection();
+ return true;
+ }
+
+ return BaseClass::CheckKeyAndValue( instring, keylength, ppOutstring );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *selection -
+//-----------------------------------------------------------------------------
+void CHintBuilderSelection::SetSelection( const char *selection )
+{
+ Q_strncpy( m_szSelection, selection, MAX_SELECTION_NAME );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : char const
+//-----------------------------------------------------------------------------
+const char *CHintBuilderSelection::GetSelection( void )
+{
+ return m_szSelection;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *pKeyValues -
+//-----------------------------------------------------------------------------
+void CHintBuilderSelection::ParseItem( KeyValues *pKeyValues )
+{
+ BaseClass::ParseItem( pKeyValues );
+
+ const char *selection = pKeyValues->GetString( "selection", "" );
+ if ( selection )
+ {
+ SetSelection( selection );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHintBuilderSelection::Think( void )
+{
+ BaseClass::Think();
+
+ C_BaseTFPlayer *player = C_BaseTFPlayer::GetLocalPlayer();
+ if ( !player )
+ return;
+
+ C_WeaponBuilder *builder = dynamic_cast< C_WeaponBuilder * >( GetActiveWeapon() );
+ if ( !builder )
+ return;
+
+ const char *selection = builder->GetCurrentSelectionObjectName();
+ if ( !selection )
+ return;
+
+ if ( !stricmp( selection, GetSelection() ) )
+ {
+ m_bCompleted = true;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class CHintBuilderStartAction : public CHintItemOrderBase
+{
+ DECLARE_CLASS( CHintBuilderStartAction, CHintItemOrderBase );
+
+public:
+ CHintBuilderStartAction( vgui::Panel *parent, const char *panelName );
+
+ virtual void Think( void );
+ virtual void SetAction( const char *type );
+ virtual char const *GetAction( void );
+
+ virtual void ParseItem( KeyValues *pKeyValues );
+
+ virtual bool CheckKeyAndValue( const char *instring, int* keylength, const char **ppOutstring );
+
+private:
+ enum
+ {
+ MAX_ACTION_NAME = 128,
+ };
+
+ char m_szAction[ MAX_ACTION_NAME ];
+};
+
+DECLARE_HINTITEMFACTORY( CHintBuilderStartAction )
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *parent -
+// *panelName -
+//-----------------------------------------------------------------------------
+CHintBuilderStartAction::CHintBuilderStartAction( vgui::Panel *parent, const char *panelName )
+ : BaseClass( parent, panelName )
+{
+ SetAction( "" );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *instring -
+// keylength -
+// **ppOutstring -
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CHintBuilderStartAction::CheckKeyAndValue( const char *instring, int* keylength, const char **ppOutstring )
+{
+ if ( !Q_strnicmp( instring, "action", strlen( "action" ) ) )
+ {
+ *keylength = strlen( "action" );
+ *ppOutstring = GetAction();
+ return true;
+ }
+
+ return BaseClass::CheckKeyAndValue( instring, keylength, ppOutstring );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *action -
+//-----------------------------------------------------------------------------
+void CHintBuilderStartAction::SetAction( const char *action )
+{
+ Q_strncpy( m_szAction, action, MAX_ACTION_NAME );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : char const
+//-----------------------------------------------------------------------------
+const char *CHintBuilderStartAction::GetAction( void )
+{
+ return m_szAction;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *pKeyValues -
+//-----------------------------------------------------------------------------
+void CHintBuilderStartAction::ParseItem( KeyValues *pKeyValues )
+{
+ BaseClass::ParseItem( pKeyValues );
+
+ const char *action = pKeyValues->GetString( "action", "" );
+ if ( action )
+ {
+ SetAction( action );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHintBuilderStartAction::Think( void )
+{
+ BaseClass::Think();
+
+ C_BaseTFPlayer *player = C_BaseTFPlayer::GetLocalPlayer();
+ if ( !player )
+ return;
+
+ C_WeaponBuilder *builder = dynamic_cast< C_WeaponBuilder * >( GetActiveWeapon() );
+ if ( !builder )
+ return;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: A fake hud element used to force the weapon hud element to draw when it's
+// not actually active
+//-----------------------------------------------------------------------------
+class CHudWeaponFlashHelper : public CHudElement, public vgui::Panel
+{
+ DECLARE_CLASS_SIMPLE( CHudWeaponFlashHelper, vgui::Panel );
+public:
+ CHudWeaponFlashHelper( const char *name );
+
+ virtual void Init( void );
+ virtual bool ShouldDraw( void );
+ virtual void Paint();
+ virtual void ApplySchemeSettings( vgui::IScheme *scheme );
+
+ // Associate a weapon
+ void SetFlashWeapon( C_BaseCombatWeapon *weapon );
+
+ // Start/stop flashing
+ void StartFlashing( void );
+ void StopFlashing( void );
+
+ // Get position of weapon icon
+ void GetWeaponIconBounds( C_BaseCombatWeapon *weapon, int& x, int& y, int& w, int& h );
+
+ // Is player using the regular weapon selection UI?
+ bool IsWeaponSelectionActive( void );
+
+private:
+
+ // Currently flashing
+ bool m_bFlashing;
+
+ // The weapon to highlight
+ EHANDLE m_hWeapon;
+
+ // The actual weapon selection hud element
+ CBaseHudWeaponSelection *m_pWeaponSelection;
+};
+
+DECLARE_HUDELEMENT( CHudWeaponFlashHelper )
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *name -
+//-----------------------------------------------------------------------------
+CHudWeaponFlashHelper::CHudWeaponFlashHelper( const char *name )
+ : CHudElement( name ), BaseClass( NULL, "HudWeaponFlashHelper" )
+{
+ vgui::Panel *pParent = g_pClientMode->GetViewport();
+ SetParent( pParent );
+
+ m_bFlashing = false;
+ m_pWeaponSelection = NULL;
+
+ SetHiddenBits( HIDEHUD_MISCSTATUS | HIDEHUD_PLAYERDEAD );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudWeaponFlashHelper::Init( void )
+{
+ CHudElement::Init();
+
+ m_pWeaponSelection = GetHudWeaponSelection();
+ Assert( m_pWeaponSelection );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CHudWeaponFlashHelper::ShouldDraw( void )
+{
+ return ( CHudElement::ShouldDraw() && m_bFlashing && m_pWeaponSelection );
+}
+
+void CHudWeaponFlashHelper::ApplySchemeSettings( vgui::IScheme *scheme )
+{
+ BaseClass::ApplySchemeSettings( scheme );
+
+ SetPaintBackgroundEnabled( false );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudWeaponFlashHelper::Paint()
+{
+ // Stop immediately if user starts to choose weapons
+ if ( m_pWeaponSelection->IsActive() )
+ {
+ StopFlashing();
+ return;
+ }
+
+ if ( g_pClientMode == ClientModeCommander() )
+ return;
+
+ C_BaseCombatWeapon *w = ( C_BaseCombatWeapon * )( (C_BaseEntity *)m_hWeapon );
+ if ( !w )
+ return;
+
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer )
+ return;
+
+ // Redo drawing of Weapon Menu
+ m_pWeaponSelection->DrawWList( pPlayer, w, true, EFFECT_R, EFFECT_G, EFFECT_B, EFFECT_A );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *weapon -
+//-----------------------------------------------------------------------------
+void CHudWeaponFlashHelper::SetFlashWeapon( C_BaseCombatWeapon *weapon )
+{
+ m_hWeapon = weapon;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudWeaponFlashHelper::StartFlashing( void )
+{
+ m_bFlashing = true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudWeaponFlashHelper::StopFlashing( void )
+{
+ m_bFlashing = false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *weapon -
+// x -
+// y -
+// w -
+// h -
+//-----------------------------------------------------------------------------
+void CHudWeaponFlashHelper::GetWeaponIconBounds( C_BaseCombatWeapon *weapon, int& x, int& y,int& w, int& h )
+{
+ x = y = w = h = 0;
+
+ if ( !m_pWeaponSelection || !weapon )
+ return;
+
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer )
+ {
+ return;
+ }
+
+ wrect_t outrect;
+ if ( !m_pWeaponSelection->ComputeRect( pPlayer, weapon, &outrect ) )
+ return;
+
+ x = outrect.left;
+ y = outrect.top;
+ w = outrect.right - outrect.left;
+ h = outrect.bottom - outrect.top;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CHudWeaponFlashHelper::IsWeaponSelectionActive( void )
+{
+ if ( m_pWeaponSelection && m_pWeaponSelection->IsActive() )
+ return true;
+
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Change to commander view hint
+//-----------------------------------------------------------------------------
+class CHintHudWeaponFlash : public CHintItemBase
+{
+ DECLARE_CLASS( CHintHudWeaponFlash, CHintItemBase );
+
+public:
+ CHintHudWeaponFlash( vgui::Panel *parent, const char *panelName );
+ ~CHintHudWeaponFlash( void );
+
+ virtual void SetKeyValue( const char *key, const char *value );
+
+ void SetWeaponName( const char *name );
+ char const *GetWeaponName( void );
+
+ virtual bool CheckKeyAndValue( const char *instring, int* keylength, const char **ppOutstring );
+
+ virtual void SetActive( bool bActive );
+
+ virtual void Think( void );
+
+private:
+ C_BaseCombatWeapon *GetWeaponOfType( const char *type );
+
+ enum
+ {
+ MAX_WEAPON_NAME = 128,
+ };
+
+ bool m_bWeaponSet;
+
+ EHANDLE m_hWeapon;
+
+ char m_szWeaponName[ MAX_WEAPON_NAME ];
+
+ CHudWeaponFlashHelper *m_pWeaponFlashHelper;
+
+ EFFECT_HANDLE m_hLineEffect;
+};
+
+DECLARE_HINTITEMFACTORY( CHintHudWeaponFlash )
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *parent -
+// *panelName -
+// *text -
+// itemwidth -
+//-----------------------------------------------------------------------------
+CHintHudWeaponFlash::CHintHudWeaponFlash( vgui::Panel *parent, const char *panelName )
+: BaseClass( parent, panelName )
+{
+ m_bWeaponSet = false;
+ SetWeaponName( "" );
+ m_pWeaponFlashHelper = NULL;
+ m_hLineEffect = EFFECT_INVALID_HANDLE;
+
+ CreateFlashEffect( this, parent );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CHintHudWeaponFlash::~CHintHudWeaponFlash( void )
+{
+ if ( m_pWeaponFlashHelper )
+ {
+ m_pWeaponFlashHelper->StopFlashing();
+ m_pWeaponFlashHelper->SetFlashWeapon( NULL );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *instring -
+// keylength -
+// **ppOutstring -
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CHintHudWeaponFlash::CheckKeyAndValue( const char *instring, int* keylength, const char **ppOutstring )
+{
+ if ( !Q_strnicmp( instring, "weapon", strlen( "weapon" ) ) )
+ {
+ *keylength = strlen( "weapon" );
+ *ppOutstring = GetWeaponName();
+ return true;
+ }
+
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : char const
+//-----------------------------------------------------------------------------
+C_BaseCombatWeapon *CHintHudWeaponFlash::GetWeaponOfType( const char *type )
+{
+ CBaseHudWeaponSelection *pHudSelection = GetHudWeaponSelection();
+ if ( !pHudSelection )
+ return NULL;
+
+ C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
+ if ( player )
+ {
+ for ( int slot = 0; slot < MAX_WEAPON_SLOTS; slot++ )
+ {
+ for ( int iPos = 0; iPos < MAX_WEAPON_POSITIONS; iPos++ )
+ {
+ C_BaseCombatWeapon *weapon = pHudSelection->GetWeaponInSlot( slot, iPos );
+ if ( !weapon )
+ continue;
+
+ if ( !stricmp( weapon->GetName(), type ) )
+ {
+ return weapon;
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *key -
+// *value -
+//-----------------------------------------------------------------------------
+void CHintHudWeaponFlash::SetKeyValue( const char *key, const char *value )
+{
+ BaseClass::SetKeyValue( key, value );
+
+ if ( !stricmp( key, "weapon" ) )
+ {
+ SetWeaponName( value );
+
+ ComputeTitle();
+ }
+ else if ( !stricmp( key, "weapontype" ) )
+ {
+ // Find the weapon itself
+ C_BaseCombatWeapon *w = GetWeaponOfType( value );
+ if ( w )
+ {
+ m_hWeapon = w;
+
+ // Create open up hud effect, etc.
+ m_pWeaponFlashHelper = GET_HUDELEMENT( CHudWeaponFlashHelper );
+ if ( m_pWeaponFlashHelper )
+ {
+ m_pWeaponFlashHelper->SetFlashWeapon( w );
+
+ int x, y, wide, tall;
+
+ m_pWeaponFlashHelper->GetWeaponIconBounds( w, x, y, wide, tall );
+
+ C_TFBaseHint *hint = static_cast< C_TFBaseHint * >( GetParent() );
+
+ m_hLineEffect = CreateAxialLineEffectToRect( this, hint, x, y, wide, tall );
+
+ hint->SetDesiredPosition( x, y + tall + 50 );
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHintHudWeaponFlash::Think( void )
+{
+ BaseClass::Think();
+
+ if ( !m_pWeaponFlashHelper )
+ return;
+
+ if ( m_pWeaponFlashHelper->IsWeaponSelectionActive() )
+ {
+ m_bCompleted = true;
+ }
+
+ bool incommander = ( g_pClientMode == ClientModeCommander() );
+
+ CPanelEffect *effect = g_pTF2RootPanel->FindEffect( m_hLineEffect );
+ if ( effect )
+ {
+ effect->SetVisible( !incommander );
+
+ C_BaseCombatWeapon *w = static_cast< C_BaseCombatWeapon * >( ( C_BaseEntity * )m_hWeapon );
+
+ // Update target rectangle
+ if ( w )
+ {
+ int x, y, wide, tall;
+
+ m_pWeaponFlashHelper->GetWeaponIconBounds( w, x, y, wide, tall );
+
+ effect->SetTargetRect( x, y, wide, tall );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : bActive -
+//-----------------------------------------------------------------------------
+void CHintHudWeaponFlash::SetActive( bool bActive )
+{
+ BaseClass::SetActive( bActive );
+
+ if ( !m_pWeaponFlashHelper )
+ return;
+
+ if ( bActive )
+ {
+ m_pWeaponFlashHelper->StartFlashing();
+ }
+ else
+ {
+ m_pWeaponFlashHelper->StopFlashing();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *name -
+//-----------------------------------------------------------------------------
+void CHintHudWeaponFlash::SetWeaponName( const char *name )
+{
+ Q_strncpy( m_szWeaponName, name, MAX_WEAPON_NAME );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : char const
+//-----------------------------------------------------------------------------
+const char *CHintHudWeaponFlash::GetWeaponName( void )
+{
+ return m_szWeaponName;
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+struct FUNCTIONLIST_t
+{
+ const char *name;
+ HINTCOMPLETIONFUNCTION pfn;
+};
+
+static FUNCTIONLIST_t g_CompletionFunctions[]=
+{
+ { NULL, NULL },
+};
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *name -
+// Output : HINTCOMPLETIONFUNCTION
+//-----------------------------------------------------------------------------
+HINTCOMPLETIONFUNCTION LookupCompletionFunction( const char *name )
+{
+ int i = 0;
+ while ( 1 )
+ {
+ FUNCTIONLIST_t *f = &g_CompletionFunctions[ i ];
+ if ( !f->name )
+ break;
+
+ if ( !stricmp( f->name, name ) )
+ {
+ return f->pfn;
+ }
+ i++;
+ }
+
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+struct HINTITEM_t
+{
+ const char *name;
+ CHintItemBase *( *pfn )( vgui::Panel *parent, const char *name );
+};
+
+static HINTITEM_t g_HintItems[]=
+{
+ { "CHintChangeToCommander", GET_HINTITEMFACTORY_NAME( CHintChangeToCommander ) },
+ { "CHintGotoObject", GET_HINTITEMFACTORY_NAME( CHintGotoObject ) },
+ { "CHintDeployWeapon", GET_HINTITEMFACTORY_NAME( CHintDeployWeapon ) },
+ { "CHintStartPlacing", GET_HINTITEMFACTORY_NAME( CHintStartPlacing ) },
+ { "CHintStartBuilding", GET_HINTITEMFACTORY_NAME( CHintStartBuilding ) },
+ { "CHintWaitBuilding", GET_HINTITEMFACTORY_NAME( CHintWaitBuilding ) },
+ { "CHintBuilderSelection", GET_HINTITEMFACTORY_NAME( CHintBuilderSelection ) },
+ { "CHintBuilderStartAction", GET_HINTITEMFACTORY_NAME( CHintBuilderStartAction ) },
+ { "CHintHudWeaponFlash", GET_HINTITEMFACTORY_NAME( CHintHudWeaponFlash ) },
+ { NULL, NULL },
+};
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *parent -
+// *name -
+// Output : CHintItemBase
+//-----------------------------------------------------------------------------
+CHintItemBase *CreateHintItem( vgui::Panel *parent, const char *name )
+{
+ int i = 0;
+ while ( 1 )
+ {
+ HINTITEM_t *hi = &g_HintItems[ i ];
+ if ( !hi->name )
+ break;
+
+ if ( !stricmp( hi->name, name ) )
+ {
+ if ( hi->pfn )
+ {
+ return (*hi->pfn)( parent, name );
+ }
+ else
+ {
+ Assert( !"Missing function pointer in CreateHintItem table!" );
+ return NULL;
+ }
+ }
+ i++;
+ }
+
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+
+CHintData g_HintDatas[] =
+{
+ // Vote
+ { "TF_HINT_VOTEFORTECHNOLOGY", TF_HINT_VOTEFORTECHNOLOGY, 0, NULL, -1 },
+
+ // Build
+ { "TF_HINT_BUILDRESOURCEPUMP", TF_HINT_BUILDRESOURCEPUMP, 0, HintEventFn_BuildObject, OBJ_RESOURCEPUMP },
+ { "TF_HINT_BUILDSENTRYGUN_PLASMA", TF_HINT_BUILDSENTRYGUN_PLASMA, 0, HintEventFn_BuildObject, OBJ_SENTRYGUN_PLASMA },
+
+ // Object interaction
+ { "TF_HINT_REPAIROBJECT", TF_HINT_REPAIROBJECT, 0, NULL, -1 },
+
+ // Technology discovery
+ { "TF_HINT_NEWTECHNOLOGY", TF_HINT_NEWTECHNOLOGY, 0, NULL, -1 },
+ { "TF_HINT_WEAPONRECEIVED", TF_HINT_WEAPONRECEIVED, 0, NULL, -1 },
+
+ // Sentinal
+ { NULL, 0, 0, NULL, -1 },
+};
+
+
+int GetNumHintDatas()
+{
+ return ARRAYSIZE( g_HintDatas );
+}
+
+
+CHintData* GetHintData( int i )
+{
+ return &g_HintDatas[i];
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : id -
+// Output : char const
+//-----------------------------------------------------------------------------
+const char *LookupHintName( int id )
+{
+ int i = 0;
+ while ( 1 )
+ {
+ CHintData *h = &g_HintDatas[ i ];
+ if ( !h->name )
+ break;
+
+ if ( h->id == id )
+ {
+ return h->name;
+ }
+
+ i++;
+ }
+
+ return NULL;
+}
+
+DECLARE_HINTFACTORY( C_TFBaseHint )
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+typedef struct
+{
+ const char *name;
+ C_TFBaseHint *( *pfn )( int id, int entity );
+}
+HINT_t;
+
+static HINT_t g_Hints[]=
+{
+ { "C_TFBaseHint", GET_HINTFACTORY_NAME( C_TFBaseHint ) },
+ { NULL, NULL },
+};
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *name -
+// id -
+// entity -
+// Output : C_TFBaseHint
+//-----------------------------------------------------------------------------
+C_TFBaseHint *FactoryCreateHint( const char *name, int id, int entity )
+{
+ int i = 0;
+ while ( 1 )
+ {
+ HINT_t *hi = &g_Hints[ i ];
+ if ( !hi->name )
+ break;
+
+ if ( !stricmp( hi->name, name ) )
+ {
+ if ( hi->pfn )
+ {
+ return (*hi->pfn)( id, entity );
+ }
+ else
+ {
+ Assert( !"Missing function pointer in FactoryCreateHint table!" );
+ return NULL;
+ }
+ }
+ i++;
+ }
+
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Generic factory for hints
+// Input : id -
+// entity -
+// Output : C_TFBaseHint
+//-----------------------------------------------------------------------------
+C_TFBaseHint *C_TFBaseHint::CreateHint( int id, const char *subsection, int entity )
+{
+ C_TFBaseHint *hint = NULL;
+ const char *hintname = LookupHintName( id );
+ if ( !hintname )
+ return NULL;
+
+ // See if we should see this hint any more
+ KeyValues *pkvStats = GetHintDisplayStats();
+ if ( pkvStats )
+ {
+ KeyValues *pkvStatSection = pkvStats->FindKey( hintname, true );
+ if ( pkvStatSection )
+ {
+ if ( subsection && subsection[0] )
+ {
+ pkvStatSection = pkvStatSection->FindKey( subsection, true );
+ }
+ }
+
+ if ( !pkvStatSection )
+ {
+ Assert( !"C_TFBaseHint::CreateHint: Problem creating hint subsection" );
+ return NULL;
+ }
+
+ int times_shown = pkvStatSection->GetInt( "times_shown", 0 );
+ pkvStatSection->SetString( "times_shown", VarArgs( "%i", times_shown ) );
+
+ int times_max = pkvStatSection->GetInt( "times_max", 3 );
+ pkvStatSection->SetString( "times_max", VarArgs( "%i", times_max ) );
+
+ if ( times_shown >= times_max )
+ return NULL;
+
+ // Remember that we've seen it again
+ times_shown++;
+ pkvStatSection->SetString( "times_shown", VarArgs( "%i", times_shown ) );
+ }
+
+ // Ask Hint manager API for key values
+ KeyValues *pkvHintSystem = GetHintKeyValues();
+ if ( pkvHintSystem )
+ {
+ //
+ // Parse the list of hints looking for name
+ KeyValues *pkvHint = pkvHintSystem->FindKey( hintname );
+ if ( pkvHint )
+ {
+ // Use classname string to construct hint
+ const char *defaultclass = "C_TFBaseHint";
+ const char *classname = pkvHint->GetString( "classname" );
+ if ( !classname || !classname[ 0 ] || !stricmp( classname, "default" ) )
+ {
+ classname = defaultclass;
+ }
+
+ hint = FactoryCreateHint( classname, id, entity );
+ if ( hint )
+ {
+ hint->ParseFromData( pkvHint );
+ }
+ }
+ }
+
+ return hint;
+}