DlgMPTeamSelect.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /******************************************************************************
  19. *
  20. * FILE
  21. * $Archive: /Commando/Code/Commando/DlgMPTeamSelect.cpp $
  22. *
  23. * DESCRIPTION
  24. * Multiplayer team selection dialog.
  25. *
  26. * PROGRAMMER
  27. * Denzil E. Long, Jr.
  28. * $Author: Denzil_l $
  29. *
  30. * VERSION INFO
  31. * $Revision: 17 $
  32. * $Modtime: 2/24/02 2:51p $
  33. *
  34. ******************************************************************************/
  35. #include "dlgmpteamselect.h"
  36. #include "wolgmode.h"
  37. #include "gamedata.h"
  38. #include "wolgameinfo.h"
  39. #include "wolloginprofile.h"
  40. #include "dlgmessagebox.h"
  41. #include "renegadedialogmgr.h"
  42. #include <combat\playertype.h>
  43. #include <wwonline\wolgameoptions.h>
  44. #include <wwui\listctrl.h>
  45. #include <wwui\comboboxctrl.h>
  46. #include <wwui\imagectrl.h>
  47. #include "resource.h"
  48. #include "string_ids.h"
  49. #include <wwtranslatedb\translatedb.h>
  50. #include "modpackagemgr.h"
  51. #include "gameinitmgr.h"
  52. using namespace WWOnline;
  53. // Player list columns
  54. enum
  55. {
  56. COL_RANK,
  57. COL_NAME,
  58. // Denzil 02/24/02 Day 1 patch - Remove clan until we can fix formating
  59. // COL_CLAN,
  60. COL_KD,
  61. COL_SCORE
  62. };
  63. // Private game options processing dispatching
  64. typedef void (*GameOptionsDispatchFunc)(DlgMPTeamSelect&, const char*);
  65. #define PARSE_INT(s, d, v) {char* ptr = strtok(s, d); if (ptr) {v = atoi(ptr);}}
  66. #define PARSE_FLOAT(s, d, v) {char* ptr = strtok(s, d); if (ptr) {v = atof(ptr);}}
  67. #define PARSE_HEXDWORD(s, d, v) {char* ptr = strtok(s, d); if (ptr) {sscanf(ptr, "%08X", &v);}}
  68. #define PARSE_HEXBYTE(s, d, v) {char* ptr = strtok(s, d); if (ptr) {sscanf(ptr, "%02X", &v);}}
  69. #define PARSE_STRING(s, d, v) {v = strtok(s, d);}
  70. static int CALLBACK ListSortCallback(ListCtrlClass* list, int index1, int index2, uint32 param)
  71. {
  72. int rank1 = (int)list->Get_Entry_Data(index1, COL_RANK);
  73. int rank2 = (int)list->Get_Entry_Data(index2, COL_RANK);
  74. return (rank1 - rank2);
  75. }
  76. /******************************************************************************
  77. *
  78. * NAME
  79. * DlgMPTeamSelect::DoDialog
  80. *
  81. * DESCRIPTION
  82. * Display team selection / team profile dialog
  83. *
  84. * INPUTS
  85. * Target - Target to receive user choice signal.
  86. *
  87. * RESULT
  88. * NONE
  89. *
  90. ******************************************************************************/
  91. void DlgMPTeamSelect::DoDialog(Signaler<MPChooseTeamSignal>& target)
  92. {
  93. DlgMPTeamSelect* dialog = new DlgMPTeamSelect;
  94. if (dialog)
  95. {
  96. if (dialog->FinalizeCreate())
  97. {
  98. dialog->Start_Dialog();
  99. dialog->SignalMe(target);
  100. }
  101. dialog->Release_Ref();
  102. }
  103. }
  104. /******************************************************************************
  105. *
  106. * NAME
  107. * DlgMPTeamSelect::DlgMpTeamSelect
  108. *
  109. * DESCRIPTION
  110. * Constructor
  111. *
  112. * INPUTS
  113. * NONE
  114. *
  115. * RESULT
  116. * NONE
  117. *
  118. ******************************************************************************/
  119. DlgMPTeamSelect::DlgMPTeamSelect(void) :
  120. MenuDialogClass(IDD_MP_TEAM_SELECT),
  121. mWOLGame(true),
  122. mCanChoose(true),
  123. mTimeRemaining(0.0f)
  124. {
  125. WWDEBUG_SAY(("DlgMPTeamSelect instantiated\n"));
  126. }
  127. /******************************************************************************
  128. *
  129. * NAME
  130. * DlgMPTeamSelect::~DlgMPTeamSelect
  131. *
  132. * DESCRIPTION
  133. * Destructor
  134. *
  135. * INPUTS
  136. * NONE
  137. *
  138. * RESULT
  139. * NONE
  140. *
  141. ******************************************************************************/
  142. DlgMPTeamSelect::~DlgMPTeamSelect()
  143. {
  144. WWDEBUG_SAY(("DlgMPTeamSelect destroyed\n"));
  145. }
  146. /******************************************************************************
  147. *
  148. * NAME
  149. * DlgMPTeamSelect::FinalizeCreate
  150. *
  151. * DESCRIPTION
  152. * Post creation initialization.
  153. *
  154. * INPUTS
  155. * NONE
  156. *
  157. * RESULT
  158. * True if successful
  159. *
  160. ******************************************************************************/
  161. bool DlgMPTeamSelect::FinalizeCreate(void)
  162. {
  163. GameModeClass* gameMode = GameModeManager::Find("WOL");
  164. if (gameMode && gameMode->Is_Active())
  165. {
  166. mWOLGame = true;
  167. mWOLSession = Session::GetInstance(false);
  168. // Cannot continue if WOL session is not initialized
  169. if (mWOLSession.IsValid() == false)
  170. {
  171. return false;
  172. }
  173. // Get the channel we have joined.
  174. const RefPtr<ChannelData>& channel = mWOLSession->GetCurrentChannel();
  175. // Cannot continue if we are not in a channel
  176. if (channel.IsValid() == false)
  177. {
  178. return false;
  179. }
  180. mGameInfo.ImportFromChannel(channel);
  181. Observer<ChannelEvent>::NotifyMe(*mWOLSession);
  182. Observer<UserEvent>::NotifyMe(*mWOLSession);
  183. }
  184. else
  185. {
  186. gameMode = GameModeManager::Find("LAN");
  187. if (gameMode && gameMode->Is_Active())
  188. {
  189. mWOLGame = false;
  190. mGameInfo.ImportFromGame(*The_Game());
  191. }
  192. }
  193. if (mGameInfo.IsDataValid() == false)
  194. {
  195. return false;
  196. }
  197. mCanChoose = (!mGameInfo.IsClanGame() && mGameInfo.IsTeamChange());
  198. return true;
  199. }
  200. /******************************************************************************
  201. *
  202. * NAME
  203. * DlgMPTeamSelect::On_Init_Dialog
  204. *
  205. * DESCRIPTION
  206. * One time dialog initialization
  207. *
  208. * INPUTS
  209. * NONE
  210. *
  211. * RESULT
  212. * NONE
  213. *
  214. ******************************************************************************/
  215. void DlgMPTeamSelect::On_Init_Dialog(void)
  216. {
  217. WWDEBUG_SAY(("DlgMPTeamSelect On_Init_Dialog\n"));
  218. MenuDialogClass::On_Init_Dialog();
  219. // Setup the team icons on the dialog
  220. ((ImageCtrlClass*)Get_Dlg_Item(IDC_GDI_TEAM_ICON))->Set_Texture("HUD_C&C_GDILOGO.TGA");
  221. ((ImageCtrlClass*)Get_Dlg_Item(IDC_NOD_TEAM_ICON))->Set_Texture("HUD_C&C_NODLOGO.TGA");
  222. // Setup the list controls
  223. ListCtrlClass* list = (ListCtrlClass*)Get_Dlg_Item(IDC_GDI_LIST_CTRL);
  224. if (list)
  225. {
  226. // Configure the columns
  227. list->Add_Column(TRANSLATE (IDS_MENU_RANK), 0.15F, Vector3(1, 1, 1));
  228. // Denzil 02/24/02 Day 1 patch - Remove clan until we can fix formatting issues.
  229. #if(0)
  230. list->Add_Column(TRANSLATE (IDS_MENU_NAME), 0.30F, Vector3(1, 1, 1));
  231. list->Add_Column(TRANSLATE (IDS_MENU_CLAN), 0.20F, Vector3(1, 1, 1));
  232. #else
  233. list->Add_Column(TRANSLATE (IDS_MENU_NAME), 0.50F, Vector3(1, 1, 1));
  234. #endif
  235. list->Add_Column(TRANSLATE (IDS_MENU_KD_RATIO), 0.15F, Vector3(1, 1, 1));
  236. list->Add_Column(TRANSLATE (IDS_MENU_SCORE), 0.20F, Vector3(1, 1, 1));
  237. }
  238. list = (ListCtrlClass*)Get_Dlg_Item(IDC_NOD_LIST_CTRL);
  239. if (list)
  240. {
  241. // Configure the columns
  242. list->Add_Column(TRANSLATE (IDS_MENU_RANK), 0.15F, Vector3(1, 1, 1));
  243. // Denzil 02/24/02 Day 1 patch - Remove clan until we can fix formatting issues.
  244. #if(0)
  245. list->Add_Column(TRANSLATE (IDS_MENU_NAME), 0.30F, Vector3(1, 1, 1));
  246. list->Add_Column(TRANSLATE (IDS_MENU_CLAN), 0.20F, Vector3(1, 1, 1));
  247. #else
  248. list->Add_Column(TRANSLATE (IDS_MENU_NAME), 0.50F, Vector3(1, 1, 1));
  249. #endif
  250. list->Add_Column(TRANSLATE (IDS_MENU_KD_RATIO), 0.15F, Vector3(1, 1, 1));
  251. list->Add_Column(TRANSLATE (IDS_MENU_SCORE), 0.20F, Vector3(1, 1, 1));
  252. }
  253. int sidePref = -1;
  254. if (mWOLGame)
  255. {
  256. // If this is not a clan game then we can use the preference.
  257. if (mGameInfo.IsClanGame() == false)
  258. {
  259. const RefPtr<LoginInfo>& login = mWOLSession->GetCurrentLogin();
  260. WWASSERT(login.IsValid());
  261. LoginProfile* profile = LoginProfile::Get(login->GetNickname());
  262. if (profile)
  263. {
  264. sidePref = profile->GetSidePreference();
  265. profile->Release_Ref();
  266. }
  267. }
  268. // The start button is disabled until we hear from the host.
  269. Enable_Dlg_Item(IDC_STARTGAME, false);
  270. // Request information about the game.
  271. RequestWOLGameInfo();
  272. }
  273. else
  274. {
  275. sidePref = cNetInterface::Get_Side_Preference();
  276. // Hide and disable the back button for LAN games.
  277. DialogControlClass* ctrl = Get_Dlg_Item(IDCANCEL);
  278. WWASSERT(ctrl != NULL);
  279. ctrl->Show(false);
  280. ctrl->Enable(false);
  281. cPlayerManager::Add_Event_Observer(*this);
  282. PopulateWithLANPlayers();
  283. }
  284. InitSideChoice(sidePref);
  285. // Activate the menu game mode (if necessary)
  286. GameModeClass* menuMode = GameModeManager::Find("Menu");
  287. if (menuMode && !menuMode->Is_Active())
  288. {
  289. menuMode->Activate();
  290. }
  291. }
  292. /******************************************************************************
  293. *
  294. * NAME
  295. * DlgMPTeamSelect::On_Frame_Update
  296. *
  297. * DESCRIPTION
  298. *
  299. * INPUTS
  300. * NONE
  301. *
  302. * RESULT
  303. * NONE
  304. *
  305. ******************************************************************************/
  306. void DlgMPTeamSelect::On_Frame_Update(void)
  307. {
  308. if (mTimeRemaining >= WWMATH_EPSILON)
  309. {
  310. mTimeRemaining -= TimeManager::Get_Frame_Real_Seconds();
  311. ShowTimeRemaining(mTimeRemaining);
  312. }
  313. MenuDialogClass::On_Frame_Update();
  314. }
  315. /******************************************************************************
  316. *
  317. * NAME
  318. * DlgMPTeamSelect::On_Command
  319. *
  320. * DESCRIPTION
  321. *
  322. * INPUTS
  323. *
  324. * RESULT
  325. * NONE
  326. *
  327. ******************************************************************************/
  328. void DlgMPTeamSelect::On_Command(int ctrlID, int message, DWORD param)
  329. {
  330. switch (ctrlID)
  331. {
  332. case IDCANCEL:
  333. case IDC_STARTGAME:
  334. {
  335. int side = GetSideChoice();
  336. MPChooseTeamSignal chooseSignal((IDC_STARTGAME == ctrlID), side);
  337. Signaler<MPChooseTeamSignal>::SendSignal(chooseSignal);
  338. End_Dialog();
  339. }
  340. break;
  341. case IDC_TEAM_AUTO_CHECK:
  342. SelectSideChoice(PLAYERTYPE_RENEGADE);
  343. break;
  344. case IDC_TEAM_GDI_CHECK:
  345. SelectSideChoice(PLAYERTYPE_GDI);
  346. break;
  347. case IDC_TEAM_NOD_CHECK:
  348. SelectSideChoice(PLAYERTYPE_NOD);
  349. break;
  350. }
  351. MenuDialogClass::On_Command(ctrlID, message, param);
  352. }
  353. /******************************************************************************
  354. *
  355. * NAME
  356. * DlgMPTeamSelect::On_Last_Menu_Ending
  357. *
  358. * DESCRIPTION
  359. * Callback from menu class signifying the close of the last menu
  360. *
  361. * INPUTS
  362. * NONE
  363. *
  364. * RESULT
  365. * NONE
  366. *
  367. ******************************************************************************/
  368. void DlgMPTeamSelect::On_Last_Menu_Ending(void)
  369. {
  370. // If this the WOL screen then return to the menu...
  371. if (GameInitMgrClass::Is_WOL_Initialized())
  372. {
  373. RenegadeDialogMgrClass::Goto_Location(RenegadeDialogMgrClass::LOC_INTERNET_GAME_LIST);
  374. }
  375. }
  376. /******************************************************************************
  377. *
  378. * NAME
  379. * DlgMPTeamSelect::InitSideChoice
  380. *
  381. * DESCRIPTION
  382. *
  383. * INPUTS
  384. * NONE
  385. *
  386. * RESULT
  387. * NONE
  388. *
  389. ******************************************************************************/
  390. void DlgMPTeamSelect::InitSideChoice(int sidePref)
  391. {
  392. Enable_Dlg_Item(IDC_TEAM_AUTO_CHECK, mCanChoose);
  393. Enable_Dlg_Item(IDC_TEAM_GDI_CHECK, mCanChoose);
  394. Enable_Dlg_Item(IDC_TEAM_NOD_CHECK, mCanChoose);
  395. // Default side selection combo to the users preference.
  396. int side = ((mCanChoose == true) ? sidePref : -1);
  397. SelectSideChoice(side);
  398. }
  399. /******************************************************************************
  400. *
  401. * NAME
  402. * DlgMPTeamSelect::SelectSideChoice
  403. *
  404. * DESCRIPTION
  405. *
  406. * INPUTS
  407. * Side -
  408. *
  409. * RESULT
  410. * NONE
  411. *
  412. ******************************************************************************/
  413. void DlgMPTeamSelect::SelectSideChoice(int side)
  414. {
  415. Check_Dlg_Button(IDC_TEAM_AUTO_CHECK, (PLAYERTYPE_RENEGADE == side));
  416. Check_Dlg_Button(IDC_TEAM_GDI_CHECK, (PLAYERTYPE_GDI == side));
  417. Check_Dlg_Button(IDC_TEAM_NOD_CHECK, (PLAYERTYPE_NOD == side));
  418. }
  419. /******************************************************************************
  420. *
  421. * NAME
  422. * DlgMPTeamSelect::GetSideChoice
  423. *
  424. * DESCRIPTION
  425. *
  426. * INPUTS
  427. * Side -
  428. *
  429. * RESULT
  430. * NONE
  431. *
  432. ******************************************************************************/
  433. int DlgMPTeamSelect::GetSideChoice(void)
  434. {
  435. if (Is_Dlg_Button_Checked(IDC_TEAM_GDI_CHECK))
  436. {
  437. return PLAYERTYPE_GDI;
  438. }
  439. else if (Is_Dlg_Button_Checked(IDC_TEAM_NOD_CHECK))
  440. {
  441. return PLAYERTYPE_NOD;
  442. }
  443. return PLAYERTYPE_RENEGADE;
  444. }
  445. /******************************************************************************
  446. *
  447. * NAME
  448. * DlgMPTeamSelect::RequestWOLGameInfo
  449. *
  450. * DESCRIPTION
  451. * Send a request to the game server for informaiton about the game.
  452. *
  453. * INPUTS
  454. * NONE
  455. *
  456. * RESULT
  457. * NONE
  458. *
  459. ******************************************************************************/
  460. void DlgMPTeamSelect::RequestWOLGameInfo(void)
  461. {
  462. WWDEBUG_SAY(("DlgMPTeamSelect requesting game info\n"));
  463. // Get the hosts name and send a request for player information.
  464. const RefPtr<ChannelData>& channel = mWOLSession->GetCurrentChannel();
  465. if (channel.IsValid())
  466. {
  467. Observer<GameOptionsMessage>::NotifyMe(*mWOLSession);
  468. mWOLSession->SendPrivateGameOptions(channel->GetName(), "RGINFO");
  469. }
  470. }
  471. /******************************************************************************
  472. *
  473. * NAME
  474. * DlgMPTeamSelect::ShowTimeRemaining
  475. *
  476. * DESCRIPTION
  477. * Set the time remaining text
  478. *
  479. * INPUTS
  480. * Seconds - Seconds remaining in the game
  481. *
  482. * RESULT
  483. * NONE
  484. *
  485. ******************************************************************************/
  486. void DlgMPTeamSelect::ShowTimeRemaining(float remainingSeconds)
  487. {
  488. int hours = 0;
  489. int mins = 0;
  490. int seconds = 0;
  491. cMiscUtil::Seconds_To_Hms(remainingSeconds, hours, mins, seconds);
  492. WideStringClass timeString(0, true);
  493. timeString.Format(L"%02d:%02d:%02d", hours, mins, seconds);
  494. WideStringClass text(0, true);
  495. text.Format(L"%s: %s", TRANSLATION(IDS_MP_TIME_REMAINING), (const WCHAR*)timeString);
  496. Set_Dlg_Item_Text(IDC_TIME_REMAINING_TEXT, (const WCHAR*)text);
  497. }
  498. /******************************************************************************
  499. *
  500. * NAME
  501. * DlgMPTeamSelect::FindPlayerInListCtrl
  502. *
  503. * DESCRIPTION
  504. * Find a player entry in the player (GDI or Nod) list control.
  505. *
  506. * INPUTS
  507. * Name - Name of player to look for.
  508. * List - On return; List control containing player entry.
  509. * Index - On return; Player entry list index
  510. *
  511. * RESULT
  512. * True if player found in one of the lists.
  513. *
  514. ******************************************************************************/
  515. bool DlgMPTeamSelect::FindPlayerInListCtrl(const WCHAR* name, ListCtrlClass*& outList, int& outIndex)
  516. {
  517. // Check in GDI player list
  518. ListCtrlClass* list = (ListCtrlClass*)Get_Dlg_Item(IDC_GDI_LIST_CTRL);
  519. if (list)
  520. {
  521. int index = list->Find_Entry(COL_NAME, name);
  522. if (index != -1)
  523. {
  524. outList = list;
  525. outIndex = index;
  526. return true;
  527. }
  528. }
  529. // Check in Nod player list
  530. list = (ListCtrlClass*)Get_Dlg_Item(IDC_NOD_LIST_CTRL);
  531. if (list)
  532. {
  533. int index = list->Find_Entry(COL_NAME, name);
  534. if (index != -1)
  535. {
  536. outList = list;
  537. outIndex = index;
  538. return true;
  539. }
  540. }
  541. return false;
  542. }
  543. /******************************************************************************
  544. *
  545. * NAME
  546. * DlgMPTeamSelect::HandleNotification(ChannelEvent)
  547. *
  548. * DESCRIPTION
  549. * Handle channel events that occur while the user is deceiding on the team.
  550. *
  551. * INPUTS
  552. * ChannelEvent -
  553. *
  554. * RESULT
  555. * NONE
  556. *
  557. ******************************************************************************/
  558. void DlgMPTeamSelect::HandleNotification(ChannelEvent& event)
  559. {
  560. // This user has been kicked from the game.
  561. if (ChannelKicked == event.GetStatus())
  562. {
  563. DlgMsgBox::DoDialog(TRANSLATE(IDS_MENU_SERVER_MESSAGE_TITLE),
  564. TRANSLATE(IDS_MENU_SERVER_KICKED_MESSAGE));
  565. End_Dialog();
  566. }
  567. }
  568. /******************************************************************************
  569. *
  570. * NAME
  571. * DlgMPTeamSelect::HandleNotification(UserEvent)
  572. *
  573. * DESCRIPTION
  574. * Handle user events that occur while the user is making their team choice.
  575. *
  576. * INPUTS
  577. *
  578. * RESULT
  579. *
  580. ******************************************************************************/
  581. void DlgMPTeamSelect::HandleNotification(UserEvent& userEvent)
  582. {
  583. const RefPtr<UserData>& user = userEvent.Subject();
  584. if (user.IsValid() == false)
  585. {
  586. return;
  587. }
  588. // Show clan information for users as it arrives
  589. switch (userEvent.GetEvent())
  590. {
  591. #if(0) // Denzil 02/24/02 Day 1 patch - Removed clan until we fix formatting
  592. case UserEvent::SquadInfo:
  593. {
  594. ListCtrlClass* list = NULL;
  595. int itemIndex = -1;
  596. bool found = FindPlayerInListCtrl(user->GetName(), list, itemIndex);
  597. if (found)
  598. {
  599. RefPtr<SquadData> clan = user->GetSquad();
  600. if (clan.IsValid())
  601. {
  602. WideStringClass clanAbbr(0, true);
  603. clanAbbr = clan->GetAbbr();
  604. list->Set_Entry_Text(itemIndex, COL_CLAN, clanAbbr);
  605. }
  606. }
  607. }
  608. break;
  609. #endif
  610. #if(0)
  611. case UserEvent::Join:
  612. mWOLSession->RequestUserDetails(user, REQUEST_SQUADINFO);
  613. break;
  614. #endif
  615. // Remove users that leave the game.
  616. case UserEvent::Leave:
  617. {
  618. ListCtrlClass* list = NULL;
  619. int itemIndex = -1;
  620. bool found = FindPlayerInListCtrl(user->GetName(), list, itemIndex);
  621. if (found)
  622. {
  623. list->Delete_Entry(itemIndex);
  624. }
  625. }
  626. break;
  627. default:
  628. break;
  629. }
  630. }
  631. /******************************************************************************
  632. *
  633. * NAME
  634. * DlgMPTeamSelect::HandleNotification(GameOptionsMessage)
  635. *
  636. * DESCRIPTION
  637. * Handle game options messages that come in from the server.
  638. *
  639. * INPUTS
  640. * GameOpts -
  641. *
  642. * RESULT
  643. * NONE
  644. *
  645. ******************************************************************************/
  646. void DlgMPTeamSelect::HandleNotification(GameOptionsMessage& message)
  647. {
  648. // Only listen to messages coming for the game host
  649. const RefPtr<ChannelData>& channel = mWOLSession->GetCurrentChannel();
  650. if (channel.IsValid() == false)
  651. {
  652. return;
  653. }
  654. const WideStringClass& hostName = channel->GetName();
  655. WideStringClass sender(0, true);
  656. sender = message.GetSendersName();
  657. if (hostName.Compare_No_Case(sender) == 0)
  658. {
  659. static struct {const char* Token; GameOptionsDispatchFunc Dispatch;} _dispatch[] =
  660. {
  661. {"GINFO:", ProcessWOLGameInfo},
  662. {"TINFO:", ProcessWOLTeamInfo},
  663. {"PINFO:", ProcessWOLPlayerInfo},
  664. {NULL, NULL}
  665. };
  666. int index = 0;
  667. const char* token = _dispatch[index].Token;
  668. const char* options = message.GetOptions();
  669. while (token)
  670. {
  671. // Find the first occurance of the token in the message
  672. char* cmd = strstr(options, token);
  673. // If the token was found and it is at the start of the message
  674. // then invoke the handler for this message.
  675. if (cmd && cmd == options)
  676. {
  677. const char* data = (options + strlen(token));
  678. _dispatch[index].Dispatch(*this, data);
  679. // We have heard from the host so it is okay to allow the player to start.
  680. Enable_Dlg_Item(IDC_STARTGAME, true);
  681. break;
  682. }
  683. ++index;
  684. token = _dispatch[index].Token;
  685. }
  686. }
  687. }
  688. /******************************************************************************
  689. *
  690. * NAME
  691. * DlgMPTeamSelect::ProcessWOLGameInfo
  692. *
  693. * DESCRIPTION
  694. * Process the game information options packet.
  695. *
  696. * INPUTS
  697. *
  698. * RESULT
  699. * NONE
  700. *
  701. ******************************************************************************/
  702. void DlgMPTeamSelect::ProcessWOLGameInfo(DlgMPTeamSelect& dialog, const char* data)
  703. {
  704. if (data)
  705. {
  706. char info[255];
  707. strncpy(info, data, 255);
  708. // Get players name
  709. unsigned long mapCRC = 0;
  710. PARSE_HEXDWORD(info, " ", mapCRC);
  711. StringClass mapname(64, true);
  712. ModPackageMgrClass::Find_Filename_From_CRC ("*.mix", mapCRC, &mapname);
  713. WideStringClass text(255, true);
  714. text.Format(TRANSLATE (IDS_MENU_MAP_NAME_FORMAT), (const char*)mapname);
  715. dialog.Set_Dlg_Item_Text(IDC_MAPNAME_TEXT, text);
  716. float timeRemaining = 0.0f;
  717. PARSE_FLOAT(NULL, " ", timeRemaining);
  718. dialog.mTimeRemaining = timeRemaining;
  719. dialog.ShowTimeRemaining(timeRemaining);
  720. int gdiScore = 0;
  721. PARSE_INT(NULL, " ", gdiScore);
  722. text.Format(TRANSLATE (IDS_MENU_SCORE_NAME_FORMAT), gdiScore);
  723. dialog.Set_Dlg_Item_Text(IDC_GDI_SCORE, text);
  724. int nodScore = 0;
  725. PARSE_INT(NULL, " ", nodScore);
  726. text.Format(TRANSLATE (IDS_MENU_SCORE_NAME_FORMAT), nodScore);
  727. dialog.Set_Dlg_Item_Text(IDC_NOD_SCORE, text);
  728. // Clear the player lists
  729. ListCtrlClass* list = (ListCtrlClass*)dialog.Get_Dlg_Item(IDC_GDI_LIST_CTRL);
  730. if (list)
  731. {
  732. list->Delete_All_Entries();
  733. }
  734. list = (ListCtrlClass*)dialog.Get_Dlg_Item(IDC_NOD_LIST_CTRL);
  735. if (list)
  736. {
  737. list->Delete_All_Entries();
  738. }
  739. }
  740. }
  741. /******************************************************************************
  742. *
  743. * NAME
  744. * DlgMPTeamSelect::ProcessWOLTeamInfo
  745. *
  746. * DESCRIPTION
  747. * Process the team information options packet.
  748. *
  749. * INPUTS
  750. *
  751. * RESULT
  752. * NONE
  753. *
  754. ******************************************************************************/
  755. void DlgMPTeamSelect::ProcessWOLTeamInfo(DlgMPTeamSelect& dialog, const char* data)
  756. {
  757. if (data)
  758. {
  759. char info[255];
  760. strncpy(info, data, 255);
  761. // Get team GDI information
  762. int teamID = 0;
  763. PARSE_INT(info, " ", teamID);
  764. int score = 0;
  765. PARSE_INT(NULL, " ", score);
  766. // Output info
  767. WideStringClass text(0, true);
  768. text.Format(TRANSLATE (IDS_MENU_SCORE_NAME_FORMAT), score);
  769. int ctrlID = ((teamID == PLAYERTYPE_GDI) ? IDC_GDI_SCORE : IDC_NOD_SCORE);
  770. dialog.Set_Dlg_Item_Text(ctrlID, text);
  771. }
  772. }
  773. /******************************************************************************
  774. *
  775. * NAME
  776. * DlgMPTeamSelect::ProcessWOLPlayerInfo
  777. *
  778. * DESCRIPTION
  779. * Process the per player information packet.
  780. *
  781. * INPUTS
  782. *
  783. * RESULT
  784. * NONE
  785. *
  786. ******************************************************************************/
  787. void DlgMPTeamSelect::ProcessWOLPlayerInfo(DlgMPTeamSelect& dialog, const char* data)
  788. {
  789. if (data)
  790. {
  791. char info[255];
  792. strncpy(info, data, 255);
  793. // Get players name
  794. char* name = "";
  795. PARSE_STRING(info, " ", name);
  796. // Team type
  797. int type = -1;
  798. PARSE_INT(NULL, " ", type);
  799. // Rank
  800. int rung = 0;
  801. PARSE_INT(NULL, " ", rung);
  802. // Kills
  803. int kills = 0;
  804. PARSE_INT(NULL, " ", kills);
  805. // Deaths
  806. int deaths = 0;
  807. PARSE_INT(NULL, " ", deaths);
  808. // Score
  809. int score = 0;
  810. PARSE_INT(NULL, " ", score);
  811. int listID = ((type == PLAYERTYPE_GDI) ? IDC_GDI_LIST_CTRL : IDC_NOD_LIST_CTRL);
  812. ListCtrlClass* list = (ListCtrlClass*)dialog.Get_Dlg_Item(listID);
  813. if (list)
  814. {
  815. WideStringClass playerName(64, true);
  816. playerName = name;
  817. int itemIndex = list->Find_Entry(COL_NAME, playerName);
  818. if (itemIndex == -1)
  819. {
  820. itemIndex = list->Insert_Entry(list->Get_Entry_Count(), L"");
  821. }
  822. if (itemIndex != -1)
  823. {
  824. WideStringClass text(255, true);
  825. // Set the players name and clan affiliation
  826. list->Set_Entry_Text(itemIndex, COL_NAME, playerName);
  827. #if(0) // Denzil 02/24/02 Day 1 patch - Remove clan until we can fix formating
  828. RefPtr<UserData> user = dialog.mWOLSession->FindUser(playerName);
  829. if (user.IsValid())
  830. {
  831. RefPtr<SquadData> clan = user->GetSquad();
  832. if (clan.IsValid())
  833. {
  834. text = clan->GetAbbr();
  835. list->Set_Entry_Text(itemIndex, COL_CLAN, text);
  836. }
  837. }
  838. #endif
  839. text.Format(L"%d/%d", kills, deaths);
  840. list->Set_Entry_Text(itemIndex, COL_KD, text);
  841. list->Set_Entry_Int(itemIndex, COL_RANK, rung);
  842. list->Set_Entry_Int(itemIndex, COL_SCORE, score);
  843. list->Sort(ListSortCallback, 0);
  844. }
  845. }
  846. }
  847. }
  848. /******************************************************************************
  849. *
  850. * NAME
  851. * DlgMPTeamSelect::HandleNotification(PlayerMgrEvent)
  852. *
  853. * DESCRIPTION
  854. *
  855. * INPUTS
  856. *
  857. * RESULT
  858. *
  859. ******************************************************************************/
  860. void DlgMPTeamSelect::HandleNotification(PlayerMgrEvent& event)
  861. {
  862. PLAYERMGR_ACTION action = event.GetAction();
  863. if ((action == PLAYER_ACTIVATED))// || (action == PLAYER_ADDED))
  864. {
  865. AddLANPlayerInfo(event.Subject());
  866. }
  867. else if ((action == PLAYER_DEACTIVATED) || (action == PLAYER_REMOVED))
  868. {
  869. RemoveLANPlayerInfo(event.Subject());
  870. }
  871. }
  872. /******************************************************************************
  873. *
  874. * NAME
  875. * DlgMPTeamSelect::ProcessWithLANPlayers
  876. *
  877. * DESCRIPTION
  878. *
  879. * INPUTS
  880. * NONE
  881. *
  882. * RESULT
  883. * NONE
  884. *
  885. ******************************************************************************/
  886. void DlgMPTeamSelect::PopulateWithLANPlayers(void)
  887. {
  888. SList<cPlayer>* playerList = cPlayerManager::Get_Player_Object_List();
  889. SLNode<cPlayer>* playerNode = playerList->Head();
  890. while (playerNode)
  891. {
  892. cPlayer* player = playerNode->Data();
  893. if (player->Get_Is_Active().Is_True())
  894. {
  895. AddLANPlayerInfo(player);
  896. }
  897. playerNode = playerNode->Next();
  898. }
  899. }
  900. /******************************************************************************
  901. *
  902. * NAME
  903. * DlgMPTeamSelect::AddLANPlayerInfo
  904. *
  905. * DESCRIPTION
  906. *
  907. * INPUTS
  908. *
  909. * RESULT
  910. *
  911. ******************************************************************************/
  912. void DlgMPTeamSelect::AddLANPlayerInfo(cPlayer* player)
  913. {
  914. WWASSERT(player != NULL);
  915. RemoveLANPlayerInfo(player);
  916. int playerType = player->Get_Player_Type();
  917. int listID = ((playerType == PLAYERTYPE_GDI) ? IDC_GDI_LIST_CTRL : IDC_NOD_LIST_CTRL);
  918. ListCtrlClass* list = (ListCtrlClass*)Get_Dlg_Item(listID);
  919. WWASSERT(list != NULL);
  920. int itemIndex = list->Insert_Entry(list->Get_Entry_Count(), L"");
  921. if (itemIndex >= 0)
  922. {
  923. list->Set_Entry_Text(itemIndex, COL_NAME, player->Get_Name());
  924. list->Set_Entry_Int(itemIndex, COL_RANK, player->Get_Rung());
  925. list->Set_Entry_Int(itemIndex, COL_SCORE, player->Get_Score());
  926. WideStringClass text(0, true);
  927. text.Format(L"%d/%d", player->Get_Kills(), player->Get_Deaths());
  928. list->Set_Entry_Text(itemIndex, COL_KD, text);
  929. // If this is the player client the mark there name with a star
  930. const WideStringClass& nickname = cNetInterface::Get_Nickname();
  931. if (nickname.Compare_No_Case(player->Get_Name()) == 0)
  932. {
  933. list->Add_Icon(itemIndex, COL_NAME, "IF_LRGSTAR.TGA");
  934. list->Set_Entry_Color(itemIndex, COL_RANK, Vector3(1.0F, 1.0F, 1.0F));
  935. list->Set_Entry_Color(itemIndex, COL_NAME, Vector3(1.0F, 1.0F, 1.0F));
  936. list->Set_Entry_Color(itemIndex, COL_KD, Vector3(1.0F, 1.0F, 1.0F));
  937. list->Set_Entry_Color(itemIndex, COL_SCORE, Vector3(1.0F, 1.0F, 1.0F));
  938. SelectSideChoice(playerType);
  939. }
  940. }
  941. list->Sort(ListSortCallback, 0);
  942. }
  943. /******************************************************************************
  944. *
  945. * NAME
  946. * DlgMPTeamSelect::RemoveLANPlayerInfo
  947. *
  948. * DESCRIPTION
  949. *
  950. * INPUTS
  951. *
  952. * RESULT
  953. *
  954. ******************************************************************************/
  955. void DlgMPTeamSelect::RemoveLANPlayerInfo(cPlayer* player)
  956. {
  957. WWASSERT(player != NULL);
  958. ListCtrlClass* list = NULL;
  959. int itemIndex = -1;
  960. bool found = FindPlayerInListCtrl(player->Get_Name(), list, itemIndex);
  961. if (found)
  962. {
  963. list->Delete_Entry(itemIndex);
  964. }
  965. }