diff options
| author | daoge_cmd <3523206925@qq.com> | 2026-03-01 12:16:08 +0800 |
|---|---|---|
| committer | daoge_cmd <3523206925@qq.com> | 2026-03-01 12:16:08 +0800 |
| commit | b691c43c44ff180d10e7d4a9afc83b98551ff586 (patch) | |
| tree | 3e9849222cbc6ba49f2f1fc6e5fe7179632c7390 /Minecraft.Client/Common/UI/UIScene_LeaderboardsMenu.cpp | |
| parent | def8cb415354ac390b7e89052a50605285f1aca9 (diff) | |
Initial commit
Diffstat (limited to 'Minecraft.Client/Common/UI/UIScene_LeaderboardsMenu.cpp')
| -rw-r--r-- | Minecraft.Client/Common/UI/UIScene_LeaderboardsMenu.cpp | 1045 |
1 files changed, 1045 insertions, 0 deletions
diff --git a/Minecraft.Client/Common/UI/UIScene_LeaderboardsMenu.cpp b/Minecraft.Client/Common/UI/UIScene_LeaderboardsMenu.cpp new file mode 100644 index 00000000..80db57f8 --- /dev/null +++ b/Minecraft.Client/Common/UI/UIScene_LeaderboardsMenu.cpp @@ -0,0 +1,1045 @@ +#include "stdafx.h" +#include "UI.h" +#include "UIScene_LeaderboardsMenu.h" +#include "..\Leaderboards\LeaderboardManager.h" +#include "..\..\..\Minecraft.World\net.minecraft.world.level.tile.h" +#include "..\..\..\Minecraft.World\net.minecraft.world.item.h" + +#define PLAYER_ONLINE_TIMER_ID 0 +#define PLAYER_ONLINE_TIMER_TIME 100 + +// if the value is greater than 32000, it's an xzp icon that needs displayed, rather than the game icon +const int UIScene_LeaderboardsMenu::TitleIcons[UIScene_LeaderboardsMenu::NUM_LEADERBOARDS][7] = +{ + { UIControl_LeaderboardList::e_ICON_TYPE_WALKED, UIControl_LeaderboardList::e_ICON_TYPE_FALLEN, Item::minecart_Id, Item::boat_Id, NULL }, + { Tile::dirt_Id, Tile::stoneBrick_Id, Tile::sand_Id, Tile::rock_Id, Tile::gravel_Id, Tile::clay_Id, Tile::obsidian_Id }, + { Item::egg_Id, Item::wheat_Id, Tile::mushroom1_Id, Tile::reeds_Id, Item::milk_Id, Tile::pumpkin_Id, NULL }, + { UIControl_LeaderboardList::e_ICON_TYPE_ZOMBIE, UIControl_LeaderboardList::e_ICON_TYPE_SKELETON, UIControl_LeaderboardList::e_ICON_TYPE_CREEPER, UIControl_LeaderboardList::e_ICON_TYPE_SPIDER, UIControl_LeaderboardList::e_ICON_TYPE_SPIDERJOKEY, UIControl_LeaderboardList::e_ICON_TYPE_ZOMBIEPIGMAN, UIControl_LeaderboardList::e_ICON_TYPE_SLIME }, +}; +const UIScene_LeaderboardsMenu::LeaderboardDescriptor UIScene_LeaderboardsMenu::LEADERBOARD_DESCRIPTORS[UIScene_LeaderboardsMenu::NUM_LEADERBOARDS][4] = { + { + UIScene_LeaderboardsMenu::LeaderboardDescriptor( 4, true, IDS_LEADERBOARD_TRAVELLING_PEACEFUL), // Travelling Peaceful + UIScene_LeaderboardsMenu::LeaderboardDescriptor( 4, true, IDS_LEADERBOARD_TRAVELLING_EASY), // Travelling Easy + UIScene_LeaderboardsMenu::LeaderboardDescriptor( 4, true, IDS_LEADERBOARD_TRAVELLING_NORMAL), // Travelling Normal + UIScene_LeaderboardsMenu::LeaderboardDescriptor( 4, true, IDS_LEADERBOARD_TRAVELLING_HARD), // Travelling Hard + }, + { + UIScene_LeaderboardsMenu::LeaderboardDescriptor( 7, false, IDS_LEADERBOARD_MINING_BLOCKS_PEACEFUL), // Mining Peaceful + UIScene_LeaderboardsMenu::LeaderboardDescriptor( 7, false, IDS_LEADERBOARD_MINING_BLOCKS_EASY), // Mining Easy + UIScene_LeaderboardsMenu::LeaderboardDescriptor( 7, false, IDS_LEADERBOARD_MINING_BLOCKS_NORMAL), // Mining Normal + UIScene_LeaderboardsMenu::LeaderboardDescriptor( 7, false, IDS_LEADERBOARD_MINING_BLOCKS_HARD), // Mining Hard + }, + { + UIScene_LeaderboardsMenu::LeaderboardDescriptor( 6, false, IDS_LEADERBOARD_FARMING_PEACEFUL), // Farming Peaceful + UIScene_LeaderboardsMenu::LeaderboardDescriptor( 6, false, IDS_LEADERBOARD_FARMING_EASY), // Farming Easy + UIScene_LeaderboardsMenu::LeaderboardDescriptor( 6, false, IDS_LEADERBOARD_FARMING_NORMAL), // Farming Normal + UIScene_LeaderboardsMenu::LeaderboardDescriptor( 6, false, IDS_LEADERBOARD_FARMING_HARD), // Farming Hard + }, + { + UIScene_LeaderboardsMenu::LeaderboardDescriptor( 0, false, -1), // + UIScene_LeaderboardsMenu::LeaderboardDescriptor( 7, false, IDS_LEADERBOARD_KILLS_EASY), // Kills Easy + UIScene_LeaderboardsMenu::LeaderboardDescriptor( 7, false, IDS_LEADERBOARD_KILLS_NORMAL), // Kills Normal + UIScene_LeaderboardsMenu::LeaderboardDescriptor( 7, false, IDS_LEADERBOARD_KILLS_HARD), // Kills Hard + }, +}; + +UIScene_LeaderboardsMenu::UIScene_LeaderboardsMenu(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer) +{ + // Setup all the Iggy references we need for this scene + initialiseMovie(); + + m_bReady=false; + + m_bPopulatedOnce = false; + + m_newTop = m_newSel = -1; + m_isProcessingStatsRead = false; + // Ignore input until we're retrieved stats, or functions will be called in here after we've backed out of the scene + m_bIgnoreInput=true; + + // Alert the app the we want to be informed of ethernet connections + app.SetLiveLinkRequired( true ); + + LeaderboardManager::Instance()->OpenSession(); + + //GetFriends(); + + m_currentLeaderboard = 0; + m_currentDifficulty = 2; + SetLeaderboardHeader(); + m_currentFilter = LeaderboardManager::eFM_Friends; + + wchar_t filterBuffer[40]; + swprintf(filterBuffer, 40, L"%ls%ls", app.GetString(IDS_LEADERBOARD_FILTER), app.GetString(IDS_LEADERBOARD_FILTER_FRIENDS)); + m_labelFilter.init(filterBuffer); + + wchar_t entriesBuffer[40]; + swprintf(entriesBuffer, 40, L"%ls%i", app.GetString(IDS_LEADERBOARD_ENTRIES), 0); + m_labelEntries.init(entriesBuffer); + + ReadStats(-1); + +#if ( defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ ) + addTimer( PLAYER_ONLINE_TIMER_ID, PLAYER_ONLINE_TIMER_TIME ); +#endif +} + +UIScene_LeaderboardsMenu::~UIScene_LeaderboardsMenu() +{ + LeaderboardManager::Instance()->CancelOperation(); + LeaderboardManager::Instance()->CloseSession(); + + // Alert the app the we no longer want to be informed of ethernet connections + app.SetLiveLinkRequired( false ); +} + +void UIScene_LeaderboardsMenu::updateTooltips() +{ + int iTooltipFriendRequest=-1; + int iTooltipGamerCardOrProfile=-1; + +#ifdef _DURANGO + //if( m_leaderboard.m_entries.size() > 0 ) + if(m_leaderboard.m_totalEntryCount > 0) + { + unsigned int selection = m_newSel; + + // If the selected user is me, don't show Send Friend Request, and show the gamer profile, not the gamer card + + // Check that the index is actually within range of the data we've got before accessing the m_leaderboard.m_entries array + int idx = selection - GetEntryStartIndex(); + if( ( idx < 0 ) || ( idx >= m_leaderboard.m_entries.size() ) ) + { + return; + } + if(m_leaderboard.m_entries[idx].m_bPlayer) + { + iTooltipGamerCardOrProfile=IDS_TOOLTIPS_VIEW_GAMERPROFILE; + } + else + { + iTooltipGamerCardOrProfile=IDS_TOOLTIPS_VIEW_GAMERCARD; + +#ifdef _XBOX + // if we're on the friends filter, then don't show the Send Friend Request + if(!m_currentFilter == LeaderboardManager::eFM_Friends) +#endif + { + // check the entry we're on + if( m_leaderboard.m_entries.size() > 0 ) + { + if( selection >= GetEntryStartIndex() && + selection < (GetEntryStartIndex() + m_leaderboard.m_entries.size()) ) + { +#ifdef _XBOX + if( (m_leaderboard.m_entries[selection - (m_leaderboard.m_entryStartIndex-1)].m_bFriend==false) + && (m_leaderboard.m_entries[selection - (m_leaderboard.m_entryStartIndex-1)].m_bRequestedFriend==false)) +#endif + { + iTooltipFriendRequest=IDS_TOOLTIPS_SEND_FRIEND_REQUEST; + } + } + } + } + } + } +#endif + + ui.SetTooltips(m_iPad, iTooltipFriendRequest, IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_CHANGE_FILTER, iTooltipGamerCardOrProfile); +} + +void UIScene_LeaderboardsMenu::updateComponents() +{ + m_parentLayer->showComponent(m_iPad,eUIComponent_Panorama,!app.GetGameStarted()); + m_parentLayer->showComponent(m_iPad,eUIComponent_Logo,false); +} + +wstring UIScene_LeaderboardsMenu::getMoviePath() +{ + return L"LeaderboardMenu"; +} + +void UIScene_LeaderboardsMenu::handleReload() +{ + // We don't allow this in splitscreen, so just go back + navigateBack(); +} + +void UIScene_LeaderboardsMenu::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled) +{ + if(m_bIgnoreInput && key != ACTION_MENU_CANCEL) return; + + ui.AnimateKeyPress(m_iPad, key, repeat, pressed, released); + + // If this is not a press, do not action + if (!pressed) return; + + + /*app.DebugPrintf( + " m_newSel = %i [bottomId] = %i [topId] = %i, [size] = %i\n", + m_newSel, + m_leaderboard.m_entries.size() == 0 ? 0 : m_leaderboard.m_entries[m_leaderboard.m_entries.size()-1].m_row, + GetEntryStartIndex(), + m_leaderboard.m_entries.size() + );*/ + + switch(key) + { + case ACTION_MENU_CANCEL: + if(pressed) + { + navigateBack(); + handled = true; + } + break; + case ACTION_MENU_UP: + --m_newSel; + if(m_newSel<0)m_newSel = 0; + sendInputToMovie(key, repeat, pressed, released); + break; + case ACTION_MENU_DOWN: + ++m_newSel; + if(m_newSel>=m_leaderboard.m_totalEntryCount) m_newSel = m_leaderboard.m_totalEntryCount - 1; + sendInputToMovie(key, repeat, pressed, released); + break; + case ACTION_MENU_LEFT_SCROLL: + case ACTION_MENU_RIGHT_SCROLL: + { + //Do nothing if a stats read is currently in progress, otherwise the system complains about to many read requests + if( pressed && m_bPopulatedOnce && LeaderboardManager::Instance()->isIdle() ) + { + //CD - Added for audio + ui.PlayUISFX(eSFX_Scroll); + + if( key == ACTION_MENU_RIGHT_SCROLL ) + { + ++m_currentDifficulty; + if( m_currentDifficulty == 4 ) + m_currentDifficulty = 0; + + if( m_currentLeaderboard == LEADERBOARD_KILLS_POSITION && m_currentDifficulty == 0 ) + m_currentDifficulty = 1; + } + else + { + if( m_currentDifficulty == 0 ) + m_currentDifficulty = 4; + --m_currentDifficulty; + + if( m_currentLeaderboard == LEADERBOARD_KILLS_POSITION && m_currentDifficulty == 0 ) + m_currentDifficulty = 3; + } + + SetLeaderboardHeader(); + + ReadStats(-1); + ui.PlayUISFX(eSFX_Press); + } + + handled = true; + } + break; + case ACTION_MENU_LEFT: + case ACTION_MENU_RIGHT: + { + //Do nothing if a stats read is currently in progress, otherwise the system complains about to many read requests + if ( pressed && m_bPopulatedOnce && LeaderboardManager::Instance()->isIdle() ) + { + //CD - Added for audio + ui.PlayUISFX(eSFX_Scroll); + + m_bReady=false; + if(key == ACTION_MENU_RIGHT) + { + ++m_currentLeaderboard; + if( m_currentLeaderboard == NUM_LEADERBOARDS ) + m_currentLeaderboard = 0; + } + else + { + if( m_currentLeaderboard == 0 ) + m_currentLeaderboard = NUM_LEADERBOARDS; + --m_currentLeaderboard; + } + + if( m_currentLeaderboard == LEADERBOARD_KILLS_POSITION && m_currentDifficulty == 0 ) + m_currentDifficulty = 1; + + SetLeaderboardHeader(); + + ReadStats(-1); + ui.PlayUISFX(eSFX_Press); + } + handled = true; + } + break; + case ACTION_MENU_PAGEUP: + case ACTION_MENU_PAGEDOWN: + { + //Do nothing if a stats read is currently in progress, otherwise the system complains about to many read requests + if( pressed && m_bPopulatedOnce && LeaderboardManager::Instance()->isIdle() ) + { + //CD - Added for audio + ui.PlayUISFX(eSFX_Scroll); + + if( m_leaderboard.m_totalEntryCount <= 10 ) + break; + + sendInputToMovie(key, repeat, pressed, released); + +#if 0 + if( key == ACTION_MENU_PAGEUP ) + { + m_newTop = m_listGamers.GetTopItem() - 10; + + if( m_newTop < 0 ) + m_newTop = 0; + + m_newSel = m_newTop; + } + else + { + + m_newTop = m_listGamers.GetTopItem() + 10; + + if( m_newTop+10 > (int)m_leaderboard.m_totalEntryCount ) + { + m_newTop = m_leaderboard.m_totalEntryCount - 10; + if( m_newTop < 0 ) + m_newTop = 0; + } + + m_newSel = m_newTop; + } +#endif + } + handled = true; + } + break; + case ACTION_MENU_X: + { + //Do nothing if a stats read is currently in progress, otherwise the system complains about to many read requests + if( pressed && m_bPopulatedOnce && LeaderboardManager::Instance()->isIdle() ) + { + //CD - Added for audio + ui.PlayUISFX(eSFX_Scroll); + + switch( m_currentFilter ) + { + case LeaderboardManager::eFM_Friends: + { + m_currentFilter = LeaderboardManager::eFM_MyScore; + wchar_t filterBuffer[40]; + swprintf(filterBuffer, 40, L"%ls%ls", app.GetString(IDS_LEADERBOARD_FILTER), app.GetString(IDS_LEADERBOARD_FILTER_MYSCORE)); + m_labelFilter.setLabel(filterBuffer); + } + break; + case LeaderboardManager::eFM_MyScore: + { + m_currentFilter = LeaderboardManager::eFM_TopRank; + wchar_t filterBuffer[40]; + swprintf(filterBuffer, 40, L"%ls%ls", app.GetString(IDS_LEADERBOARD_FILTER), app.GetString(IDS_LEADERBOARD_FILTER_OVERALL)); + m_labelFilter.setLabel(filterBuffer); + } + break; + case LeaderboardManager::eFM_TopRank: + { + m_currentFilter = LeaderboardManager::eFM_Friends; + wchar_t filterBuffer[40]; + swprintf(filterBuffer, 40, L"%ls%ls", app.GetString(IDS_LEADERBOARD_FILTER), app.GetString(IDS_LEADERBOARD_FILTER_FRIENDS)); + m_labelFilter.setLabel(filterBuffer); + } + break; + } + + ReadStats(-1); + ui.PlayUISFX(eSFX_Press); + } + handled = true; + } + break; + case ACTION_MENU_Y: + { +#ifdef _DURANGO + //Show gamercard + //if( m_leaderboard.m_entries.size() > 0 ) + if(m_leaderboard.m_totalEntryCount > 0) + { + unsigned int selection = m_newSel; + if( selection >= GetEntryStartIndex() && + selection < (GetEntryStartIndex() + m_leaderboard.m_entries.size()) ) + { + PlayerUID uid = m_leaderboard.m_entries[selection - GetEntryStartIndex()].m_xuid; + if( uid != INVALID_XUID ) + { + ProfileManager.ShowProfileCard(ProfileManager.GetLockedProfile(),uid); + ui.PlayUISFX(eSFX_Press); + } + } + } +#endif + handled = true; + } + break; + case ACTION_MENU_A: + { +#ifdef _DURANGO + //Send friend request if the filter mode is not friend, and they're not a friend or a pending friend +#ifdef _XBOX + if( m_currentFilter != LeaderboardManager::eFM_Friends ) +#endif + { + if( m_leaderboard.m_entries.size() > 0 ) + { + unsigned int selection = m_newSel; + if( selection >= GetEntryStartIndex() && + selection < (GetEntryStartIndex() + m_leaderboard.m_entries.size()) ) + { + //If not the player and neither currently a friend or requested to be a friend + if( !m_leaderboard.m_entries[selection - GetEntryStartIndex()].m_bPlayer +#ifdef _XBOX + && !m_leaderboard.m_entries[selection - (m_leaderboard.m_entryStartIndex-1) ].m_bFriend + && !m_leaderboard.m_entries[selection - (m_leaderboard.m_entryStartIndex-1) ].m_bRequestedFriend +#endif + ) + { + PlayerUID xuid = m_leaderboard.m_entries[selection - GetEntryStartIndex()].m_xuid; + if( xuid != INVALID_XUID ) + { + ProfileManager.ShowAddFriend(m_iPad,xuid); + ui.PlayUISFX(eSFX_Press); + } + } + } + } + } +#endif + handled = true; + } + break; + } +} + +void UIScene_LeaderboardsMenu::ReadStats(int startIndex) +{ + //If startIndex == -1, then use default values + if( startIndex == -1 ) + { + m_newEntryIndex = 1; + m_newReadSize = READ_SIZE; + + m_newEntriesCount = 0; + + m_leaderboard.m_totalEntryCount = 0; + + m_listEntries.clearList(); + } + else + { + m_newEntryIndex = (unsigned int)startIndex; + // m_newReadSize = min((int)READ_SIZE, (int)m_leaderboard.m_totalEntryCount-(startIndex-1)); + } + + //app.DebugPrintf("Requesting stats read %d - %d - %d\n", m_currentLeaderboard, startIndex == -1 ? m_currentFilter : LeaderboardManager::eFM_TopRank, m_currentDifficulty); + + LeaderboardManager::EFilterMode filtermode; + if ( m_currentFilter == LeaderboardManager::eFM_MyScore + || m_currentFilter == LeaderboardManager::eFM_TopRank ) + { + filtermode = (startIndex == -1 ? m_currentFilter : LeaderboardManager::eFM_TopRank); + } + else + { + // 4J-JEV: Friends filter shouldn't switch to toprank. + filtermode = m_currentFilter; + } + + switch (filtermode) + { + case LeaderboardManager::eFM_TopRank: + LeaderboardManager::Instance()->ReadStats_TopRank( this, + m_currentDifficulty, (LeaderboardManager::EStatsType) m_currentLeaderboard, + m_newEntryIndex, m_newReadSize + ); + break; + case LeaderboardManager::eFM_MyScore: + { + PlayerUID uid; + ProfileManager.GetXUID(ProfileManager.GetPrimaryPad(),&uid, true); + LeaderboardManager::Instance()->ReadStats_MyScore( this, + m_currentDifficulty, (LeaderboardManager::EStatsType) m_currentLeaderboard, + uid /*ignored on PS3*/, + m_newReadSize + ); + } + break; + case LeaderboardManager::eFM_Friends: + { + PlayerUID uid; + ProfileManager.GetXUID(ProfileManager.GetPrimaryPad(),&uid, true); + LeaderboardManager::Instance()->ReadStats_Friends( this, + m_currentDifficulty, (LeaderboardManager::EStatsType) m_currentLeaderboard, + uid /*ignored on PS3*/, + m_newEntryIndex, m_newReadSize + ); + } + break; + } + + //Show the loading message + m_labelInfo.setLabel(app.GetString(IDS_LEADERBOARD_LOADING)); + m_labelInfo.setVisible(true); +} + +bool UIScene_LeaderboardsMenu::OnStatsReadComplete(LeaderboardManager::eStatsReturn retIn, int numResults, LeaderboardManager::ViewOut results) +{ + //CScene_Leaderboards* scene = reinterpret_cast<CScene_Leaderboards*>(userdata); + + m_isProcessingStatsRead = true; + + //bool noResults = LeaderboardManager::Instance()->GetStatsState() != XboxLeaderboardManager::eStatsState_Ready; + bool ret; + + //app.DebugPrintf("Leaderboards read %d stats\n", numResults); + if (retIn == LeaderboardManager::eStatsReturn_Success) + { + m_numStats = numResults; + m_stats = results; + ret = RetrieveStats(); + } + else ret = true; + + //else LeaderboardManager::Instance()->SetStatsRetrieved(false); + + PopulateLeaderboard(retIn); + + updateTooltips(); + + m_isProcessingStatsRead = false; + + // allow user input now + m_bIgnoreInput=false; + + return ret; +} + +bool UIScene_LeaderboardsMenu::RetrieveStats() +{ + if(app.DebugSettingsOn() && (app.GetGameSettingsDebugMask()&(1L<<eDebugSetting_DebugLeaderboards))) + { + m_leaderboard.m_totalEntryCount = NUM_ENTRIES; + m_leaderboard.m_numColumns = LEADERBOARD_DESCRIPTORS[m_currentLeaderboard][m_currentDifficulty].m_columnCount; + + //For each entry in the leaderboard + for(unsigned int entryIndex=0; entryIndex < NUM_ENTRIES; entryIndex++) + { + m_leaderboard.m_entries.push_back(LeaderboardEntry()); + m_leaderboard.m_entries[entryIndex].m_xuid = INVALID_XUID; + + m_leaderboard.m_entries[entryIndex].m_row = entryIndex; + m_leaderboard.m_entries[entryIndex].m_rank = entryIndex+1; + swprintf(m_leaderboard.m_entries[entryIndex].m_wcRank, 12, L"12345678");//(int)m_leaderboard.m_entries[entryIndex].m_rank); + + swprintf(m_leaderboard.m_entries[entryIndex].m_gamerTag, 17, L"WWWWWWWWWWWWWWWW"); + + //m_leaderboard.m_entries[entryIndex].m_locale = (entryIndex % 37) + 1; + + bool isDistanceLeaderboard = LEADERBOARD_DESCRIPTORS[m_currentLeaderboard][m_currentDifficulty].m_isDistanceLeaderboard; + + for( unsigned int i=0 ; i<m_leaderboard.m_numColumns ; i++ ) + { + if( !isDistanceLeaderboard ) + { + m_leaderboard.m_entries[entryIndex].m_columns[i] = USHRT_MAX; + swprintf(m_leaderboard.m_entries[entryIndex].m_wcColumns[i], 12, L"%u", m_leaderboard.m_entries[entryIndex].m_columns[i]); + } + else + { + m_leaderboard.m_entries[entryIndex].m_columns[i] = UINT_MAX; + swprintf(m_leaderboard.m_entries[entryIndex].m_wcColumns[i], 12, L"%.1fkm", ((float)m_leaderboard.m_entries[entryIndex].m_columns[i])/100.f/1000.f); + } + } + + m_leaderboard.m_entries[entryIndex].m_bPlayer = (entryIndex == 0); + m_leaderboard.m_entries[entryIndex].m_bOnline = (entryIndex != 0); + m_leaderboard.m_entries[entryIndex].m_bFriend = (entryIndex != 0); + m_leaderboard.m_entries[entryIndex].m_bRequestedFriend = false; + } + + //LeaderboardManager::Instance()->SetStatsRetrieved(true); + + m_newEntryIndex = 0; + m_newEntriesCount = NUM_ENTRIES; + + return true; + } + + //assert( LeaderboardManager::Instance()->GetStats() != NULL ); + //PXUSER_STATS_READ_RESULTS stats = LeaderboardManager::Instance()->GetStats(); + //if( m_currentFilter == LeaderboardManager::eFM_Friends ) LeaderboardManager::Instance()->SortFriendStats(); + + bool isDistanceLeaderboard = LEADERBOARD_DESCRIPTORS[m_currentLeaderboard][m_currentDifficulty].m_isDistanceLeaderboard; + + m_newEntriesCount = m_stats.m_numQueries; + + // First read + if( m_leaderboard.m_totalEntryCount == 0 ) + { + m_leaderboard.m_entries.clear(); + +#if _DURANGO + m_leaderboard.m_totalEntryCount = m_numStats; +#else + m_leaderboard.m_totalEntryCount = (m_currentFilter == LeaderboardManager::eFM_Friends) ? m_newEntriesCount : m_numStats; +#endif + + if( m_leaderboard.m_totalEntryCount == 0 || m_newEntriesCount == 0 ) + { + //LeaderboardManager::Instance()->SetStatsRetrieved(false); + return false; + } + + m_leaderboard.m_numColumns = m_stats.m_queries[0].m_statsSize; + + for( unsigned int entryIndex=0 ; entryIndex < m_newEntriesCount; ++entryIndex ) + { + m_leaderboard.m_entries.push_back(LeaderboardEntry()); + CopyLeaderboardEntry(&(m_stats.m_queries[entryIndex]), entryIndex, isDistanceLeaderboard); + } + + m_newEntryIndex = 0; + + // Clear these values so that we know whether or not they are set in the next block + m_newTop = -1; + m_newSel = -1; + + // If the filter mode is "My Score" then centre the list around the entries and select the player's score + if( m_currentFilter == LeaderboardManager::eFM_MyScore) + { + //Centre the leaderboard list on the entries + m_newTop = GetEntryStartIndex(); + + //Select the player entry + for( unsigned int i = GetEntryStartIndex(); i< GetEntryStartIndex() + m_leaderboard.m_entries.size(); ++i ) + { + if( m_leaderboard.m_entries[i - GetEntryStartIndex()].m_bPlayer ) + { + m_newSel = i; // this might be off the screen! + // and reposition the top one + if(m_newSel-m_newTop>9) + { + m_newTop=m_newSel-9; + } + break; + } + } + } + + // If not set, default to start index + if (m_newSel < 0) m_newTop = m_newSel = GetEntryStartIndex(); + } + // Additional read + else + { + if(m_newEntryIndex < GetEntryStartIndex() && m_newEntryIndex == 1) + { + // If we're at the top the new entries count is incorrect, so amend + m_newEntriesCount = GetEntryStartIndex(); + } + + bool deleteFront = false; + bool deleteBack = false; + + bool trim = m_leaderboard.m_entries.size() + m_newEntriesCount >= NUM_ENTRIES; + + unsigned int insertPosition = 0; + + // If the first new entry is at a smaller index than the current first entry + if(m_newEntryIndex < GetEntryStartIndex()) + { + insertPosition = 0; + if (trim) deleteBack = true; + } + else + { + insertPosition = m_leaderboard.m_entries.size(); + if (trim) deleteFront = true; + } + + m_newEntryIndex = insertPosition; + + // Copy results to entries list + for( unsigned int i=0 ; i < m_newEntriesCount ; ++i ) + { + m_leaderboard.m_entries.insert(m_leaderboard.m_entries.begin() + insertPosition, LeaderboardEntry()); + CopyLeaderboardEntry(&(m_stats.m_queries[i]), insertPosition, isDistanceLeaderboard); + + insertPosition++; + } + + if (deleteFront) + { + // Delete front x entries + m_leaderboard.m_entries.erase(m_leaderboard.m_entries.begin(), m_leaderboard.m_entries.begin() + READ_SIZE); + m_newEntryIndex -= m_newReadSize; + } + else if (deleteBack) + { + // Delete back x entries + m_leaderboard.m_entries.erase(m_leaderboard.m_entries.end() - READ_SIZE, m_leaderboard.m_entries.end()); + } + } + + return true; +} + +void UIScene_LeaderboardsMenu::CopyLeaderboardEntry(LeaderboardManager::ReadScore *statsRow, int leaderboardEntryIndex, bool isDistanceLeaderboard) +{ + LeaderboardEntry* leaderboardEntry = &(m_leaderboard.m_entries[leaderboardEntryIndex]); + + ZeroMemory(leaderboardEntry, sizeof(LeaderboardEntry)); + leaderboardEntry->m_xuid = statsRow->m_uid; + + // Copy the rank + leaderboardEntry->m_rank = statsRow->m_rank; + DWORD displayRank = leaderboardEntry->m_rank; + if(displayRank > 9999999) displayRank = 9999999; + swprintf(leaderboardEntry->m_wcRank, 12, L"%u", displayRank); + + leaderboardEntry->m_idsErrorMessage = statsRow->m_idsErrorMessage; + + // Build a row ID + if (m_currentFilter == LeaderboardManager::eFM_Friends) + { + // If friends don't ID rows by rank + leaderboardEntry->m_row = leaderboardEntryIndex; + } + else + { + leaderboardEntry->m_row = statsRow->m_rank - 1; + if (leaderboardEntryIndex > 0) { + // Check this row ID (/rank) against the last one, it might be the same + // (this happens on PS3 when players have the same score, i.e. if they share 76th position there'll be two rank 76 + // and the following entry will be rank 78) + LeaderboardEntry* prevEntry = &(m_leaderboard.m_entries[leaderboardEntryIndex - 1]); + if (leaderboardEntry->m_row <= prevEntry->m_row) + { + leaderboardEntry->m_row = prevEntry->m_row + 1; + } + } + } + +#ifdef __PS3__ + // m_name can be unicode characters somehow for Japan - should use m_onlineID + wstring wstr=convStringToWstring(statsRow->m_uid.getOnlineID()); + swprintf(leaderboardEntry->m_gamerTag, XUSER_NAME_SIZE, L"%ls",wstr.c_str()); +#else + memcpy(leaderboardEntry->m_gamerTag, statsRow->m_name.data(), statsRow->m_name.size() * sizeof(wchar_t)); +#endif + + // Copy the other columns + for( unsigned int i=0 ; i<statsRow->m_statsSize ; i++ ) + { + leaderboardEntry->m_columns[i] = statsRow->m_statsData[i]; + ZeroMemory(leaderboardEntry->m_wcColumns[i],12*sizeof(WCHAR)); + if( !isDistanceLeaderboard ) + { + DWORD displayValue = leaderboardEntry->m_columns[i]; + if(displayValue > 99999) displayValue = 99999; + swprintf(leaderboardEntry->m_wcColumns[i], 12, L"%u",displayValue); +#ifdef _DEBUG + //app.DebugPrintf("Value - %d\n",leaderboardEntry->m_columns[i]); +#endif + } + else + { + // check how many digits we have + int iDigitC=0; + unsigned int uiVal=leaderboardEntry->m_columns[i]; +// uiVal=0xFFFFFFFF; +// leaderboardEntry->m_columns[i-1]=uiVal; + + while(uiVal!=0) + { + uiVal/=10; + iDigitC++; + } + +#ifdef _DEBUG + //app.DebugPrintf("Value - %d\n",leaderboardEntry->m_columns[i]); +#endif + if(iDigitC<4) + { + // m + swprintf(leaderboardEntry->m_wcColumns[i], 12, L"%um", leaderboardEntry->m_columns[i]); +#ifdef _DEBUG + //app.DebugPrintf("Display - %um\n", leaderboardEntry->m_columns[i]); +#endif + } + else if(iDigitC<8) + { + // km with a .X + swprintf(leaderboardEntry->m_wcColumns[i], 12, L"%.1fkm", ((float)leaderboardEntry->m_columns[i])/1000.f); +#ifdef _DEBUG + //app.DebugPrintf("Display - %.1fkm\n", ((float)leaderboardEntry->m_columns[i])/1000.f); +#endif + } + else + { + // bigger than that, so no decimal point + swprintf(leaderboardEntry->m_wcColumns[i], 12, L"%.0fkm", ((float)leaderboardEntry->m_columns[i])/1000.f); +#ifdef _DEBUG + //app.DebugPrintf("Display - %.0fkm\n", ((float)leaderboardEntry->m_columns[i])/1000.f); +#endif + } + } + } + +#ifdef _DURANGO + //Is the player + PlayerUID myXuid; + ProfileManager.GetXUID(ProfileManager.GetPrimaryPad(),&myXuid,true); + if( statsRow->m_uid == myXuid ) + { + leaderboardEntry->m_bPlayer = true; + leaderboardEntry->m_bOnline = false; + leaderboardEntry->m_bFriend = false; + leaderboardEntry->m_bRequestedFriend = false; + } + else + { + leaderboardEntry->m_bPlayer = false; + leaderboardEntry->m_bOnline = false; + leaderboardEntry->m_bFriend = false; + leaderboardEntry->m_bRequestedFriend = false; + +#ifdef _XBOX + //Check for friend status + for( unsigned int friendIndex=0 ; friendIndex<m_numFriends ; ++friendIndex ) + { + if( m_friends[friendIndex].xuid == statsRow->m_uid ) + { + if( ( m_friends[friendIndex].dwFriendState & ( XONLINE_FRIENDSTATE_FLAG_SENTREQUEST | XONLINE_FRIENDSTATE_FLAG_RECEIVEDREQUEST ) ) == 0 ) + { + //Is friend, might be online + leaderboardEntry->m_bFriend = true; + leaderboardEntry->m_bOnline = ( m_friends[friendIndex].dwFriendState & XONLINE_FRIENDSTATE_FLAG_ONLINE ); + leaderboardEntry->m_bRequestedFriend = false; + } + else + { + //Friend request sent but not accepted yet + leaderboardEntry->m_bOnline = false; + leaderboardEntry->m_bFriend = false; + leaderboardEntry->m_bRequestedFriend = true; + } + + break; + } + } +#endif + } +#endif +} + +void UIScene_LeaderboardsMenu::PopulateLeaderboard(LeaderboardManager::eStatsReturn ret) +{ + int iValidSlots=SetLeaderboardTitleIcons(); + if( ret == LeaderboardManager::eStatsReturn_Success && m_leaderboard.m_totalEntryCount > 0 ) + { + m_listEntries.setupTitles( app.GetString( IDS_LEADERBOARD_RANK ), app.GetString( IDS_LEADERBOARD_GAMERTAG ) ); + + //Update entries display + wchar_t entriesBuffer[40]; + if(app.DebugSettingsOn() && (app.GetGameSettingsDebugMask()&(1L<<eDebugSetting_DebugLeaderboards))) + { + swprintf(entriesBuffer, 40, L"%ls12345678", app.GetString(IDS_LEADERBOARD_ENTRIES)); + } + else + { + swprintf(entriesBuffer, 40, L"%ls%i", app.GetString(IDS_LEADERBOARD_ENTRIES), m_leaderboard.m_totalEntryCount); + } + + m_labelEntries.setLabel(entriesBuffer); + m_labelInfo.setLabel(L""); + m_labelInfo.setVisible( false ); + + m_listEntries.initLeaderboard(m_newSel, m_leaderboard.m_totalEntryCount, LEADERBOARD_DESCRIPTORS[m_currentLeaderboard][m_currentDifficulty].m_columnCount); + + int startIndex = m_newEntryIndex; + int entryCount = m_newEntriesCount; + + for(DWORD i = startIndex; i < (startIndex + entryCount); ++i) + { + bool isLast = i == ((startIndex + entryCount) - 1); + + int idsErrorMessage = m_leaderboard.m_entries[i].m_idsErrorMessage; + + if (idsErrorMessage > 0) + { + m_listEntries.addDataSet( + isLast, + m_leaderboard.m_entries[i].m_row, + m_leaderboard.m_entries[i].m_rank, + m_leaderboard.m_entries[i].m_gamerTag, + + true, // 4J-JEV: Has error message to display. + + app.GetString(idsErrorMessage), + L"", L"", L"", L"", L"", L"" + ); + } + else + { + m_listEntries.addDataSet( + isLast, + m_leaderboard.m_entries[i].m_row, + m_leaderboard.m_entries[i].m_rank, + m_leaderboard.m_entries[i].m_gamerTag, + + // 4J-TomK | The bDisplayMessage Flag defines if Leaderboard Data should be + // displayed (false) or if a specific message (true - when data is private for example) + // should be displayed. The message itself should be passed on in col0! + false, + + m_leaderboard.m_entries[i].m_wcColumns[0], + m_leaderboard.m_entries[i].m_wcColumns[1], + m_leaderboard.m_entries[i].m_wcColumns[2], + m_leaderboard.m_entries[i].m_wcColumns[3], + m_leaderboard.m_entries[i].m_wcColumns[4], + m_leaderboard.m_entries[i].m_wcColumns[5], + m_leaderboard.m_entries[i].m_wcColumns[6] + ); + } + } + } + else + { + m_listEntries.setupTitles( L"", L"" ); + + //Update entries display (to zero) + wchar_t entriesBuffer[40]; + swprintf(entriesBuffer, 40, L"%ls0", app.GetString(IDS_LEADERBOARD_ENTRIES)); + m_labelEntries.setLabel(entriesBuffer); + + //Show the no results message +#if !(defined(_XBOX) || defined(_WINDOWS64)) // 4J Stu - Temp to get the win build running, but so we check this for other platforms + if (ret == LeaderboardManager::eStatsReturn_NetworkError) + m_labelInfo.setLabel(app.GetString(IDS_ERROR_NETWORK)); + else +#endif + m_labelInfo.setLabel(app.GetString(IDS_LEADERBOARD_NORESULTS)); + m_labelInfo.setVisible(true); + } + m_bPopulatedOnce = true; +} + +void UIScene_LeaderboardsMenu::SetLeaderboardHeader() +{ + m_labelLeaderboard.setLabel(app.GetString(LEADERBOARD_DESCRIPTORS[m_currentLeaderboard][m_currentDifficulty].m_title)); +} + +int UIScene_LeaderboardsMenu::SetLeaderboardTitleIcons() +{ + int iValidIcons=0; + + for(int i=0;i<7;i++) + { + if(TitleIcons[m_currentLeaderboard][i]==0) + { + //m_pHTitleIconSlots[i]->SetShow(FALSE); + } + else + { + iValidIcons++; + m_listEntries.setColumnIcon(i,TitleIcons[m_currentLeaderboard][i]); + } + } + + return iValidIcons; +} + +void UIScene_LeaderboardsMenu::customDraw(IggyCustomDrawCallbackRegion *region) +{ + int slotId = -1; + swscanf((wchar_t*)region->name,L"slot_%d",&slotId); + if (slotId == -1) + { + //app.DebugPrintf("This is not the control we are looking for\n"); + } + else + { + shared_ptr<ItemInstance> item = shared_ptr<ItemInstance>( new ItemInstance(TitleIcons[m_currentLeaderboard][slotId], 1, 0) ); + customDrawSlotControl(region,m_iPad,item,1.0f,false,false); + } +} + +void UIScene_LeaderboardsMenu::handleSelectionChanged(F64 selectedId) +{ + ui.PlayUISFX(eSFX_Focus); + m_newSel = (int)selectedId; + updateTooltips(); +} + +// Handle a request from Iggy for more data +void UIScene_LeaderboardsMenu::handleRequestMoreData(F64 startIndex, bool up) +{ + unsigned int item = (int)startIndex; + + if( m_leaderboard.m_totalEntryCount > 0 && (item+1) < GetEntryStartIndex() ) + { + if( LeaderboardManager::Instance()->isIdle() ) + { + int readIndex = (GetEntryStartIndex() + 1) - READ_SIZE; + if( readIndex <= 0 ) + readIndex = 1; + assert( readIndex >= 1 && readIndex <= (int)m_leaderboard.m_totalEntryCount ); + ReadStats(readIndex); + } + } + else if( m_leaderboard.m_totalEntryCount > 0 && (item+1) >= (GetEntryStartIndex() + m_leaderboard.m_entries.size()) ) + { + if( LeaderboardManager::Instance()->isIdle() ) + { + int readIndex = (GetEntryStartIndex() + 1) + m_leaderboard.m_entries.size(); + assert( readIndex >= 1 && readIndex <= (int)m_leaderboard.m_totalEntryCount ); + ReadStats(readIndex); + } + } +} + +void UIScene_LeaderboardsMenu::handleTimerComplete(int id) +{ +#if ( defined __PS3__ || defined __ORBIS__ || defined __PSVITA__) + switch(id) + { + case PLAYER_ONLINE_TIMER_ID: +#ifndef _WINDOWS64 + if(ProfileManager.IsSignedInLive(ProfileManager.GetPrimaryPad())==false) + { + // check the player hasn't gone offline + // If they have, bring up the PSN warning and exit from the leaderboards + unsigned int uiIDA[1]; + uiIDA[0]=IDS_OK; + C4JStorage::EMessageResult result = ui.RequestMessageBox( IDS_CONNECTION_LOST, g_NetworkManager.CorrectErrorIDS(IDS_CONNECTION_LOST_LIVE_NO_EXIT), uiIDA,1,ProfileManager.GetPrimaryPad(),UIScene_LeaderboardsMenu::ExitLeaderboards,this, app.GetStringTable()); + } +#endif + break; + } +#endif +} + +int UIScene_LeaderboardsMenu::ExitLeaderboards(void *pParam,int iPad,C4JStorage::EMessageResult result) +{ + UIScene_LeaderboardsMenu* pClass = (UIScene_LeaderboardsMenu*)pParam; + + pClass->navigateBack(); + + return 0; +} + +// Get entry start size, if no entries returns 0 +int UIScene_LeaderboardsMenu::GetEntryStartIndex() +{ + return m_leaderboard.m_entries.size() == 0 ? 0 : m_leaderboard.m_entries[0].m_row; +} |
