dlgmpingamechat.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837
  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. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : Combat *
  23. * *
  24. * $Archive:: /Commando/Code/commando/dlgmpingamechat.cpp $*
  25. * *
  26. * Author:: Tom SS *
  27. * *
  28. * $Modtime:: 2/19/02 2:40p $*
  29. * *
  30. * $Revision:: 20 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "dlgmpingamechat.h"
  36. #include "cnetwork.h"
  37. #include "dialogcontrol.h"
  38. #include "dialogmgr.h"
  39. #include "gamedata.h"
  40. #include "cstextobj.h"
  41. #include "sctextobj.h"
  42. #include "comboboxctrl.h"
  43. #include "playermanager.h"
  44. #include "player.h"
  45. #include "listctrl.h"
  46. #include "messagewindow.h"
  47. #include "wolgmode.h"
  48. #include "translatedb.h"
  49. #include "string_ids.h"
  50. static const WCHAR* Get_Parameter_From_String(const WCHAR* command, WideStringClass& param);
  51. ////////////////////////////////////////////////////////////////
  52. //
  53. // MPChatChildDialogClass
  54. //
  55. ////////////////////////////////////////////////////////////////
  56. MPChatChildDialogClass::MPChatChildDialogClass (void) :
  57. MessageType (TEXT_MESSAGE_PUBLIC),
  58. TestForAutoCompletion (false),
  59. EndDialogOnSend (true),
  60. ChildDialogClass (IDD_CHAT_MODULE)
  61. {
  62. return ;
  63. }
  64. ////////////////////////////////////////////////////////////////
  65. //
  66. // On_Init_Dialog
  67. //
  68. ////////////////////////////////////////////////////////////////
  69. void
  70. MPChatChildDialogClass::On_Init_Dialog (void)
  71. {
  72. WWASSERT (The_Game () != NULL);
  73. //
  74. // Allow the base class to process the message
  75. //
  76. ChildDialogClass::On_Init_Dialog ();
  77. //
  78. // Set the text of the type control accordingly
  79. //
  80. if (MessageType == TEXT_MESSAGE_TEAM) {
  81. Set_Dlg_Item_Text (IDC_TYPE_STATIC, TRANSLATE (IDS_MENU_TEAM_MESSAGE));
  82. } else if (MessageType == TEXT_MESSAGE_PUBLIC) {
  83. Set_Dlg_Item_Text (IDC_TYPE_STATIC, TRANSLATE (IDS_MENU_PUBLIC_MESSAGE));
  84. }
  85. //
  86. // Put the focus into the text control
  87. //
  88. ((EditCtrlClass *)Get_Dlg_Item (IDC_MESSAGE_EDIT))->Set_Text_Limit (100);
  89. Get_Dlg_Item (IDC_MESSAGE_EDIT)->Set_Focus ();
  90. return ;
  91. }
  92. ////////////////////////////////////////////////////////////////
  93. //
  94. // Send_Message
  95. //
  96. ////////////////////////////////////////////////////////////////
  97. void
  98. MPChatChildDialogClass::Process_Message (void)
  99. {
  100. // Get the text to send...
  101. WideStringClass message(0, true);
  102. message = Get_Dlg_Item_Text(IDC_MESSAGE_EDIT);
  103. message.Trim();
  104. if (message.Is_Empty() == false) {
  105. if (Process_Commands(message) == false) {
  106. TextMessageEnum message_type = MessageType;
  107. int recipient_id = -1;
  108. bool is_ok_to_send = true;
  109. //
  110. // Determine who to send the message to...
  111. //
  112. if (RecipientName.Is_Empty() == false) {
  113. //
  114. // Lookup the player we're sending the message to
  115. //
  116. cPlayer *recipient = cPlayerManager::Find_Player (RecipientName);
  117. if (recipient != NULL) {
  118. message_type = TEXT_MESSAGE_PRIVATE;
  119. recipient_id = recipient->Get_Id ();
  120. } else {
  121. is_ok_to_send = false;
  122. }
  123. }
  124. //
  125. // Transmit the message
  126. //
  127. if (is_ok_to_send) {
  128. Send_Message(message, message_type, recipient_id);
  129. }
  130. }
  131. //
  132. // Clear the edit control
  133. //
  134. Set_Dlg_Item_Text (IDC_MESSAGE_EDIT, L"");
  135. }
  136. return ;
  137. }
  138. void MPChatChildDialogClass::Send_Message(WideStringClass& message, TextMessageEnum type, int recipientID)
  139. {
  140. //
  141. // Send the message
  142. //
  143. if (cNetwork::I_Am_Client ()) {
  144. cCsTextObj *event_obj = new cCsTextObj;
  145. event_obj->Init(message, type, cNetwork::Get_My_Id(), recipientID);
  146. } else {
  147. cScTextObj *event_obj = new cScTextObj;
  148. event_obj->Init(message, type, false, HOST_TEXT_SENDER, recipientID);
  149. }
  150. }
  151. ////////////////////////////////////////////////////////////////
  152. //
  153. // Process Commands
  154. //
  155. ////////////////////////////////////////////////////////////////
  156. bool MPChatChildDialogClass::Process_Commands(const WCHAR* message)
  157. {
  158. // Does this look like a command?
  159. if (message && message[0] == L'/') {
  160. // Separate the parameters into individual strings
  161. WideStringClass command(255, true);
  162. const WCHAR* curr_pos = Get_Parameter_From_String(&message[1], command);
  163. if (command.Get_Length() > 0 && curr_pos[0] != 0) {
  164. // Kick a player from the game
  165. if (command.Compare_No_Case(L"kick") == 0) {
  166. GameModeClass* gameMode = GameModeManager::Find("WOL");
  167. if (gameMode && gameMode->Is_Active()) {
  168. // Get the name parameter from the string
  169. WideStringClass user_name(64, true);
  170. curr_pos = Get_Parameter_From_String(curr_pos, user_name);
  171. if (user_name.Get_Length() > 0) {
  172. WolGameModeClass* wolGame = reinterpret_cast<WolGameModeClass*>(gameMode);
  173. wolGame->Kick_Player(user_name);
  174. }
  175. }
  176. return true;
  177. }
  178. // Page users outside of this game.
  179. if (command.Compare_No_Case(L"page") == 0) {
  180. GameModeClass* gameMode = GameModeManager::Find("WOL");
  181. if (gameMode && gameMode->Is_Active()) {
  182. // Get the name parameter from the string
  183. WideStringClass user_name(64, true);
  184. curr_pos = Get_Parameter_From_String(curr_pos, user_name);
  185. if (user_name.Get_Length() > 0) {
  186. WideStringClass message(0, true);
  187. message = curr_pos;
  188. message.Trim();
  189. // If the user is in this game then just send them a private message.
  190. cPlayer* recipient = cPlayerManager::Find_Player(user_name);
  191. if (recipient) {
  192. int recipient_id = recipient->Get_Id();
  193. Send_Message(message, TEXT_MESSAGE_PRIVATE, recipient_id);
  194. } else {
  195. // Page external users.
  196. WolGameModeClass* wolGame = reinterpret_cast<WolGameModeClass*>(gameMode);
  197. wolGame->Page_WOL_User(user_name, message);
  198. }
  199. }
  200. }
  201. return true;
  202. }
  203. // Reply to the last page
  204. if (command.Compare_No_Case(L"r") == 0) {
  205. GameModeClass* gameMode = GameModeManager::Find("WOL");
  206. if (gameMode && gameMode->Is_Active()) {
  207. WolGameModeClass* wolGame = reinterpret_cast<WolGameModeClass*>(gameMode);
  208. WideStringClass message(0, true);
  209. message = curr_pos;
  210. message.Trim();
  211. wolGame->Reply_Last_Page(message);
  212. }
  213. return true;
  214. }
  215. // Locate a WOL user
  216. if (command.Compare_No_Case(L"locate") == 0) {
  217. GameModeClass* gameMode = GameModeManager::Find("WOL");
  218. if (gameMode && gameMode->Is_Active()) {
  219. // Get the name parameter from the string
  220. WideStringClass user_name(64, true);
  221. curr_pos = Get_Parameter_From_String(curr_pos, user_name);
  222. if (user_name.Get_Length() > 0) {
  223. WolGameModeClass* wolGame = reinterpret_cast<WolGameModeClass*>(gameMode);
  224. wolGame->Locate_WOL_User(user_name);
  225. }
  226. }
  227. return true;
  228. }
  229. // Invite another WOL user to this game
  230. if (command.Compare_No_Case(L"invite") == 0) {
  231. GameModeClass* gameMode = GameModeManager::Find("WOL");
  232. if (gameMode && gameMode->Is_Active()) {
  233. // Get the name parameter from the string
  234. WideStringClass user_name(64, true);
  235. curr_pos = Get_Parameter_From_String(curr_pos, user_name);
  236. if (user_name.Get_Length() > 0) {
  237. WolGameModeClass* wolGame = reinterpret_cast<WolGameModeClass*>(gameMode);
  238. WideStringClass message(0, true);
  239. message = curr_pos;
  240. message.Trim();
  241. wolGame->Invite_WOL_User(user_name, message);
  242. }
  243. }
  244. return true;
  245. }
  246. // Join another WOL user at their location
  247. if (command.Compare_No_Case(L"join") == 0) {
  248. GameModeClass* gameMode = GameModeManager::Find("WOL");
  249. if (gameMode && gameMode->Is_Active()) {
  250. // Get the name parameter from the string
  251. WideStringClass user_name(64, true);
  252. curr_pos = Get_Parameter_From_String(curr_pos, user_name);
  253. if (user_name.Get_Length() > 0) {
  254. WolGameModeClass* wolGame = reinterpret_cast<WolGameModeClass*>(gameMode);
  255. wolGame->Join_WOL_User(user_name);
  256. }
  257. }
  258. return true;
  259. }
  260. }
  261. }
  262. return false;
  263. }
  264. ////////////////////////////////////////////////////////////////
  265. //
  266. // Get_Parameter_From_String
  267. //
  268. ////////////////////////////////////////////////////////////////
  269. const WCHAR* Get_Parameter_From_String(const WCHAR* command, WideStringClass& param)
  270. {
  271. #define LOCAL_STRIP_WHITESPACE(str) \
  272. while (str[0] != 0 && str[0] == L' ') {++str;}
  273. // Strip off whitespace
  274. LOCAL_STRIP_WHITESPACE(command);
  275. const WCHAR* curr_pos = command;
  276. // Look for the first whitespace break
  277. while (curr_pos[0] != 0 && curr_pos[0] != L' ') {
  278. ++curr_pos;
  279. }
  280. // Return the string contents to the caller
  281. int length = ((curr_pos + 1) - command);
  282. if (length > 0) {
  283. WCHAR* buffer = param.Get_Buffer(length + 1);
  284. wcsncpy(buffer, command, length);
  285. buffer[length - 1] = 0;
  286. }
  287. // Strip off whitespace
  288. LOCAL_STRIP_WHITESPACE(curr_pos);
  289. return curr_pos;
  290. }
  291. //////////////////////////////////////////////////////////////////////
  292. //
  293. // Auto_Complete_Name
  294. //
  295. //////////////////////////////////////////////////////////////////////
  296. void
  297. MPChatChildDialogClass::Auto_Complete_Name (void)
  298. {
  299. EditCtrlClass *edit_ctrl = (EditCtrlClass *)Get_Dlg_Item (IDC_MESSAGE_EDIT);
  300. if (edit_ctrl == NULL) {
  301. return ;
  302. }
  303. //
  304. // Examine everything left of the caret
  305. //
  306. int caret_pos = edit_ctrl->Get_Caret_Pos ();
  307. if (caret_pos > 0) {
  308. //
  309. // Get the message
  310. //
  311. WideStringClass message = Get_Dlg_Item_Text (IDC_MESSAGE_EDIT);
  312. int message_len = message.Get_Length ();
  313. if (message_len > 0) {
  314. //
  315. // Check to see if we are typing in a command
  316. //
  317. int cmd_start_index = 0;
  318. int cmd_end_index = 0;
  319. if (Find_Current_Command (message, cmd_start_index, cmd_end_index)) {
  320. cmd_start_index ++;
  321. //
  322. // Try to find the start of the name
  323. //
  324. const WCHAR *name_start = message.Peek_Buffer () + cmd_start_index;
  325. //
  326. // Make a copy of the first part of the message before the command
  327. //
  328. WideStringClass first_part (cmd_start_index + 1, true);
  329. ::wcsncpy (first_part.Peek_Buffer (), message, cmd_start_index);
  330. first_part.Peek_Buffer ()[cmd_start_index] = 0;
  331. //
  332. // Make a copy of the remainder of the message after the command
  333. //
  334. WideStringClass last_part (message_len - cmd_end_index, true);
  335. ::wcscpy (last_part.Peek_Buffer (), message.Peek_Buffer () + cmd_end_index);
  336. //
  337. // Copy the typed characters into their own buffer
  338. //
  339. int typed_len = caret_pos - cmd_start_index;
  340. WideStringClass typed_name (typed_len + 1, true);
  341. ::wcsncpy (typed_name.Peek_Buffer (), name_start, typed_len);
  342. typed_name.Peek_Buffer ()[typed_len] = 0;
  343. //
  344. // Try to complete the name that the user typed in
  345. //
  346. WideStringClass completed_name (0, true);
  347. Complete_Player_Name (typed_name, completed_name);
  348. //
  349. // Did we find a valid completed name?
  350. //
  351. int completed_name_len = completed_name.Get_Length ();
  352. if (completed_name_len >= typed_len) {
  353. CurrRecipientName = completed_name;
  354. //
  355. // Rebuild the message...
  356. //
  357. WideStringClass new_message (first_part);
  358. new_message += completed_name;
  359. new_message += last_part;
  360. //
  361. // Put the new text into the edit control and reset the caret
  362. //
  363. edit_ctrl->Set_Text (new_message);
  364. edit_ctrl->Set_Caret_Pos (caret_pos);
  365. //
  366. // Hilight the auto-completed characters
  367. //
  368. int hilight_end = caret_pos + (completed_name_len - typed_len);
  369. edit_ctrl->Set_Sel (caret_pos, hilight_end);
  370. } else {
  371. CurrRecipientName = L"";
  372. }
  373. }
  374. }
  375. }
  376. return ;
  377. }
  378. //////////////////////////////////////////////////////////////////////
  379. //
  380. // Complete_Player_Name
  381. //
  382. //////////////////////////////////////////////////////////////////////
  383. void
  384. MPChatChildDialogClass::Complete_Player_Name (const WCHAR *typed_name, WideStringClass &completed_name)
  385. {
  386. int typed_len = ::wcslen (typed_name);
  387. //
  388. // Require more then one character for any name starting with "R'. This is
  389. // so that Denzil's "reply to last page" code will work...
  390. //
  391. if (typed_len == 1 && (typed_name[0] == L'r' || typed_name[0] == L'R')) {
  392. return ;
  393. }
  394. //
  395. // Find the player's name that most closely matches the typed name
  396. //
  397. for ( SLNode<cPlayer> *player_node = cPlayerManager::Get_Player_Object_List ()->Head ();
  398. player_node != NULL;
  399. player_node = player_node->Next ())
  400. {
  401. cPlayer *player = player_node->Data ();
  402. WWASSERT (player != NULL);
  403. if (player->Get_Is_Active().Is_False()) {
  404. continue;
  405. }
  406. const WCHAR *player_name = player->Get_Name ();
  407. //
  408. // Is this the best match so far?
  409. //
  410. if (::wcsnicmp (player_name, typed_name, typed_len) == 0) {
  411. if ( completed_name.Get_Length () == 0 ||
  412. ::wcsicmp (player_name, completed_name) < 0)
  413. {
  414. completed_name = player_name;
  415. }
  416. }
  417. }
  418. return ;
  419. }
  420. //////////////////////////////////////////////////////////////////////
  421. //
  422. // On_EditCtrl_Enter_Pressed
  423. //
  424. //////////////////////////////////////////////////////////////////////
  425. void
  426. MPChatChildDialogClass::On_EditCtrl_Enter_Pressed (EditCtrlClass *edit_ctrl, int ctrl_id)
  427. {
  428. //
  429. // Send the message
  430. //
  431. Process_Message ();
  432. //
  433. // Close the dialog
  434. //
  435. if (EndDialogOnSend) {
  436. Get_Parent_Dialog ()->End_Dialog ();
  437. }
  438. return ;
  439. }
  440. //////////////////////////////////////////////////////////////////////
  441. //
  442. // On_EditCtrl_Change
  443. //
  444. //////////////////////////////////////////////////////////////////////
  445. void
  446. MPChatChildDialogClass::On_EditCtrl_Change (EditCtrlClass *edit_ctrl, int ctrl_id)
  447. {
  448. if (TestForAutoCompletion == false) {
  449. return ;
  450. }
  451. //
  452. // Examine everything left of the caret
  453. //
  454. int caret_pos = edit_ctrl->Get_Caret_Pos ();
  455. if (caret_pos > 0) {
  456. //
  457. // Get the message
  458. //
  459. WideStringClass message = Get_Dlg_Item_Text (IDC_MESSAGE_EDIT);
  460. if (message.Get_Length () > 0) {
  461. //
  462. // Check to see if we are typing in a command
  463. //
  464. int cmd_start_index = 0;
  465. int cmd_end_index = 0;
  466. if (Find_Current_Command (message, cmd_start_index, cmd_end_index)) {
  467. //
  468. // Fill in the rest of the name for the user
  469. //
  470. Auto_Complete_Name ();
  471. }
  472. }
  473. }
  474. return ;
  475. }
  476. //////////////////////////////////////////////////////////////////////
  477. //
  478. // Find_Current_Command
  479. //
  480. //////////////////////////////////////////////////////////////////////
  481. bool
  482. MPChatChildDialogClass::Find_Current_Command(const WCHAR* message, int& start_index, int& end_index)
  483. {
  484. EditCtrlClass *edit_ctrl = (EditCtrlClass *)Get_Dlg_Item (IDC_MESSAGE_EDIT);
  485. if (edit_ctrl == NULL) {
  486. return false;
  487. }
  488. bool retval = false;
  489. //
  490. // Get the caret position so we can determine where to
  491. // start looking for the command
  492. //
  493. int caret_pos = edit_ctrl->Get_Caret_Pos ();
  494. if (caret_pos > 0) {
  495. //
  496. // Look to see if there is a command designator preceding the caret.
  497. //
  498. const WCHAR *command_start = ::wcsrchr (message, L'/');
  499. if (command_start != NULL) {
  500. start_index = command_start - message;
  501. command_start ++;
  502. //
  503. // Check to ensure there isn't a space between the designator
  504. // and the caret
  505. //
  506. const WCHAR *first_space = ::wcschr (command_start, L' ');
  507. if (first_space == NULL) {
  508. end_index = ::wcslen (message);
  509. retval = true;
  510. } else if (caret_pos <= (first_space - message)) {
  511. end_index = (first_space - message);
  512. retval = true;
  513. }
  514. }
  515. }
  516. return retval;
  517. }
  518. //////////////////////////////////////////////////////////////////////
  519. //
  520. // On_EditCtrl_Key_Down
  521. //
  522. //////////////////////////////////////////////////////////////////////
  523. bool
  524. MPChatChildDialogClass::On_EditCtrl_Key_Down
  525. (
  526. EditCtrlClass * edit_ctrl,
  527. uint32 key_id,
  528. uint32 key_data
  529. )
  530. {
  531. bool retval = false;
  532. TestForAutoCompletion = false;
  533. //
  534. // Examine everything left of the caret
  535. //
  536. int caret_pos = edit_ctrl->Get_Caret_Pos ();
  537. if (caret_pos > 0) {
  538. //
  539. // Get the message
  540. //
  541. WideStringClass message = Get_Dlg_Item_Text (IDC_MESSAGE_EDIT);
  542. if (message.Get_Length () > 0) {
  543. //
  544. // Check to see if we are typing in a command
  545. //
  546. int cmd_start_index = 0;
  547. int cmd_end_index = 0;
  548. if (Find_Current_Command (message, cmd_start_index, cmd_end_index)) {
  549. //
  550. // Special-case the space key
  551. //
  552. if (key_id == VK_SPACE && CurrRecipientName.Get_Length () > 0) {
  553. RecipientName = CurrRecipientName;
  554. //
  555. // Erase the user's name from the string
  556. //
  557. message.Erase (cmd_start_index, cmd_end_index - cmd_start_index);
  558. edit_ctrl->Set_Text (message);
  559. edit_ctrl->Set_Caret_Pos (cmd_start_index);
  560. //
  561. // Update the dialog with the user's name...
  562. //
  563. WideStringClass heading_text(0, true);
  564. heading_text.Format (L"%s:", CurrRecipientName.Peek_Buffer ());
  565. Set_Dlg_Item_Text (IDC_TYPE_STATIC, heading_text);
  566. //
  567. // Eat the spacebar...
  568. //
  569. retval = true;
  570. } else if (key_id != VK_BACK && key_id != VK_DELETE) {
  571. TestForAutoCompletion = true;
  572. }
  573. }
  574. }
  575. }
  576. return retval;
  577. }
  578. ////////////////////////////////////////////////////////////////
  579. //
  580. // On_Command
  581. //
  582. ////////////////////////////////////////////////////////////////
  583. void
  584. MPChatChildDialogClass::On_Command (int ctrl_id, int message_id, DWORD param)
  585. {
  586. switch (ctrl_id)
  587. {
  588. case IDC_SEND:
  589. Process_Message ();
  590. if (EndDialogOnSend) {
  591. Get_Parent_Dialog ()->End_Dialog ();
  592. }
  593. break;
  594. }
  595. ChildDialogClass::On_Command (ctrl_id, message_id, param);
  596. return ;
  597. }
  598. ////////////////////////////////////////////////////////////////
  599. //
  600. // MPIngameChatPopupClass
  601. //
  602. ////////////////////////////////////////////////////////////////
  603. MPIngameChatPopupClass::MPIngameChatPopupClass (void) :
  604. DefaultType (TEXT_MESSAGE_PUBLIC),
  605. ChatModule (NULL),
  606. PopupDialogClass (IDD_MULTIPLAY_INGAME_CHAT)
  607. {
  608. //
  609. // Configure the background renderer
  610. //
  611. StyleMgrClass::Configure_Renderer (&WindowBackgroundRenderer);
  612. WindowBackgroundRenderer.Get_Shader ()->Set_Depth_Compare (ShaderClass::PASS_ALWAYS);
  613. return ;
  614. }
  615. ////////////////////////////////////////////////////////////////
  616. //
  617. // ~MPIngameChatPopupClass
  618. //
  619. ////////////////////////////////////////////////////////////////
  620. MPIngameChatPopupClass::~MPIngameChatPopupClass (void)
  621. {
  622. REF_PTR_RELEASE (ChatModule);
  623. return ;
  624. }
  625. ////////////////////////////////////////////////////////////////
  626. //
  627. // On_Init_Dialog
  628. //
  629. ////////////////////////////////////////////////////////////////
  630. void
  631. MPIngameChatPopupClass::On_Init_Dialog (void)
  632. {
  633. WWASSERT (The_Game () != NULL);
  634. //
  635. // Align the window with the bottom of the screen
  636. //
  637. const RectClass &screen_rect = Render2DClass::Get_Screen_Resolution ();
  638. RectClass window_rect = Get_Rect ();
  639. float height = window_rect.Height ();
  640. window_rect.Bottom = int(screen_rect.Bottom - 40.0F);
  641. window_rect.Top = int(window_rect.Bottom - height);
  642. Set_Rect (window_rect);
  643. //
  644. // Insert the chat module dialog into our window area
  645. //
  646. ChatModule = new MPChatChildDialogClass;
  647. ChatModule->Set_Default_Type (DefaultType);
  648. ChatModule->Start_Dialog ();
  649. Add_Child_Dialog (ChatModule);
  650. ChatModule->Set_Rect (window_rect);
  651. //
  652. // Darken the background behind this window
  653. //
  654. WindowBackgroundRenderer.Add_Quad (window_rect, RGBA_TO_INT32 (0, 0, 0, 200));
  655. WindowBackgroundRenderer.Enable_Texturing (false);
  656. //
  657. // Let the base class process...
  658. //
  659. Set_Background_Darkened (false);
  660. PopupDialogClass::On_Init_Dialog ();
  661. return ;
  662. }
  663. ////////////////////////////////////////////////////////////////
  664. //
  665. // Render
  666. //
  667. ////////////////////////////////////////////////////////////////
  668. void
  669. MPIngameChatPopupClass::Render (void)
  670. {
  671. //
  672. // Render the black backdrop
  673. //
  674. WindowBackgroundRenderer.Render ();
  675. //
  676. // Allow the base class to render
  677. //
  678. PopupDialogClass::Render ();
  679. return ;
  680. }
  681. ////////////////////////////////////////////////////////////////
  682. //
  683. // On_Command
  684. //
  685. ////////////////////////////////////////////////////////////////
  686. void
  687. MPIngameChatPopupClass::On_Command (int ctrl_id, int message_id, DWORD param)
  688. {
  689. /*switch (ctrl_id)
  690. {
  691. case IDOK:
  692. ChatModule->Send_Message ();
  693. End_Dialog ();
  694. break;
  695. }*/
  696. PopupDialogClass::On_Command (ctrl_id, message_id, param);
  697. return ;
  698. }