4jcraft/Minecraft.Client/Platform/Common/UI/UIScene_LeaderboardsMenu.cpp

1091 lines
41 KiB
C++

#include "../../Minecraft.World/Platform/stdafx.h"
#include "UI.h"
#include "UIScene_LeaderboardsMenu.h"
#include "../Leaderboards/LeaderboardManager.h"
#include "../../Minecraft.World/Headers/net.minecraft.world.level.tile.h"
#include "../../Minecraft.World/Headers/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::cobblestone_Id, Tile::sand_Id, Tile::stone_Id,
Tile::gravel_Id, Tile::clay_Id, Tile::obsidian_Id},
{Item::egg_Id, Item::wheat_Id, Tile::mushroom_brown_Id, Tile::reeds_Id,
Item::bucket_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), m_interface(LeaderboardManager::Instance()) {
// 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);
// 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() {
// 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);
}
std::wstring UIScene_LeaderboardsMenu::getMoviePath() {
return L"LeaderboardMenu";
}
void UIScene_LeaderboardsMenu::tick() {
UIScene::tick();
m_interface.tick();
}
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;
default:
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 = std::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: {
m_interface.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);
m_interface.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);
m_interface.ReadStats_Friends(
this, m_currentDifficulty,
(LeaderboardManager::EStatsType)m_currentLeaderboard,
uid /*ignored on PS3*/, m_newEntryIndex, m_newReadSize);
} break;
default:
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);
m_numStats = numResults;
m_stats = results;
ret = RetrieveStats();
// 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;
unsigned int 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
std::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_t));
if (!isDistanceLeaderboard) {
unsigned int 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 (unsigned int 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 = parseSlotId(region->name);
if (slotId == -1) {
// assert(0);
app.DebugPrintf("This is not the control we are looking for\n");
} else {
std::shared_ptr<ItemInstance> item = std::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.RequestErrorMessage(
IDS_CONNECTION_LOST,
g_NetworkManager.CorrectErrorIDS(
IDS_CONNECTION_LOST_LIVE_NO_EXIT),
uiIDA, 1, ProfileManager.GetPrimaryPad(),
UIScene_LeaderboardsMenu::ExitLeaderboards, this);
}
#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;
}