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.
1469 lines
39 KiB
1469 lines
39 KiB
![]()
4 years ago
|
//========= 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;
|
||
|
}
|