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.
1468 lines
39 KiB
1468 lines
39 KiB
//========= 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; |
|
}
|
|
|