12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037 |
- /*
- ===========================================================================
- Doom 3 BFG Edition GPL Source Code
- Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
- This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
- Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
- In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
- If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
- ===========================================================================
- */
- #pragma hdrstop
- #include "../../idLib/precompiled.h"
- #include "../Game_local.h"
- const static int NUM_LEADERBOARD_ITEMS = 16;
- const int MAX_STAT_LISTINGS = 16;
- static const int MAX_ROWS_PER_BLOCK = 50;
- idMenuScreen_Shell_Leaderboards::~idMenuScreen_Shell_Leaderboards() {
- if ( lbCache != NULL ) {
- delete lbCache;
- lbCache = NULL;
- }
- }
- // Helper functions for formatting leaderboard columns
- static idStr FormatTime( int64 time ) {
- int minutes = time / ( 1000 * 60 );
- int seconds = ( time - ( minutes * 1000 * 60 ) ) / 1000;
- int mseconds = time - ( ( minutes * 1000 * 60 ) + ( seconds * 1000 ) );
- return idStr( va( "%02d:%02d.%03d", minutes, seconds, mseconds ) );
- }
- static idStr FormatCash( int64 cash ) { return idStr::FormatCash( static_cast<int32>( cash ) ); }
- static int32 FormatNumber( int64 number ) { return static_cast<int32>( number ); }
- static idSWFScriptVar FormatColumn( const columnDef_t * columnDef, int64 score ) {
- switch( columnDef->displayType ) {
- case STATS_COLUMN_DISPLAY_TIME_MILLISECONDS: return idSWFScriptVar( FormatTime( score ) );
- case STATS_COLUMN_DISPLAY_CASH: return idSWFScriptVar( FormatCash( score ) );
- default: return idSWFScriptVar( FormatNumber( score ) );
- }
- }
- /*
- ========================
- idMenuScreen_Shell_Leaderboards::Initialize
- ========================
- */
- void idMenuScreen_Shell_Leaderboards::Initialize( idMenuHandler * data ) {
- idMenuScreen::Initialize( data );
- if ( data != NULL ) {
- menuGUI = data->GetGUI();
- }
- lbCache = new idLBCache();
- lbCache->Reset();
- SetSpritePath( "menuLeaderboards" );
- options = new (TAG_SWF) idMenuWidget_DynamicList();
- options->SetNumVisibleOptions( NUM_LEADERBOARD_ITEMS );
- options->SetSpritePath( GetSpritePath(), "info", "options" );
- options->SetWrappingAllowed( true );
- while ( options->GetChildren().Num() < NUM_LEADERBOARD_ITEMS ) {
- idMenuWidget_Button * const buttonWidget = new (TAG_SWF) idMenuWidget_Button();
- buttonWidget->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_PRESS_FOCUSED, options->GetChildren().Num() );
- buttonWidget->Initialize( data );
- options->AddChild( buttonWidget );
- }
- options->Initialize( data );
- AddChild( options );
- btnBack = new (TAG_SWF) idMenuWidget_Button();
- btnBack->Initialize( data );
- btnBack->SetLabel( "#str_swf_party_lobby" );
- btnBack->SetSpritePath( GetSpritePath(), "info", "btnBack" );
- btnBack->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_GO_BACK );
- AddChild( btnBack );
- btnNext = new (TAG_SWF) idMenuWidget_Button();
- btnNext->Initialize( data );
- btnNext->SetLabel( "#str_swf_next" );
- btnNext->SetSpritePath( GetSpritePath(), "info", "btnNext" );
- btnNext->AddEventAction( WIDGET_EVENT_PRESS ).Set( new (TAG_SWF) idWidgetActionHandler( this, WIDGET_ACTION_EVENT_TAB_NEXT, WIDGET_EVENT_TAB_NEXT ) );
- AddChild( btnNext );
- btnPrev = new (TAG_SWF) idMenuWidget_Button();
- btnPrev->Initialize( data );
- btnPrev->SetLabel( "#str_swf_prev" );
- btnPrev->SetSpritePath( GetSpritePath(), "info", "btnPrevious" );
- btnPrev->AddEventAction( WIDGET_EVENT_PRESS ).Set( new (TAG_SWF) idWidgetActionHandler( this, WIDGET_ACTION_EVENT_TAB_PREV, WIDGET_EVENT_TAB_PREV ) );
- AddChild( btnPrev );
- btnPageDwn = new (TAG_SWF) idMenuWidget_Button();
- btnPageDwn->Initialize( data );
- btnPageDwn->SetLabel( "#str_swf_next_page" );
- btnPageDwn->SetSpritePath( GetSpritePath(), "info", "btnPageDwn" );
- idSWFParmList parms;
- parms.Append( MAX_STAT_LISTINGS - 1 );
- btnPageDwn->AddEventAction( WIDGET_EVENT_PRESS ).Set( new (TAG_SWF) idWidgetActionHandler( this, WIDGET_ACTION_EVENT_SCROLL_PAGE_DOWN_START_REPEATER, WIDGET_EVENT_SCROLL_PAGEDWN ) );
- btnPageDwn->AddEventAction( WIDGET_EVENT_RELEASE ).Set( new (TAG_SWF) idWidgetActionHandler( this, WIDGET_ACTION_EVENT_STOP_REPEATER, WIDGET_EVENT_SCROLL_PAGEDWN_RELEASE ) );
- AddChild( btnPageDwn );
- btnPageUp = new (TAG_SWF) idMenuWidget_Button();
- btnPageUp->Initialize( data );
- btnPageUp->SetLabel( "#str_swf_prev_page" );
- btnPageUp->SetSpritePath( GetSpritePath(), "info", "btnPageUp" );
- parms.Clear();
- parms.Append( MAX_STAT_LISTINGS - 1 );
- btnPageUp->AddEventAction( WIDGET_EVENT_PRESS ).Set( new (TAG_SWF) idWidgetActionHandler( this, WIDGET_ACTION_EVENT_SCROLL_PAGE_UP_START_REPEATER, WIDGET_EVENT_SCROLL_PAGEUP ) );
- btnPageUp->AddEventAction( WIDGET_EVENT_RELEASE ).Set( new (TAG_SWF) idWidgetActionHandler( this, WIDGET_ACTION_EVENT_STOP_REPEATER, WIDGET_EVENT_SCROLL_PAGEUP_RELEASE ) );
- AddChild( btnPageUp );
- AddEventAction( WIDGET_EVENT_SCROLL_DOWN_LSTICK ).Set( new (TAG_SWF) idWidgetActionHandler( this, WIDGET_ACTION_EVENT_SCROLL_DOWN_START_REPEATER_VARIABLE, WIDGET_EVENT_SCROLL_DOWN_LSTICK ) );
- AddEventAction( WIDGET_EVENT_SCROLL_UP_LSTICK ).Set( new (TAG_SWF) idWidgetActionHandler( this, WIDGET_ACTION_EVENT_SCROLL_UP_START_REPEATER_VARIABLE, WIDGET_EVENT_SCROLL_UP_LSTICK ) );
- AddEventAction( WIDGET_EVENT_SCROLL_DOWN_LSTICK_RELEASE ).Set( new (TAG_SWF) idWidgetActionHandler( this, WIDGET_ACTION_EVENT_STOP_REPEATER, WIDGET_EVENT_SCROLL_DOWN_LSTICK_RELEASE ) );
- AddEventAction( WIDGET_EVENT_SCROLL_UP_LSTICK_RELEASE ).Set( new (TAG_SWF) idWidgetActionHandler( this, WIDGET_ACTION_EVENT_STOP_REPEATER, WIDGET_EVENT_SCROLL_UP_LSTICK_RELEASE ) );
- AddEventAction( WIDGET_EVENT_SCROLL_DOWN ).Set( new (TAG_SWF) idWidgetActionHandler( this, WIDGET_ACTION_EVENT_SCROLL_DOWN_START_REPEATER_VARIABLE, WIDGET_EVENT_SCROLL_DOWN ) );
- AddEventAction( WIDGET_EVENT_SCROLL_UP ).Set( new (TAG_SWF) idWidgetActionHandler( this, WIDGET_ACTION_EVENT_SCROLL_UP_START_REPEATER_VARIABLE, WIDGET_EVENT_SCROLL_UP ) );
- AddEventAction( WIDGET_EVENT_SCROLL_DOWN_RELEASE ).Set( new (TAG_SWF) idWidgetActionHandler( this, WIDGET_ACTION_EVENT_STOP_REPEATER, WIDGET_EVENT_SCROLL_DOWN_RELEASE ) );
- AddEventAction( WIDGET_EVENT_SCROLL_UP_RELEASE ).Set( new (TAG_SWF) idWidgetActionHandler( this, WIDGET_ACTION_EVENT_STOP_REPEATER, WIDGET_EVENT_SCROLL_UP_RELEASE ) );
- AddEventAction( WIDGET_EVENT_SCROLL_PAGEDWN ).Set( new (TAG_SWF) idWidgetActionHandler( this, WIDGET_ACTION_EVENT_SCROLL_PAGE_DOWN_START_REPEATER, WIDGET_EVENT_SCROLL_PAGEDWN ) );
- AddEventAction( WIDGET_EVENT_SCROLL_PAGEUP ).Set( new (TAG_SWF) idWidgetActionHandler( this, WIDGET_ACTION_EVENT_SCROLL_PAGE_UP_START_REPEATER, WIDGET_EVENT_SCROLL_PAGEUP ) );
- AddEventAction( WIDGET_EVENT_SCROLL_PAGEDWN_RELEASE ).Set( new (TAG_SWF) idWidgetActionHandler( this, WIDGET_ACTION_EVENT_STOP_REPEATER, WIDGET_EVENT_SCROLL_PAGEDWN_RELEASE ) );
- AddEventAction( WIDGET_EVENT_SCROLL_PAGEUP_RELEASE ).Set( new (TAG_SWF) idWidgetActionHandler( this, WIDGET_ACTION_EVENT_STOP_REPEATER, WIDGET_EVENT_SCROLL_PAGEUP_RELEASE ) );
- AddEventAction( WIDGET_EVENT_TAB_NEXT ).Set( new (TAG_SWF) idWidgetActionHandler( this, WIDGET_ACTION_EVENT_TAB_NEXT, WIDGET_EVENT_TAB_NEXT ) );
- AddEventAction( WIDGET_EVENT_TAB_PREV ).Set( new (TAG_SWF) idWidgetActionHandler( this, WIDGET_ACTION_EVENT_TAB_PREV, WIDGET_EVENT_TAB_PREV ) );
-
- leaderboards.Clear();
- const idList< mpMap_t > maps = common->GetMapList();
- const char ** gameModes = NULL;
- const char ** gameModesDisplay = NULL;
- int numModes = game->GetMPGameModes( &gameModes, &gameModesDisplay );
- for ( int mapIndex = 0; mapIndex < maps.Num(); ++mapIndex ) {
- for ( int modeIndex = 0; modeIndex < numModes; ++modeIndex ) {
- // Check the supported modes on the map.
- if( maps[ mapIndex ].supportedModes & BIT( modeIndex ) ) {
- int boardID = LeaderboardLocal_GetID( mapIndex, modeIndex );
- const leaderboardDefinition_t * lbDef = Sys_FindLeaderboardDef( boardID );
- if ( lbDef != NULL ) {
- doomLeaderboard_t lb = doomLeaderboard_t( lbDef, lbDef->boardName );
- leaderboards.Append( lb );
- }
- }
- }
- }
- }
- /*
- ========================
- idMenuScreen_Shell_Leaderboards::PumpLBCache
- ========================
- */
- void idMenuScreen_Shell_Leaderboards::PumpLBCache() {
- if ( lbCache == NULL ) {
- return;
- }
-
- lbCache->Pump();
- }
- /*
- ========================
- idMenuScreen_Shell_Leaderboards::ClearLeaderboard
- ========================
- */
- void idMenuScreen_Shell_Leaderboards::ClearLeaderboard() {
- if ( lbCache == NULL ) {
- return;
- }
- lbCache->Reset();
- }
- /*
- ========================
- idMenuScreen_Shell_Leaderboards::Update
- ========================
- */
- void idMenuScreen_Shell_Leaderboards::Update() {
- if ( menuData != NULL ) {
- idMenuWidget_CommandBar * cmdBar = menuData->GetCmdBar();
- if ( cmdBar != NULL ) {
- cmdBar->ClearAllButtons();
- idMenuWidget_CommandBar::buttonInfo_t * buttonInfo;
- buttonInfo = cmdBar->GetButton( idMenuWidget_CommandBar::BUTTON_JOY2 );
- if ( menuData->GetPlatform() != 2 ) {
- buttonInfo->label = "#str_00395";
- }
- buttonInfo->action.Set( WIDGET_ACTION_GO_BACK );
- buttonInfo = cmdBar->GetButton( idMenuWidget_CommandBar::BUTTON_JOY3 );
- buttonInfo->label = "#str_online_leaderboards_toggle_filter";
- buttonInfo->action.Set( WIDGET_ACTION_JOY3_ON_PRESS );
-
- if ( !lbCache->IsLoadingNewLeaderboard() && !lbCache->IsRequestingRows() && options != NULL && options->GetTotalNumberOfOptions() > 0 ) {
- buttonInfo = cmdBar->GetButton( idMenuWidget_CommandBar::BUTTON_JOY1 );
- if ( menuData->GetPlatform() != 2 ) {
- buttonInfo->label = "#str_swf_view_profile";
- }
- buttonInfo->action.Set( WIDGET_ACTION_PRESS_FOCUSED );
- }
- }
- }
- idSWFScriptObject & root = GetSWFObject()->GetRootObject();
- if ( BindSprite( root ) ) {
- idSWFTextInstance * heading = GetSprite()->GetScriptObject()->GetNestedText( "info", "txtHeading" );
- if ( heading != NULL ) {
- heading->SetText( lbCache->GetFilterStrType() );
- heading->SetStrokeInfo( true, 0.75f, 1.75f );
- }
- idSWFSpriteInstance * gradient = GetSprite()->GetScriptObject()->GetNestedSprite( "info", "gradient" );
- if ( gradient != NULL && heading != NULL ) {
- gradient->SetXPos( heading->GetTextLength() );
- }
- }
- if ( btnBack != NULL ) {
- btnBack->BindSprite( root );
- }
- idMenuScreen::Update();
- }
- /*
- ========================
- idMenuScreen_Shell_Leaderboards::ShowScreen
- ========================
- */
- void idMenuScreen_Shell_Leaderboards::ShowScreen( const mainMenuTransition_t transitionType ) {
- idMenuScreen::ShowScreen( transitionType );
-
- if ( GetSprite() != NULL ) {
- lbHeading = GetSprite()->GetScriptObject()->GetNestedText( "info", "txtLbType" );
- if ( menuData != NULL && menuData->GetGUI() != NULL ) {
- idSWFScriptObject * const shortcutKeys = menuData->GetGUI()->GetGlobal( "shortcutKeys" ).GetObject();
- if ( verify( shortcutKeys != NULL ) ) {
-
- // TAB NEXT
- idSWFScriptObject * const btnTabNext = GetSprite()->GetScriptObject()->GetNestedObj( "info", "btnNext" );
- if ( btnTabNext != NULL ) {
- btnTabNext->Set( "onPress", new ( TAG_SWF ) WrapWidgetSWFEvent( this, WIDGET_EVENT_TAB_NEXT, 0 ) );
- shortcutKeys->Set( "JOY6", btnTabNext );
- if ( btnTabNext->GetSprite() != NULL && menuData != NULL ) {
- btnTabNext->GetSprite()->StopFrame( menuData->GetPlatform() + 1 );
- }
- }
- // TAB PREV
- idSWFScriptObject * const btnTabPrev = GetSprite()->GetScriptObject()->GetNestedObj( "info", "btnPrevious" );
- if ( btnTabPrev != NULL ) {
- btnTabPrev->Set( "onPress", new ( TAG_SWF ) WrapWidgetSWFEvent( this, WIDGET_EVENT_TAB_PREV, 0 ) );
- shortcutKeys->Set( "JOY5", btnTabPrev );
- if ( btnTabPrev->GetSprite() != NULL && menuData != NULL ) {
- btnTabPrev->GetSprite()->StopFrame( menuData->GetPlatform() + 1 );
- }
- }
-
- // TAB NEXT
- idSWFScriptObject * const btnDwn = GetSprite()->GetScriptObject()->GetNestedObj( "info", "btnPageDwn" );
- if ( btnDwn != NULL ) {
- btnDwn->Set( "onPress", new ( TAG_SWF ) WrapWidgetSWFEvent( this, WIDGET_EVENT_SCROLL_PAGEDWN, 0 ) );
- shortcutKeys->Set( "JOY_TRIGGER2", btnDwn );
- if ( btnDwn->GetSprite() != NULL && menuData != NULL ) {
- btnDwn->GetSprite()->StopFrame( menuData->GetPlatform() + 1 );
- }
- }
- // TAB PREV
- idSWFScriptObject * const btnUp = GetSprite()->GetScriptObject()->GetNestedObj( "info", "btnPageUp" );
- if ( btnUp != NULL ) {
- btnUp->Set( "onPress", new ( TAG_SWF ) WrapWidgetSWFEvent( this, WIDGET_EVENT_SCROLL_PAGEUP, 0 ) );
- shortcutKeys->Set( "JOY_TRIGGER1", btnUp );
- if ( btnUp->GetSprite() != NULL && menuData != NULL ) {
- btnUp->GetSprite()->StopFrame( menuData->GetPlatform() + 1 );
- }
- }
- }
- }
- }
- SetLeaderboardIndex();
- if ( menuData == NULL ) {
- return;
- }
- int platform = menuData->GetPlatform();
- if ( btnNext != NULL && btnNext->GetSprite() != NULL ) {
- idSWFSpriteInstance * btnImg = btnNext->GetSprite()->GetScriptObject()->GetNestedSprite( "btnImg" );
- if ( btnImg != NULL ) {
- if ( platform == 2 ) {
- btnImg->SetVisible( false );
- } else {
- btnImg->SetVisible( true );
- btnImg->StopFrame( platform + 1 );
- }
- }
- }
- if ( btnPrev != NULL && btnPrev->GetSprite() != NULL ) {
- idSWFSpriteInstance * btnImg = btnPrev->GetSprite()->GetScriptObject()->GetNestedSprite( "btnImg" );
- if ( btnImg != NULL ) {
- if ( platform == 2 ) {
- btnImg->SetVisible( false );
- } else {
- btnImg->SetVisible( true );
- btnImg->StopFrame( platform + 1 );
- }
- }
- }
- if ( btnPageDwn != NULL && btnPageDwn->GetSprite() != NULL ) {
- idSWFSpriteInstance * btnImg = btnPageDwn->GetSprite()->GetScriptObject()->GetNestedSprite( "btnImg" );
- if ( btnImg != NULL ) {
- if ( platform == 2 ) {
- btnImg->SetVisible( false );
- } else {
- btnImg->SetVisible( true );
- btnImg->StopFrame( platform + 1 );
- }
- }
- }
- if ( btnPageUp != NULL && btnPageUp->GetSprite() != NULL ) {
- idSWFSpriteInstance * btnImg = btnPageUp->GetSprite()->GetScriptObject()->GetNestedSprite( "btnImg" );
- if ( btnImg != NULL ) {
- if ( platform == 2 ) {
- btnImg->SetVisible( false );
- } else {
- btnImg->SetVisible( true );
- btnImg->StopFrame( platform + 1 );
- }
- }
- }
-
- }
- /*
- ========================
- idMenuScreen_Shell_Leaderboards::HideScreen
- ========================
- */
- void idMenuScreen_Shell_Leaderboards::HideScreen( const mainMenuTransition_t transitionType ) {
- idMenuScreen::HideScreen( transitionType );
- }
- /*
- ========================
- idMenuScreen_Shell_Leaderboards::HandleAction
- ========================
- */
- bool idMenuScreen_Shell_Leaderboards::HandleAction( idWidgetAction & action, const idWidgetEvent & event, idMenuWidget * widget, bool forceHandled ) {
- if ( menuData == NULL ) {
- return true;
- }
- if ( menuData->ActiveScreen() != SHELL_AREA_LEADERBOARDS ) {
- return false;
- }
- widgetAction_t actionType = action.GetType();
- const idSWFParmList & parms = action.GetParms();
- switch ( actionType ) {
- case WIDGET_ACTION_GO_BACK: {
- menuData->SetNextScreen( SHELL_AREA_PARTY_LOBBY, MENU_TRANSITION_SIMPLE );
- return true;
- }
- case WIDGET_ACTION_JOY3_ON_PRESS: {
- lbCache->CycleFilter();
- refreshLeaderboard = true;
- return true;
- }
- case WIDGET_ACTION_PRESS_FOCUSED: {
- if ( options == NULL ) {
- return true;
- }
- int index = options->GetFocusIndex();
- if ( parms.Num() != 0 ) {
- index = parms[0].ToInteger();
- }
- if ( lbCache->GetEntryIndex() != index ) {
- lbCache->SetEntryIndex( index );
- refreshLeaderboard = true;
- return true;
- }
- const idLeaderboardCallback::row_t * row = lbCache->GetLeaderboardRow( lbCache->GetRowOffset() + lbCache->GetEntryIndex() );
- if ( row != NULL ) {
- lbCache->DisplayGamerCardUI( row );
- }
- return true;
- }
- case WIDGET_ACTION_SCROLL_TAB: {
- int delta = parms[0].ToInteger();
- lbIndex += delta;
- SetLeaderboardIndex();
- return true;
- }
- case WIDGET_ACTION_SCROLL_VERTICAL_VARIABLE: {
- if ( parms.Num() == 0 ) {
- return true;
- }
- if ( options == NULL ) {
- return true;
- }
- int dir = parms[ 0 ].ToInteger();
- if ( lbCache->Scroll( dir ) ) {
- // TODO_SPARTY: play scroll sound
- refreshLeaderboard = true;
- }
- return true;
- }
- case WIDGET_ACTION_SCROLL_PAGE: {
- if ( parms.Num() == 0 ) {
- return true;
- }
- if ( options == NULL ) {
- return true;
- }
- int dir = parms[ 0 ].ToInteger();
- if ( lbCache->ScrollOffset( dir ) ) {
- refreshLeaderboard = true;
- }
- return true;
- }
- }
- return idMenuWidget::HandleAction( action, event, widget, forceHandled );
- }
- /*
- ========================
- idMenuScreen_Shell_Leaderboards::UpdateLeaderboard
- ========================
- */
- void idMenuScreen_Shell_Leaderboards::UpdateLeaderboard( const idLeaderboardCallback * callback ) {
- lbCache->Update( callback );
- if ( callback->GetErrorCode() != LEADERBOARD_ERROR_NONE ) {
- if ( !session->GetSignInManager().IsMasterLocalUserOnline() ) {
- refreshWhenMasterIsOnline = true;
- }
- }
- refreshLeaderboard = true;
- }
- /*
- ========================
- idMenuScreen_Shell_Leaderboards::SetLeaderboardIndex
- ========================
- */
- void idMenuScreen_Shell_Leaderboards::SetLeaderboardIndex() {
-
- if ( lbIndex >= leaderboards.Num() ) {
- lbIndex = 0;
- } else if ( lbIndex < 0 ) {
- lbIndex = leaderboards.Num() - 1;
- }
- const leaderboardDefinition_t * leaderboardDef = leaderboards[ lbIndex ].lb;
- for ( int i = 0; i < leaderboardDef->numColumns; i++ ) {
- /*if ( leaderboardDef->columnDefs[i].displayType != STATS_COLUMN_NEVER_DISPLAY ) {
- gameLocal->GetMainMenu()->mainMenu->SetGlobal( va("columnname%d",i), leaderboardDef->columnDefs[i].locDisplayName );
- }*/
- }
- lbCache->SetLeaderboard( leaderboardDef, lbCache->GetFilter() );
- refreshLeaderboard = true;
- }
- /*
- ========================
- idMenuScreen_Shell_Leaderboards::RefreshLeaderboard
- ========================
- */
- void idMenuScreen_Shell_Leaderboards::RefreshLeaderboard() {
- if ( refreshWhenMasterIsOnline ) {
- SetLeaderboardIndex();
- refreshWhenMasterIsOnline = false;
- }
-
- if ( !refreshLeaderboard ) {
- return;
- }
- refreshLeaderboard = false;
- bool upArrow = false;
- bool downArrow = false;
- int focusIndex = -1;
- idList< idList< idStr, TAG_IDLIB_LIST_MENU >, TAG_IDLIB_LIST_MENU > lbListings;
- if ( !lbCache->IsLoadingNewLeaderboard() && lbCache->GetErrorCode() == LEADERBOARD_DISPLAY_ERROR_NONE ) {
- for ( int addIndex = 0; addIndex < MAX_STAT_LISTINGS; ++addIndex ) {
- idList< idStr > values;
- int index = lbCache->GetRowOffset() + addIndex;
- const idLeaderboardCallback::row_t * row = lbCache->GetLeaderboardRow( index ); // If this row is not in the cache, this will kick off a request
- if ( row != NULL ) {
- values.Append( va( "%i", (int)row->rank ) );
- values.Append( row->name );
- values.Append( FormatColumn( &lbCache->GetLeaderboard()->columnDefs[0], row->columns[0] ).ToString() );
- }
- if ( lbCache->GetEntryIndex() == addIndex ) {
- focusIndex = addIndex;
- }
- lbListings.Append( values );
- }
- if ( lbCache->GetRowOffset() != 0 ) {
- upArrow = true;
- }
- if ( ( lbCache->GetRowOffset() + MAX_STAT_LISTINGS ) < lbCache->GetNumRowsInLeaderboard() ) {
- downArrow = true;
- }
- }
- if ( lbHeading != NULL ) {
- lbHeading->SetText( leaderboards[ lbIndex ].name );
- lbHeading->SetStrokeInfo( true, 0.75f, 1.75f );
- }
- if ( focusIndex >= 0 ) {
- options->SetFocusIndex( focusIndex );
- }
- if ( btnPageDwn != NULL && btnPageDwn->GetSprite() != NULL ) {
- btnPageDwn->GetSprite()->SetVisible( downArrow );
- }
- if ( btnPageUp != NULL && btnPageUp->GetSprite() != NULL ) {
- btnPageUp->GetSprite()->SetVisible( upArrow );
- }
- options->SetListData( lbListings );
- Update();
- const char * leaderboardErrorStrings[] = {
- "",
- "#str_online_leaderboards_error_failed", // failed
- "", // not online - players are just taken back to multiplayer menu
- "#str_online_leaderboards_error_not_ranked", // not ranked
- };
- compile_time_assert( sizeof( leaderboardErrorStrings ) / sizeof( leaderboardErrorStrings[0] ) == LEADERBOARD_DISPLAY_ERROR_MAX );
- bool isLoading = lbCache->IsLoadingNewLeaderboard();
- idStr error = leaderboardErrorStrings[ lbCache->GetErrorCode() ];
- if ( isLoading ) {
- ShowMessage( true, "#str_online_loading", true );
- } else {
- if ( !error.IsEmpty() ) {
- ShowMessage( true, error, false );
- } else {
- if ( lbCache->GetNumRowsInLeaderboard() > 0 ) {
- ShowMessage( false, "", false );
- } else {
- ShowMessage( true, "#str_online_leaderboards_no_data", false );
- }
- }
- }
- }
- /*
- ========================
- idMenuScreen_Shell_Leaderboards::ShowMessage
- ========================
- */
- void idMenuScreen_Shell_Leaderboards::ShowMessage( bool show, idStr message, bool spinner ) {
- if ( !menuData || !menuData->GetGUI() ) {
- return;
- }
-
- idSWFSpriteInstance * pacifier = menuData->GetGUI()->GetRootObject().GetNestedSprite( "menuLeaderboards", "info", "pacifier" );
- if ( !pacifier ) {
- return;
- }
- if ( show ) {
- if ( spinner && options != NULL && options->GetSprite() != NULL ) {
- options->GetSprite()->SetAlpha( 0.35f );
- } else if ( options != NULL && options->GetSprite() != NULL ) {
- options->GetSprite()->SetVisible( false );
- }
- pacifier->SetVisible( true );
- idSWFTextInstance * txtMsg = pacifier->GetScriptObject()->GetNestedText( "message" );
- if ( txtMsg != NULL ) {
- txtMsg->SetText( message );
- txtMsg->SetStrokeInfo( true, 0.75f, 1.75f );
- }
-
- idSWFSpriteInstance * spriteSpinner = pacifier->GetScriptObject()->GetNestedSprite( "graphic" );
- if ( spriteSpinner != NULL ) {
- spriteSpinner->StopFrame( spinner ? 1 : 2 );
- }
- } else {
- if ( options != NULL && options->GetSprite() != NULL ) {
- options->GetSprite()->SetVisible( true );
- options->GetSprite()->SetAlpha( 1.0f );
- }
- pacifier->SetVisible( false );
- }
- }
- //*************************************************************************************************************************
- // LBCACHE
- //*************************************************************************************************************************
- class LBCallback : public idLeaderboardCallback
- {
- public:
- LBCallback() {}
- void Call() {
- gameLocal.Shell_UpdateLeaderboard( this );
- }
- LBCallback * Clone() const {
- return new LBCallback( *this );
- }
- };
- /*
- ========================
- idLBCache::Pump
- ========================
- */
- void idLBCache::Pump() {
- if ( loadingNewLeaderboard || requestingRows ) {
- return;
- }
- if ( pendingDef != NULL ) {
- SetLeaderboard( pendingDef, pendingFilter );
- }
- }
- /*
- ========================
- idLBCache::Reset
- ========================
- */
- void idLBCache::Reset() {
- for ( int i = 0; i < NUM_ROW_BLOCKS; i++ ) {
- rowBlocks[i].startIndex = 0;
- rowBlocks[i].rows.Clear();
- }
- def = NULL;
- filter = DEFAULT_LEADERBOARD_FILTER;
- pendingDef = NULL;
- pendingFilter = DEFAULT_LEADERBOARD_FILTER;
- rowOffset = 0;
- requestingRows = false;
- numRowsInLeaderboard = 0;
- entryIndex = 0;
- loadingNewLeaderboard = false;
- }
- /*
- ========================
- idLBCache::SetLeaderboard
- ========================
- */
- void idLBCache::SetLeaderboard( const leaderboardDefinition_t * def_, leaderboardFilterMode_t filter_ ) {
- // If we are busy waiting on results from a previous request, queue up this request
- if ( loadingNewLeaderboard || requestingRows ) {
- pendingDef = def_;
- pendingFilter = filter_;
- return;
- }
- //idLib::Printf( "SetLeaderboard 0x%p.\n", def_ );
- // Reset all
- Reset();
- // Set leaderboard and filter
- def = def_;
- filter = filter_;
- loadingNewLeaderboard = true; // This means we are waiting on the first set of results for this new leaderboard
- localIndex = -1; // don't know where the user is in the rows yet
- // Kick off initial stats request (which is initially based on the filter type)
- if ( filter == LEADERBOARD_FILTER_MYSCORE ) {
- LBCallback cb;
- session->LeaderboardDownload( 0, def, 0, MAX_ROWS_PER_BLOCK, cb );
- } else if ( filter == LEADERBOARD_FILTER_FRIENDS ) {
- LBCallback cb;
- session->LeaderboardDownload( 0, def, -1, 100, cb ); // Request up to 100 friends
- } else {
- LBCallback cb;
- session->LeaderboardDownload( 0, def, rowOffset + 1, MAX_ROWS_PER_BLOCK, cb );
- //session->LeaderboardDownload( 0, def, rowOffset + 1, 10, cb ); // For testing
- }
- }
- /*
- ========================
- idLBCache::CycleFilter
- ========================
- */
- void idLBCache::CycleFilter() {
- // Set the proper filter
- if ( filter == LEADERBOARD_FILTER_OVERALL ) {
- filter = LEADERBOARD_FILTER_MYSCORE;
- } else if ( filter == LEADERBOARD_FILTER_MYSCORE ) {
- filter = LEADERBOARD_FILTER_FRIENDS;
- } else {
- filter = LEADERBOARD_FILTER_OVERALL;
- }
- // Reset the leaderboard with the new filter
- SetLeaderboard( def, filter );
- }
- /*
- ========================
- idLBCache::GetFilterStrType
- ========================
- */
- idStr idLBCache::GetFilterStrType() {
- if ( filter == LEADERBOARD_FILTER_FRIENDS ) {
- return idLocalization::GetString( "#str_swf_leaderboards_friends_heading" );
- } else if ( filter == LEADERBOARD_FILTER_MYSCORE ) {
- return idLocalization::GetString( "#str_swf_leaderboards_global_self_heading" );
- }
- return idLocalization::GetString( "#str_swf_leaderboards_global_heading" );
- }
- /*
- ========================
- idLBCache::Scroll
- ========================
- */
- bool idLBCache::Scroll( int amount ) {
- if ( GetErrorCode() != LEADERBOARD_DISPLAY_ERROR_NONE ) {
- return false; // don't allow scrolling on errors
- }
- // Remember old offsets so we know if anything moved
- int oldEntryIndex = entryIndex;
- int oldRowOffset = rowOffset;
- // Move cursor index by scroll amount
- entryIndex += amount;
- // Clamp cursor index (scrolling row offset if we can)
- if ( entryIndex < 0 ) {
- rowOffset += entryIndex;
- entryIndex = 0;
- } else if ( entryIndex >= numRowsInLeaderboard ) {
- entryIndex = numRowsInLeaderboard - 1;
- rowOffset = entryIndex - ( MAX_STAT_LISTINGS - 1 );
- } else if ( entryIndex >= MAX_STAT_LISTINGS ) {
- rowOffset += entryIndex - ( MAX_STAT_LISTINGS - 1 );
- entryIndex = MAX_STAT_LISTINGS - 1;
- }
- // Clamp row offset
- rowOffset = idMath::ClampInt( 0, Max( numRowsInLeaderboard - MAX_STAT_LISTINGS, 0 ), rowOffset );
- // Let caller know if anything actually changed
- return ( oldEntryIndex != entryIndex || oldRowOffset != rowOffset );
- }
- /*
- ========================
- idLBCache::ScrollOffset
- ========================
- */
- bool idLBCache::ScrollOffset( int amount ) {
- if ( GetErrorCode() != LEADERBOARD_DISPLAY_ERROR_NONE ) {
- return false; // don't allow scrolling on errors
- }
- // Remember old offsets so we know if anything moved
- int oldEntryIndex = entryIndex;
- int oldRowOffset = rowOffset;
- rowOffset += amount;
- // Clamp row offset
- rowOffset = idMath::ClampInt( 0, Max( numRowsInLeaderboard - MAX_STAT_LISTINGS, 0 ), rowOffset );
- if ( rowOffset != oldRowOffset ) {
- entryIndex -= amount; // adjust in opposite direction so same item stays selected
- entryIndex = idMath::ClampInt( 0, rowOffset + ( MAX_STAT_LISTINGS - 1 ), entryIndex );
- } else {
- entryIndex += amount;
- entryIndex = idMath::ClampInt( 0, numRowsInLeaderboard - 1, entryIndex );
- }
- // Let caller know if anything actually changed
- return ( oldEntryIndex != entryIndex || oldRowOffset != rowOffset );
- }
- /*
- ========================
- idLBCache::FindFreeRowBlock
- ========================
- */
- idLBRowBlock * idLBCache::FindFreeRowBlock() {
- int bestTime = 0;
- int bestBlockIndex = 0;
- for ( int i = 0; i < NUM_ROW_BLOCKS; i++ ) {
- if ( rowBlocks[i].rows.Num() == 0 ) {
- return &rowBlocks[i]; // Prefer completely empty blocks
- }
- // Search for oldest block in the mean time
- if ( i == 0 || rowBlocks[i].lastTime < bestTime ) {
- bestBlockIndex = i;
- bestTime = rowBlocks[i].lastTime;
- }
- }
- return &rowBlocks[bestBlockIndex];
- }
- /*
- ========================
- idLBCache::CallbackErrorToDisplayError
- ========================
- */
- leaderboardDisplayError_t idLBCache::CallbackErrorToDisplayError( leaderboardError_t errorCode ) {
- switch ( errorCode ) {
- case LEADERBOARD_ERROR_NONE:
- return LEADERBOARD_DISPLAY_ERROR_NONE;
- default:
- return LEADERBOARD_DISPLAY_ERROR_FAILED;
- }
- }
- /*
- ========================
- idLBCache::Update
- ========================
- */
- void idLBCache::Update( const idLeaderboardCallback * callback ) {
- requestingRows = false;
- //idLib::Printf( "Stats returned.\n" );
- errorCode = CallbackErrorToDisplayError( callback->GetErrorCode() );
- // check if trying to view "My Score" leaderboard when you aren't ranked yet
- if ( loadingNewLeaderboard && filter == LEADERBOARD_FILTER_MYSCORE && callback->GetLocalIndex() == -1 && errorCode == LEADERBOARD_DISPLAY_ERROR_NONE ) {
- errorCode = LEADERBOARD_DISPLAY_ERROR_NOT_RANKED;
- }
- if ( errorCode != LEADERBOARD_DISPLAY_ERROR_NONE ) {
- numRowsInLeaderboard = 0;
- loadingNewLeaderboard = false;
- switch ( errorCode ) {
- case LEADERBOARD_DISPLAY_ERROR_NOT_ONLINE:
- /*idMenuHandler_Shell * shell = gameLocal.Shell_GetHandler();
- if ( shell != NULL ) {
- shell->SetNextScreen( SHELL_AREA_ROOT, MENU_TRANSITION_SIMPLE );
- }*/
- common->Dialog().AddDialog( GDM_CONNECTION_LOST, DIALOG_ACCEPT, NULL, NULL, true, "", 0, true );
- break;
- default:
- break;
- }
- return;
- }
- if ( callback->GetDef() != def ) {
- // Not the leaderboard we are looking for (This should no longer be possible)
- idLib::Printf( "Wrong leaderboard.\n" );
- numRowsInLeaderboard = 0;
- loadingNewLeaderboard = false;
- return;
- }
- // Get total rows in this leaderboard
- numRowsInLeaderboard = callback->GetNumRowsInLeaderboard();
- // Store the index that the master user is in, if we haven't already found the index
- if ( callback->GetLocalIndex() != -1 ) {
- localIndex = callback->GetStartIndex() + callback->GetLocalIndex();
- }
- if ( loadingNewLeaderboard == true ) {
- // Default to viewing the local user (if the right filter mode is set)
- if ( callback->GetLocalIndex() != -1 && ( filter == LEADERBOARD_FILTER_MYSCORE || filter == LEADERBOARD_FILTER_FRIENDS ) ) {
- // Put their name and cursor at the top
- rowOffset = callback->GetLocalIndex() + callback->GetStartIndex();
- entryIndex = 0;
- // Scroll the cursor up to center their name as much as possible
- Scroll( -MAX_STAT_LISTINGS / 2 );
- // Set the cursor to their name
- entryIndex = ( callback->GetLocalIndex() + callback->GetStartIndex() ) - rowOffset;
- }
- loadingNewLeaderboard = false;
- }
- // Find a a row block to store these new rows
- idLBRowBlock * rowBlock = FindFreeRowBlock();
- rowBlock->lastTime = Sys_Milliseconds(); // Freshen row
- rowBlock->startIndex = callback->GetStartIndex();
- rowBlock->rows = callback->GetRows();
- }
- /*
- ========================
- idLBCache::GetLeaderboardRow
- ========================
- */
- const idLeaderboardCallback::row_t * idLBCache::GetLeaderboardRow( int row ) {
- if ( loadingNewLeaderboard ) {
- return NULL; // If we are refreshing (seeing this leaderboard for the first time), force NULL till we get first set of results
- }
- if ( row >= numRowsInLeaderboard ) {
- return NULL;
- }
- // Find it in the cache
- for ( int i = 0; i < NUM_ROW_BLOCKS; i++ ) {
- int startIndex = rowBlocks[i].startIndex;
- int lastIndex = startIndex + rowBlocks[i].rows.Num() - 1;
- if ( row >= startIndex && row <= lastIndex ) {
- rowBlocks[i].lastTime = Sys_Milliseconds(); // Freshen row
- return &rowBlocks[i].rows[row - startIndex];
- }
- }
- // Not found, kick off a request to download it
- // (this will not allow more than one request at a time)
- if ( !requestingRows ) {
- // If we don't have this row, kick off a request to get it
- LBCallback cb;
- requestingRows = true;
- session->LeaderboardDownload( 0, def, row + 1, MAX_ROWS_PER_BLOCK, cb );
- //session->LeaderboardDownload( 0, def, row + 1, 10, cb );
- //idLib::Printf( "Stat request\n" );
- }
- return NULL;
- }
- /*
- ========================
- idMainMenu::SetSPLeaderboardFromMenuSettings
- ========================
- */
- void idLBCache::DisplayGamerCardUI( const idLeaderboardCallback::row_t * row ) {
- }
|