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.
1625 lines
53 KiB
1625 lines
53 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//=============================================================================// |
|
|
|
#include "cbase.h" |
|
#include "quest_item_panel.h" |
|
#include "tf_hud_item_progress_tracker.h" |
|
#include "quest_log_panel.h" |
|
#include "c_tf_player.h" |
|
#include "econ_item_description.h" |
|
#include "clientmode_tf.h" |
|
#include <vgui_controls/AnimationController.h> |
|
#include "quest_objective_manager.h" |
|
#include "econ_quests.h" |
|
#include "confirm_dialog.h" |
|
#include "tf_quest_restriction.h" |
|
#include "item_model_panel.h" |
|
#include "tf_gc_client.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include <tier0/memdbgon.h> |
|
|
|
void AddSubKeyNamed( KeyValues *pKeys, const char *pszName ); |
|
|
|
const float k_flQuestDecodeTime = 2.f; |
|
const float k_flQuestTurnInTime = 5.f; |
|
ConVar tf_quest_turn_in_confirm_opt_out( "tf_quest_turn_in_confirm_opt_out", "0", FCVAR_ARCHIVE, "If nonzero, don't confirm submitting a contract that does not have all of the bonus points" ); |
|
|
|
extern CQuestLogPanel *GetQuestLog(); |
|
extern CQuestTooltip* g_spTextTooltip; |
|
|
|
extern const char *s_pszMMTypes[kMatchmakingTypeCount]; |
|
extern const char *s_pszGameModes[eNumGameCategories]; |
|
|
|
void SelectGroup( EMatchmakingGroupType eGroup, bool bSelected ); |
|
void SelectCategory( EGameCategory eCategory, bool bSelected ); |
|
|
|
void PromptOrFireCommand( const char* pszCommand ); |
|
|
|
static void ConfirmDiscardQuest( bool bConfirmed, void* pContext ) |
|
{ |
|
CQuestItemPanel *pQuestItemPanel = ( CQuestItemPanel* )pContext; |
|
if ( pQuestItemPanel ) |
|
{ |
|
pQuestItemPanel->OnConfirmDelete( bConfirmed ); |
|
} |
|
} |
|
|
|
static void ConfirmEquipLoaners( bool bConfirmed, void* pContext ) |
|
{ |
|
CQuestItemPanel *pQuestItemPanel = ( CQuestItemPanel* )pContext; |
|
if ( pQuestItemPanel ) |
|
{ |
|
pQuestItemPanel->OnConfirmEquipLoaners( bConfirmed ); |
|
} |
|
} |
|
|
|
static void ConfirmTurnInQuest( bool bConfirmed, void* pContext ) |
|
{ |
|
if ( bConfirmed ) |
|
{ |
|
CQuestItemPanel *pQuestItemPanel = (CQuestItemPanel*)pContext; |
|
if ( pQuestItemPanel ) |
|
{ |
|
pQuestItemPanel->OnCompleteQuest(); |
|
} |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: fill vecLoanerItems with loaners def indices from pQuest |
|
//----------------------------------------------------------------------------- |
|
static int GetLoanerListFromQuest( const CEconItemView *pQuest, CUtlVector< item_definition_index_t >& vecLoanerItems ) |
|
{ |
|
if ( !pQuest ) |
|
return 0; |
|
|
|
// loaners from the quest |
|
const CUtlVector< CTFRequiredQuestItemsSet >& vecQuestRequiredItems = pQuest->GetItemDefinition()->GetQuestDef()->GetRequiredItemSets(); |
|
FOR_EACH_VEC( vecQuestRequiredItems, i ) |
|
{ |
|
// don't add dups |
|
if ( vecLoanerItems.Find( vecQuestRequiredItems[i].GetLoanerItemDef() ) == vecLoanerItems.InvalidIndex() ) |
|
{ |
|
vecLoanerItems.AddToTail( vecQuestRequiredItems[i].GetLoanerItemDef() ); |
|
} |
|
} |
|
|
|
// loaners from the objectives |
|
//{ |
|
// // Get all the objectives |
|
// QuestObjectiveDefVec_t vecChosenObjectives; |
|
// pQuest->GetItemDefinition()->GetQuestDef()->GetRolledObjectivesForItem( vecChosenObjectives, pQuest ); |
|
|
|
// // Get all the items we need to give as loaners from the objectives |
|
// FOR_EACH_VEC( vecChosenObjectives, i ) |
|
// { |
|
// const CUtlVector< CTFRequiredQuestItemsSet >& vecObjectiveRequiredItems = vecChosenObjectives[ i ]->GetConditions()->GetRequiredItemSets(); |
|
// FOR_EACH_VEC( vecObjectiveRequiredItems, iRequired ) |
|
// { |
|
// // don't add dups |
|
// if ( vecLoanerItems.Find( vecObjectiveRequiredItems[ iRequired ].GetLoanerItemDef() ) == vecLoanerItems.InvalidIndex() ) |
|
// { |
|
// vecLoanerItems.AddToTail( vecObjectiveRequiredItems[ iRequired ].GetLoanerItemDef() ); |
|
// } |
|
// } |
|
// } |
|
//} |
|
|
|
return vecLoanerItems.Count(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: fill vecGrantedLoaners with granted loaners from specific quest ID |
|
//----------------------------------------------------------------------------- |
|
static int GetLoanersFromLocalInventory( const itemid_t& questID, const CUtlVector< item_definition_index_t >& vecLoanerItems, CUtlVector< CEconItemView* >& vecGrantedLoaners ) |
|
{ |
|
if ( vecLoanerItems.Count() > 0 ) |
|
{ |
|
CPlayerInventory *pLocalInv = InventoryManager()->GetLocalInventory(); |
|
int nCount = pLocalInv->GetItemCount(); |
|
for ( int i = 0; i < nCount; ++i ) |
|
{ |
|
CEconItemView* pItem = pLocalInv->GetItem( i ); |
|
|
|
bool bIsLoaner = false; |
|
// check if the item is a loaner and is associated with this quest |
|
FOR_EACH_VEC( vecLoanerItems, iLoaner ) |
|
{ |
|
if ( vecLoanerItems[iLoaner] == pItem->GetItemDefIndex() && GetAssociatedQuestItemID( pItem ) == questID ) |
|
{ |
|
bIsLoaner = true; |
|
break; |
|
} |
|
} |
|
|
|
// already granted this loaner, remove from the list to give |
|
if ( bIsLoaner ) |
|
{ |
|
vecGrantedLoaners.AddToTail( pItem ); |
|
} |
|
|
|
// found all given loaners |
|
if ( vecLoanerItems.Count() == vecGrantedLoaners.Count() ) |
|
{ |
|
break; |
|
} |
|
} |
|
} |
|
|
|
return vecGrantedLoaners.Count(); |
|
} |
|
|
|
|
|
DECLARE_BUILD_FACTORY( CInputProxyPanel ) |
|
CInputProxyPanel::CInputProxyPanel( Panel *parent, const char *pszPanelName ) |
|
: BaseClass( parent, pszPanelName ) |
|
{} |
|
|
|
void CInputProxyPanel::AddPanelForCommand( EInputTypes eInputType, Panel* pPanel, const char* pszCommand ) |
|
{ |
|
m_vecRedirectPanels[ eInputType ].AddToTail( { pPanel, pszCommand } ); |
|
} |
|
|
|
void CInputProxyPanel::OnCursorMoved( int x, int y ) |
|
{ |
|
FOR_EACH_VEC( m_vecRedirectPanels[ INPUT_MOUSE_MOVE ], i ) |
|
{ |
|
PostMessage( m_vecRedirectPanels[ INPUT_MOUSE_MOVE ][ i ].m_pPanel, new KeyValues( m_vecRedirectPanels[ INPUT_MOUSE_MOVE ][ i ].m_pszCommand, "x", x, "y", y ) ); |
|
} |
|
} |
|
|
|
void CInputProxyPanel::OnCursorEntered() |
|
{ |
|
FOR_EACH_VEC( m_vecRedirectPanels[ INPUT_MOUSE_ENTER ], i ) |
|
{ |
|
PostMessage( m_vecRedirectPanels[ INPUT_MOUSE_ENTER ][ i ].m_pPanel, new KeyValues( m_vecRedirectPanels[ INPUT_MOUSE_ENTER ][ i ].m_pszCommand ) ); |
|
} |
|
} |
|
|
|
void CInputProxyPanel::OnCursorExited() |
|
{ |
|
FOR_EACH_VEC( m_vecRedirectPanels[ INPUT_MOUSE_EXIT ], i ) |
|
{ |
|
PostMessage( m_vecRedirectPanels[ INPUT_MOUSE_EXIT ][ i ].m_pPanel, new KeyValues( m_vecRedirectPanels[ INPUT_MOUSE_EXIT ][ i ].m_pszCommand ) ); |
|
} |
|
} |
|
|
|
void CInputProxyPanel::OnMousePressed(MouseCode code) |
|
{ |
|
FOR_EACH_VEC( m_vecRedirectPanels[ INPUT_MOUSE_PRESS ], i ) |
|
{ |
|
PostMessage( m_vecRedirectPanels[ INPUT_MOUSE_PRESS ][ i ].m_pPanel, new KeyValues( m_vecRedirectPanels[ INPUT_MOUSE_PRESS ][ i ].m_pszCommand, "code", code ) ); |
|
} |
|
} |
|
|
|
void CInputProxyPanel::OnMouseDoublePressed(MouseCode code) |
|
{ |
|
FOR_EACH_VEC( m_vecRedirectPanels[ INPUT_MOUSE_DOUBLE_PRESS ], i ) |
|
{ |
|
PostMessage( m_vecRedirectPanels[ INPUT_MOUSE_DOUBLE_PRESS ][ i ].m_pPanel, new KeyValues( m_vecRedirectPanels[ INPUT_MOUSE_DOUBLE_PRESS ][ i ].m_pszCommand, "code", code ) ); |
|
} |
|
} |
|
|
|
void CInputProxyPanel::OnMouseReleased(MouseCode code) |
|
{ |
|
FOR_EACH_VEC( m_vecRedirectPanels[ INPUT_MOUSE_RELEASED ], i ) |
|
{ |
|
PostMessage( m_vecRedirectPanels[ INPUT_MOUSE_RELEASED ][ i ].m_pPanel, new KeyValues( m_vecRedirectPanels[ INPUT_MOUSE_RELEASED ][ i ].m_pszCommand, "code", code ) ); |
|
} |
|
} |
|
|
|
void CInputProxyPanel::OnMouseWheeled(int delta) |
|
{ |
|
FOR_EACH_VEC( m_vecRedirectPanels[ INPUT_MOUSE_WHEEL ], i ) |
|
{ |
|
PostMessage( m_vecRedirectPanels[ INPUT_MOUSE_WHEEL ][ i ].m_pPanel, new KeyValues( m_vecRedirectPanels[ INPUT_MOUSE_WHEEL ][ i ].m_pszCommand, "delta", delta ) ); |
|
} |
|
} |
|
|
|
|
|
DECLARE_BUILD_FACTORY( CQuestStatusPanel ) |
|
|
|
CQuestStatusPanel::CQuestStatusPanel( Panel *parent, const char *pszPanelName ) |
|
: EditablePanel( parent, pszPanelName ) |
|
, m_pMovingContainer( NULL ) |
|
, m_bShouldBeVisible( false ) |
|
{ |
|
m_pMovingContainer = new EditablePanel( this, "movingcontainer" ); |
|
m_transitionTimer.Invalidate(); |
|
} |
|
|
|
void CQuestStatusPanel::SetShow( bool bShow ) |
|
{ |
|
if ( bShow != m_bShouldBeVisible ) |
|
{ |
|
m_transitionTimer.Start( 0.6f ); |
|
} |
|
m_bShouldBeVisible = bShow; |
|
SetVisible( m_bShouldBeVisible ); |
|
} |
|
|
|
void CQuestStatusPanel::OnThink() |
|
{ |
|
BaseClass::OnThink(); |
|
|
|
const int nStartY = m_bShouldBeVisible ? m_iHiddenY : m_iVisibleY; |
|
const int nEndY = m_bShouldBeVisible ? m_iVisibleY : m_iHiddenY; |
|
|
|
float flProgress = 1.f; |
|
if ( !m_transitionTimer.IsElapsed() ) |
|
{ |
|
flProgress = Bias( RemapValClamped( m_transitionTimer.GetElapsedTime(), 0.f , m_transitionTimer.GetCountdownDuration(), 0.f, 1.f ), 0.7f ); |
|
} |
|
flProgress = RemapVal( flProgress, 0.f, 1.f, (float)nStartY, (float)nEndY ); |
|
|
|
m_pMovingContainer->SetPos( m_pMovingContainer->GetXPos(), flProgress ); |
|
SetVisible( m_bShouldBeVisible || flProgress > 0.f ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CQuestItemPanel::CQuestItemPanel( Panel *parent, const char *pszPanelName, CEconItemView* pQuestItem, CScrollableQuestList* pQuestList ) |
|
: EditablePanel( parent, pszPanelName ) |
|
, m_hQuestItem( NULL ) |
|
, m_eState( STATE_NORMAL ) |
|
, m_pTurnInContainer( NULL ) |
|
, m_pTurnInDimmer( NULL ) |
|
, m_pszCompleteSound( NULL ) |
|
, m_pFrontFolderContainer( NULL ) |
|
, m_pBackFolderContainer( NULL ) |
|
, m_bCollapsed( true ) |
|
, m_pQuestList( pQuestList ) |
|
, m_pQuestPaperContainer( NULL ) |
|
, m_pTitleButton( NULL ) |
|
, m_pIdentifyContainer( NULL ) |
|
, m_pIdentifyDimmer( NULL ) |
|
, m_pKVCipherStrings( NULL ) |
|
, m_pPhotoStatic( NULL ) |
|
, m_pFlavorScrollingContainer( NULL ) |
|
, m_pTurningInLabel( NULL ) |
|
, m_pFindServerButton( NULL ) |
|
, m_pLoanerContainerPanel( NULL ) |
|
, m_pRequestLoanerItemsButton( NULL ) |
|
, m_pEquipLoanerItemsButton( NULL ) |
|
, m_pItemTrackerPanel( NULL ) |
|
, m_pKVItemTracker( NULL ) |
|
, m_pObjectiveExplanationLabel( NULL ) |
|
, m_pEncodedStatus( NULL ) |
|
, m_pInactiveStatus( NULL ) |
|
, m_pReadyToTurnInStatus( NULL ) |
|
, m_pExpirationLabel( NULL ) |
|
, m_pTurnInButton( NULL ) |
|
, m_bHasAllControls( false ) |
|
, m_pDiscardButton( NULL ) |
|
{ |
|
SetItem( pQuestItem ); |
|
m_StateTimer.Invalidate(); |
|
|
|
ListenForGameEvent( "quest_objective_completed" ); |
|
ListenForGameEvent( "player_spawn" ); |
|
ListenForGameEvent( "client_disconnect" ); |
|
ListenForGameEvent( "inventory_updated" ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CQuestItemPanel::~CQuestItemPanel() |
|
{ |
|
if ( m_pItemTrackerPanel ) |
|
{ |
|
m_pItemTrackerPanel->MarkForDeletion(); |
|
m_pItemTrackerPanel = NULL; |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestItemPanel::ApplySchemeSettings( IScheme *pScheme ) |
|
{ |
|
BaseClass::ApplySchemeSettings ( pScheme ); |
|
AddActionSignalTarget( GetQuestLog() ); |
|
LoadResFileForCurrentItem(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestItemPanel::LoadResFileForCurrentItem() |
|
{ |
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); |
|
const char *pszResFile = "Resource/UI/quests/QuestItemPanel_Base.res"; |
|
|
|
if ( m_hQuestItem ) |
|
{ |
|
const GameItemDefinition_t *pItemDef = m_hQuestItem->GetItemDefinition(); |
|
// Get our quest theme |
|
const CQuestThemeDefinition *pTheme = pItemDef->GetQuestDef()->GetQuestTheme(); |
|
if ( pTheme ) |
|
{ |
|
pszResFile = pTheme->GetQuestItemResFile(); |
|
} |
|
} |
|
|
|
KeyValues *pConditions = new KeyValues( "conditions" ); |
|
if ( pConditions ) |
|
{ |
|
char uilanguage[64]; |
|
uilanguage[0] = 0; |
|
engine->GetUILanguage( uilanguage, sizeof( uilanguage ) ); |
|
char szCondition[64]; |
|
Q_snprintf( szCondition, sizeof( szCondition ), "if_%s", uilanguage ); |
|
AddSubKeyNamed( pConditions, szCondition ); |
|
} |
|
|
|
SetMouseInputEnabled( true ); // Slam this to true. When panels get created, they'll inherit their parents' mouse enabled state |
|
// and if we've been fiddling with it, we might accidently create all child panels with mouse input disabled. |
|
// Setting this to true just before the controls are made gives them a chance to be mouse enabled if they want. |
|
LoadControlSettings( pszResFile, NULL, NULL, pConditions ); |
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, m_strReset ); |
|
|
|
m_pMainContainer = FindControl<EditablePanel>( "MainContainer" ); |
|
if ( m_pMainContainer ) |
|
{ |
|
m_pMainContainer->AddActionSignalTarget( this ); |
|
} |
|
|
|
m_pQuestPaperContainer = FindControl<EditablePanel>( "QuestPaperContainer", true ); |
|
m_pFrontFolderContainer = FindControl<EditablePanel>( "FrontFolderContainer", true ); |
|
Assert( m_pFrontFolderContainer ); |
|
if ( m_pFrontFolderContainer ) |
|
{ |
|
m_pFrontFolderImage = m_pFrontFolderContainer->FindControl<ImagePanel>( "FrontFolderImage", true ); |
|
Assert( m_pFrontFolderImage ); |
|
|
|
m_pEncodedStatus = m_pFrontFolderContainer->FindControl< CQuestStatusPanel >( "EncodedStatus", true ); |
|
m_pInactiveStatus = m_pFrontFolderContainer->FindControl< CQuestStatusPanel >( "InactiveStatus", true ); |
|
m_pReadyToTurnInStatus = m_pFrontFolderContainer->FindControl< CQuestStatusPanel >( "ReadyToTurnInStatus", true ); |
|
} |
|
m_pBackFolderContainer = FindControl<EditablePanel>( "BackFolderContainer", true ); |
|
Assert( m_pBackFolderContainer ); |
|
if ( m_pBackFolderContainer ) |
|
{ |
|
m_pBackFolderImage = m_pBackFolderContainer->FindControl<ImagePanel>( "BackFolderImage", true ); |
|
Assert( m_pBackFolderImage ); |
|
} |
|
|
|
if ( m_pQuestPaperContainer ) |
|
{ |
|
#if defined( STAGING_ONLY ) || defined( DEBUG ) |
|
// don't do this in public |
|
m_pDiscardButton = new CExButton( m_pQuestPaperContainer, "Discard", "Discard", this, "discard_quest" ); |
|
m_pDiscardButton->SetEnabled( true ); |
|
m_pDiscardButton->SizeToContents(); |
|
m_pDiscardButton->SetZPos( 101 ); |
|
m_pDiscardButton->SetPos( 70, 40 ); |
|
m_pDiscardButton->SetVisible( false ); |
|
#endif // STAGING_ONLY || DEBUG |
|
|
|
m_pFindServerButton = m_pQuestPaperContainer->FindControl< CExButton >( "FindServerButton", true ); |
|
|
|
m_pLoanerContainerPanel = m_pQuestPaperContainer->FindControl< EditablePanel >( "LoanerContainerPanel", true ); |
|
if ( m_pLoanerContainerPanel ) |
|
{ |
|
m_pRequestLoanerItemsButton = m_pLoanerContainerPanel->FindControl< CExButton >( "RequestLoanerItemsButton", true ); |
|
m_pEquipLoanerItemsButton = m_pLoanerContainerPanel->FindControl< CExButton >( "EquipLoanerItemsButton", true ); |
|
for ( int i = 0; i < ARRAYSIZE( m_pLoanerItemModelPanel ); ++i ) |
|
{ |
|
m_pLoanerItemModelPanel[i] = m_pLoanerContainerPanel->FindControl< CItemModelPanel >( CFmtStr( "Loaner%dItemModelPanel", i + 1 ), true ); |
|
} |
|
} |
|
|
|
m_pTitleButton = m_pQuestPaperContainer->FindControl<CExButton>( "TitleButton", true ); |
|
m_pIdentifyContainer = m_pQuestPaperContainer->FindControl<EditablePanel>( "IdentifyButtonContainer", true ); |
|
if ( m_pIdentifyContainer ) |
|
{ |
|
m_pIdentifyDimmer = m_pIdentifyContainer->FindControl<EditablePanel>( "Dimmer", true ); |
|
m_pIdentifyButton = m_pIdentifyContainer->FindControl<CExButton>( "IdentifyButton", true ); |
|
} |
|
Assert( m_pIdentifyContainer ); |
|
|
|
m_pEncodedImage = m_pQuestPaperContainer->FindControl<ImagePanel>( "EncodedImage", true ); |
|
|
|
m_pPhotoStatic = m_pQuestPaperContainer->FindControl<ImagePanel>( "StaticPhoto", true ); |
|
Assert( m_pPhotoStatic ); |
|
|
|
m_pFlavorScrollingContainer = m_pQuestPaperContainer->FindControl<CExScrollingEditablePanel>( "ScrollableBottomContainer", true ); |
|
Assert( m_pFlavorScrollingContainer ); |
|
|
|
if ( m_pFlavorScrollingContainer ) |
|
{ |
|
m_pObjectiveExplanationLabel = m_pFlavorScrollingContainer->FindControl< Label >( "QuestObjectiveExplanation", true ); |
|
} |
|
|
|
CInputProxyPanel* pInputProxy = m_pQuestPaperContainer->FindControl< CInputProxyPanel >( "PaperInputProxyPanel", true ); |
|
if ( pInputProxy ) |
|
{ |
|
// Make the scroller scroll |
|
pInputProxy->AddPanelForCommand( CInputProxyPanel::INPUT_MOUSE_WHEEL, m_pFlavorScrollingContainer, "MouseWheeled" ); |
|
|
|
// Make the title glow |
|
pInputProxy->AddPanelForCommand( CInputProxyPanel::INPUT_MOUSE_ENTER, m_pTitleButton, "CursorEntered" ); |
|
pInputProxy->AddPanelForCommand( CInputProxyPanel::INPUT_MOUSE_EXIT, m_pTitleButton, "CursorExited" ); |
|
|
|
// Capture clicks to expand/contract |
|
pInputProxy->AddPanelForCommand( CInputProxyPanel::INPUT_MOUSE_RELEASED, this, "MouseReleased" ); |
|
} |
|
|
|
m_pTurnInContainer = m_pQuestPaperContainer->FindControl< EditablePanel >( "TurnInContainer" ); |
|
Assert( m_pTurnInContainer ); |
|
if ( m_pTurnInContainer ) |
|
{ |
|
m_pTurnInDimmer = m_pTurnInContainer->FindControl< EditablePanel >( "Dimmer", true ); |
|
Assert( m_pTurnInContainer ); |
|
|
|
m_pTurnInButton = m_pTurnInContainer->FindControl< Button >( "TurnInButton", true ); |
|
Assert( m_pTurnInButton ); |
|
|
|
m_pTurnInSpinnerContainer = m_pTurnInContainer->FindControl< EditablePanel>( "TurnInSpinnerContainer", true ); |
|
Assert( m_pTurnInSpinnerContainer ); |
|
|
|
if ( m_pTurnInSpinnerContainer ) |
|
{ |
|
m_pTurningInLabel = m_pTurnInSpinnerContainer->FindControl< Label >( "TurningInLabel", true ); |
|
Assert( m_pTurningInLabel ); |
|
} |
|
} |
|
|
|
m_pAcceptedImage = m_pQuestPaperContainer->FindControl< ImagePanel >( "AcceptedImage", true ); |
|
Assert( m_pAcceptedImage ); |
|
} |
|
|
|
if ( m_pFrontFolderContainer ) |
|
{ |
|
CInputProxyPanel* pInputProxy = m_pFrontFolderContainer->FindControl< CInputProxyPanel >( "FrontInputProxyPanel", true ); |
|
if ( pInputProxy ) |
|
{ |
|
pInputProxy->AddPanelForCommand( CInputProxyPanel::INPUT_MOUSE_ENTER, m_pInactiveStatus, "CursorEntered" ); |
|
pInputProxy->AddPanelForCommand( CInputProxyPanel::INPUT_MOUSE_EXIT, m_pInactiveStatus, "CursorExited" ); |
|
|
|
// Make the title glow |
|
pInputProxy->AddPanelForCommand( CInputProxyPanel::INPUT_MOUSE_ENTER, m_pTitleButton, "CursorEntered" ); |
|
pInputProxy->AddPanelForCommand( CInputProxyPanel::INPUT_MOUSE_EXIT, m_pTitleButton, "CursorExited" ); |
|
|
|
// Make the backdrop highlight |
|
pInputProxy->AddPanelForCommand( CInputProxyPanel::INPUT_MOUSE_ENTER, this, "CollapsedGlowStart" ); |
|
pInputProxy->AddPanelForCommand( CInputProxyPanel::INPUT_MOUSE_EXIT, this, "CollapsedGlowEnd" ); |
|
|
|
// Capture clicks to expand/contract |
|
pInputProxy->AddPanelForCommand( CInputProxyPanel::INPUT_MOUSE_RELEASED, this, "MouseReleased" ); |
|
} |
|
} |
|
|
|
m_pExpirationLabel = FindControl<Label>( "QuestExpirationWarning", true ); |
|
m_pFlavorText = FindControl<Label>( "QuestFlavorText", true ); |
|
|
|
SetupObjectivesPanels( true ); |
|
|
|
if ( pConditions ) |
|
{ |
|
pConditions->deleteThis(); |
|
} |
|
|
|
m_bHasAllControls = m_pQuestPaperContainer |
|
&& m_pFrontFolderContainer |
|
&& m_pFrontFolderImage |
|
&& m_pBackFolderContainer |
|
&& m_pBackFolderImage |
|
&& m_pEncodedStatus |
|
&& m_pInactiveStatus |
|
&& m_pReadyToTurnInStatus |
|
&& m_pFlavorText |
|
&& m_pObjectiveExplanationLabel |
|
&& m_pExpirationLabel |
|
&& m_pTurnInContainer |
|
&& m_pTurnInDimmer |
|
&& m_pTurnInButton |
|
&& m_pIdentifyButton |
|
&& m_pTurnInSpinnerContainer |
|
&& m_pTitleButton |
|
&& m_pIdentifyDimmer |
|
&& m_pIdentifyContainer |
|
&& m_pPhotoStatic |
|
&& m_pAcceptedImage |
|
&& m_pTurningInLabel |
|
&& m_pFlavorScrollingContainer |
|
&& m_pItemTrackerPanel |
|
&& m_pEncodedImage |
|
&& m_pMainContainer; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestItemPanel::ApplySettings( KeyValues *inResourceData ) |
|
{ |
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); |
|
BaseClass::ApplySettings( inResourceData ); |
|
|
|
if ( m_hQuestItem ) |
|
{ |
|
m_vecFoldersImages.Purge(); |
|
KeyValues *pKVFoldersBlock = inResourceData->FindKey( "folders" ); |
|
Assert( pKVFoldersBlock ); |
|
if ( pKVFoldersBlock ) |
|
{ |
|
FOR_EACH_TRUE_SUBKEY( pKVFoldersBlock, pKVFolder ) |
|
{ |
|
auto& folder = m_vecFoldersImages[ m_vecFoldersImages.AddToTail() ]; |
|
folder.m_strFront = pKVFolder->GetString( "front", NULL); |
|
folder.m_strBack = pKVFolder->GetString( "back", NULL ); |
|
} |
|
} |
|
else |
|
{ |
|
const GameItemDefinition_t *pItemDef = m_hQuestItem->GetItemDefinition(); |
|
// Get our quest theme |
|
const CQuestThemeDefinition *pTheme = pItemDef->GetQuestDef()->GetQuestTheme(); |
|
if ( pTheme ) |
|
{ |
|
Warning( "%s %s is missing 'folders' data\n", pItemDef->GetQuestDef()->GetCorrespondingOperationName(), pTheme->GetQuestItemResFile() ); |
|
} |
|
} |
|
} |
|
|
|
if ( 1/*m_pKVItemTracker == NULL*/ ) |
|
{ |
|
KeyValues *pTrackerKV = inResourceData->FindKey( "tracker_kv" ); |
|
|
|
if ( pTrackerKV ) |
|
{ |
|
m_pKVItemTracker = pTrackerKV->MakeCopy(); |
|
} |
|
} |
|
|
|
m_strEncodedText = inResourceData->GetString( "encoded_text", NULL ); |
|
m_strExpireText = inResourceData->GetString( "expire_text", NULL ); |
|
m_strItemTrackerResFile = inResourceData->GetString( "TrackerPanelResFile", NULL ); |
|
// Sound effects |
|
m_strTurnInSound = inResourceData->GetString( "turn_in_sound", NULL ); |
|
m_strTurnInSuccessSound = inResourceData->GetString( "turn_in_success_sound", NULL ); |
|
m_strDecodeSound = inResourceData->GetString( "decode_sound", NULL ); |
|
m_strExpandSound = inResourceData->GetString( "expand_sound", NULL ); |
|
m_strCollapseSound = inResourceData->GetString( "collapse_sound", NULL ); |
|
|
|
// Animations |
|
m_strReset = inResourceData->GetString( "anim_reset", NULL ); |
|
m_strAnimExpand = inResourceData->GetString( "anim_expand", NULL ); |
|
m_strAnimCollapse = inResourceData->GetString( "anim_collapse", NULL ); |
|
m_strTurningIn = inResourceData->GetString( "anim_turning_in", NULL ); |
|
m_strHighlightOn = inResourceData->GetString( "anim_highlight_on", NULL ); |
|
m_strHighlightOff = inResourceData->GetString( "anim_highlight_off", NULL ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestItemPanel::PerformLayout( void ) |
|
{ |
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); |
|
BaseClass::PerformLayout(); |
|
|
|
if ( !HasAllControls() ) |
|
return; |
|
|
|
m_pIdentifyContainer->SetVisible( m_eState == STATE_UNIDENTIFIED ); |
|
m_pTurnInContainer->SetVisible( m_eState == STATE_COMPLETED || m_eState == STATE_TURNING_IN__GC_RESPONDED || m_eState == STATE_TURNING_IN__WAITING_FOR_GC); |
|
m_pTurnInButton->SetVisible( m_eState == STATE_COMPLETED ); |
|
m_pTurnInSpinnerContainer->SetVisible( m_eState == STATE_TURNING_IN__GC_RESPONDED || m_eState == STATE_TURNING_IN__WAITING_FOR_GC ); |
|
m_pPhotoStatic->SetVisible( m_eState == STATE_UNIDENTIFIED || m_eState == STATE_IDENTIFYING ); |
|
m_pFindServerButton->SetVisible( m_eState == STATE_NORMAL ); |
|
|
|
// only exist in non public build |
|
if ( m_pDiscardButton ) |
|
{ |
|
m_pDiscardButton->SetVisible( m_eState == STATE_NORMAL ); |
|
} |
|
|
|
// loaners |
|
if ( m_eState == STATE_NORMAL || m_eState == STATE_COMPLETED ) |
|
{ |
|
// get all loaners required from quest |
|
CUtlVector< item_definition_index_t > vecLoanerItems; |
|
bool bRequiredLoaners = GetLoanerListFromQuest( m_hQuestItem, vecLoanerItems ) > 0; |
|
|
|
// get all granted loaners from this quest |
|
CUtlVector< CEconItemView* > vecGrantedLoaners; |
|
if ( bRequiredLoaners ) |
|
{ |
|
GetLoanersFromLocalInventory( m_hQuestItem->GetItemID(), vecLoanerItems, vecGrantedLoaners ); |
|
} |
|
|
|
if ( bRequiredLoaners ) |
|
{ |
|
m_pLoanerContainerPanel->SetVisible( true ); |
|
bool bAllGranted = vecLoanerItems.Count() == vecGrantedLoaners.Count(); |
|
m_pRequestLoanerItemsButton->SetVisible( !bAllGranted ); |
|
m_pEquipLoanerItemsButton->SetVisible( bAllGranted ); |
|
|
|
for ( int i = 0; i < ARRAYSIZE( m_pLoanerItemModelPanel ); ++i ) |
|
{ |
|
// try to use the granted items first |
|
if ( i < vecGrantedLoaners.Count() ) |
|
{ |
|
m_pLoanerItemModelPanel[i]->SetItem( vecGrantedLoaners[i] ); |
|
m_pLoanerItemModelPanel[i]->SetVisible( true ); |
|
} |
|
// In case we don't get all the loaner items, use fake items as second option |
|
else if ( i < vecLoanerItems.Count() ) |
|
{ |
|
CEconItemView tempItem; |
|
tempItem.Init( vecLoanerItems[i], AE_UNIQUE, AE_USE_SCRIPT_VALUE, true ); |
|
|
|
m_pLoanerItemModelPanel[i]->SetItem( &tempItem ); |
|
m_pLoanerItemModelPanel[i]->SetVisible( true ); |
|
} |
|
else |
|
{ |
|
m_pLoanerItemModelPanel[i]->SetVisible( false ); |
|
} |
|
} |
|
} |
|
else |
|
{ |
|
m_pLoanerContainerPanel->SetVisible( false ); |
|
} |
|
} |
|
else |
|
{ |
|
m_pLoanerContainerPanel->SetVisible( false ); |
|
} |
|
|
|
|
|
|
|
m_pEncodedStatus->SetShow( m_eState == STATE_UNIDENTIFIED ); |
|
m_pReadyToTurnInStatus->SetShow( m_eState == STATE_COMPLETED || m_eState == STATE_TURNING_IN__GC_RESPONDED || m_eState == STATE_TURNING_IN__WAITING_FOR_GC ); |
|
|
|
float flDecodeAmount = 1.f; |
|
// Only cypher-style decoding needs to decode |
|
if ( m_eDecodeStyle == DECODE_STYLE_CYPHER && m_eState == STATE_UNIDENTIFIED ) |
|
{ |
|
flDecodeAmount = 0.f; |
|
} |
|
|
|
m_pEncodedImage->SetAlpha( m_eState == STATE_UNIDENTIFIED ? 255 : 0 ); |
|
|
|
if ( m_hQuestItem ) |
|
{ |
|
m_pTitleButton->SetText( GetDecodedString( "name", flDecodeAmount ) ); |
|
|
|
int nScrollableYOffset = 0; |
|
// Check if the quest is going to expire soon (within a week). If so, show a "This is going to be destroyed" message. |
|
const CRTime nExpirationTime = m_hQuestItem->GetExpirationDate(); |
|
const CRTime nOneWeekFromNow = CRTime::RTime32DateAdd( CRTime::RTime32TimeCur(), 1, k_ETimeUnitWeek ); |
|
const bool bExpiringSoon = nExpirationTime.GetRTime32() != RTime32(0) && nExpirationTime < nOneWeekFromNow; |
|
m_pExpirationLabel->SetVisible( bExpiringSoon ); |
|
if ( bExpiringSoon ) |
|
{ |
|
CLocalizedRTime32 locTime = { nExpirationTime.GetRTime32(), false, GLocalizationProvider(), NULL }; |
|
m_pExpirationLabel->SetText( CConstructLocalizedString( g_pVGuiLocalize->Find( m_strExpireText ), locTime ) ); |
|
m_pExpirationLabel->InvalidateLayout( true ); |
|
m_pExpirationLabel->SizeToContents(); |
|
nScrollableYOffset += m_pExpirationLabel->GetTall(); |
|
} |
|
|
|
m_pObjectiveExplanationLabel->SetPos( 0, nScrollableYOffset ); |
|
m_pObjectiveExplanationLabel->SetText( GetDecodedString( "explanation", flDecodeAmount ) ); |
|
m_pObjectiveExplanationLabel->InvalidateLayout( true ); // So we get the right height when we do SizeToContents below |
|
m_pObjectiveExplanationLabel->SizeToContents(); |
|
nScrollableYOffset += m_pObjectiveExplanationLabel->GetTall(); |
|
|
|
m_pFlavorText->SetText( GetDecodedString( "desc", flDecodeAmount ) ); |
|
int nWide, nTall; |
|
m_pFlavorText->GetTextImage()->GetContentSize( nWide, nTall ); |
|
m_pFlavorText->SetTall( nTall + 20 ); |
|
|
|
m_pItemTrackerPanel->SetPos( m_pItemTrackerPanel->GetXPos(), nScrollableYOffset ); |
|
nScrollableYOffset += m_pItemTrackerPanel->GetTall(); |
|
|
|
// Put the flavor text below the obectives |
|
m_pFlavorText->SetPos( m_pFlavorText->GetXPos(), nScrollableYOffset ); |
|
|
|
m_pFlavorScrollingContainer->InvalidateLayout( true ); |
|
m_pFlavorScrollingContainer->InvalidateLayout(); |
|
m_pFlavorScrollingContainer->ResetScrollAmount(); |
|
|
|
|
|
// Randomize our folder images based on original ID |
|
if ( m_vecFoldersImages.Count() ) |
|
{ |
|
RandomSeed( m_hQuestItem->GetSOCData() ? m_hQuestItem->GetSOCData()->GetOriginalID() : m_hQuestItem->GetItemDefIndex() ); |
|
int idx = RandomInt( 0, m_vecFoldersImages.Count() - 1 ); |
|
|
|
m_pFrontFolderImage->SetImage( m_vecFoldersImages[ idx ].m_strFront ); |
|
m_pBackFolderImage->SetImage( m_vecFoldersImages[ idx ].m_strBack ); |
|
} |
|
} |
|
|
|
UpdateInvalidReasons(); |
|
|
|
if ( m_pItemTrackerPanel ) |
|
{ |
|
auto& vecObjectives = m_pItemTrackerPanel->GetAttributePanels(); |
|
FOR_EACH_VEC( vecObjectives, i ) |
|
{ |
|
// Only do this when unidentified. The panel updates its own string, and we don't want to stomp it |
|
if ( m_eState == STATE_UNIDENTIFIED ) |
|
{ |
|
const wchar_t *pszString = GetDecodedString( CFmtStr( "objective%d", i ), flDecodeAmount ); |
|
vecObjectives[ i ]->SetDialogVariable( "attr_desc", pszString ); |
|
} |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
bool CQuestItemPanel::IsCursorOverMainContainer() const |
|
{ |
|
return m_pMainContainer ? m_pMainContainer->IsCursorOver() : false; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestItemPanel::SetupObjectivesPanels( bool bRecreate ) |
|
{ |
|
if ( m_pItemTrackerPanel && bRecreate ) |
|
{ |
|
m_pItemTrackerPanel->MarkForDeletion(); |
|
m_pItemTrackerPanel = NULL; |
|
} |
|
|
|
if ( !m_hQuestItem ) |
|
return; |
|
|
|
if ( !m_pItemTrackerPanel ) |
|
{ |
|
m_pItemTrackerPanel = new CItemTrackerPanel( m_pFlavorScrollingContainer, "ItemTrackerPanel", m_hQuestItem->GetSOCData(), m_strItemTrackerResFile ); |
|
m_pItemTrackerPanel->SetAutoDelete( false ); |
|
SETUP_PANEL( m_pItemTrackerPanel ); |
|
} |
|
else |
|
{ |
|
// Get all the panels created |
|
m_pItemTrackerPanel->SetItem( m_hQuestItem->GetSOCData() ); |
|
m_pItemTrackerPanel->InvalidateLayout( true ); |
|
} |
|
|
|
m_pItemTrackerPanel->SetTall( m_pItemTrackerPanel->GetContentTall() ); |
|
|
|
// Need to re-layout so the flavor text gets properly positioned under |
|
// all of the objectives |
|
InvalidateLayout(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestItemPanel::SetItem( CEconItemView* pItem ) |
|
{ |
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); |
|
if ( pItem == m_hQuestItem ) |
|
{ |
|
return; |
|
} |
|
|
|
m_bCollapsed = true; |
|
m_hQuestItem.SetItem( pItem ); |
|
|
|
if ( m_pItemTrackerPanel && pItem ) |
|
{ |
|
m_pItemTrackerPanel->SetItem( pItem->GetSOCData() ); |
|
} |
|
|
|
// By default |
|
SetState( STATE_NORMAL ); |
|
|
|
if ( m_hQuestItem ) |
|
{ |
|
if ( IsQuestItemReadyToTurnIn( m_hQuestItem ) ) |
|
{ |
|
SetState( STATE_COMPLETED ); |
|
} |
|
else if ( IsUnacknowledged() ) |
|
{ |
|
SetState( STATE_UNIDENTIFIED ); |
|
} |
|
|
|
// Snag the quickplay map (if there is one) |
|
m_strQuickPlayMap = m_hQuestItem->GetItemDefinition()->GetQuestDef()->GetQuickplayMapName(); |
|
|
|
m_strMatchmakingGroupName = m_hQuestItem->GetItemDefinition()->GetQuestDef()->GetMatchmakingGroupName(); |
|
m_strMatchmakingCategoryName = m_hQuestItem->GetItemDefinition()->GetQuestDef()->GetMatchmakingCategoryName(); |
|
m_strMatchmakingMapName = m_hQuestItem->GetItemDefinition()->GetQuestDef()->GetMatchmakingMapName(); |
|
} |
|
|
|
// Reload res file so we get the right art |
|
LoadResFileForCurrentItem(); |
|
|
|
// Capture strings after controls are created |
|
CaptureAndEncodeStrings(); |
|
|
|
InvalidateLayout(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Returns if the character is one that we don't want to re-encode |
|
// as another, or one that we don't want to encode another to in |
|
// order to maintain line breaks so that the decoding sequence is |
|
// easier for the user to follow. |
|
//----------------------------------------------------------------------------- |
|
bool IsNonEncodeCharacter( const wchar_t& wch) |
|
{ |
|
switch ( wch ) |
|
{ |
|
case L'\x000A': |
|
case L'\x000B': |
|
case L'\x000C': |
|
case L'\x000D': |
|
case L'\x0085': |
|
case L'\x2028': |
|
case L'\x2029': |
|
case L' ': |
|
return true; |
|
} |
|
|
|
return false; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestItemPanel::CaptureAndEncodeStrings() |
|
{ |
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); |
|
|
|
if ( !m_hQuestItem ) |
|
return; |
|
|
|
// Clean up any existing values |
|
if ( m_pKVCipherStrings ) |
|
{ |
|
m_pKVCipherStrings->deleteThis(); |
|
m_pKVCipherStrings = NULL; |
|
} |
|
|
|
m_pKVCipherStrings = new KeyValues( "cipherstrings" ); |
|
KeyValues *pKVDecoded = m_pKVCipherStrings->CreateNewKey(); |
|
pKVDecoded->SetName( "decoded" ); |
|
|
|
{ |
|
// Capture the description/flavor string |
|
const char *pszLocToken = m_hQuestItem->GetItemDefinition()->GetQuestDef()->GetRolledDescriptionForItem( m_hQuestItem->GetSOCData() ); |
|
pKVDecoded->SetWString( "desc", g_pVGuiLocalize->Find( pszLocToken ) ); |
|
} |
|
|
|
if ( m_pObjectiveExplanationLabel ) |
|
{ |
|
wchar_t wszBuff[512]; |
|
m_pObjectiveExplanationLabel->GetText( wszBuff, ARRAYSIZE( wszBuff ) ); |
|
pKVDecoded->SetWString( "explanation", wszBuff ); |
|
} |
|
|
|
auto& vecObjectives = m_pItemTrackerPanel->GetAttributePanels(); |
|
// Capture objective strings |
|
FOR_EACH_VEC( vecObjectives, i ) |
|
{ |
|
CItemAttributeProgressPanel *pObjective = vecObjectives[ i ]; |
|
KeyValues *pKV = pObjective->GetDialogVariables(); |
|
pKVDecoded->SetWString( CFmtStr( "objective%d", i ), pKV->GetWString( "attr_desc" ) ); |
|
} |
|
|
|
// Create encoded strings from the decoded strings |
|
KeyValues *pKVEncoded = pKVDecoded->MakeCopy(); |
|
pKVEncoded->SetName( "encoded" ); |
|
|
|
m_pKVCipherStrings->AddSubKey( pKVEncoded ); |
|
|
|
RandomSeed( m_hQuestItem->GetSOCData() ? m_hQuestItem->GetSOCData()->GetOriginalID() : m_hQuestItem->GetItemDefIndex() ); |
|
|
|
// "encode" each string by scrambling |
|
FOR_EACH_VALUE( pKVEncoded, pKVString ) |
|
{ |
|
const wchar_t *pWString = pKVString->GetWString(); |
|
wchar wszBuff[4096]; |
|
loc_scpy_safe( wszBuff, pWString ); |
|
int nStrLen = Q_wcslen( wszBuff ); |
|
|
|
// Go through the entire string and swap each character |
|
// with another random character in the string |
|
int i=0; |
|
while( wszBuff[i] != 0 && i < ARRAYSIZE( wszBuff ) ) |
|
{ |
|
// Dont scramble spaces to maintain line breaks |
|
if ( !IsNonEncodeCharacter( wszBuff[i] ) ) |
|
{ |
|
// Scramble, but keep trying if we scramble to a space |
|
do |
|
{ |
|
wszBuff[i] = *(pWString + RandomInt( 0, nStrLen - 1 ) ); |
|
} while ( IsNonEncodeCharacter( wszBuff[i] ) ); |
|
|
|
} |
|
|
|
i++; |
|
} |
|
|
|
pKVEncoded->SetWString( pKVString->GetName(), wszBuff ); |
|
} |
|
|
|
const char *pszLocToken = m_hQuestItem->GetItemDefinition()->GetQuestDef()->GetRolledNameForItem( m_hQuestItem->GetSOCData() ); |
|
const wchar_t* pwszName = g_pVGuiLocalize->Find( pszLocToken ); |
|
// Force the encrypted version of the quest title to be "<Encrypted>". |
|
pKVEncoded->SetWString( "name", g_pVGuiLocalize->Find( m_strEncodedText ) ); |
|
pKVDecoded->SetWString( "name", pwszName ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestItemPanel::OnCommand( const char *command ) |
|
{ |
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); |
|
BaseClass::OnCommand( command ); |
|
|
|
if ( FStrEq( command, "discard_quest" ) ) |
|
{ |
|
OnDiscardQuest(); |
|
} |
|
else if ( FStrEq( command, "select" ) ) |
|
{ |
|
m_pQuestList->SetSelected( this, false ); |
|
} |
|
else if ( FStrEq( command, "turnin" ) ) |
|
{ |
|
if ( m_hQuestItem && m_hQuestItem->GetItemDefinition() && m_hQuestItem->GetItemDefinition()->GetQuestDef() ) |
|
{ |
|
if ( !tf_quest_turn_in_confirm_opt_out.GetBool() && ( GetEarnedBonusPoints( m_hQuestItem ) != m_hQuestItem->GetItemDefinition()->GetQuestDef()->GetMaxBonusPoints() ) ) |
|
{ |
|
CTFGenericConfirmOptOutDialog *pPanel = ShowConfirmOptOutDialog( "#TF_Quest_TurnIn_Title", "#TF_Quest_TurnIn_Text", |
|
"#TF_Quest_TurnIn_Yes", "#TF_Quest_TurnIn_No", |
|
"#TF_Quest_TurnIn_Ask_Opt_Out", "tf_quest_turn_in_confirm_opt_out", |
|
ConfirmTurnInQuest ); |
|
if ( pPanel ) |
|
{ |
|
pPanel->SetContext( this ); |
|
return; |
|
} |
|
} |
|
else |
|
{ |
|
OnCompleteQuest(); |
|
} |
|
} |
|
} |
|
else if ( FStrEq( command, "identify" ) ) |
|
{ |
|
OnIdentify(); |
|
} |
|
else if ( FStrEq( command, "request_loaner_items" ) ) |
|
{ |
|
GCSDK::CProtoBufMsg< CMsgGCQuestObjective_RequestLoanerItems > msg( k_EMsgGCQuestObjective_RequestLoanerItems ); |
|
msg.Body().set_quest_item_id( m_hQuestItem->GetItemID() ); |
|
GCClientSystem()->BSendMessage( msg ); |
|
} |
|
else if ( FStrEq( command, "equip_loaner_items" ) ) |
|
{ |
|
OnEquipLoaners(); |
|
} |
|
else if( Q_strnicmp( "playsound", command, 9 ) == 0 ) |
|
{ |
|
vgui::surface()->PlaySound( command + 10 ); |
|
} |
|
else if ( FStrEq( "mm_casual_open", command ) ) |
|
{ |
|
if ( GTFGCClientSystem() ) |
|
{ |
|
if ( ( m_strMatchmakingGroupName != 0 ) || ( m_strMatchmakingCategoryName != 0 ) || ( m_strMatchmakingMapName != 0 ) ) |
|
{ |
|
GTFGCClientSystem()->ClearCasualSearchCriteria(); |
|
|
|
if ( m_strMatchmakingGroupName != 0 ) |
|
{ |
|
int iGroupType = StringFieldToInt( m_strMatchmakingGroupName.Get(), s_pszMMTypes, ARRAYSIZE( s_pszMMTypes ) ); |
|
if ( iGroupType > -1 ) |
|
{ |
|
SelectGroup( (EMatchmakingGroupType)iGroupType, true ); |
|
} |
|
} |
|
|
|
if ( m_strMatchmakingCategoryName != 0 ) |
|
{ |
|
int iCategoryType = StringFieldToInt( m_strMatchmakingCategoryName.Get(), s_pszGameModes, ARRAYSIZE( s_pszGameModes ) ); |
|
if ( iCategoryType > -1 ) |
|
{ |
|
SelectCategory( (EGameCategory)iCategoryType, true ); |
|
} |
|
} |
|
|
|
if ( m_strMatchmakingMapName != 0 ) |
|
{ |
|
if ( GetItemSchema() ) |
|
{ |
|
const MapDef_t *pMap = GetItemSchema()->GetMasterMapDefByName( m_strMatchmakingMapName.Get() ); |
|
if ( pMap ) |
|
{ |
|
GTFGCClientSystem()->SelectCasualMap( pMap->m_nDefIndex, true ); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
// Defaulting to 12v12 |
|
GTFGCClientSystem()->SetLadderType( k_nMatchGroup_Casual_12v12 ); |
|
PromptOrFireCommand( "OpenMatchmakingLobby casual" ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
const wchar_t* CQuestItemPanel::GetDecodedString( const char* pszKeyName, float flPercentDecoded ) |
|
{ |
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); |
|
static wchar_t wszBuff[4096]; |
|
KeyValues *pKVEncoded = m_pKVCipherStrings->FindKey( "encoded" ); |
|
KeyValues *pKVDecoded = m_pKVCipherStrings->FindKey( "decoded" ); |
|
|
|
// Trivial work? |
|
if ( flPercentDecoded <= 0.f ) |
|
{ |
|
return pKVEncoded->GetWString( pszKeyName ); |
|
} |
|
else if ( flPercentDecoded >= 1.f ) |
|
{ |
|
return pKVDecoded->GetWString( pszKeyName ); |
|
} |
|
|
|
loc_scpy_safe( wszBuff, pKVEncoded->GetWString( pszKeyName ) ); |
|
const locchar_t* pwszDecoded = pKVDecoded->GetWString( pszKeyName ); |
|
int nLength = loc_strlen( pwszDecoded ); |
|
int nMaxCopy = nLength * flPercentDecoded; |
|
// Not using V_wcsncpy because it null terminates. |
|
wcsncpy( wszBuff, pwszDecoded, nMaxCopy ); |
|
|
|
return wszBuff; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestItemPanel::OnThink() |
|
{ |
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); |
|
|
|
switch ( m_eState ) |
|
{ |
|
case STATE_IDENTIFYING: |
|
{ |
|
// Have we finished? |
|
if ( m_StateTimer.HasStarted() && m_StateTimer.IsElapsed() ) |
|
{ |
|
m_pItemTrackerPanel->InvalidateLayout(); |
|
m_StateTimer.Invalidate(); |
|
SetState( STATE_NORMAL ); |
|
|
|
// Play a reveal sound? |
|
const GameItemDefinition_t *pItemDef = m_hQuestItem->GetItemDefinition(); |
|
const CQuestThemeDefinition *pTheme = pItemDef->GetQuestDef()->GetQuestTheme(); |
|
if ( pTheme ) |
|
{ |
|
const char *pszRevealSound = pTheme->GetRevealSound(); |
|
if ( pszRevealSound && pszRevealSound[0] ) |
|
{ |
|
vgui::surface()->PlaySound( pszRevealSound ); |
|
} |
|
} |
|
} |
|
|
|
float flPercent = m_StateTimer.GetElapsedTime() / m_StateTimer.GetCountdownDuration(); |
|
|
|
switch( m_eDecodeStyle ) |
|
{ |
|
case DECODE_STYLE_CYPHER: |
|
{ |
|
// Slowly "decode" the text in the lables |
|
m_pTitleButton->SetText( GetDecodedString( "name", flPercent ) ); |
|
m_pFlavorText->SetText( GetDecodedString( "desc", flPercent ) ); |
|
m_pObjectiveExplanationLabel->SetText( GetDecodedString( "explanation", flPercent ) ); |
|
|
|
auto& vecObjectives = m_pItemTrackerPanel->GetAttributePanels(); |
|
FOR_EACH_VEC( vecObjectives, i ) |
|
{ |
|
const wchar_t *pszString = GetDecodedString( CFmtStr( "objective%d", i ), flPercent ); |
|
vecObjectives[ i ]->SetDialogVariable( "attr_desc", pszString ); |
|
} |
|
break; |
|
} |
|
case DECODE_STYLE_PANEL_FADE: |
|
{ |
|
// Slowly fade out the encode image |
|
m_pEncodedImage->SetAlpha( 255 * ( 1.f - flPercent ) ); |
|
break; |
|
} |
|
default: |
|
Assert( 0 ); |
|
} |
|
|
|
break; |
|
} |
|
case STATE_TURNING_IN__WAITING_FOR_GC: |
|
{ |
|
// Have we finished? |
|
if ( m_StateTimer.HasStarted() && m_StateTimer.IsElapsed() ) |
|
{ |
|
m_pQuestList->SetCompletingPanel( NULL ); |
|
m_StateTimer.Invalidate(); |
|
|
|
// Bring up confirm dialog |
|
CTFGenericConfirmDialog *pDialog = new CTFGenericConfirmDialog( "#TF_Trading_Timeout_Title", "#TF_Trading_Timeout_Text", "#TF_OK", NULL, NULL, NULL ); |
|
|
|
if ( pDialog ) |
|
{ |
|
pDialog->SetContext( this ); |
|
pDialog->Show(); |
|
} |
|
|
|
SetState( STATE_COMPLETED ); |
|
} |
|
|
|
// Intentionally fall through |
|
} |
|
case STATE_TURNING_IN__GC_RESPONDED: |
|
{ |
|
// Have we finished? |
|
if ( m_StateTimer.HasStarted() && m_StateTimer.IsElapsed() ) |
|
{ |
|
SetState( STATE_SHOW_ACCEPTED ); |
|
m_StateTimer.Start( 3.f ); |
|
m_pAcceptedImage->SetVisible( true ); |
|
|
|
vgui::surface()->PlaySound( m_strTurnInSuccessSound ); |
|
} |
|
|
|
if ( m_pTurningInLabel ) |
|
{ |
|
int nPeriods = m_StateTimer.GetElapsedTime() / 0.3f; |
|
nPeriods %= 4; // Only do up to 3 periods |
|
|
|
wchar_t wszTurningInText[64]; |
|
char szTurningInLocToken[128]; |
|
m_pTurningInLabel->GetTextImage()->GetUnlocalizedText( szTurningInLocToken, ARRAYSIZE( szTurningInLocToken ) ); |
|
V_snwprintf( wszTurningInText, ARRAYSIZE( wszTurningInText ), L"%ls", g_pVGuiLocalize->Find( szTurningInLocToken ) ); |
|
|
|
while ( nPeriods > 0 ) |
|
{ |
|
V_wcsncat( wszTurningInText, L".", ARRAYSIZE( wszTurningInText ) ); |
|
--nPeriods; |
|
} |
|
|
|
m_pTurningInLabel->SetText( wszTurningInText ); |
|
} |
|
|
|
break; |
|
} |
|
case STATE_SHOW_ACCEPTED: |
|
{ |
|
if ( m_StateTimer.HasStarted() && m_StateTimer.IsElapsed() ) |
|
{ |
|
m_pQuestList->SetCompletingPanel( NULL ); |
|
m_StateTimer.Invalidate(); |
|
|
|
engine->ClientCmd_Unrestricted( "gameui_allowescapetoshow\n" ); |
|
|
|
InventoryManager()->ShowItemsPickedUp( true, false ); |
|
GetQuestLog()->AttachToGameUI(); |
|
GetQuestLog()->MarkQuestsDirty(); |
|
m_pQuestList->PopulateQuestLists(); |
|
|
|
engine->ClientCmd_Unrestricted( "gameui_preventescapetoshow\n" ); |
|
|
|
if ( m_pszCompleteSound ) |
|
{ |
|
vgui::surface()->PlaySound( m_pszCompleteSound ); |
|
} |
|
} |
|
else |
|
{ |
|
float flPercent = Clamp( m_StateTimer.GetElapsedTime() / 0.2f, 0.f, 1.f ); |
|
m_nPaperXShakePos = sin( m_StateTimer.GetElapsedTime() * 200.f ) * ( 1.f - flPercent ) * 8.f; |
|
m_nPaperYShakePos = sin( m_StateTimer.GetElapsedTime() * 200.f ) * ( 1.f - flPercent ) * 8.f; |
|
m_pQuestPaperContainer->SetPos( m_nPaperXPos + m_nPaperXShakePos, m_nPaperYPos + m_nPaperYShakePos ); |
|
} |
|
|
|
break; |
|
} |
|
case STATE_UNIDENTIFIED: |
|
{ |
|
// Do nothing |
|
break; |
|
} |
|
case STATE_COMPLETED: |
|
{ |
|
// Do nothing |
|
break; |
|
} |
|
default: |
|
// Do nothing |
|
break; |
|
} |
|
|
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestItemPanel::FireGameEvent( IGameEvent *event ) |
|
{ |
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); |
|
if( FStrEq( event->GetName(), "quest_objective_completed" ) ) |
|
{ |
|
itemid_t nIDLow = 0x00000000FFFFFFFF & (itemid_t)event->GetInt( "quest_item_id_low" ); |
|
itemid_t nIDHi = 0xFFFFFFFF00000000 & (itemid_t)event->GetInt( "quest_item_id_hi" ) << 32; |
|
itemid_t nID = nIDLow | nIDHi; |
|
if ( m_hQuestItem && nID == m_hQuestItem->GetID() ) |
|
{ |
|
SetupObjectivesPanels( false ); |
|
|
|
if ( IsQuestItemReadyToTurnIn( m_hQuestItem ) ) |
|
{ |
|
SetState( STATE_COMPLETED ); |
|
} |
|
|
|
PerformLayout(); |
|
} |
|
} |
|
else if ( FStrEq( event->GetName(), "player_spawn" ) |
|
|| FStrEq( event->GetName(), "client_disconnect" ) ) |
|
{ |
|
InvalidateLayout(); |
|
} |
|
else if ( FStrEq( "inventory_updated", event->GetName() ) ) |
|
{ |
|
// InvalidateLayout(); |
|
} |
|
} |
|
|
|
void CQuestItemPanel::OnMouseReleased( MouseCode code ) |
|
{ |
|
OnCommand( "select" ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Update our invalid reasons |
|
//----------------------------------------------------------------------------- |
|
void CQuestItemPanel::UpdateInvalidReasons() |
|
{ |
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); |
|
InvalidReasonsContainer_t invalidReasons; |
|
bool bAllAreInvalid = false; |
|
|
|
C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer(); |
|
if ( pLocalPlayer && m_hQuestItem ) |
|
{ |
|
// Get the tracker for the items |
|
const CQuestItemTracker* pItemTracker = QuestObjectiveManager()->GetTypedTracker< CQuestItemTracker* >( m_hQuestItem->GetItemID() ); |
|
// Get invalid reasons |
|
if ( pItemTracker ) |
|
{ |
|
int nNumInvalid = pItemTracker->IsValidForPlayer( pLocalPlayer, invalidReasons ); |
|
bAllAreInvalid = pItemTracker->GetTrackers().Count() == nNumInvalid; |
|
} |
|
|
|
// Build a string describing why the current quest can't be worked on |
|
if ( !invalidReasons.IsValid() ) |
|
{ |
|
CUtlVector< CUtlString > vecStrings; |
|
// Get the strings that explain each reasons |
|
GetInvalidReasonsNames( invalidReasons, vecStrings ); |
|
|
|
wchar_t wszBuff[ 1024 ]; |
|
|
|
// Start with the explanation |
|
V_swprintf_safe( wszBuff, L"%ls", g_pVGuiLocalize->Find( "#TF_QuestInvalid_Explanation" ) ); |
|
|
|
// Add in each reason why the quest is invalid |
|
for( int i = 0; i < vecStrings.Count(); ++ i ) |
|
{ |
|
V_wcscat_safe( wszBuff, L"\n\n" ); |
|
V_wcscat_safe( wszBuff, g_pVGuiLocalize->Find( vecStrings[i] ) ); |
|
} |
|
|
|
// This gets snagged by CQuestTooltip |
|
m_pInactiveStatus->SetDialogVariable( "tiptext", wszBuff ); |
|
} |
|
} |
|
|
|
// Visible if there's a reason why we're invalid |
|
bool bShow = bAllAreInvalid && m_eState == STATE_NORMAL; |
|
m_pInactiveStatus->SetShow( bShow ); |
|
m_pInactiveStatus->SetMouseInputEnabled( bShow ); |
|
m_pInactiveStatus->SetTooltip( g_spTextTooltip, NULL ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Start a glow |
|
//----------------------------------------------------------------------------- |
|
void CQuestItemPanel::OnCollapsedGlowStart( void ) |
|
{ |
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, m_strHighlightOn ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Stop the glow |
|
//----------------------------------------------------------------------------- |
|
void CQuestItemPanel::OnCollapsedGlowEnd( void ) |
|
{ |
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, m_strHighlightOff ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Delete the quest. |
|
//----------------------------------------------------------------------------- |
|
void CQuestItemPanel::OnDiscardQuest( void ) |
|
{ |
|
#if !defined(STAGING_ONLY) && !defined(DEBUG) |
|
// Not in public! |
|
return; |
|
#endif |
|
|
|
if ( m_pQuestList->GetCompletingPanel() == NULL ) |
|
{ |
|
// Bring up confirm dialog |
|
CTFGenericConfirmDialog *pDialog = new CTFGenericConfirmDialog( "#QuestConfirmDiscard_Title", "#QuestConfirmDiscard_Body", "#X_DiscardItem", "#Cancel", &ConfirmDiscardQuest, NULL ); |
|
if ( pDialog ) |
|
{ |
|
pDialog->SetContext( this ); |
|
pDialog->Show(); |
|
} |
|
|
|
const GameItemDefinition_t *pItemDef = m_hQuestItem->GetItemDefinition(); |
|
// Get our quest theme |
|
const CQuestThemeDefinition *pTheme = pItemDef->GetQuestDef()->GetQuestTheme(); |
|
if ( pTheme ) |
|
{ |
|
const char *pszDiscardSound = pTheme->GetDiscardSound(); |
|
if ( pszDiscardSound && pszDiscardSound[0] ) |
|
{ |
|
vgui::surface()->PlaySound( pszDiscardSound ); |
|
} |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Equip loaners for local player |
|
//----------------------------------------------------------------------------- |
|
void CQuestItemPanel::OnEquipLoaners( void ) |
|
{ |
|
if ( !m_hQuestItem ) |
|
return; |
|
|
|
if ( m_pQuestList->GetCompletingPanel() == NULL ) |
|
{ |
|
// Bring up confirm dialog |
|
CTFGenericConfirmDialog *pDialog = new CTFGenericConfirmDialog( "#QuestConfirmEquipLoaners_Title", "#QuestConfirmEquipLoaners_Body", "#Equip", "#Cancel", &ConfirmEquipLoaners, NULL ); |
|
if ( pDialog ) |
|
{ |
|
pDialog->SetContext( this ); |
|
pDialog->Show(); |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Send a message to the GC to evaluate completion of this quest |
|
//----------------------------------------------------------------------------- |
|
void CQuestItemPanel::OnCompleteQuest( void ) |
|
{ |
|
if ( !m_hQuestItem ) |
|
return; |
|
|
|
// Double check that they're not just forcing the command |
|
if ( IsQuestItemReadyToTurnIn( m_hQuestItem ) && m_pQuestList->GetCompletingPanel() == NULL ) |
|
{ |
|
m_pQuestList->SetCompletingPanel( this ); |
|
|
|
SetState( STATE_TURNING_IN__WAITING_FOR_GC ); |
|
|
|
// Use the timer for turning in the quest |
|
m_StateTimer.Start( k_flQuestTurnInTime ); |
|
vgui::surface()->PlaySound( m_strTurnInSound ); |
|
|
|
GCSDK::CProtoBufMsg< CMsgGCQuestComplete_Request > msg( k_EMsgGCQuestComplete_Request ); |
|
|
|
msg.Body().set_quest_item_id( m_hQuestItem->GetItemID() ); |
|
|
|
GCClientSystem()->BSendMessage( msg ); |
|
|
|
PostActionSignal( new KeyValues("CompleteQuest") ); |
|
|
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, m_strTurningIn ); |
|
|
|
const GameItemDefinition_t *pItemDef = m_hQuestItem->GetItemDefinition(); |
|
// Get our quest theme |
|
const CQuestThemeDefinition *pTheme = pItemDef->GetQuestDef()->GetQuestTheme(); |
|
if ( pTheme ) |
|
{ |
|
m_pszCompleteSound = pTheme->GetRewardSound(); |
|
} |
|
} |
|
} |
|
|
|
void CQuestItemPanel::OnIdentify() |
|
{ |
|
if ( IsUnacknowledged() ) |
|
{ |
|
SetState( STATE_IDENTIFYING ); |
|
|
|
// Use the timer for identifying progress |
|
m_StateTimer.Start( k_flQuestDecodeTime ); |
|
vgui::surface()->PlaySound( m_strDecodeSound ); |
|
|
|
// ack item |
|
CEconItemView *pModifyItem = m_hQuestItem; |
|
TFInventoryManager()->AcknowledgeItem( pModifyItem, false ); |
|
TFInventoryManager()->SetItemBackpackPosition( pModifyItem, (uint32)-1, false, true ); |
|
|
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( m_pQuestPaperContainer, "QuestItem_StaticPhoto_Reveal" ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestItemPanel::OnConfirmDelete( bool bConfirm ) |
|
{ |
|
// Delete the quest |
|
if ( bConfirm && m_hQuestItem ) |
|
{ |
|
GCSDK::CProtoBufMsg< CMsgGCQuestDiscard_Request > msg( k_EMsgGCQuestDiscard_Request ); |
|
|
|
msg.Body().set_quest_item_id( m_hQuestItem->GetItemID() ); |
|
|
|
GCClientSystem()->BSendMessage( msg ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestItemPanel::OnConfirmEquipLoaners( bool bConfirm ) |
|
{ |
|
// equip loaners |
|
if ( bConfirm && m_hQuestItem ) |
|
{ |
|
// get all loaners required from quest |
|
CUtlVector< item_definition_index_t > vecLoanerItems; |
|
bool bRequiredLoaners = GetLoanerListFromQuest( m_hQuestItem, vecLoanerItems ); |
|
|
|
// get all granted loaners from this quest |
|
CUtlVector< CEconItemView* > vecGrantedLoaners; |
|
if ( bRequiredLoaners ) |
|
{ |
|
GetLoanersFromLocalInventory( m_hQuestItem->GetItemID(), vecLoanerItems, vecGrantedLoaners ); |
|
} |
|
|
|
for ( int i=0; i<vecGrantedLoaners.Count(); ++i ) |
|
{ |
|
CEconItemView *pItem = vecGrantedLoaners[i]; |
|
if ( pItem ) |
|
{ |
|
// do it for first class that can equip |
|
for ( int iClass = TF_FIRST_NORMAL_CLASS; iClass < TF_LAST_NORMAL_CLASS; ++iClass ) |
|
{ |
|
if ( pItem->GetStaticData()->CanBeUsedByClass( iClass ) ) |
|
{ |
|
int iSlot = pItem->GetStaticData()->GetLoadoutSlot( iClass ); |
|
TFInventoryManager()->EquipItemInLoadout( iClass, iSlot, pItem->GetItemID() ); |
|
|
|
// take the player to character loadout page |
|
engine->ClientCmd_Unrestricted( CFmtStr( "open_charinfo_direct %d", iClass ) ); |
|
break; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestItemPanel::QuestCompletedResponse() |
|
{ |
|
// If we werent the one listening, dont bother |
|
if ( m_eState != STATE_TURNING_IN__WAITING_FOR_GC ) |
|
return; |
|
|
|
m_pQuestPaperContainer->GetPos( m_nPaperXPos, m_nPaperYPos ); |
|
m_nPaperXShakePos = m_nPaperYShakePos = 0; |
|
|
|
SetState( STATE_TURNING_IN__GC_RESPONDED ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestItemPanel::SetSelected( bool bSelected, bool bImmediate ) |
|
{ |
|
bool bPrevCollapsedSide = m_bCollapsed; |
|
m_bCollapsed = ( !m_bCollapsed && bSelected ) || ( !bSelected ); |
|
|
|
if ( !bImmediate && bPrevCollapsedSide != m_bCollapsed ) |
|
{ |
|
if ( m_bCollapsed ) |
|
{ |
|
vgui::surface()->PlaySound( m_strCollapseSound ); |
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, m_strAnimCollapse ); |
|
} |
|
else |
|
{ |
|
vgui::surface()->PlaySound( m_strExpandSound ); |
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, m_strAnimExpand ); |
|
} |
|
} |
|
else |
|
{ |
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, m_strReset ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
bool CQuestItemPanel::IsUnacknowledged() |
|
{ |
|
if ( !m_hQuestItem ) |
|
return false; |
|
|
|
return IsQuestItemUnidentified( m_hQuestItem->GetSOCData() ); |
|
} |
|
|
|
void CQuestItemPanel::SetState( EItemPanelState_t eState ) |
|
{ |
|
m_eState = eState; |
|
InvalidateLayout(); |
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: GC Msg handler to handle a loaner item response |
|
//----------------------------------------------------------------------------- |
|
class CGCLoanerRequestResponse : public GCSDK::CGCClientJob |
|
{ |
|
public: |
|
CGCLoanerRequestResponse( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {} |
|
|
|
virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket ) |
|
{ |
|
GCSDK::CProtoBufMsg<CMsgGCQuestObjective_RequestLoanerResponse> msg( pNetPacket ); |
|
|
|
// Show them the items they just got loaned! |
|
InventoryManager()->ShowItemsPickedUp( true, false ); |
|
|
|
return true; |
|
} |
|
}; |
|
|
|
GC_REG_JOB( GCSDK::CGCClient, CGCLoanerRequestResponse, "CGCLoanerRequestResponse", k_EMsgGCQuestObjective_RequestLoanerResponse, GCSDK::k_EServerTypeGCClient );
|
|
|