leaderboardscreen.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896
  1. #include "pch.h"
  2. //////////////////////////////////////////////////////////////////////////////
  3. //
  4. // LeaderBoard Screen
  5. //
  6. //////////////////////////////////////////////////////////////////////////////
  7. extern bool g_bDisableZoneClub;
  8. class LeaderBoardScreen :
  9. public Screen,
  10. public EventTargetContainer<LeaderBoardScreen>,
  11. public IItemEvent::Sink,
  12. public TEvent<ZString>::Sink,
  13. public TrekClientEventSink
  14. {
  15. public:
  16. TRef<INameSpace> m_pns;
  17. TRef<Pane> m_ppane;
  18. TRef<ButtonPane> m_pbuttonBack;
  19. TRef<ButtonPane> m_pbuttonPlayerProfile;
  20. TRef<ButtonPane> m_pbuttonPlayerProfile2;
  21. TRef<ButtonPane> m_pbuttonSquadProfile;
  22. TRef<ButtonPane> m_pbuttonSquads;
  23. TRef<ButtonPane> m_pbuttonWeb;
  24. TRef<TEvent<ZString>::Sink> m_psinkSearchEdit;
  25. TRef<ButtonPane> m_pbuttonSearch;
  26. TRef<ButtonPane> m_pbuttonFindMe;
  27. TRef<ButtonPane> m_pbuttonTop;
  28. TRef<ButtonPane> m_pbuttonPageUp;
  29. TRef<ButtonPane> m_pbuttonPageDown;
  30. TRef<EditPane> m_peditPane;
  31. TRef<ButtonBarPane> m_pbuttonbarStats;
  32. TRef<ListPane> m_plistTopPlayer;
  33. TRef<ListPane> m_plistPaneStats;
  34. TRef<WrapImage> m_pwrapImageCiv;
  35. TRef<ComboPane> m_pcomboCiv;
  36. TRef<IItemEvent::Sink> m_psinkStats;
  37. TRef<IItemEvent::Source> m_peventStats;
  38. TRef<TEvent<ZString>::Source> m_peventSearchEdit;
  39. TRef<IKeyboardInput> m_pkeyboardInputOldFocus;
  40. TVector<int> m_viStatsColumns;
  41. enum { cLinesPerScreen = 28 };
  42. ZString m_strBasis;
  43. int m_idBasis;
  44. LeaderBoardEntry m_vEntries[cLinesPerScreen * 3];
  45. LeaderBoardEntry m_entryNumber1; // the highest or lowest ranked player
  46. int m_cEntries;
  47. int m_nOffset;
  48. CivID m_civId;
  49. static LeaderBoardScreen* s_pLeaderBoard;
  50. enum StatsColumn
  51. {
  52. colPosition,
  53. colPlayerName,
  54. colRank,
  55. colOverallRating,
  56. colCombatRating,
  57. colGamesPlayed,
  58. colTimePlayed,
  59. colCommanderWins,
  60. colWins,
  61. colLosses,
  62. colKills,
  63. colDeaths,
  64. colBaseKills,
  65. colBaseCaptures,
  66. maxCol
  67. };
  68. class PlayerPainter : public ItemPainter
  69. {
  70. const TVector<int>& m_viColumns;
  71. LeaderBoardScreen* m_pparent;
  72. public:
  73. PlayerPainter(const TVector<int>& viColumns, LeaderBoardScreen* pparent)
  74. : m_viColumns(viColumns), m_pparent(pparent) {};
  75. int GetXSize()
  76. {
  77. return m_viColumns[maxCol - 1];
  78. }
  79. int GetYSize()
  80. {
  81. return 12;
  82. }
  83. void Paint(ItemID pitemArg, Surface* psurface, bool bSelected, bool bFocus)
  84. {
  85. if (pitemArg == NULL)
  86. return;
  87. if (bSelected)
  88. {
  89. psurface->FillRect(
  90. WinRect(0, 0, GetXSize(), GetYSize()),
  91. Color(1, 0, 0)
  92. );
  93. }
  94. PaintText(pitemArg, psurface, 0.85f * Color::White());
  95. }
  96. int GetColOffset(StatsColumn col)
  97. {
  98. assert(col >= 0 && col < maxCol);
  99. if (col == 0)
  100. return 0;
  101. else
  102. return m_viColumns[col - 1];
  103. }
  104. void PaintText(ItemID pitemArg, Surface* psurface, Color color)
  105. {
  106. LeaderBoardEntry* pplayer = (LeaderBoardEntry*)pitemArg;
  107. if (pplayer == NULL)
  108. return;
  109. // draw the player's position
  110. if (m_pparent->FindSortColumn() != colPlayerName)
  111. {
  112. psurface->DrawString(
  113. TrekResources::SmallFont(),
  114. color,
  115. WinPoint(GetColOffset(colPosition) + 2, 0),
  116. pplayer->nPosition
  117. );
  118. }
  119. // draw the player's name
  120. WinRect rectClipOld = psurface->GetClipRect();
  121. psurface->SetClipRect(WinRect(WinPoint(GetColOffset(colPlayerName) + 2, 0), WinPoint(GetColOffset(colOverallRating), GetYSize()))); // clip name to fit in column
  122. psurface->DrawString(
  123. TrekResources::SmallFont(),
  124. color,
  125. WinPoint(GetColOffset(colPlayerName) + 2, 0),
  126. pplayer->CharacterName
  127. );
  128. psurface->RestoreClipRect(rectClipOld);
  129. // draw the player rank
  130. rectClipOld = psurface->GetClipRect();
  131. psurface->SetClipRect(WinRect(WinPoint(GetColOffset(colRank) + 2, 0), WinPoint(GetColOffset(colOverallRating), GetYSize()))); // clip rank to fit in column
  132. psurface->DrawString(
  133. TrekResources::SmallFont(),
  134. color,
  135. WinPoint(GetColOffset(colRank) + 2, 0),
  136. trekClient.LookupRankName(pplayer->rank, m_pparent->m_civId)
  137. );
  138. psurface->RestoreClipRect(rectClipOld);
  139. // draw the player's ratings
  140. psurface->DrawString(
  141. TrekResources::SmallFont(),
  142. color,
  143. WinPoint(GetColOffset(colOverallRating) + 5, 0),
  144. (int)pplayer->fTotalScore
  145. );
  146. psurface->DrawString(
  147. TrekResources::SmallFont(),
  148. color,
  149. WinPoint(GetColOffset(colCombatRating) + 3, 0),
  150. pplayer->rating
  151. );
  152. int nHoursPlayed = pplayer->nMinutesPlayed / 60;
  153. int nMinutesPlayed = pplayer->nMinutesPlayed - nHoursPlayed * 60;
  154. ZString strTimePlayed = ZString(nHoursPlayed) +
  155. (nHoursPlayed > 999 ?
  156. "h" :
  157. ((nMinutesPlayed < 10) ? ":0" : ":") + ZString(nMinutesPlayed));
  158. psurface->DrawString(
  159. TrekResources::SmallFont(),
  160. color,
  161. WinPoint(GetColOffset(colTimePlayed) + 3, 0),
  162. strTimePlayed
  163. );
  164. psurface->DrawString(
  165. TrekResources::SmallFont(),
  166. color,
  167. WinPoint(GetColOffset(colCommanderWins) + 3, 0),
  168. pplayer->cTotalCommanderWins
  169. );
  170. psurface->DrawString(
  171. TrekResources::SmallFont(),
  172. color,
  173. WinPoint(GetColOffset(colGamesPlayed) + 3, 0),
  174. pplayer->cTotalGamesPlayed
  175. );
  176. psurface->DrawString(
  177. TrekResources::SmallFont(),
  178. color,
  179. WinPoint(GetColOffset(colWins) + 3, 0),
  180. pplayer->cTotalWins
  181. );
  182. psurface->DrawString(
  183. TrekResources::SmallFont(),
  184. color,
  185. WinPoint(GetColOffset(colLosses) + 3, 0),
  186. pplayer->cTotalLosses
  187. );
  188. psurface->DrawString(
  189. TrekResources::SmallFont(),
  190. color,
  191. WinPoint(GetColOffset(colKills) + 3, 0),
  192. pplayer->cTotalKills
  193. );
  194. psurface->DrawString(
  195. TrekResources::SmallFont(),
  196. color,
  197. WinPoint(GetColOffset(colDeaths) + 3, 0),
  198. pplayer->cTotalDeaths
  199. );
  200. psurface->DrawString(
  201. TrekResources::SmallFont(),
  202. color,
  203. WinPoint(GetColOffset(colBaseKills) + 3, 0),
  204. pplayer->cTotalBaseKills
  205. );
  206. psurface->DrawString(
  207. TrekResources::SmallFont(),
  208. color,
  209. WinPoint(GetColOffset(colBaseCaptures) + 3, 0),
  210. pplayer->cTotalBaseCaptures
  211. );
  212. }
  213. };
  214. class TopPlayerPainter : public PlayerPainter
  215. {
  216. public:
  217. TopPlayerPainter(const TVector<int>& viColumns, LeaderBoardScreen* pparent)
  218. : PlayerPainter(viColumns, pparent) {};
  219. void Paint(ItemID pitemArg, Surface* psurface, bool bSelected, bool bFocus)
  220. {
  221. PaintText(pitemArg, psurface, Color::White());
  222. }
  223. };
  224. public:
  225. LeaderBoardScreen(Modeler* pmodeler, const ZString& strCharacter) :
  226. m_nOffset(0)
  227. {
  228. TRef<IObject> pobjStatsColumns;
  229. TRef<INameSpace> pnsLeaderBoardScreenData = GetModeler()->CreateNameSpace("leaderboardscreendata");
  230. pnsLeaderBoardScreenData->AddMember("civImage", (Value*)(m_pwrapImageCiv = new WrapImage(Image::GetEmpty())));
  231. m_pns = pmodeler->GetNameSpace("LeaderBoardscreen");
  232. CastTo(m_ppane, m_pns->FindMember("screen"));
  233. CastTo(m_pbuttonBack, m_pns->FindMember("backButtonPane"));
  234. CastTo(m_pbuttonPlayerProfile, m_pns->FindMember("playerProfileButtonPane"));
  235. CastTo(m_pbuttonPlayerProfile2, m_pns->FindMember("playerProfile2ButtonPane"));
  236. CastTo(m_pbuttonSquadProfile, m_pns->FindMember("squadProfileButtonPane"));
  237. CastTo(m_pbuttonSquads, m_pns->FindMember("squadsButtonPane"));
  238. CastTo(m_pbuttonWeb, m_pns->FindMember("webButtonPane"));
  239. CastTo(m_pcomboCiv, m_pns->FindMember("civFilterComboPane"));
  240. CastTo(m_peditPane, (Pane*)m_pns->FindMember("searchEditPane"));
  241. CastTo(m_pbuttonSearch, m_pns->FindMember("searchButtonPane"));
  242. CastTo(m_pbuttonFindMe, m_pns->FindMember("findMeButtonPane"));
  243. CastTo(m_pbuttonbarStats, m_pns->FindMember("statsListHeader"));
  244. CastTo(m_plistPaneStats, (Pane*)m_pns->FindMember("statsListPane"));
  245. CastTo(m_plistTopPlayer, (Pane*)m_pns->FindMember("topListPane"));
  246. CastTo(pobjStatsColumns, m_pns->FindMember("statsColumns"));
  247. CastTo(m_pbuttonTop, m_pns->FindMember("topButtonPane"));
  248. CastTo(m_pbuttonPageUp, m_pns->FindMember("pageUpButtonPane"));
  249. CastTo(m_pbuttonPageDown, m_pns->FindMember("pageDownButtonPane"));
  250. //
  251. // Buttons
  252. //
  253. AddEventTarget(OnButtonBack, m_pbuttonBack->GetEventSource());
  254. AddEventTarget(OnButtonFindMe, m_pbuttonFindMe->GetEventSource());
  255. AddEventTarget(OnButtonPlayerProfile, m_pbuttonPlayerProfile->GetEventSource());
  256. AddEventTarget(OnButtonZoneWeb, m_pbuttonWeb->GetEventSource());
  257. AddEventTarget(OnButtonPlayerProfile, m_pbuttonPlayerProfile2->GetEventSource());
  258. AddEventTarget(OnButtonSquadProfile, m_pbuttonSquadProfile->GetEventSource());
  259. m_pbuttonSquadProfile->SetEnabled(!g_bDisableZoneClub);
  260. m_pbuttonSquads->SetEnabled(!g_bDisableZoneClub);
  261. AddEventTarget(OnButtonSquadProfile, m_pbuttonSquads->GetEventSource());
  262. AddEventTarget(OnButtonTop, m_pbuttonTop->GetEventSource());
  263. AddEventTarget(OnButtonPageUp, m_pbuttonPageUp->GetEventSource());
  264. AddEventTarget(OnButtonPageUp, m_pbuttonPageUp->GetDoubleClickEventSource());
  265. AddEventTarget(OnButtonPageDown, m_pbuttonPageDown->GetEventSource());
  266. AddEventTarget(OnButtonPageDown, m_pbuttonPageDown->GetDoubleClickEventSource());
  267. AddEventTarget(OnButtonBarStats, m_pbuttonbarStats->GetEventSource());
  268. //
  269. // civ combo
  270. //
  271. FillCombo(m_pcomboCiv, "CivNames");
  272. AddEventTarget(OnCivChange, m_pcomboCiv->GetEventSource());
  273. //
  274. // search box
  275. //
  276. m_peditPane->SetTextColor(Color::Black());
  277. m_peventSearchEdit = m_peditPane->GetChangeEvent();
  278. m_peventSearchEdit->AddSink(m_psinkSearchEdit = new TEvent<ZString>>::Delegate(this));
  279. m_pkeyboardInputOldFocus = GetWindow()->GetFocus();
  280. GetWindow()->SetFocus();
  281. GetWindow()->SetFocus(m_peditPane);
  282. m_strBasis = strCharacter.IsEmpty() ? trekClient.GetNameLogonClubServer() : strCharacter;
  283. m_idBasis = strCharacter.IsEmpty() ? -2 : -1;
  284. AddEventTarget(OnButtonSearch, m_pbuttonSearch->GetEventSource());
  285. m_cEntries = 0;
  286. s_pLeaderBoard = this;
  287. //
  288. // Player Stats
  289. //
  290. ParseIntVector(pobjStatsColumns, m_viStatsColumns);
  291. m_plistPaneStats->SetItemPainter(new PlayerPainter(m_viStatsColumns, this));
  292. m_plistTopPlayer->SetItemPainter(new TopPlayerPainter(m_viStatsColumns, this));
  293. m_peventStats = m_plistPaneStats->GetSelectionEventSource();
  294. m_peventStats->AddSink(m_psinkStats = new IItemEvent::Delegate(this));
  295. m_pbuttonbarStats->SetChecked(colOverallRating, true);
  296. OnCivChange(0);
  297. }
  298. ~LeaderBoardScreen()
  299. {
  300. m_peventSearchEdit->RemoveSink(m_psinkSearchEdit);
  301. m_peventStats->RemoveSink(m_psinkStats);
  302. GetWindow()->SetFocus(m_pkeyboardInputOldFocus);
  303. GetModeler()->UnloadNameSpace(m_pns);
  304. s_pLeaderBoard = NULL;
  305. }
  306. static void ForwardLeaderBoardMessage(FEDMESSAGE * pLeaderBoardMessage)
  307. {
  308. if (s_pLeaderBoard)
  309. {
  310. s_pLeaderBoard->HandleLeaderBoardMessage(pLeaderBoardMessage);
  311. }
  312. }
  313. void FillCombo(ComboPane* pcombo, const char* szContentName)
  314. {
  315. IObjectList* plist;
  316. CastTo(plist, m_pns->FindMember(szContentName));
  317. plist->GetFirst();
  318. int index = 0;
  319. while (plist->GetCurrent() != NULL) {
  320. pcombo->AddItem(GetString(plist->GetCurrent()), index);
  321. plist->GetNext();
  322. ++index;
  323. }
  324. }
  325. float FindFloatValue(int index, const char* szTableName)
  326. {
  327. IObjectList* plist;
  328. CastTo(plist, m_pns->FindMember(szTableName));
  329. plist->GetFirst();
  330. while (index > 0) {
  331. plist->GetNext();
  332. --index;
  333. }
  334. return GetNumber(plist->GetCurrent());
  335. }
  336. int FindIntValue(int index, const char* szTableName)
  337. {
  338. return (int)FindFloatValue(index, szTableName);
  339. }
  340. ZString FindStringValue(int index, const char* szTableName)
  341. {
  342. IObjectList* plist;
  343. CastTo(plist, m_pns->FindMember(szTableName));
  344. plist->GetFirst();
  345. while (index > 0) {
  346. plist->GetNext();
  347. --index;
  348. }
  349. return GetString(plist->GetCurrent());
  350. }
  351. bool OnButtonSearch()
  352. {
  353. ZString str = m_peditPane->GetString();
  354. if (!str.IsEmpty())
  355. {
  356. m_strBasis = str;
  357. m_idBasis = NA;
  358. ClearListBoxes();
  359. UpdateData();
  360. }
  361. m_peditPane->SetString(ZString());
  362. return true;
  363. }
  364. void UpdateButtons()
  365. {
  366. m_pbuttonPlayerProfile->SetEnabled(m_cEntries > 0);
  367. m_pbuttonPlayerProfile2->SetEnabled(m_cEntries > 0);
  368. m_pbuttonSquadProfile->SetEnabled(!g_bDisableZoneClub && m_cEntries > 0);
  369. m_pbuttonSquads->SetEnabled(!g_bDisableZoneClub && m_cEntries > 0);
  370. m_pbuttonPageUp->SetEnabled(CanPageUp());
  371. m_pbuttonPageDown->SetEnabled(CanPageDown());
  372. }
  373. void ClearListBoxes()
  374. {
  375. m_cEntries = 0;
  376. UpdateListBoxes();
  377. }
  378. bool OnEvent(TEvent<ZString>::Source* pevent, ZString str)
  379. {
  380. if (!str.IsEmpty())
  381. {
  382. m_strBasis = str;
  383. m_idBasis = NA;
  384. ClearListBoxes();
  385. UpdateData();
  386. }
  387. m_peditPane->SetString(ZString());
  388. return true;
  389. }
  390. bool OnCivChange(int index)
  391. {
  392. int civID = FindIntValue(index, "CivIDs");
  393. m_pwrapImageCiv->SetImage(GetModeler()->LoadImage(FindStringValue(index, "CivBackgrounds"), true));
  394. ClearListBoxes();
  395. UpdateData();
  396. return true;
  397. }
  398. bool OnEvent(IItemEvent::Source *pevent, ItemID pitem)
  399. {
  400. if (pitem)
  401. {
  402. // set the basis to be the selected character
  403. m_strBasis = ((LeaderBoardEntry*)pitem)->CharacterName;
  404. m_idBasis = ((LeaderBoardEntry*)pitem)->idCharacter;
  405. }
  406. return true;
  407. }
  408. bool OnButtonBack()
  409. {
  410. GetWindow()->screen(ScreenIDZoneClubScreen);
  411. return true;
  412. }
  413. bool OnButtonFindMe()
  414. {
  415. m_strBasis = trekClient.m_szClubCharName;
  416. m_idBasis = NA;
  417. ClearListBoxes();
  418. UpdateData();
  419. return true;
  420. }
  421. bool OnButtonPlayerProfile()
  422. {
  423. if (m_cEntries > 0 && !m_strBasis.IsEmpty())
  424. {
  425. GetWindow()->CharInfoScreenForPlayer(m_idBasis);
  426. }
  427. return true;
  428. }
  429. bool OnButtonSquadProfile()
  430. {
  431. if (m_cEntries > 0 && !m_strBasis.IsEmpty())
  432. {
  433. GetWindow()->SquadScreenForPlayer(PCC(m_strBasis), m_idBasis, NULL);
  434. }
  435. return true;
  436. }
  437. bool OnButtonZoneWeb()
  438. {
  439. // note: users can also access web page from the introscreen
  440. GetWindow()->ShowWebPage();
  441. return true;
  442. }
  443. bool OnButtonGames()
  444. {
  445. return true;
  446. }
  447. bool OnButtonTop()
  448. {
  449. m_strBasis = "";
  450. m_idBasis = NA;
  451. ClearListBoxes();
  452. UpdateData();
  453. return true;
  454. }
  455. int CalcPageUpBasis()
  456. {
  457. if (m_cEntries <= 0)
  458. return m_nOffset;
  459. else
  460. return max(0, m_nOffset - cLinesPerScreen + cLinesPerScreen/2); // rounding trick
  461. }
  462. bool CanPageUp()
  463. {
  464. return (CalcPageUpBasis() < m_nOffset);
  465. }
  466. bool OnButtonPageUp()
  467. {
  468. if (CanPageUp())
  469. {
  470. int indexBasis = CalcPageUpBasis();
  471. m_strBasis = m_vEntries[indexBasis].CharacterName;
  472. m_idBasis = m_vEntries[indexBasis].idCharacter;
  473. UpdateListBoxes();
  474. UpdateData();
  475. }
  476. return true;
  477. }
  478. int CalcPageDownBasis()
  479. {
  480. if (m_cEntries <= 0)
  481. return m_nOffset;
  482. else
  483. return min(m_cEntries - 1, m_nOffset + cLinesPerScreen + cLinesPerScreen/2);
  484. }
  485. bool CanPageDown()
  486. {
  487. return (CalcPageDownBasis() >= m_nOffset + cLinesPerScreen);
  488. }
  489. bool OnButtonPageDown()
  490. {
  491. if (CanPageDown())
  492. {
  493. int indexBasis = CalcPageDownBasis();
  494. m_strBasis = m_vEntries[indexBasis].CharacterName;
  495. m_idBasis = m_vEntries[indexBasis].idCharacter;
  496. UpdateListBoxes();
  497. UpdateData();
  498. }
  499. return true;
  500. }
  501. StatsColumn FindSortColumn()
  502. {
  503. for (int i = 0; i <= maxCol; i++)
  504. {
  505. if (m_pbuttonbarStats->GetChecked(i)
  506. || m_pbuttonbarStats->GetChecked2(i)
  507. )
  508. {
  509. return (StatsColumn)i;
  510. }
  511. }
  512. ZError("unreached");
  513. return colPlayerName;
  514. };
  515. bool OnButtonBarStats(int iButton)
  516. {
  517. // if they click on the position button, ignore the click.
  518. if (iButton == colPosition)
  519. return true;
  520. bool bReverse = false;//m_pbuttonbarStats->GetChecked(iButton);
  521. ItemID pselection = m_plistPaneStats->GetSelection();
  522. // do radio-button behavior
  523. for (int i = 0; i < maxCol; i++)
  524. {
  525. m_pbuttonbarStats->SetChecked(i, false);
  526. m_pbuttonbarStats->SetChecked2(i, false);
  527. }
  528. if (bReverse)
  529. m_pbuttonbarStats->SetChecked2(iButton, true);
  530. else
  531. m_pbuttonbarStats->SetChecked(iButton, true);
  532. ClearListBoxes();
  533. UpdateData();
  534. return true;
  535. }
  536. LeaderBoardSort ColumnToSort(StatsColumn col)
  537. {
  538. switch (col)
  539. {
  540. case colPlayerName:
  541. return lbSortName;
  542. case colRank:
  543. return lbSortRank;
  544. case colOverallRating:
  545. return lbSortScore;
  546. case colCombatRating:
  547. return lbSortRating;
  548. case colTimePlayed:
  549. return lbSortTimePlayed;
  550. case colCommanderWins:
  551. return lbSortCommanderWins;
  552. case colGamesPlayed:
  553. return lbSortGamesPlayed;
  554. case colWins:
  555. return lbSortWins;
  556. case colLosses:
  557. return lbSortLosses;
  558. case colKills:
  559. return lbSortKills;
  560. case colDeaths:
  561. return lbSortDeaths;
  562. case colBaseKills:
  563. return lbSortBaseKills;
  564. case colBaseCaptures:
  565. return lbSortBaseCaptures;
  566. case colPosition:
  567. default:
  568. ZError("invalid column");
  569. return lbSortScore;
  570. };
  571. }
  572. void UpdateData()
  573. {
  574. StatsColumn sortCol = FindSortColumn();
  575. BEGIN_PFM_CREATE(trekClient.m_fmClub, pfmLeaderBoardQuery, C, LEADER_BOARD_QUERY)
  576. END_PFM_CREATE
  577. if ((m_idBasis != NA && m_idBasis != -2) || m_strBasis.IsEmpty())
  578. pfmLeaderBoardQuery->szBasis[0] = '\0';
  579. else
  580. strcpy(pfmLeaderBoardQuery->szBasis, m_strBasis);
  581. pfmLeaderBoardQuery->idBasis = m_idBasis;
  582. pfmLeaderBoardQuery->civid = m_civId = FindIntValue(m_pcomboCiv->GetSelection(), "CivIDs");
  583. pfmLeaderBoardQuery->sort = ColumnToSort(sortCol);
  584. trekClient.SendClubMessages();
  585. };
  586. int OffsetOfCharacter(ZString szCharacterName)
  587. {
  588. return OffsetOfCharacter(szCharacterName, m_vEntries, m_cEntries);
  589. }
  590. int OffsetOfCharacter(const char* szCharacterName, LeaderBoardEntry* vEntries, int cEntries)
  591. {
  592. for (int i = 0; i < cEntries; i++)
  593. {
  594. if (_stricmp(vEntries[i].CharacterName, szCharacterName) == 0)
  595. {
  596. return i;
  597. }
  598. }
  599. return -1;
  600. }
  601. int OffsetOfCharacterPrefix(const char* szCharacterPrefix, LeaderBoardEntry* vEntries, int cEntries)
  602. {
  603. for (int i = 0; i < cEntries; i++)
  604. {
  605. int nLength = strlen(szCharacterPrefix);
  606. if (_strnicmp(vEntries[i].CharacterName, szCharacterPrefix, nLength) == 0)
  607. {
  608. return i;
  609. }
  610. }
  611. return -1;
  612. }
  613. void HandleLeaderBoardMessage(FEDMESSAGE *pLeaderBoardMessage)
  614. {
  615. switch (pLeaderBoardMessage->fmid)
  616. {
  617. case FM_S_LEADER_BOARD_QUERY_FAIL:
  618. {
  619. CASTPFM(pfmLeaderBoardQueryFail, S, LEADER_BOARD_QUERY_FAIL, pLeaderBoardMessage);
  620. if (pfmLeaderBoardQueryFail->szBasis[0] == '\0')
  621. {
  622. TRef<IMessageBox> pmsgBox = CreateMessageBox(
  623. "No characters were found for the chosen faction.");
  624. GetWindow()->GetPopupContainer()->OpenPopup(pmsgBox, false);
  625. }
  626. else
  627. {
  628. TRef<IMessageBox> pmsgBox = CreateMessageBox(
  629. "Could not find ranking info for \'"
  630. + ZString(pfmLeaderBoardQueryFail->szBasis) + "\'");
  631. GetWindow()->GetPopupContainer()->OpenPopup(pmsgBox, false);
  632. }
  633. break;
  634. }
  635. break;
  636. case FM_S_LEADER_BOARD_LIST:
  637. {
  638. CASTPFM(pfmLeaderBoardList, S, LEADER_BOARD_LIST, pLeaderBoardMessage);
  639. ZAssert(pfmLeaderBoardList->cEntries > 0
  640. && pfmLeaderBoardList->cEntries <= cLinesPerScreen * 3);
  641. LeaderBoardEntry* vEntriesNew = (LeaderBoardEntry*)FM_VAR_REF(pfmLeaderBoardList, ventryPlayers);
  642. int indexBasis;
  643. // if we are getting the top players, set the basis to be
  644. // the first player in the list.
  645. if (m_strBasis.IsEmpty())
  646. {
  647. m_strBasis = vEntriesNew[0].CharacterName;
  648. indexBasis = 0;
  649. }
  650. else
  651. indexBasis = OffsetOfCharacter(m_strBasis, vEntriesNew, pfmLeaderBoardList->cEntries);
  652. // if this was the first search, allow the top players in the list to have been returned
  653. if (m_idBasis == -2 && indexBasis == -1 && pfmLeaderBoardList->cEntries > 0)
  654. {
  655. m_strBasis = vEntriesNew[0].CharacterName;
  656. indexBasis = 0;
  657. }
  658. // if we are searching by name, allow a prefix
  659. if (m_idBasis == -1 && indexBasis == -1)
  660. {
  661. indexBasis = OffsetOfCharacterPrefix(m_strBasis, vEntriesNew, pfmLeaderBoardList->cEntries);
  662. }
  663. if (indexBasis != -1)
  664. {
  665. m_cEntries = pfmLeaderBoardList->cEntries;
  666. m_entryNumber1 = pfmLeaderBoardList->entryNumber1;
  667. memcpy(m_vEntries, vEntriesNew, sizeof(LeaderBoardEntry) * m_cEntries);
  668. // find the basis's character id
  669. m_idBasis = vEntriesNew[indexBasis].idCharacter;
  670. m_strBasis = vEntriesNew[indexBasis].CharacterName;
  671. UpdateListBoxes();
  672. }
  673. }
  674. break;
  675. }
  676. }
  677. void UpdateListBoxes()
  678. {
  679. TRef<TListListWrapper<LeaderBoardEntry*> > plistTopPlayer = new TListListWrapper<LeaderBoardEntry*>();
  680. if (m_cEntries > 0)
  681. plistTopPlayer->PushEnd(&m_entryNumber1);
  682. m_plistTopPlayer->SetList(plistTopPlayer);
  683. TRef<TListListWrapper<LeaderBoardEntry*> > plistStats = new TListListWrapper<LeaderBoardEntry*>();
  684. if (m_cEntries > 0)
  685. {
  686. // figure out the offset in the list at which to start
  687. int nOffsetBasis = OffsetOfCharacter(m_strBasis);
  688. m_nOffset = max(0, min(m_cEntries - cLinesPerScreen,
  689. nOffsetBasis - (cLinesPerScreen-1)/2));
  690. for (int i = 0; i < cLinesPerScreen && i + m_nOffset < m_cEntries; ++i)
  691. {
  692. plistStats->PushEnd(&m_vEntries[i + m_nOffset]);
  693. }
  694. m_plistPaneStats->SetList(plistStats);
  695. m_plistPaneStats->SetSelection(&m_vEntries[nOffsetBasis]);
  696. }
  697. else
  698. m_plistPaneStats->SetList(plistStats);
  699. UpdateButtons();
  700. }
  701. //////////////////////////////////////////////////////////////////////////////
  702. //
  703. // Screen Methods
  704. //
  705. //////////////////////////////////////////////////////////////////////////////
  706. Pane* GetPane()
  707. {
  708. return m_ppane;
  709. }
  710. };
  711. LeaderBoardScreen* LeaderBoardScreen::s_pLeaderBoard = NULL;
  712. //////////////////////////////////////////////////////////////////////////////
  713. //
  714. // Constructor
  715. //
  716. //////////////////////////////////////////////////////////////////////////////
  717. TRef<Screen> CreateLeaderBoardScreen(Modeler* pmodeler, const ZString strCharacter)
  718. {
  719. return new LeaderBoardScreen(pmodeler, strCharacter);
  720. }
  721. void ForwardLeaderBoardMessage(FEDMESSAGE * pLeaderBoardMessage)
  722. {
  723. LeaderBoardScreen::ForwardLeaderBoardMessage(pLeaderBoardMessage);
  724. }