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.
1182 lines
37 KiB
1182 lines
37 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//=============================================================================// |
|
|
|
#include "cbase.h" |
|
#include "quest_log_panel.h" |
|
#include "ienginevgui.h" |
|
#include "c_tf_gamestats.h" |
|
#include "store/store_panel.h" |
|
#include "econ/econ_ui.h" |
|
#include "clientmode_tf.h" |
|
#include "tf_hud_mainmenuoverride.h" |
|
#include "vgui_int.h" |
|
#include "IGameUIFuncs.h" // for key bindings |
|
#include <vgui_controls/AnimationController.h> |
|
#include "tf_item_inventory.h" |
|
#include "vgui/IInput.h" |
|
#include "item_ad_panel.h" |
|
#include "vgui_controls/ProgressBar.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include <tier0/memdbgon.h> |
|
|
|
void AddSubKeyNamed( KeyValues *pKeys, const char *pszName ); |
|
|
|
static CItemModelPanelToolTip* g_spItemTooltip = NULL; |
|
CQuestTooltip* g_spTextTooltip = NULL; |
|
|
|
CQuestLogPanel *GetQuestLog() |
|
{ |
|
CQuestLogPanel *pQuestLogPanel = (CQuestLogPanel*)gViewPortInterface->FindPanelByName( PANEL_QUEST_LOG ); |
|
return pQuestLogPanel; |
|
} |
|
|
|
//------------------------------------------------------------------------------------------------------------------- |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CScrollableQuestList::CScrollableQuestList( vgui::Panel *parent, const char *pszPanelName ) |
|
: EditablePanel( parent, pszPanelName ) |
|
, m_pCompletingPanel( NULL ) |
|
, m_bQuestsLayoutDirty( false ) |
|
, m_pszNoQuests( NULL ) |
|
, m_pszNeedAPass( NULL ) |
|
, m_pszNotPossible( NULL ) |
|
{ |
|
m_pContainer = new EditablePanel( this, "Container" ); |
|
m_vecQuestItemPanels.SetSize( 2 ); |
|
|
|
FOR_EACH_VEC( m_vecQuestItemPanels, i ) |
|
{ |
|
m_vecQuestItemPanels[ i ] = new CQuestItemPanel( m_pContainer, "QuestItemPanel", NULL, this ); |
|
} |
|
} |
|
|
|
CScrollableQuestList::~CScrollableQuestList() |
|
{ |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CScrollableQuestList::ApplySchemeSettings( vgui::IScheme *pScheme ) |
|
{ |
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); |
|
BaseClass::ApplySchemeSettings( pScheme ); |
|
|
|
const char *pszResFile = "Resource/UI/econ/ScrollableQuestList.res"; |
|
|
|
// Check if the operation wants to override our default res file |
|
const auto& mapOperations = GetItemSchema()->GetOperationDefinitions(); |
|
FOR_EACH_MAP_FAST( mapOperations, i ) |
|
{ |
|
CEconOperationDefinition* pCurrentOperation = mapOperations[i]; |
|
// Take the first active operation's res file that's different than default |
|
if ( pCurrentOperation->IsActive() && pCurrentOperation->GetQuestListOverrideResFile() ) |
|
{ |
|
// Use the first found for now |
|
pszResFile = pCurrentOperation->GetQuestListOverrideResFile(); |
|
break; |
|
} |
|
} |
|
|
|
LoadControlSettings( pszResFile ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CScrollableQuestList::ApplySettings( KeyValues *inResourceData ) |
|
{ |
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); |
|
BaseClass::ApplySettings( inResourceData ); |
|
|
|
m_pszNoQuests = inResourceData->GetString( "no_quests", "#QuestLog_NoQuests" ); |
|
m_pszNeedAPass = inResourceData->GetString( "need_a_pass", "#QuestLog_NeedPassForContracts" ); |
|
m_pszNotPossible = inResourceData->GetString( "not_possible", "#QuestLog_NoContractsPossible" ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CScrollableQuestList::PerformLayout( void ) |
|
{ |
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); |
|
BaseClass::PerformLayout(); |
|
|
|
m_pContainer->InvalidateLayout( true ); |
|
|
|
FOR_EACH_VEC( m_vecQuestItemPanels, i ) |
|
{ |
|
m_vecQuestItemPanels[ i ]->InvalidateLayout( true, true ); |
|
m_vecQuestItemPanels[ i ]->SetZPos( 1 + i ); |
|
} |
|
|
|
PositionQuestItemPanels(); |
|
|
|
UpdateEmptyMessage(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CScrollableQuestList::OnThink() |
|
{ |
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); |
|
if ( m_bQuestsLayoutDirty ) |
|
{ |
|
m_bQuestsLayoutDirty = false; |
|
|
|
PositionQuestItemPanels(); |
|
} |
|
|
|
// Conditionally turn mouse input on/off based on where the mouse is |
|
FOR_EACH_VEC( m_vecQuestItemPanels, i ) |
|
{ |
|
m_vecQuestItemPanels[i]->SetMouseInputEnabled( m_vecQuestItemPanels[i]->IsCursorOverMainContainer() ); |
|
} |
|
} |
|
|
|
void CScrollableQuestList::OnCommand( const char *command ) |
|
{ |
|
if ( FStrEq( command, "deselect_all" ) ) |
|
{ |
|
SetSelected( NULL, false ); |
|
} |
|
|
|
BaseClass::OnCommand( command ); |
|
} |
|
|
|
int QuestSort_AcquiredTime( CQuestItemPanel* const* p1, CQuestItemPanel* const* p2 ) |
|
{ |
|
if ( !(*p1)->GetItem() ) |
|
return -1; |
|
|
|
if ( !(*p2)->GetItem() ) |
|
return 1; |
|
|
|
// Newest items first |
|
return (*p1)->GetItem()->GetID() - (*p2)->GetItem()->GetID(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CScrollableQuestList::PositionQuestItemPanels() |
|
{ |
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); |
|
// We dont do anything when a quest is completing |
|
if ( m_pCompletingPanel != NULL ) |
|
return; |
|
|
|
int nVisible = 0; |
|
FOR_EACH_VEC( m_vecQuestItemPanels, i ) |
|
{ |
|
CQuestItemPanel* pPanel = m_vecQuestItemPanels[i]; |
|
if ( pPanel ) |
|
{ |
|
pPanel->SetVisible( pPanel->GetItem() ); |
|
|
|
if ( pPanel->GetItem() ) |
|
{ |
|
++nVisible; |
|
} |
|
} |
|
} |
|
|
|
CExLabel *pLabel = FindControl<CExLabel>( "EmptyLabel", true ); |
|
if ( pLabel ) |
|
{ |
|
pLabel->SetVisible( nVisible == 0 ); |
|
} |
|
|
|
// Check for a selected panel |
|
const CQuestItemPanel* pSelected = NULL; |
|
FOR_EACH_VEC( m_vecQuestItemPanels, i ) |
|
{ |
|
if ( m_vecQuestItemPanels[i]->IsSelected() ) |
|
{ |
|
Assert( pSelected == NULL ); |
|
pSelected = m_vecQuestItemPanels[i]; |
|
} |
|
} |
|
|
|
struct FolderCommands_t |
|
{ |
|
const char* m_pszSelected; |
|
const char* m_pszOtherIsSelected; |
|
const char* m_pszNoneSelected; |
|
}; |
|
|
|
const FolderCommands_t folderCommands[] = { { "QuestItem_Back_Selected", "QuestItem_Back_OtherSelected", "QuestItem_Back_NoneSelected" } |
|
, { "QuestItem_Front_Selected", "QuestItem_Front_OtherSelected", "QuestItem_Front_NoneSelected" } }; |
|
|
|
// Update the positions |
|
FOR_EACH_VEC( m_vecQuestItemPanels, i ) |
|
{ |
|
// This is the selected panel |
|
if ( pSelected == m_vecQuestItemPanels[ i ] ) |
|
{ |
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( m_vecQuestItemPanels[ i ], folderCommands[i].m_pszSelected ); |
|
} |
|
else if ( pSelected ) // Some other panel is selected |
|
{ |
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( m_vecQuestItemPanels[ i ], folderCommands[i].m_pszOtherIsSelected ); |
|
} |
|
else // No panel is selected |
|
{ |
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( m_vecQuestItemPanels[ i ], folderCommands[i].m_pszNoneSelected ); |
|
} |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CScrollableQuestList::SetSelected( CQuestItemPanel *pItem, bool bImmediately ) |
|
{ |
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); |
|
FOR_EACH_VEC( m_vecQuestItemPanels, i ) |
|
{ |
|
m_vecQuestItemPanels[ i ]->SetSelected( m_vecQuestItemPanels[ i ] == pItem, bImmediately ); |
|
} |
|
|
|
PositionQuestItemPanels(); |
|
} |
|
|
|
bool DoesLootlistDropQuests( const CEconLootListDefinition* pLootList ) |
|
{ |
|
FOR_EACH_VEC( pLootList->GetLootListContents(), j ) |
|
{ |
|
const CEconLootListDefinition::drop_item_t& item = pLootList->GetLootListContents()[j]; |
|
// 0 and greater means item. Less than 0 means nested lootlist |
|
if( item.m_iItemOrLootlistDef >= 0 ) |
|
{ |
|
const GameItemDefinition_t* pItemDef = assert_cast<const GameItemDefinition_t *>( GetItemSchema()->GetItemDefinition( item.m_iItemOrLootlistDef ) ); |
|
if( pItemDef ) |
|
{ |
|
return pItemDef->GetQuestDef(); |
|
} |
|
} |
|
else |
|
{ |
|
// Get the nested lootlist |
|
int iLLIndex = (item.m_iItemOrLootlistDef * -1) - 1; |
|
const CEconLootListDefinition *pNestedLootList = GetItemSchema()->GetLootListByIndex( iLLIndex ); |
|
Assert( pNestedLootList ); |
|
if ( !pNestedLootList ) |
|
continue; |
|
|
|
// Dig through all of this lootlist's entries |
|
return DoesLootlistDropQuests( pNestedLootList ); |
|
} |
|
} |
|
|
|
return false; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Update what message we show when we have no quests |
|
//----------------------------------------------------------------------------- |
|
void CScrollableQuestList::UpdateEmptyMessage() |
|
{ |
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); |
|
|
|
CCyclingAdContainerPanel* pPassStoreAd = FindControl< CCyclingAdContainerPanel >( "ItemAd", true ); |
|
if ( !pPassStoreAd ) |
|
return; |
|
|
|
pPassStoreAd->SetVisible( false ); |
|
SetDialogVariable( "noquests", "" ); |
|
|
|
FOR_EACH_VEC( m_vecQuestItemPanels, i ) |
|
{ |
|
// Case 1 above |
|
if ( m_vecQuestItemPanels[ i ]->GetItem() ) |
|
return; |
|
} |
|
|
|
// By default, there's no operations going on, and there's no ad to show |
|
const char *pszNoQuestsText = m_pszNotPossible; |
|
|
|
// Find any active quest-dropping operations |
|
const auto& mapOperations = GetItemSchema()->GetOperationDefinitions(); |
|
FOR_EACH_MAP_FAST( mapOperations, iOperation ) |
|
{ |
|
CEconOperationDefinition *pOperation = mapOperations[ iOperation ]; |
|
const CSchemaLootListDefHandle pOperationLootlist( pOperation->GetOperationLootlist() ); |
|
// Must still be dropping, and be dropping quests |
|
if ( CRTime::RTime32TimeCur() < pOperation->GetStopGivingToPlayerDate() && pOperationLootlist && DoesLootlistDropQuests( pOperationLootlist ) ) |
|
{ |
|
// If there's a required item and a gateway item |
|
if ( pOperation->GetRequiredItemDefIndex() != INVALID_ITEM_DEF_INDEX && pOperation->GetGatewayItemDefIndex() != INVALID_ITEM_DEF_INDEX ) |
|
{ |
|
// And the user doesn't have the required item |
|
if ( TFInventoryManager()->GetLocalTFInventory()->FindFirstItembyItemDef( pOperation->GetRequiredItemDefIndex() ) == NULL ) |
|
{ |
|
// The user needs to get the item |
|
pszNoQuestsText = m_pszNeedAPass; |
|
|
|
bool bStoreIsReady = EconUI()->GetStorePanel() && EconUI()->GetStorePanel()->GetPriceSheet() && EconUI()->GetStorePanel()->GetCart() && steamapicontext && steamapicontext->SteamUser(); |
|
bool bGatewayItemInStore = false; |
|
// Check if the gateway item is in the Mann Co Store |
|
if ( bStoreIsReady ) |
|
{ |
|
bGatewayItemInStore = EconUI()->GetStorePanel()->GetPriceSheet()->GetEntry( pOperation->GetGatewayItemDefIndex() ) != NULL; |
|
} |
|
|
|
CEconItemDefinition* pGatewayItemDef = GetItemSchema()->GetItemDefinition( pOperation->GetGatewayItemDefIndex() ); |
|
Assert( pGatewayItemDef ); |
|
if ( !pGatewayItemDef ) |
|
return; |
|
|
|
// Cook up KVs for this item ad |
|
KeyValuesAD pKVItemAd( "items" ); // The panel will copy these |
|
KeyValues* pKVItem = pKVItemAd->CreateNewKey(); |
|
pKVItem->SetName( "0" ); |
|
pKVItem->SetString( "item", pGatewayItemDef->GetDefinitionName() ); |
|
pKVItem->SetInt( "show_market", bGatewayItemInStore ? 0 : 1 ); |
|
|
|
pPassStoreAd->SetVisible( true ); |
|
pPassStoreAd->SetItemKVs( pKVItemAd ); |
|
|
|
// This is the most important thing to communicate. Don't let other operations stomp it. |
|
break; |
|
} |
|
} |
|
|
|
pszNoQuestsText = m_pszNoQuests; |
|
// Don't break. Give more important operations a chance to present |
|
} |
|
} |
|
|
|
SetDialogVariable( "noquests", g_pVGuiLocalize->Find( pszNoQuestsText ) ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CScrollableQuestList::PopulateQuestLists() |
|
{ |
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); |
|
// We dont do anything when a quest is completing |
|
if ( m_pCompletingPanel != NULL ) |
|
return; |
|
|
|
DirtyQuestLayout(); |
|
|
|
CUtlVector< CEconItemView * > vecQuestItems; |
|
TFInventoryManager()->GetAllQuestItems( &vecQuestItems ); |
|
|
|
CUtlVector< CQuestItemPanel* > vecAvailablePanels; |
|
|
|
FOR_EACH_VEC( m_vecQuestItemPanels, i ) |
|
{ |
|
bool bFound = false; |
|
if ( m_vecQuestItemPanels[ i ]->GetItem() ) |
|
{ |
|
FOR_EACH_VEC_BACK( vecQuestItems, j ) |
|
{ |
|
// See if the item in the panel is still in the list of items we own |
|
if ( m_vecQuestItemPanels[ i ]->GetItem()->GetOriginalID() == vecQuestItems[ j ]->GetOriginalID() ) |
|
{ |
|
// Refresh it |
|
m_vecQuestItemPanels[ i ]->InvalidateLayout(); |
|
vecQuestItems.Remove( j ); |
|
bFound = true; |
|
break; |
|
} |
|
} |
|
} |
|
|
|
// Didn't find it. Clear it out |
|
if ( !bFound ) |
|
{ |
|
if ( m_vecQuestItemPanels[ i ]->GetItem() ) |
|
{ |
|
m_vecQuestItemPanels[ i ]->SetItem( NULL ); |
|
} |
|
|
|
if ( m_vecQuestItemPanels[ i ]->IsSelected() ) |
|
{ |
|
SetSelected( m_vecQuestItemPanels[ i ], false ); |
|
} |
|
|
|
vecAvailablePanels.AddToTail( m_vecQuestItemPanels[ i ] ); |
|
} |
|
} |
|
|
|
for ( int i = 0 ; i < vecQuestItems.Count(); ++i ) |
|
{ |
|
CEconItemView *pItem = vecQuestItems[i]; |
|
|
|
if ( i < vecAvailablePanels.Count() ) |
|
{ |
|
vecAvailablePanels[ i ]->SetItem( pItem ); |
|
} |
|
else if ( i >= m_vecQuestItemPanels.Count() ) |
|
{ |
|
Assert( !"Ran out of quest panels!" ); |
|
} |
|
} |
|
|
|
// Sort the panels to make sure they're in order |
|
m_vecQuestItemPanels.Sort( &QuestSort_AcquiredTime ); |
|
|
|
// Sorting is done manually |
|
FOR_EACH_VEC( m_vecQuestItemPanels, i ) |
|
{ |
|
m_vecQuestItemPanels[ i ]->SetZPos( i + 1 ); |
|
} |
|
|
|
PositionQuestItemPanels(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CScrollableQuestList::QuestCompletedResponse() |
|
{ |
|
FOR_EACH_VEC( m_vecQuestItemPanels, i ) |
|
{ |
|
m_vecQuestItemPanels[i]->QuestCompletedResponse(); |
|
} |
|
|
|
// PopulateQuestLists(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Return true if any quest item panels are in the passed in state |
|
//----------------------------------------------------------------------------- |
|
bool CScrollableQuestList::AnyQuestItemPanelsInState( CQuestItemPanel::EItemPanelState_t eState ) const |
|
{ |
|
FOR_EACH_VEC( m_vecQuestItemPanels, i ) |
|
{ |
|
if ( m_vecQuestItemPanels[i]->GetState() == eState ) |
|
return true; |
|
} |
|
|
|
return false; |
|
} |
|
|
|
//------------------------------------------------------------------------------------------------------------------- |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CQuestLogPanel::CQuestLogPanel( IViewPort *pViewPort ) |
|
: EditablePanel( NULL, PANEL_QUEST_LOG ) |
|
, m_bWaitingForComplete( false ) |
|
, m_pQuestList( NULL ) |
|
, m_bInventoryDirty( true ) |
|
, m_iQuestLogKey( BUTTON_CODE_INVALID ) |
|
{ |
|
if (g_pVGuiLocalize) |
|
{ |
|
g_pVGuiLocalize->AddFile( "resource/tf_quests_%language%.txt" ); |
|
} |
|
|
|
vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/ClientScheme.res", "ClientScheme"); |
|
SetScheme(scheme); |
|
SetProportional( true ); |
|
|
|
ListenForGameEvent( "inventory_updated" ); |
|
ListenForGameEvent( "gameui_hidden" ); |
|
ListenForGameEvent( "gc_connected" ); |
|
|
|
// Create the item model panel tooltip |
|
m_pMouseOverItemPanel = new CItemModelPanel( this, "mouseoveritempanel" ); |
|
m_pMouseOverTooltip = new CItemModelPanelToolTip( this ); |
|
m_pMouseOverTooltip->SetupPanels( this, m_pMouseOverItemPanel ); |
|
|
|
// Create the text tooltip |
|
m_pToolTip = new CQuestTooltip( this ); |
|
m_pToolTipEmbeddedPanel = new vgui::EditablePanel( this, "TooltipPanel" ); |
|
m_pToolTipEmbeddedPanel->SetKeyBoardInputEnabled( false ); |
|
m_pToolTipEmbeddedPanel->SetMouseInputEnabled( false ); |
|
// m_pToolTipEmbeddedPanel->MakePopup(); |
|
m_pToolTip->SetEmbeddedPanel( m_pToolTipEmbeddedPanel ); |
|
m_pToolTip->SetTooltipDelay( 0 ); |
|
|
|
EditablePanel *pMainContainer = new EditablePanel( this, "MainContainer" ); |
|
m_pQuestList = new CScrollableQuestList( pMainContainer, "QuestList" ); |
|
|
|
m_pProgressPanel = new EditablePanel( this, "ProgressPanel" ); |
|
|
|
m_pDebugButton = new CExButton( pMainContainer, "Options", "Options", this, "open_debug_menu" ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Look into the moused-over panel and take "tiptext" from its dialog |
|
// variables and set it as our own. |
|
//----------------------------------------------------------------------------- |
|
void CQuestTooltip::ShowTooltip( Panel *pCurrentPanel ) |
|
{ |
|
EditablePanel* pEditableCurrentPanel = dynamic_cast< EditablePanel* >( pCurrentPanel ); |
|
if ( pEditableCurrentPanel ) |
|
{ |
|
KeyValues* pKVVariables = pEditableCurrentPanel->GetDialogVariables(); |
|
const wchar_t *pwszTipText = pKVVariables->GetWString( "tiptext", L"" ); |
|
m_pEmbeddedPanel->SetDialogVariable( "tiptext", pwszTipText ); |
|
} |
|
|
|
BaseClass::ShowTooltip( pCurrentPanel ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Position ourselves down and to the right as far as posible |
|
//----------------------------------------------------------------------------- |
|
void CQuestTooltip::PositionWindow( Panel *pTipPanel ) |
|
{ |
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); |
|
int iTipW, iTipH; |
|
pTipPanel->GetSize( iTipW, iTipH ); |
|
|
|
int cursorX, cursorY; |
|
vgui::input()->GetCursorPos(cursorX, cursorY); |
|
|
|
int px, py, wide, tall; |
|
ipanel()->GetAbsPos( m_pEmbeddedPanel->GetParent()->GetVPanel(), px, py ); |
|
m_pEmbeddedPanel->GetParent()->GetSize(wide, tall); |
|
|
|
if ( !m_pEmbeddedPanel->IsPopup() ) |
|
{ |
|
// Move the cursor into our parent space |
|
cursorX -= px; |
|
cursorY -= py; |
|
} |
|
|
|
// Dangle as far down and as far right as possible |
|
int nXPos = cursorX - Max( 0, ( ( iTipW + cursorX ) - wide ) ); |
|
int nYPos = ( cursorY + 20 )- Max( 0, ( ( iTipH + cursorY + 20 ) - tall ) ) ; |
|
|
|
pTipPanel->SetPos( nXPos, nYPos ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CQuestLogPanel::~CQuestLogPanel() |
|
{ |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestLogPanel::AttachToGameUI( void ) |
|
{ |
|
C_CTFGameStats::ImmediateWriteInterfaceEvent( "interface_open", "quest_log_panel" ); |
|
|
|
if ( GetClientModeTFNormal()->GameUI() ) |
|
{ |
|
GetClientModeTFNormal()->GameUI()->SetMainMenuOverride( GetVPanel() ); |
|
} |
|
|
|
SetKeyBoardInputEnabled( true ); |
|
SetMouseInputEnabled( true ); |
|
SetCursor(dc_arrow); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
const char *CQuestLogPanel::GetName( void ) |
|
{ |
|
return PANEL_QUEST_LOG; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestLogPanel::ApplySchemeSettings( IScheme *pScheme ) |
|
{ |
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); |
|
BaseClass::ApplySchemeSettings( pScheme ); |
|
|
|
const char *pszResFile = "Resource/UI/econ/QuestLogPanel.res"; |
|
|
|
// Check if the operation wants to override our default res file |
|
const auto& mapOperations = GetItemSchema()->GetOperationDefinitions(); |
|
FOR_EACH_MAP_FAST( mapOperations, i ) |
|
{ |
|
CEconOperationDefinition* pOperation = mapOperations[i]; |
|
if ( pOperation->IsActive() && pOperation->IsCampaign() ) |
|
{ |
|
// Use the first found for now |
|
if ( pOperation->GetQuestLogOverrideResFile() ) |
|
{ |
|
pszResFile = pOperation->GetQuestLogOverrideResFile(); |
|
} |
|
break; |
|
} |
|
} |
|
|
|
LoadControlSettings( pszResFile ); |
|
|
|
g_spItemTooltip = m_pMouseOverTooltip; |
|
g_spTextTooltip = m_pToolTip; |
|
|
|
// The outer dim / close button |
|
{ |
|
Button* pButton = FindControl<Button>( "OutsideCloseButton" ); |
|
if ( pButton ) |
|
{ |
|
pButton->AddActionSignalTarget( this ); |
|
pButton->SetPaintBackgroundEnabled( false ); |
|
} |
|
} |
|
|
|
m_pQuestList->InvalidateLayout( false, true ); |
|
|
|
Assert( m_pQuestList ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestLogPanel::PerformLayout() |
|
{ |
|
BaseClass::PerformLayout(); |
|
|
|
if ( GetUniverse() != k_EUniversePublic ) |
|
{ |
|
int x, y; |
|
m_pDebugButton->GetParent()->GetPos( x, y ); |
|
int w, h; |
|
m_pDebugButton->GetParent()->GetSize( w, h ); |
|
m_pDebugButton->SizeToContents(); |
|
m_pDebugButton->SetVisible( true ); |
|
m_pDebugButton->SetPos( x + w - m_pDebugButton->GetWide() - 60, y + 15 ); |
|
m_pDebugButton->SetZPos( 1000 ); |
|
} |
|
else |
|
{ |
|
m_pDebugButton->SetVisible( false ); |
|
} |
|
|
|
UpdateQuestsItemPanels(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestLogPanel::OnCommand( const char *pCommand ) |
|
{ |
|
if ( FStrEq( pCommand, "close" ) ) |
|
{ |
|
if ( enginevgui->IsGameUIVisible() ) |
|
{ |
|
ShowPanel( false ); |
|
} |
|
else |
|
{ |
|
IViewPortPanel *pQuestLog = ( gViewPortInterface->FindPanelByName( PANEL_QUEST_LOG ) ); |
|
if ( pQuestLog ) |
|
{ |
|
gViewPortInterface->ShowPanel( pQuestLog, false ); |
|
} |
|
} |
|
} |
|
else if ( Q_stricmp( "open_debug_menu", pCommand ) == 0 ) |
|
{ |
|
if ( GetUniverse() == k_EUniverseBeta || GetUniverse() == k_EUniverseDev ) |
|
{ |
|
const char *pszContextMenuBorder = "NotificationDefault"; |
|
const char *pszContextMenuFont = "HudFontMediumSecondary"; |
|
|
|
Menu *pContextMenu = new Menu( this, "ContextMenu" ); |
|
pContextMenu->SetBorder( scheme()->GetIScheme( GetScheme() )->GetBorder( pszContextMenuBorder ) ); |
|
pContextMenu->SetFont( scheme()->GetIScheme( GetScheme() )->GetFont( pszContextMenuFont ) ); |
|
|
|
|
|
MenuBuilder contextMenuBuilder( pContextMenu, this ); |
|
|
|
const auto& mapOperations = GetItemSchema()->GetOperationDefinitions(); |
|
FOR_EACH_MAP_FAST( mapOperations, iOperation ) |
|
{ |
|
bool bHasAnyQuests = false; |
|
Menu* pOperationSubMenu = NULL; |
|
|
|
CEconOperationDefinition *pOperation = mapOperations[ iOperation ]; |
|
const CEconLootListDefinition *pLootListDef = GetItemSchema()->GetLootListByName( pOperation->GetOperationLootlist() ); |
|
if ( pLootListDef ) |
|
{ |
|
auto& vecContents = pLootListDef->GetLootListContents(); |
|
FOR_EACH_VEC( vecContents, i ) |
|
{ |
|
if ( vecContents[i].m_iItemOrLootlistDef > 0 ) |
|
{ |
|
const GameItemDefinition_t* pItemDef = (GameItemDefinition_t*)GetItemSchema()->GetItemDefinition( vecContents[i].m_iItemOrLootlistDef ); |
|
if ( pItemDef && pItemDef->GetQuestDef() ) |
|
{ |
|
if ( !bHasAnyQuests ) |
|
{ |
|
bHasAnyQuests = true; |
|
|
|
pOperationSubMenu = new Menu( this, "OperationSubMenu" ); |
|
pOperationSubMenu->SetBorder( scheme()->GetIScheme( GetScheme() )->GetBorder( pszContextMenuBorder ) ); |
|
pOperationSubMenu->SetFont( scheme()->GetIScheme( GetScheme() )->GetFont( pszContextMenuFont ) ); |
|
|
|
contextMenuBuilder.AddCascadingMenuItem( pOperation->GetName(), pOperationSubMenu, "operations" ); |
|
} |
|
|
|
pOperationSubMenu->AddMenuItem( pItemDef->GetItemBaseName(), CFmtStr( "give%s", pItemDef->GetDefinitionName() ), this ); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
bool bHasAnyQuests = false; |
|
Menu* pAllSubMenu = NULL; |
|
|
|
FOR_EACH_MAP_FAST( GetItemSchema()->GetItemDefinitionMap(), i ) |
|
{ |
|
const GameItemDefinition_t* pItemDef = (GameItemDefinition_t*)GetItemSchema()->GetItemDefinitionMap()[ i ]; |
|
if ( pItemDef->GetQuestDef() ) |
|
{ |
|
if ( !bHasAnyQuests ) |
|
{ |
|
bHasAnyQuests = true; |
|
|
|
pAllSubMenu = new Menu( this, "AllSubMenu" ); |
|
pAllSubMenu->SetBorder( scheme()->GetIScheme( GetScheme() )->GetBorder( pszContextMenuBorder ) ); |
|
pAllSubMenu->SetFont( scheme()->GetIScheme( GetScheme() )->GetFont( pszContextMenuFont ) ); |
|
|
|
contextMenuBuilder.AddCascadingMenuItem( "all", pAllSubMenu, "all" ); |
|
} |
|
|
|
pAllSubMenu->AddMenuItem( pItemDef->GetItemBaseName(), CFmtStr( "give%s", pItemDef->GetDefinitionName() ), this ); |
|
} |
|
} |
|
|
|
// Position to the cursor's position |
|
int nX, nY; |
|
g_pVGuiInput->GetCursorPosition( nX, nY ); |
|
pContextMenu->SetPos( nX - 1, nY - 1 ); |
|
|
|
pContextMenu->SetVisible(true); |
|
pContextMenu->AddActionSignalTarget(this); |
|
} |
|
} |
|
else if ( Q_strnicmp( "give", pCommand, 4 ) == 0 ) |
|
{ |
|
if ( GetUniverse() != k_EUniversePublic ) |
|
{ |
|
if ( !steamapicontext || !steamapicontext->SteamUser() ) |
|
{ |
|
Msg("Not connected to Steam.\n"); |
|
return; |
|
} |
|
|
|
CSteamID steamIDForPlayer = steamapicontext->SteamUser()->GetSteamID(); |
|
if ( !steamIDForPlayer.IsValid() ) |
|
{ |
|
Msg("Failed to find a valid steamID for the local player.\n"); |
|
return; |
|
} |
|
|
|
const char* pszItemToGive = pCommand + 4; |
|
Msg( "Sending request to generate '%s' for Local Player (%llu)\n", pszItemToGive, steamIDForPlayer.ConvertToUint64() ); |
|
|
|
CItemSelectionCriteria criteria; |
|
|
|
GCSDK::CProtoBufMsg<CMsgDevNewItemRequest> msg( k_EMsgGCDev_NewItemRequest ); |
|
msg.Body().set_receiver( steamIDForPlayer.ConvertToUint64() ); |
|
|
|
criteria.SetIgnoreEnabledFlag( true ); |
|
if ( !criteria.BAddCondition( "name", k_EOperator_String_EQ, pszItemToGive, true ) || |
|
!criteria.BSerializeToMsg( *msg.Body().mutable_criteria() ) ) |
|
{ |
|
Msg( "Failed to add condition and/or serialize item grant request. This is probably caused by having a string that's too long.\n" ); |
|
return; |
|
} |
|
GCClientSystem()->BSendMessage( msg ); |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestLogPanel::FireGameEvent( IGameEvent *event ) |
|
{ |
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); |
|
// Listen for inventory updates in case our item gets changed while the user |
|
// is looking at us. We want to re-do our entire layout since a quest might |
|
// have been equipped / destroyed / completed and we need to re-categorize |
|
// all the user's quests. |
|
if ( FStrEq( event->GetName(), "inventory_updated" ) && !m_bWaitingForComplete ) |
|
{ |
|
m_bInventoryDirty = true; |
|
|
|
if ( IsVisible() ) |
|
{ |
|
if ( m_pQuestList ) |
|
{ |
|
m_pQuestList->PopulateQuestLists(); |
|
m_pQuestList->UpdateEmptyMessage(); |
|
} |
|
|
|
UpdateQuestsItemPanels(); |
|
} |
|
} |
|
else if ( FStrEq( event->GetName(), "gameui_hidden" ) ) |
|
{ |
|
ShowPanel( false ); |
|
return; |
|
} |
|
else if ( FStrEq( event->GetName(), "gc_connected" ) ) |
|
{ |
|
m_bInventoryDirty = true; |
|
InvalidateLayout( false, true ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestLogPanel::ShowPanel( bool bShow ) |
|
{ |
|
// Snag this so we know what to listen for |
|
m_iQuestLogKey = gameuifuncs->GetButtonCodeForBind( "show_quest_log" ); |
|
|
|
if ( m_pQuestList && bShow ) |
|
{ |
|
m_pQuestList->SetSelected( NULL, true ); |
|
m_pQuestList->DirtyQuestLayout(); |
|
} |
|
|
|
SetVisible( bShow ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestLogPanel::OnKeyCodePressed( KeyCode code ) |
|
{ |
|
if ( code == m_iQuestLogKey || code == STEAMCONTROLLER_B ) |
|
{ |
|
ShowPanel( false ); |
|
return; |
|
} |
|
|
|
BaseClass::OnKeyCodePressed( code ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestLogPanel::OnKeyCodeTyped( KeyCode code ) |
|
{ |
|
if ( code == KEY_ESCAPE ) |
|
{ |
|
if ( IsVisible() ) |
|
{ |
|
SetVisible( false ); |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestLogPanel::SetVisible( bool bState ) |
|
{ |
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); |
|
// Default to showing the active quests upon opening |
|
if ( bState == true ) |
|
{ |
|
UpdateQuestsItemPanels(); |
|
|
|
IGameEvent *event = gameeventmanager->CreateEvent( "questlog_opened" ); |
|
if ( event ) |
|
{ |
|
gameeventmanager->FireEventClientSide( event ); |
|
} |
|
|
|
if ( enginevgui->IsGameUIVisible() ) |
|
{ |
|
AttachToGameUI(); |
|
} |
|
else |
|
{ |
|
ipanel()->SetParent( GetVPanel(), VGui_GetClientDLLRootPanel() ); |
|
|
|
MakePopup( false, true ); |
|
SetKeyBoardInputEnabled( true ); |
|
SetMouseInputEnabled( true ); |
|
MoveToFront(); |
|
} |
|
|
|
engine->ClientCmd_Unrestricted( "gameui_preventescapetoshow\n" ); |
|
vgui::surface()->PlaySound( "ui/panel_open.wav" ); |
|
} |
|
else if ( IsVisible() ) |
|
{ |
|
// Detach from the GameUI when we hide |
|
IViewPortPanel *pMMOverride = gViewPortInterface->FindPanelByName( PANEL_MAINMENUOVERRIDE ); |
|
if ( pMMOverride ) |
|
{ |
|
((CHudMainMenuOverride*)pMMOverride)->AttachToGameUI(); |
|
} |
|
|
|
engine->ClientCmd_Unrestricted( "gameui_allowescapetoshow\n" ); |
|
vgui::surface()->PlaySound( "ui/panel_close.wav" ); |
|
} |
|
|
|
BaseClass::SetVisible( bState ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestLogPanel::QuestCompletedResponse() |
|
{ |
|
m_bWaitingForComplete = false; |
|
m_bInventoryDirty = true; |
|
|
|
if ( m_pQuestList ) |
|
m_pQuestList->QuestCompletedResponse(); |
|
|
|
//UpdateQuestsItemPanels(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestLogPanel::UpdateQuestsItemPanels() |
|
{ |
|
UpdateBadgeProgressPanels(); |
|
|
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); |
|
if ( m_bInventoryDirty ) |
|
{ |
|
m_pQuestList->QuestCompletedResponse(); |
|
|
|
if ( m_pQuestList ) |
|
{ |
|
m_pQuestList->PopulateQuestLists(); |
|
m_pQuestList->UpdateEmptyMessage(); |
|
} |
|
} |
|
|
|
m_bInventoryDirty = false; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestLogPanel::MarkQuestsDirty() |
|
{ |
|
m_bInventoryDirty = true; |
|
|
|
if ( IsVisible() ) |
|
{ |
|
UpdateQuestsItemPanels(); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Return true if any quest item panels are in the passed in state |
|
//----------------------------------------------------------------------------- |
|
bool CQuestLogPanel::AnyQuestItemPanelsInState( CQuestItemPanel::EItemPanelState_t eState ) const |
|
{ |
|
return m_pQuestList->AnyQuestItemPanelsInState( eState ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestLogPanel::OnCompleteQuest( void ) |
|
{ |
|
m_bWaitingForComplete = true; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CQuestLogPanel::UpdateBadgeProgressPanels() |
|
{ |
|
CEconOperationDefinition *pCurrentOperation = NULL; |
|
const auto& mapOperations = GetItemSchema()->GetOperationDefinitions(); |
|
FOR_EACH_MAP_FAST( mapOperations, i ) |
|
{ |
|
CEconOperationDefinition* pOperation = mapOperations[i]; |
|
if ( pOperation->IsActive() && pOperation->IsCampaign() ) |
|
{ |
|
pCurrentOperation = pOperation; |
|
break; |
|
} |
|
} |
|
|
|
if ( pCurrentOperation ) |
|
{ |
|
CEconItemView *pCoin = TFInventoryManager()->GetLocalTFInventory()->FindFirstItembyItemDef( pCurrentOperation->GetRequiredItemDefIndex() ); |
|
if ( pCoin ) |
|
{ |
|
m_pProgressPanel->SetVisible( true ); |
|
CItemModelPanel *pCoinPanel = m_pProgressPanel->FindControl< CItemModelPanel >( "CoinModelPanel" ); |
|
if ( pCoinPanel ) |
|
{ |
|
pCoinPanel->SetItem( pCoin ); |
|
} |
|
|
|
uint32 nNumCompletedContracts = 0; |
|
{ |
|
uint32 nCompletedContractsTemp = 0; |
|
GetKilleaterValueByEvent( pCoin, kKillEaterEvent_CosmeticOperationContractsCompleted, nCompletedContractsTemp ); |
|
nNumCompletedContracts = Max( nNumCompletedContracts, nCompletedContractsTemp ); |
|
// Halloween has it's own thing for whatever reason |
|
GetKilleaterValueByEvent( pCoin, kKillEaterEvent_HalloweenContractsCompleted, nCompletedContractsTemp ); |
|
nNumCompletedContracts = Max( nNumCompletedContracts, nCompletedContractsTemp ); |
|
Assert( pCurrentOperation->GetMaxDropCount() > 0 ); |
|
} |
|
|
|
uint32 nNumContractPoints = 0; |
|
{ |
|
uint32 nContractsPointsTemp = 0; |
|
GetKilleaterValueByEvent( pCoin, kKillEaterEvent_CosmeticOperationContractsPoints, nContractsPointsTemp ); |
|
nNumContractPoints = Max( nContractsPointsTemp, nNumContractPoints ); |
|
// Halloween has it's own thing for whatever reason |
|
GetKilleaterValueByEvent( pCoin, kKillEaterEvent_HalloweenSouls, nContractsPointsTemp ); |
|
nNumContractPoints = Max( nContractsPointsTemp, nNumContractPoints ); |
|
} |
|
|
|
EditablePanel *pBadgeContainer = m_pProgressPanel->FindControl< EditablePanel >( "BadgeMeterContainer" ); |
|
if ( pBadgeContainer ) |
|
{ |
|
ContinuousProgressBar *pBadgeProgressBar = pBadgeContainer->FindControl< ContinuousProgressBar >( "BadgeProgressMeter" ); |
|
if ( pBadgeProgressBar ) |
|
{ |
|
const char *pszLevelingDataName = GetItemSchema()->GetKillEaterScoreTypeLevelingDataName( kKillEaterEvent_HalloweenSouls ); |
|
Assert( pszLevelingDataName ); |
|
|
|
const CUtlVector<CItemLevelingDefinition> *pLevelingData = GetItemSchema()->GetItemLevelingData( pszLevelingDataName ); |
|
Assert( pLevelingData ); |
|
|
|
int nRequiredPointsToNextRank = 0; |
|
int nRequiredPointsToCurrentRank = 0; |
|
const char *pszCurrentLevelName = NULL; |
|
FOR_EACH_VEC( (*pLevelingData), i ) |
|
{ |
|
pszCurrentLevelName = (*pLevelingData)[i].GetNameLocalizationKey(); |
|
|
|
const uint32 nRank = (*pLevelingData)[i].GetRequiredScore(); |
|
if ( nNumContractPoints < nRank ) |
|
{ |
|
nRequiredPointsToNextRank = nRank; |
|
break; |
|
} |
|
else |
|
{ |
|
nRequiredPointsToCurrentRank = nRank; |
|
} |
|
} |
|
|
|
// if no next level, just use max points |
|
if ( nRequiredPointsToNextRank == 0 ) |
|
{ |
|
// assuming each contract's worth 130 (100 point + 30 bonus) |
|
nRequiredPointsToNextRank = pCurrentOperation->GetMaxDropCount() * 130; |
|
} |
|
|
|
float flProgress = (float)( nNumContractPoints - nRequiredPointsToCurrentRank ) / (float)( nRequiredPointsToNextRank - nRequiredPointsToCurrentRank ); |
|
pBadgeProgressBar->SetProgress( flProgress ); |
|
|
|
CExLabel *pLabel = m_pProgressPanel->FindControl< CExLabel >( "BadgeProgressLabel" ); |
|
if ( pLabel ) |
|
{ |
|
pLabel->SetText( CConstructLocalizedString( g_pVGuiLocalize->Find( "QuestLog_BadgeProgress" ), g_pVGuiLocalize->Find( pszCurrentLevelName ) ) ); |
|
} |
|
|
|
CExLabel *pScoreLabel = pBadgeContainer->FindControl< CExLabel >( "BadgeProgressMeterText" ); |
|
if ( pScoreLabel ) |
|
{ |
|
pScoreLabel->SetText( CFmtStr( "%d/%d", nNumContractPoints, nRequiredPointsToNextRank ) ); |
|
} |
|
} |
|
} |
|
|
|
EditablePanel *pContractContainer = m_pProgressPanel->FindControl< EditablePanel >( "ContractMeterContainer" ); |
|
if ( pContractContainer ) |
|
{ |
|
ContinuousProgressBar *pContractProgressBar = pContractContainer->FindControl< ContinuousProgressBar >( "ContractsCompletedProgressMeter" ); |
|
if ( pContractProgressBar ) |
|
{ |
|
pContractProgressBar->SetProgress( (float)nNumCompletedContracts / (float)pCurrentOperation->GetMaxDropCount() ); |
|
|
|
CExLabel *pLabel = pContractContainer->FindControl< CExLabel >( "ContractsCompletedProgressMeterText" ); |
|
if ( pLabel ) |
|
{ |
|
pLabel->SetText( CFmtStr( "%d", nNumCompletedContracts ) ); |
|
} |
|
} |
|
} |
|
} |
|
else |
|
{ |
|
m_pProgressPanel->SetVisible( false ); |
|
} |
|
} |
|
else |
|
{ |
|
m_pProgressPanel->SetVisible( false ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: GC Msg handler for when a quest has been completed |
|
//----------------------------------------------------------------------------- |
|
class CGCCompleteQuestCompleteResponse : public GCSDK::CGCClientJob |
|
{ |
|
public: |
|
CGCCompleteQuestCompleteResponse( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {} |
|
|
|
virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket ) |
|
{ |
|
GCSDK::CGCMsg<MsgGCStandardResponse_t> msg( pNetPacket ); |
|
|
|
itemid_t nNewToolID = 0; |
|
if( !msg.BReadUint64Data( &nNewToolID ) ) |
|
return true; |
|
|
|
CQuestLogPanel *pQuestLog = GetQuestLog(); |
|
if ( pQuestLog ) |
|
{ |
|
pQuestLog->QuestCompletedResponse(); |
|
} |
|
|
|
return true; |
|
} |
|
}; |
|
|
|
GC_REG_JOB( GCSDK::CGCClient, CGCCompleteQuestCompleteResponse, "CGCCompleteQuestCompleteResponse", k_EMsgGCQuestCompleted, GCSDK::k_EServerTypeGCClient ); |
|
|
|
|
|
#ifdef STAGING_ONLY |
|
static void cc_tf_quest_log_reload() |
|
{ |
|
CQuestLogPanel *pQuestLog = GetQuestLog(); |
|
if ( pQuestLog ) |
|
{ |
|
pQuestLog->MarkQuestsDirty(); |
|
pQuestLog->InvalidateLayout( true, true ); |
|
gViewPortInterface->ShowPanel( pQuestLog, true ); |
|
} |
|
} |
|
ConCommand tf_quest_log_reload( "tf_quest_log_reload", cc_tf_quest_log_reload ); |
|
#endif
|
|
|