the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1#include "stdafx.h"
2#include "UI.h"
3#include "UIScene_LeaderboardsMenu.h"
4#include "..\Leaderboards\LeaderboardManager.h"
5#include "..\..\..\Minecraft.World\net.minecraft.world.level.tile.h"
6#include "..\..\..\Minecraft.World\net.minecraft.world.item.h"
7
8#define PLAYER_ONLINE_TIMER_ID 0
9#define PLAYER_ONLINE_TIMER_TIME 100
10
11// if the value is greater than 32000, it's an xzp icon that needs displayed, rather than the game icon
12const int UIScene_LeaderboardsMenu::TitleIcons[UIScene_LeaderboardsMenu::NUM_LEADERBOARDS][7] =
13{
14 { UIControl_LeaderboardList::e_ICON_TYPE_WALKED, UIControl_LeaderboardList::e_ICON_TYPE_FALLEN, Item::minecart_Id, Item::boat_Id, NULL },
15 { Tile::dirt_Id, Tile::cobblestone_Id, Tile::sand_Id, Tile::stone_Id, Tile::gravel_Id, Tile::clay_Id, Tile::obsidian_Id },
16 { Item::egg_Id, Item::wheat_Id, Tile::mushroom_brown_Id, Tile::reeds_Id, Item::bucket_milk_Id, Tile::pumpkin_Id, NULL },
17 { 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 },
18};
19const UIScene_LeaderboardsMenu::LeaderboardDescriptor UIScene_LeaderboardsMenu::LEADERBOARD_DESCRIPTORS[UIScene_LeaderboardsMenu::NUM_LEADERBOARDS][4] = {
20 {
21 UIScene_LeaderboardsMenu::LeaderboardDescriptor( 4, true, IDS_LEADERBOARD_TRAVELLING_PEACEFUL), // Travelling Peaceful
22 UIScene_LeaderboardsMenu::LeaderboardDescriptor( 4, true, IDS_LEADERBOARD_TRAVELLING_EASY), // Travelling Easy
23 UIScene_LeaderboardsMenu::LeaderboardDescriptor( 4, true, IDS_LEADERBOARD_TRAVELLING_NORMAL), // Travelling Normal
24 UIScene_LeaderboardsMenu::LeaderboardDescriptor( 4, true, IDS_LEADERBOARD_TRAVELLING_HARD), // Travelling Hard
25 },
26 {
27 UIScene_LeaderboardsMenu::LeaderboardDescriptor( 7, false, IDS_LEADERBOARD_MINING_BLOCKS_PEACEFUL), // Mining Peaceful
28 UIScene_LeaderboardsMenu::LeaderboardDescriptor( 7, false, IDS_LEADERBOARD_MINING_BLOCKS_EASY), // Mining Easy
29 UIScene_LeaderboardsMenu::LeaderboardDescriptor( 7, false, IDS_LEADERBOARD_MINING_BLOCKS_NORMAL), // Mining Normal
30 UIScene_LeaderboardsMenu::LeaderboardDescriptor( 7, false, IDS_LEADERBOARD_MINING_BLOCKS_HARD), // Mining Hard
31 },
32 {
33 UIScene_LeaderboardsMenu::LeaderboardDescriptor( 6, false, IDS_LEADERBOARD_FARMING_PEACEFUL), // Farming Peaceful
34 UIScene_LeaderboardsMenu::LeaderboardDescriptor( 6, false, IDS_LEADERBOARD_FARMING_EASY), // Farming Easy
35 UIScene_LeaderboardsMenu::LeaderboardDescriptor( 6, false, IDS_LEADERBOARD_FARMING_NORMAL), // Farming Normal
36 UIScene_LeaderboardsMenu::LeaderboardDescriptor( 6, false, IDS_LEADERBOARD_FARMING_HARD), // Farming Hard
37 },
38 {
39 UIScene_LeaderboardsMenu::LeaderboardDescriptor( 0, false, -1), //
40 UIScene_LeaderboardsMenu::LeaderboardDescriptor( 7, false, IDS_LEADERBOARD_KILLS_EASY), // Kills Easy
41 UIScene_LeaderboardsMenu::LeaderboardDescriptor( 7, false, IDS_LEADERBOARD_KILLS_NORMAL), // Kills Normal
42 UIScene_LeaderboardsMenu::LeaderboardDescriptor( 7, false, IDS_LEADERBOARD_KILLS_HARD), // Kills Hard
43 },
44};
45
46UIScene_LeaderboardsMenu::UIScene_LeaderboardsMenu(int iPad, void *initData, UILayer *parentLayer)
47 : UIScene(iPad, parentLayer), m_interface(LeaderboardManager::Instance())
48{
49 // Setup all the Iggy references we need for this scene
50 initialiseMovie();
51
52 m_bReady=false;
53
54 m_bPopulatedOnce = false;
55
56 m_newTop = m_newSel = -1;
57 m_isProcessingStatsRead = false;
58 // Ignore input until we're retrieved stats, or functions will be called in here after we've backed out of the scene
59 m_bIgnoreInput=true;
60
61 // Alert the app the we want to be informed of ethernet connections
62 app.SetLiveLinkRequired( true );
63
64 //GetFriends();
65
66 m_currentLeaderboard = 0;
67 m_currentDifficulty = 2;
68 SetLeaderboardHeader();
69 m_currentFilter = LeaderboardManager::eFM_Friends;
70
71 wchar_t filterBuffer[40];
72 swprintf(filterBuffer, 40, L"%ls%ls", app.GetString(IDS_LEADERBOARD_FILTER), app.GetString(IDS_LEADERBOARD_FILTER_FRIENDS));
73 m_labelFilter.init(filterBuffer);
74
75 wchar_t entriesBuffer[40];
76 swprintf(entriesBuffer, 40, L"%ls%i", app.GetString(IDS_LEADERBOARD_ENTRIES), 0);
77 m_labelEntries.init(entriesBuffer);
78
79 ReadStats(-1);
80
81#if ( defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ )
82 addTimer( PLAYER_ONLINE_TIMER_ID, PLAYER_ONLINE_TIMER_TIME );
83#endif
84}
85
86UIScene_LeaderboardsMenu::~UIScene_LeaderboardsMenu()
87{
88 // Alert the app the we no longer want to be informed of ethernet connections
89 app.SetLiveLinkRequired( false );
90}
91
92void UIScene_LeaderboardsMenu::updateTooltips()
93{
94 int iTooltipFriendRequest=-1;
95 int iTooltipGamerCardOrProfile=-1;
96
97#ifdef _DURANGO
98 //if( m_leaderboard.m_entries.size() > 0 )
99 if(m_leaderboard.m_totalEntryCount > 0)
100 {
101 unsigned int selection = m_newSel;
102
103 // If the selected user is me, don't show Send Friend Request, and show the gamer profile, not the gamer card
104
105 // Check that the index is actually within range of the data we've got before accessing the m_leaderboard.m_entries array
106 int idx = selection - GetEntryStartIndex();
107 if( ( idx < 0 ) || ( idx >= m_leaderboard.m_entries.size() ) )
108 {
109 return;
110 }
111 if(m_leaderboard.m_entries[idx].m_bPlayer)
112 {
113 iTooltipGamerCardOrProfile=IDS_TOOLTIPS_VIEW_GAMERPROFILE;
114 }
115 else
116 {
117 iTooltipGamerCardOrProfile=IDS_TOOLTIPS_VIEW_GAMERCARD;
118
119#ifdef _XBOX
120 // if we're on the friends filter, then don't show the Send Friend Request
121 if(!m_currentFilter == LeaderboardManager::eFM_Friends)
122#endif
123 {
124 // check the entry we're on
125 if( m_leaderboard.m_entries.size() > 0 )
126 {
127 if( selection >= GetEntryStartIndex() &&
128 selection < (GetEntryStartIndex() + m_leaderboard.m_entries.size()) )
129 {
130#ifdef _XBOX
131 if( (m_leaderboard.m_entries[selection - (m_leaderboard.m_entryStartIndex-1)].m_bFriend==false)
132 && (m_leaderboard.m_entries[selection - (m_leaderboard.m_entryStartIndex-1)].m_bRequestedFriend==false))
133#endif
134 {
135 iTooltipFriendRequest=IDS_TOOLTIPS_SEND_FRIEND_REQUEST;
136 }
137 }
138 }
139 }
140 }
141 }
142#endif
143
144 ui.SetTooltips(m_iPad, iTooltipFriendRequest, IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_CHANGE_FILTER, iTooltipGamerCardOrProfile);
145}
146
147void UIScene_LeaderboardsMenu::updateComponents()
148{
149 m_parentLayer->showComponent(m_iPad,eUIComponent_Panorama,!app.GetGameStarted());
150 m_parentLayer->showComponent(m_iPad,eUIComponent_Logo,false);
151}
152
153wstring UIScene_LeaderboardsMenu::getMoviePath()
154{
155 return L"LeaderboardMenu";
156}
157
158void UIScene_LeaderboardsMenu::tick()
159{
160 UIScene::tick();
161 m_interface.tick();
162}
163
164void UIScene_LeaderboardsMenu::handleReload()
165{
166 // We don't allow this in splitscreen, so just go back
167 navigateBack();
168}
169
170void UIScene_LeaderboardsMenu::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled)
171{
172 if(m_bIgnoreInput && key != ACTION_MENU_CANCEL) return;
173
174 ui.AnimateKeyPress(m_iPad, key, repeat, pressed, released);
175
176 // If this is not a press, do not action
177 if (!pressed) return;
178
179
180 /*app.DebugPrintf(
181 " m_newSel = %i [bottomId] = %i [topId] = %i, [size] = %i\n",
182 m_newSel,
183 m_leaderboard.m_entries.size() == 0 ? 0 : m_leaderboard.m_entries[m_leaderboard.m_entries.size()-1].m_row,
184 GetEntryStartIndex(),
185 m_leaderboard.m_entries.size()
186 );*/
187
188 switch(key)
189 {
190 case ACTION_MENU_CANCEL:
191 if(pressed)
192 {
193 navigateBack();
194 handled = true;
195 }
196 break;
197 case ACTION_MENU_UP:
198 --m_newSel;
199 if(m_newSel<0)m_newSel = 0;
200 sendInputToMovie(key, repeat, pressed, released);
201 break;
202 case ACTION_MENU_DOWN:
203 ++m_newSel;
204 if(m_newSel>=m_leaderboard.m_totalEntryCount) m_newSel = m_leaderboard.m_totalEntryCount - 1;
205 sendInputToMovie(key, repeat, pressed, released);
206 break;
207 case ACTION_MENU_LEFT_SCROLL:
208 case ACTION_MENU_RIGHT_SCROLL:
209 {
210 //Do nothing if a stats read is currently in progress, otherwise the system complains about to many read requests
211 if( pressed && m_bPopulatedOnce && LeaderboardManager::Instance()->isIdle() )
212 {
213 //CD - Added for audio
214 ui.PlayUISFX(eSFX_Scroll);
215
216 if( key == ACTION_MENU_RIGHT_SCROLL )
217 {
218 ++m_currentDifficulty;
219 if( m_currentDifficulty == 4 )
220 m_currentDifficulty = 0;
221
222 if( m_currentLeaderboard == LEADERBOARD_KILLS_POSITION && m_currentDifficulty == 0 )
223 m_currentDifficulty = 1;
224 }
225 else
226 {
227 if( m_currentDifficulty == 0 )
228 m_currentDifficulty = 4;
229 --m_currentDifficulty;
230
231 if( m_currentLeaderboard == LEADERBOARD_KILLS_POSITION && m_currentDifficulty == 0 )
232 m_currentDifficulty = 3;
233 }
234
235 SetLeaderboardHeader();
236
237 ReadStats(-1);
238 ui.PlayUISFX(eSFX_Press);
239 }
240
241 handled = true;
242 }
243 break;
244 case ACTION_MENU_LEFT:
245 case ACTION_MENU_RIGHT:
246 {
247 //Do nothing if a stats read is currently in progress, otherwise the system complains about to many read requests
248 if ( pressed && m_bPopulatedOnce && LeaderboardManager::Instance()->isIdle() )
249 {
250 //CD - Added for audio
251 ui.PlayUISFX(eSFX_Scroll);
252
253 m_bReady=false;
254 if(key == ACTION_MENU_RIGHT)
255 {
256 ++m_currentLeaderboard;
257 if( m_currentLeaderboard == NUM_LEADERBOARDS )
258 m_currentLeaderboard = 0;
259 }
260 else
261 {
262 if( m_currentLeaderboard == 0 )
263 m_currentLeaderboard = NUM_LEADERBOARDS;
264 --m_currentLeaderboard;
265 }
266
267 if( m_currentLeaderboard == LEADERBOARD_KILLS_POSITION && m_currentDifficulty == 0 )
268 m_currentDifficulty = 1;
269
270 SetLeaderboardHeader();
271
272 ReadStats(-1);
273 ui.PlayUISFX(eSFX_Press);
274 }
275 handled = true;
276 }
277 break;
278 case ACTION_MENU_PAGEUP:
279 case ACTION_MENU_PAGEDOWN:
280 {
281 //Do nothing if a stats read is currently in progress, otherwise the system complains about to many read requests
282 if( pressed && m_bPopulatedOnce && LeaderboardManager::Instance()->isIdle() )
283 {
284 //CD - Added for audio
285 ui.PlayUISFX(eSFX_Scroll);
286
287 if( m_leaderboard.m_totalEntryCount <= 10 )
288 break;
289
290 sendInputToMovie(key, repeat, pressed, released);
291
292#if 0
293 if( key == ACTION_MENU_PAGEUP )
294 {
295 m_newTop = m_listGamers.GetTopItem() - 10;
296
297 if( m_newTop < 0 )
298 m_newTop = 0;
299
300 m_newSel = m_newTop;
301 }
302 else
303 {
304
305 m_newTop = m_listGamers.GetTopItem() + 10;
306
307 if( m_newTop+10 > (int)m_leaderboard.m_totalEntryCount )
308 {
309 m_newTop = m_leaderboard.m_totalEntryCount - 10;
310 if( m_newTop < 0 )
311 m_newTop = 0;
312 }
313
314 m_newSel = m_newTop;
315 }
316#endif
317 }
318 handled = true;
319 }
320 break;
321 case ACTION_MENU_X:
322 {
323 //Do nothing if a stats read is currently in progress, otherwise the system complains about to many read requests
324 if( pressed && m_bPopulatedOnce && LeaderboardManager::Instance()->isIdle() )
325 {
326 //CD - Added for audio
327 ui.PlayUISFX(eSFX_Scroll);
328
329 switch( m_currentFilter )
330 {
331 case LeaderboardManager::eFM_Friends:
332 {
333 m_currentFilter = LeaderboardManager::eFM_MyScore;
334 wchar_t filterBuffer[40];
335 swprintf(filterBuffer, 40, L"%ls%ls", app.GetString(IDS_LEADERBOARD_FILTER), app.GetString(IDS_LEADERBOARD_FILTER_MYSCORE));
336 m_labelFilter.setLabel(filterBuffer);
337 }
338 break;
339 case LeaderboardManager::eFM_MyScore:
340 {
341 m_currentFilter = LeaderboardManager::eFM_TopRank;
342 wchar_t filterBuffer[40];
343 swprintf(filterBuffer, 40, L"%ls%ls", app.GetString(IDS_LEADERBOARD_FILTER), app.GetString(IDS_LEADERBOARD_FILTER_OVERALL));
344 m_labelFilter.setLabel(filterBuffer);
345 }
346 break;
347 case LeaderboardManager::eFM_TopRank:
348 {
349 m_currentFilter = LeaderboardManager::eFM_Friends;
350 wchar_t filterBuffer[40];
351 swprintf(filterBuffer, 40, L"%ls%ls", app.GetString(IDS_LEADERBOARD_FILTER), app.GetString(IDS_LEADERBOARD_FILTER_FRIENDS));
352 m_labelFilter.setLabel(filterBuffer);
353 }
354 break;
355 }
356
357 ReadStats(-1);
358 ui.PlayUISFX(eSFX_Press);
359 }
360 handled = true;
361 }
362 break;
363 case ACTION_MENU_Y:
364 {
365#ifdef _DURANGO
366 //Show gamercard
367 //if( m_leaderboard.m_entries.size() > 0 )
368 if(m_leaderboard.m_totalEntryCount > 0)
369 {
370 unsigned int selection = m_newSel;
371 if( selection >= GetEntryStartIndex() &&
372 selection < (GetEntryStartIndex() + m_leaderboard.m_entries.size()) )
373 {
374 PlayerUID uid = m_leaderboard.m_entries[selection - GetEntryStartIndex()].m_xuid;
375 if( uid != INVALID_XUID )
376 {
377 ProfileManager.ShowProfileCard(ProfileManager.GetLockedProfile(),uid);
378 ui.PlayUISFX(eSFX_Press);
379 }
380 }
381 }
382#endif
383 handled = true;
384 }
385 break;
386 case ACTION_MENU_A:
387 {
388#ifdef _DURANGO
389 //Send friend request if the filter mode is not friend, and they're not a friend or a pending friend
390#ifdef _XBOX
391 if( m_currentFilter != LeaderboardManager::eFM_Friends )
392#endif
393 {
394 if( m_leaderboard.m_entries.size() > 0 )
395 {
396 unsigned int selection = m_newSel;
397 if( selection >= GetEntryStartIndex() &&
398 selection < (GetEntryStartIndex() + m_leaderboard.m_entries.size()) )
399 {
400 //If not the player and neither currently a friend or requested to be a friend
401 if( !m_leaderboard.m_entries[selection - GetEntryStartIndex()].m_bPlayer
402#ifdef _XBOX
403 && !m_leaderboard.m_entries[selection - (m_leaderboard.m_entryStartIndex-1) ].m_bFriend
404 && !m_leaderboard.m_entries[selection - (m_leaderboard.m_entryStartIndex-1) ].m_bRequestedFriend
405#endif
406 )
407 {
408 PlayerUID xuid = m_leaderboard.m_entries[selection - GetEntryStartIndex()].m_xuid;
409 if( xuid != INVALID_XUID )
410 {
411 ProfileManager.ShowAddFriend(m_iPad,xuid);
412 ui.PlayUISFX(eSFX_Press);
413 }
414 }
415 }
416 }
417 }
418#endif
419 handled = true;
420 }
421 break;
422 }
423}
424
425void UIScene_LeaderboardsMenu::ReadStats(int startIndex)
426{
427 //If startIndex == -1, then use default values
428 if( startIndex == -1 )
429 {
430 m_newEntryIndex = 1;
431 m_newReadSize = READ_SIZE;
432
433 m_newEntriesCount = 0;
434
435 m_leaderboard.m_totalEntryCount = 0;
436
437 m_listEntries.clearList();
438 }
439 else
440 {
441 m_newEntryIndex = (unsigned int)startIndex;
442 // m_newReadSize = min((int)READ_SIZE, (int)m_leaderboard.m_totalEntryCount-(startIndex-1));
443 }
444
445 //app.DebugPrintf("Requesting stats read %d - %d - %d\n", m_currentLeaderboard, startIndex == -1 ? m_currentFilter : LeaderboardManager::eFM_TopRank, m_currentDifficulty);
446
447 LeaderboardManager::EFilterMode filtermode;
448 if ( m_currentFilter == LeaderboardManager::eFM_MyScore
449 || m_currentFilter == LeaderboardManager::eFM_TopRank )
450 {
451 filtermode = (startIndex == -1 ? m_currentFilter : LeaderboardManager::eFM_TopRank);
452 }
453 else
454 {
455 // 4J-JEV: Friends filter shouldn't switch to toprank.
456 filtermode = m_currentFilter;
457 }
458
459 switch (filtermode)
460 {
461 case LeaderboardManager::eFM_TopRank:
462 {
463 m_interface.ReadStats_TopRank(
464 this,
465 m_currentDifficulty, (LeaderboardManager::EStatsType) m_currentLeaderboard,
466 m_newEntryIndex, m_newReadSize
467 );
468 }
469 break;
470 case LeaderboardManager::eFM_MyScore:
471 {
472 PlayerUID uid;
473 ProfileManager.GetXUID(ProfileManager.GetPrimaryPad(),&uid, true);
474 m_interface.ReadStats_MyScore( this,
475 m_currentDifficulty, (LeaderboardManager::EStatsType) m_currentLeaderboard,
476 uid /*ignored on PS3*/,
477 m_newReadSize
478 );
479 }
480 break;
481 case LeaderboardManager::eFM_Friends:
482 {
483 PlayerUID uid;
484 ProfileManager.GetXUID(ProfileManager.GetPrimaryPad(),&uid, true);
485 m_interface.ReadStats_Friends( this,
486 m_currentDifficulty, (LeaderboardManager::EStatsType) m_currentLeaderboard,
487 uid /*ignored on PS3*/,
488 m_newEntryIndex, m_newReadSize
489 );
490 }
491 break;
492 }
493
494 //Show the loading message
495 m_labelInfo.setLabel(app.GetString(IDS_LEADERBOARD_LOADING));
496 m_labelInfo.setVisible(true);
497}
498
499bool UIScene_LeaderboardsMenu::OnStatsReadComplete(LeaderboardManager::eStatsReturn retIn, int numResults, LeaderboardManager::ViewOut results)
500{
501 //CScene_Leaderboards* scene = reinterpret_cast<CScene_Leaderboards*>(userdata);
502
503 m_isProcessingStatsRead = true;
504
505 //bool noResults = LeaderboardManager::Instance()->GetStatsState() != XboxLeaderboardManager::eStatsState_Ready;
506 bool ret;
507
508 //app.DebugPrintf("Leaderboards read %d stats\n", numResults);
509
510 m_numStats = numResults;
511 m_stats = results;
512 ret = RetrieveStats();
513
514 //else LeaderboardManager::Instance()->SetStatsRetrieved(false);
515
516 PopulateLeaderboard(retIn);
517
518 updateTooltips();
519
520 m_isProcessingStatsRead = false;
521
522 // allow user input now
523 m_bIgnoreInput=false;
524
525 return ret;
526}
527
528bool UIScene_LeaderboardsMenu::RetrieveStats()
529{
530 if(app.DebugSettingsOn() && (app.GetGameSettingsDebugMask()&(1L<<eDebugSetting_DebugLeaderboards)))
531 {
532 m_leaderboard.m_totalEntryCount = NUM_ENTRIES;
533 m_leaderboard.m_numColumns = LEADERBOARD_DESCRIPTORS[m_currentLeaderboard][m_currentDifficulty].m_columnCount;
534
535 //For each entry in the leaderboard
536 for(unsigned int entryIndex=0; entryIndex < NUM_ENTRIES; entryIndex++)
537 {
538 m_leaderboard.m_entries.push_back(LeaderboardEntry());
539 m_leaderboard.m_entries[entryIndex].m_xuid = INVALID_XUID;
540
541 m_leaderboard.m_entries[entryIndex].m_row = entryIndex;
542 m_leaderboard.m_entries[entryIndex].m_rank = entryIndex+1;
543 swprintf(m_leaderboard.m_entries[entryIndex].m_wcRank, 12, L"12345678");//(int)m_leaderboard.m_entries[entryIndex].m_rank);
544
545 swprintf(m_leaderboard.m_entries[entryIndex].m_gamerTag, 17, L"WWWWWWWWWWWWWWWW");
546
547 //m_leaderboard.m_entries[entryIndex].m_locale = (entryIndex % 37) + 1;
548
549 bool isDistanceLeaderboard = LEADERBOARD_DESCRIPTORS[m_currentLeaderboard][m_currentDifficulty].m_isDistanceLeaderboard;
550
551 for( unsigned int i=0 ; i<m_leaderboard.m_numColumns ; i++ )
552 {
553 if( !isDistanceLeaderboard )
554 {
555 m_leaderboard.m_entries[entryIndex].m_columns[i] = USHRT_MAX;
556 swprintf(m_leaderboard.m_entries[entryIndex].m_wcColumns[i], 12, L"%u", m_leaderboard.m_entries[entryIndex].m_columns[i]);
557 }
558 else
559 {
560 m_leaderboard.m_entries[entryIndex].m_columns[i] = UINT_MAX;
561 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);
562 }
563 }
564
565 m_leaderboard.m_entries[entryIndex].m_bPlayer = (entryIndex == 0);
566 m_leaderboard.m_entries[entryIndex].m_bOnline = (entryIndex != 0);
567 m_leaderboard.m_entries[entryIndex].m_bFriend = (entryIndex != 0);
568 m_leaderboard.m_entries[entryIndex].m_bRequestedFriend = false;
569 }
570
571 //LeaderboardManager::Instance()->SetStatsRetrieved(true);
572
573 m_newEntryIndex = 0;
574 m_newEntriesCount = NUM_ENTRIES;
575
576 return true;
577 }
578
579 //assert( LeaderboardManager::Instance()->GetStats() != NULL );
580 //PXUSER_STATS_READ_RESULTS stats = LeaderboardManager::Instance()->GetStats();
581 //if( m_currentFilter == LeaderboardManager::eFM_Friends ) LeaderboardManager::Instance()->SortFriendStats();
582
583 bool isDistanceLeaderboard = LEADERBOARD_DESCRIPTORS[m_currentLeaderboard][m_currentDifficulty].m_isDistanceLeaderboard;
584
585 m_newEntriesCount = m_stats.m_numQueries;
586
587 // First read
588 if( m_leaderboard.m_totalEntryCount == 0 )
589 {
590 m_leaderboard.m_entries.clear();
591
592#if _DURANGO
593 m_leaderboard.m_totalEntryCount = m_numStats;
594#else
595 m_leaderboard.m_totalEntryCount = (m_currentFilter == LeaderboardManager::eFM_Friends) ? m_newEntriesCount : m_numStats;
596#endif
597
598 if( m_leaderboard.m_totalEntryCount == 0 || m_newEntriesCount == 0 )
599 {
600 //LeaderboardManager::Instance()->SetStatsRetrieved(false);
601 return false;
602 }
603
604 m_leaderboard.m_numColumns = m_stats.m_queries[0].m_statsSize;
605
606 for( unsigned int entryIndex=0 ; entryIndex < m_newEntriesCount; ++entryIndex )
607 {
608 m_leaderboard.m_entries.push_back(LeaderboardEntry());
609 CopyLeaderboardEntry(&(m_stats.m_queries[entryIndex]), entryIndex, isDistanceLeaderboard);
610 }
611
612 m_newEntryIndex = 0;
613
614 // Clear these values so that we know whether or not they are set in the next block
615 m_newTop = -1;
616 m_newSel = -1;
617
618 // If the filter mode is "My Score" then centre the list around the entries and select the player's score
619 if( m_currentFilter == LeaderboardManager::eFM_MyScore)
620 {
621 //Centre the leaderboard list on the entries
622 m_newTop = GetEntryStartIndex();
623
624 //Select the player entry
625 for( unsigned int i = GetEntryStartIndex(); i< GetEntryStartIndex() + m_leaderboard.m_entries.size(); ++i )
626 {
627 if( m_leaderboard.m_entries[i - GetEntryStartIndex()].m_bPlayer )
628 {
629 m_newSel = i; // this might be off the screen!
630 // and reposition the top one
631 if(m_newSel-m_newTop>9)
632 {
633 m_newTop=m_newSel-9;
634 }
635 break;
636 }
637 }
638 }
639
640 // If not set, default to start index
641 if (m_newSel < 0) m_newTop = m_newSel = GetEntryStartIndex();
642 }
643 // Additional read
644 else
645 {
646 if(m_newEntryIndex < GetEntryStartIndex() && m_newEntryIndex == 1)
647 {
648 // If we're at the top the new entries count is incorrect, so amend
649 m_newEntriesCount = GetEntryStartIndex();
650 }
651
652 bool deleteFront = false;
653 bool deleteBack = false;
654
655 bool trim = m_leaderboard.m_entries.size() + m_newEntriesCount >= NUM_ENTRIES;
656
657 unsigned int insertPosition = 0;
658
659 // If the first new entry is at a smaller index than the current first entry
660 if(m_newEntryIndex < GetEntryStartIndex())
661 {
662 insertPosition = 0;
663 if (trim) deleteBack = true;
664 }
665 else
666 {
667 insertPosition = m_leaderboard.m_entries.size();
668 if (trim) deleteFront = true;
669 }
670
671 m_newEntryIndex = insertPosition;
672
673 // Copy results to entries list
674 for( unsigned int i=0 ; i < m_newEntriesCount ; ++i )
675 {
676 m_leaderboard.m_entries.insert(m_leaderboard.m_entries.begin() + insertPosition, LeaderboardEntry());
677 CopyLeaderboardEntry(&(m_stats.m_queries[i]), insertPosition, isDistanceLeaderboard);
678
679 insertPosition++;
680 }
681
682 if (deleteFront)
683 {
684 // Delete front x entries
685 m_leaderboard.m_entries.erase(m_leaderboard.m_entries.begin(), m_leaderboard.m_entries.begin() + READ_SIZE);
686 m_newEntryIndex -= m_newReadSize;
687 }
688 else if (deleteBack)
689 {
690 // Delete back x entries
691 m_leaderboard.m_entries.erase(m_leaderboard.m_entries.end() - READ_SIZE, m_leaderboard.m_entries.end());
692 }
693 }
694
695 return true;
696}
697
698void UIScene_LeaderboardsMenu::CopyLeaderboardEntry(LeaderboardManager::ReadScore *statsRow, int leaderboardEntryIndex, bool isDistanceLeaderboard)
699{
700 LeaderboardEntry* leaderboardEntry = &(m_leaderboard.m_entries[leaderboardEntryIndex]);
701
702 ZeroMemory(leaderboardEntry, sizeof(LeaderboardEntry));
703 leaderboardEntry->m_xuid = statsRow->m_uid;
704
705 // Copy the rank
706 leaderboardEntry->m_rank = statsRow->m_rank;
707 DWORD displayRank = leaderboardEntry->m_rank;
708 if(displayRank > 9999999) displayRank = 9999999;
709 swprintf(leaderboardEntry->m_wcRank, 12, L"%u", displayRank);
710
711 leaderboardEntry->m_idsErrorMessage = statsRow->m_idsErrorMessage;
712
713 // Build a row ID
714 if (m_currentFilter == LeaderboardManager::eFM_Friends)
715 {
716 // If friends don't ID rows by rank
717 leaderboardEntry->m_row = leaderboardEntryIndex;
718 }
719 else
720 {
721 leaderboardEntry->m_row = statsRow->m_rank - 1;
722 if (leaderboardEntryIndex > 0) {
723 // Check this row ID (/rank) against the last one, it might be the same
724 // (this happens on PS3 when players have the same score, i.e. if they share 76th position there'll be two rank 76
725 // and the following entry will be rank 78)
726 LeaderboardEntry* prevEntry = &(m_leaderboard.m_entries[leaderboardEntryIndex - 1]);
727 if (leaderboardEntry->m_row <= prevEntry->m_row)
728 {
729 leaderboardEntry->m_row = prevEntry->m_row + 1;
730 }
731 }
732 }
733
734#ifdef __PS3__
735 // m_name can be unicode characters somehow for Japan - should use m_onlineID
736 wstring wstr=convStringToWstring(statsRow->m_uid.getOnlineID());
737 swprintf(leaderboardEntry->m_gamerTag, XUSER_NAME_SIZE, L"%ls",wstr.c_str());
738#else
739 memcpy(leaderboardEntry->m_gamerTag, statsRow->m_name.data(), statsRow->m_name.size() * sizeof(wchar_t));
740#endif
741
742 // Copy the other columns
743 for( unsigned int i=0 ; i<statsRow->m_statsSize ; i++ )
744 {
745 leaderboardEntry->m_columns[i] = statsRow->m_statsData[i];
746 ZeroMemory(leaderboardEntry->m_wcColumns[i],12*sizeof(WCHAR));
747 if( !isDistanceLeaderboard )
748 {
749 DWORD displayValue = leaderboardEntry->m_columns[i];
750 if(displayValue > 99999) displayValue = 99999;
751 swprintf(leaderboardEntry->m_wcColumns[i], 12, L"%u",displayValue);
752#ifdef _DEBUG
753 //app.DebugPrintf("Value - %d\n",leaderboardEntry->m_columns[i]);
754#endif
755 }
756 else
757 {
758 // check how many digits we have
759 int iDigitC=0;
760 unsigned int uiVal=leaderboardEntry->m_columns[i];
761// uiVal=0xFFFFFFFF;
762// leaderboardEntry->m_columns[i-1]=uiVal;
763
764 while(uiVal!=0)
765 {
766 uiVal/=10;
767 iDigitC++;
768 }
769
770#ifdef _DEBUG
771 //app.DebugPrintf("Value - %d\n",leaderboardEntry->m_columns[i]);
772#endif
773 if(iDigitC<4)
774 {
775 // m
776 swprintf(leaderboardEntry->m_wcColumns[i], 12, L"%um", leaderboardEntry->m_columns[i]);
777#ifdef _DEBUG
778 //app.DebugPrintf("Display - %um\n", leaderboardEntry->m_columns[i]);
779#endif
780 }
781 else if(iDigitC<8)
782 {
783 // km with a .X
784 swprintf(leaderboardEntry->m_wcColumns[i], 12, L"%.1fkm", ((float)leaderboardEntry->m_columns[i])/1000.f);
785#ifdef _DEBUG
786 //app.DebugPrintf("Display - %.1fkm\n", ((float)leaderboardEntry->m_columns[i])/1000.f);
787#endif
788 }
789 else
790 {
791 // bigger than that, so no decimal point
792 swprintf(leaderboardEntry->m_wcColumns[i], 12, L"%.0fkm", ((float)leaderboardEntry->m_columns[i])/1000.f);
793#ifdef _DEBUG
794 //app.DebugPrintf("Display - %.0fkm\n", ((float)leaderboardEntry->m_columns[i])/1000.f);
795#endif
796 }
797 }
798 }
799
800#ifdef _DURANGO
801 //Is the player
802 PlayerUID myXuid;
803 ProfileManager.GetXUID(ProfileManager.GetPrimaryPad(),&myXuid,true);
804 if( statsRow->m_uid == myXuid )
805 {
806 leaderboardEntry->m_bPlayer = true;
807 leaderboardEntry->m_bOnline = false;
808 leaderboardEntry->m_bFriend = false;
809 leaderboardEntry->m_bRequestedFriend = false;
810 }
811 else
812 {
813 leaderboardEntry->m_bPlayer = false;
814 leaderboardEntry->m_bOnline = false;
815 leaderboardEntry->m_bFriend = false;
816 leaderboardEntry->m_bRequestedFriend = false;
817
818#ifdef _XBOX
819 //Check for friend status
820 for( unsigned int friendIndex=0 ; friendIndex<m_numFriends ; ++friendIndex )
821 {
822 if( m_friends[friendIndex].xuid == statsRow->m_uid )
823 {
824 if( ( m_friends[friendIndex].dwFriendState & ( XONLINE_FRIENDSTATE_FLAG_SENTREQUEST | XONLINE_FRIENDSTATE_FLAG_RECEIVEDREQUEST ) ) == 0 )
825 {
826 //Is friend, might be online
827 leaderboardEntry->m_bFriend = true;
828 leaderboardEntry->m_bOnline = ( m_friends[friendIndex].dwFriendState & XONLINE_FRIENDSTATE_FLAG_ONLINE );
829 leaderboardEntry->m_bRequestedFriend = false;
830 }
831 else
832 {
833 //Friend request sent but not accepted yet
834 leaderboardEntry->m_bOnline = false;
835 leaderboardEntry->m_bFriend = false;
836 leaderboardEntry->m_bRequestedFriend = true;
837 }
838
839 break;
840 }
841 }
842#endif
843 }
844#endif
845}
846
847void UIScene_LeaderboardsMenu::PopulateLeaderboard(LeaderboardManager::eStatsReturn ret)
848{
849 int iValidSlots=SetLeaderboardTitleIcons();
850 if( ret == LeaderboardManager::eStatsReturn_Success && m_leaderboard.m_totalEntryCount > 0 )
851 {
852 m_listEntries.setupTitles( app.GetString( IDS_LEADERBOARD_RANK ), app.GetString( IDS_LEADERBOARD_GAMERTAG ) );
853
854 //Update entries display
855 wchar_t entriesBuffer[40];
856 if(app.DebugSettingsOn() && (app.GetGameSettingsDebugMask()&(1L<<eDebugSetting_DebugLeaderboards)))
857 {
858 swprintf(entriesBuffer, 40, L"%ls12345678", app.GetString(IDS_LEADERBOARD_ENTRIES));
859 }
860 else
861 {
862 swprintf(entriesBuffer, 40, L"%ls%i", app.GetString(IDS_LEADERBOARD_ENTRIES), m_leaderboard.m_totalEntryCount);
863 }
864
865 m_labelEntries.setLabel(entriesBuffer);
866 m_labelInfo.setLabel(L"");
867 m_labelInfo.setVisible( false );
868
869 m_listEntries.initLeaderboard(m_newSel, m_leaderboard.m_totalEntryCount, LEADERBOARD_DESCRIPTORS[m_currentLeaderboard][m_currentDifficulty].m_columnCount);
870
871 int startIndex = m_newEntryIndex;
872 int entryCount = m_newEntriesCount;
873
874 for(DWORD i = startIndex; i < (startIndex + entryCount); ++i)
875 {
876 bool isLast = i == ((startIndex + entryCount) - 1);
877
878 int idsErrorMessage = m_leaderboard.m_entries[i].m_idsErrorMessage;
879
880 if (idsErrorMessage > 0)
881 {
882 m_listEntries.addDataSet(
883 isLast,
884 m_leaderboard.m_entries[i].m_row,
885 m_leaderboard.m_entries[i].m_rank,
886 m_leaderboard.m_entries[i].m_gamerTag,
887
888 true, // 4J-JEV: Has error message to display.
889
890 app.GetString(idsErrorMessage),
891 L"", L"", L"", L"", L"", L""
892 );
893 }
894 else
895 {
896 m_listEntries.addDataSet(
897 isLast,
898 m_leaderboard.m_entries[i].m_row,
899 m_leaderboard.m_entries[i].m_rank,
900 m_leaderboard.m_entries[i].m_gamerTag,
901
902 // 4J-TomK | The bDisplayMessage Flag defines if Leaderboard Data should be
903 // displayed (false) or if a specific message (true - when data is private for example)
904 // should be displayed. The message itself should be passed on in col0!
905 false,
906
907 m_leaderboard.m_entries[i].m_wcColumns[0],
908 m_leaderboard.m_entries[i].m_wcColumns[1],
909 m_leaderboard.m_entries[i].m_wcColumns[2],
910 m_leaderboard.m_entries[i].m_wcColumns[3],
911 m_leaderboard.m_entries[i].m_wcColumns[4],
912 m_leaderboard.m_entries[i].m_wcColumns[5],
913 m_leaderboard.m_entries[i].m_wcColumns[6]
914 );
915 }
916 }
917 }
918 else
919 {
920 m_listEntries.setupTitles( L"", L"" );
921
922 //Update entries display (to zero)
923 wchar_t entriesBuffer[40];
924 swprintf(entriesBuffer, 40, L"%ls0", app.GetString(IDS_LEADERBOARD_ENTRIES));
925 m_labelEntries.setLabel(entriesBuffer);
926
927 //Show the no results message
928#if !(defined(_XBOX) || defined(_WINDOWS64)) // 4J Stu - Temp to get the win build running, but so we check this for other platforms
929 if (ret == LeaderboardManager::eStatsReturn_NetworkError)
930 m_labelInfo.setLabel(app.GetString(IDS_ERROR_NETWORK));
931 else
932#endif
933 m_labelInfo.setLabel(app.GetString(IDS_LEADERBOARD_NORESULTS));
934 m_labelInfo.setVisible(true);
935 }
936 m_bPopulatedOnce = true;
937}
938
939void UIScene_LeaderboardsMenu::SetLeaderboardHeader()
940{
941 m_labelLeaderboard.setLabel(app.GetString(LEADERBOARD_DESCRIPTORS[m_currentLeaderboard][m_currentDifficulty].m_title));
942}
943
944int UIScene_LeaderboardsMenu::SetLeaderboardTitleIcons()
945{
946 int iValidIcons=0;
947
948 for(int i=0;i<7;i++)
949 {
950 if(TitleIcons[m_currentLeaderboard][i]==0)
951 {
952 //m_pHTitleIconSlots[i]->SetShow(FALSE);
953 }
954 else
955 {
956 iValidIcons++;
957 m_listEntries.setColumnIcon(i,TitleIcons[m_currentLeaderboard][i]);
958 }
959 }
960
961 return iValidIcons;
962}
963
964void UIScene_LeaderboardsMenu::customDraw(IggyCustomDrawCallbackRegion *region)
965{
966 int slotId = -1;
967 swscanf((wchar_t*)region->name,L"slot_%d",&slotId);
968 if (slotId == -1)
969 {
970 //app.DebugPrintf("This is not the control we are looking for\n");
971 }
972 else
973 {
974 shared_ptr<ItemInstance> item = shared_ptr<ItemInstance>( new ItemInstance(TitleIcons[m_currentLeaderboard][slotId], 1, 0) );
975 customDrawSlotControl(region,m_iPad,item,1.0f,false,false);
976 }
977}
978
979void UIScene_LeaderboardsMenu::handleSelectionChanged(F64 selectedId)
980{
981 ui.PlayUISFX(eSFX_Focus);
982 m_newSel = (int)selectedId;
983 updateTooltips();
984}
985
986// Handle a request from Iggy for more data
987void UIScene_LeaderboardsMenu::handleRequestMoreData(F64 startIndex, bool up)
988{
989 unsigned int item = (int)startIndex;
990
991 if( m_leaderboard.m_totalEntryCount > 0 && (item+1) < GetEntryStartIndex() )
992 {
993 if( LeaderboardManager::Instance()->isIdle() )
994 {
995 int readIndex = (GetEntryStartIndex() + 1) - READ_SIZE;
996 if( readIndex <= 0 )
997 readIndex = 1;
998 assert( readIndex >= 1 && readIndex <= (int)m_leaderboard.m_totalEntryCount );
999 ReadStats(readIndex);
1000 }
1001 }
1002 else if( m_leaderboard.m_totalEntryCount > 0 && (item+1) >= (GetEntryStartIndex() + m_leaderboard.m_entries.size()) )
1003 {
1004 if( LeaderboardManager::Instance()->isIdle() )
1005 {
1006 int readIndex = (GetEntryStartIndex() + 1) + m_leaderboard.m_entries.size();
1007 assert( readIndex >= 1 && readIndex <= (int)m_leaderboard.m_totalEntryCount );
1008 ReadStats(readIndex);
1009 }
1010 }
1011}
1012
1013void UIScene_LeaderboardsMenu::handleTimerComplete(int id)
1014{
1015#if ( defined __PS3__ || defined __ORBIS__ || defined __PSVITA__)
1016 switch(id)
1017 {
1018 case PLAYER_ONLINE_TIMER_ID:
1019#ifndef _WINDOWS64
1020 if(ProfileManager.IsSignedInLive(ProfileManager.GetPrimaryPad())==false)
1021 {
1022 // check the player hasn't gone offline
1023 // If they have, bring up the PSN warning and exit from the leaderboards
1024 unsigned int uiIDA[1];
1025 uiIDA[0]=IDS_OK;
1026 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);
1027 }
1028#endif
1029 break;
1030 }
1031#endif
1032}
1033
1034int UIScene_LeaderboardsMenu::ExitLeaderboards(void *pParam,int iPad,C4JStorage::EMessageResult result)
1035{
1036 UIScene_LeaderboardsMenu* pClass = (UIScene_LeaderboardsMenu*)pParam;
1037
1038 pClass->navigateBack();
1039
1040 return 0;
1041}
1042
1043// Get entry start size, if no entries returns 0
1044int UIScene_LeaderboardsMenu::GetEntryStartIndex()
1045{
1046 return m_leaderboard.m_entries.size() == 0 ? 0 : m_leaderboard.m_entries[0].m_row;
1047}