dlgcncpurchasemainmenu.cpp 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015
  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 : Commando *
  23. * *
  24. * $Archive:: /Commando/Code/Commando/dlgcncpurchasemainmenu.cpp $*
  25. * *
  26. * Author:: Patrick Smith *
  27. * *
  28. * $Modtime:: 2/15/02 9:41p $*
  29. * *
  30. * $Revision:: 21 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "dlgcncpurchasemainmenu.h"
  36. #include "dlgcncpurchasemenu.h"
  37. #include "resource.h"
  38. #include "buttonctrl.h"
  39. #include "globalsettings.h"
  40. #include "combat.h"
  41. #include "basecontroller.h"
  42. #include "soldier.h"
  43. #include "playertype.h"
  44. #include "string_ids.h"
  45. #include "vehiclefactorygameobj.h"
  46. #include "soldierfactorygameobj.h"
  47. #include "translatedb.h"
  48. #include "assets.h"
  49. #include "purchasesettings.h"
  50. #include "dlgmpingamechat.h"
  51. #include "gamemode.h"
  52. #include "gameinitmgr.h"
  53. #include "merchandisectrl.h"
  54. #include "teampurchasesettings.h"
  55. #include "vendor.h"
  56. #include "playerdata.h"
  57. #include "dialogmgr.h"
  58. #include "combat.h"
  59. #include "listctrl.h"
  60. #include "messagewindow.h"
  61. #include "weapons.h"
  62. #include "weaponbag.h"
  63. #include "powerup.h"
  64. #include "input.h"
  65. #include "dinput.h"
  66. #include "hud.h"
  67. #include "gamedata.h"
  68. #include "specialbuilds.h"
  69. bool CNCPurchaseMainMenuClass::SecretsEnabled = false;
  70. ////////////////////////////////////////////////////////////////
  71. //
  72. // CNCPurchaseMainMenuClass
  73. //
  74. ////////////////////////////////////////////////////////////////
  75. CNCPurchaseMainMenuClass::CNCPurchaseMainMenuClass (void) :
  76. Team (PurchaseSettingsDefClass::TEAM_GDI),
  77. ChatModule (NULL),
  78. RefreshTimer (0),
  79. MessageLogLength (0),
  80. MenuDialogClass (IDD_CNC_PURCHASE_MAIN_SCREEN)
  81. {
  82. return ;
  83. }
  84. ////////////////////////////////////////////////////////////////
  85. //
  86. // ~CNCPurchaseMainMenuClass
  87. //
  88. ////////////////////////////////////////////////////////////////
  89. CNCPurchaseMainMenuClass::~CNCPurchaseMainMenuClass (void)
  90. {
  91. GameInitMgrClass::Continue_Game ();
  92. REF_PTR_RELEASE (ChatModule);
  93. return ;
  94. }
  95. ////////////////////////////////////////////////////////////////
  96. //
  97. // On_Init_Dialog
  98. //
  99. ////////////////////////////////////////////////////////////////
  100. void
  101. CNCPurchaseMainMenuClass::On_Init_Dialog (void)
  102. {
  103. ButtonCtrlClass *chars_button = (ButtonCtrlClass *)Get_Dlg_Item (IDC_CHARACTERS_BUTTON);
  104. ButtonCtrlClass *vehicles_button = (ButtonCtrlClass *)Get_Dlg_Item (IDC_VEHICLES_BUTTON);
  105. //
  106. // Get the global settings
  107. //
  108. GlobalSettingsDef *settings = GlobalSettingsDef::Get_Global_Settings ();
  109. StringClass chars_texture;
  110. StringClass vehicles_texture;
  111. //
  112. // Determine which textures to use for the buttons
  113. //
  114. if (Team == PurchaseSettingsDefClass::TEAM_GDI) {
  115. ::Strip_Path_From_Filename (chars_texture, settings->Get_Purchase_GDI_Characters_Texture ());
  116. ::Strip_Path_From_Filename (vehicles_texture, settings->Get_Purchase_GDI_Vehicles_Texture ());
  117. } else if (Team == PurchaseSettingsDefClass::TEAM_NOD) {
  118. ::Strip_Path_From_Filename (chars_texture, settings->Get_Purchase_NOD_Characters_Texture ());
  119. ::Strip_Path_From_Filename (vehicles_texture, settings->Get_Purchase_NOD_Vehicles_Texture ());
  120. } else if (Team == PurchaseSettingsDefClass::TEAM_MUTANT_NOD) {
  121. ::Strip_Path_From_Filename (chars_texture, settings->Get_Purchase_NOD_MUT_Characters_Texture ());
  122. ::Strip_Path_From_Filename (vehicles_texture, settings->Get_Purchase_NOD_MUT_Vehicles_Texture ());
  123. } else {
  124. ::Strip_Path_From_Filename (chars_texture, settings->Get_Purchase_GDI_MUT_Characters_Texture ());
  125. ::Strip_Path_From_Filename (vehicles_texture, settings->Get_Purchase_GDI_MUT_Vehicles_Texture ());
  126. }
  127. //
  128. // Configure the bitmap buttons
  129. //
  130. chars_button->Set_Bitmap (chars_texture, NULL);
  131. vehicles_button->Set_Bitmap (vehicles_texture, NULL);
  132. RefreshTimer = 0;
  133. Configure_Purchase_Controls ();
  134. //
  135. // Get the rectangle where the chat UI will exist
  136. //
  137. const RectClass &chat_rect = Get_Dlg_Item (IDC_CHAT_AREA)->Get_Window_Rect ();
  138. //
  139. // Insert the chat module dialog into the bottom portion of our window
  140. //
  141. ChatModule = new MPChatChildDialogClass;
  142. ChatModule->Set_Default_Type (TEXT_MESSAGE_TEAM);
  143. ChatModule->Start_Dialog ();
  144. Add_Child_Dialog (ChatModule);
  145. ChatModule->Set_Rect (chat_rect);
  146. ChatModule->Set_End_Dialog_On_Send (false);
  147. //
  148. // Force the hot-key colors to be white
  149. //
  150. Get_Dlg_Item (IDC_HOTKEY_TEXT_01)->Set_Text_Color (Vector3 (1.0F, 1.0F, 1.0F));
  151. Get_Dlg_Item (IDC_HOTKEY_TEXT_02)->Set_Text_Color (Vector3 (1.0F, 1.0F, 1.0F));
  152. Get_Dlg_Item (IDC_HOTKEY_TEXT_03)->Set_Text_Color (Vector3 (1.0F, 1.0F, 1.0F));
  153. Get_Dlg_Item (IDC_HOTKEY_TEXT_04)->Set_Text_Color (Vector3 (1.0F, 1.0F, 1.0F));
  154. Get_Dlg_Item (IDC_HOTKEY_TEXT_05)->Set_Text_Color (Vector3 (1.0F, 1.0F, 1.0F));
  155. Get_Dlg_Item (IDC_HOTKEY_TEXT_06)->Set_Text_Color (Vector3 (1.0F, 1.0F, 1.0F));
  156. Get_Dlg_Item (IDC_HOTKEY_TEXT_07)->Set_Text_Color (Vector3 (1.0F, 1.0F, 1.0F));
  157. Get_Dlg_Item (IDC_HOTKEY_TEXT_08)->Set_Text_Color (Vector3 (1.0F, 1.0F, 1.0F));
  158. //
  159. // Configure the message log list ctrl
  160. //
  161. ListCtrlClass *list_ctrl = (ListCtrlClass *)Get_Dlg_Item (IDC_LIST_CTRL);
  162. if (list_ctrl != NULL) {
  163. list_ctrl->Add_Column (L"", 1.0F, Vector3 (1, 1, 1));
  164. }
  165. //
  166. // Activate the menu game mode (if necessary)
  167. //
  168. GameModeClass *menu_game_mode = GameModeManager::Find ("Menu");
  169. if (menu_game_mode != NULL && menu_game_mode->Is_Active () == false) {
  170. menu_game_mode->Activate ();
  171. }
  172. MenuDialogClass::On_Init_Dialog ();
  173. //
  174. // Force focus to be on the "characters" button
  175. //
  176. Get_Dlg_Item (IDC_CHARACTERS_BUTTON)->Set_Focus ();
  177. return ;
  178. }
  179. ////////////////////////////////////////////////////////////////
  180. //
  181. // On_Destroy
  182. //
  183. ////////////////////////////////////////////////////////////////
  184. void
  185. CNCPurchaseMainMenuClass::On_Destroy (void)
  186. {
  187. MenuDialogClass::On_Destroy ();
  188. return ;
  189. }
  190. ////////////////////////////////////////////////////////////////
  191. //
  192. // Configure_Purchase_Controls
  193. //
  194. ////////////////////////////////////////////////////////////////
  195. void
  196. CNCPurchaseMainMenuClass::Configure_Purchase_Controls (void)
  197. {
  198. const int CTRL_IDS[4] =
  199. {
  200. IDC_ENLISTED_PURCHASE_01,
  201. IDC_ENLISTED_PURCHASE_02,
  202. IDC_ENLISTED_PURCHASE_03,
  203. IDC_ENLISTED_PURCHASE_04
  204. };
  205. //
  206. // Lookup the purchase settings for this team
  207. //
  208. TeamPurchaseSettingsDefClass *definition = NULL;
  209. definition = TeamPurchaseSettingsDefClass::Get_Definition ((TeamPurchaseSettingsDefClass::TEAM)Team);
  210. for (int index = 0; index < 4; index ++) {
  211. //
  212. // Get the control for this entry
  213. //
  214. MerchandiseCtrlClass *ctrl = (MerchandiseCtrlClass *)Get_Dlg_Item (CTRL_IDS[index]);
  215. if (ctrl != NULL) {
  216. //
  217. // Configure the merchandise settings
  218. //
  219. ctrl->Set_Text (definition->Get_Enlisted_Name (index));
  220. ctrl->Set_Cost (0);
  221. ctrl->Set_Texture (definition->Get_Enlisted_Texture (index));
  222. ctrl->Set_User_Data (index);
  223. }
  224. }
  225. //
  226. // Configure the beacon purchase object
  227. //
  228. MerchandiseCtrlClass *ctrl = (MerchandiseCtrlClass *)Get_Dlg_Item (IDC_BEACON_PURCHASE);
  229. if (ctrl != NULL) {
  230. ctrl->Set_Text (definition->Get_Beacon_Name ());
  231. ctrl->Set_Cost (definition->Get_Beacon_Cost ());
  232. ctrl->Set_Texture (definition->Get_Beacon_Texture ());
  233. }
  234. //
  235. // Configure the supply purchase object
  236. //
  237. ctrl = (MerchandiseCtrlClass *)Get_Dlg_Item (IDC_SUPPLY_PURCHASE);
  238. if (ctrl != NULL) {
  239. ctrl->Set_Text (definition->Get_Supply_Name ());
  240. ctrl->Set_Cost (0);
  241. ctrl->Set_Texture (definition->Get_Supply_Texture ());
  242. }
  243. return ;
  244. }
  245. ////////////////////////////////////////////////////////////////
  246. //
  247. // Render
  248. //
  249. ////////////////////////////////////////////////////////////////
  250. void
  251. CNCPurchaseMainMenuClass::Render (void)
  252. {
  253. MenuDialogClass::Render ();
  254. HUDClass::Damage_Render ();
  255. return ;
  256. }
  257. ////////////////////////////////////////////////////////////////
  258. //
  259. // On_Command
  260. //
  261. ////////////////////////////////////////////////////////////////
  262. void
  263. CNCPurchaseMainMenuClass::On_Command (int ctrl_id, int message_id, DWORD param)
  264. {
  265. if (SecretsEnabled && The_Game()->IsLaddered.Is_True()) {
  266. SecretsEnabled = false;
  267. }
  268. switch (ctrl_id)
  269. {
  270. case IDC_BUY:
  271. Purchase ();
  272. break;
  273. case IDC_CHARACTERS_BUTTON:
  274. #ifdef MULTIPLAYERDEMO
  275. Do_Purchase_Screen (PurchaseSettingsDefClass::TYPE_CLASSES);
  276. #else
  277. if ((SecretsEnabled) && (Input::Is_Button_Down(DIK_LMENU))) {
  278. Do_Purchase_Screen (PurchaseSettingsDefClass::TYPE_SECRET_CLASSES);
  279. } else {
  280. Do_Purchase_Screen (PurchaseSettingsDefClass::TYPE_CLASSES);
  281. }
  282. #endif
  283. break;
  284. case IDC_VEHICLES_BUTTON:
  285. #ifdef MULTIPLAYERDEMO
  286. Do_Purchase_Screen (PurchaseSettingsDefClass::TYPE_VEHICLES);
  287. #else
  288. if ((SecretsEnabled) && (Input::Is_Button_Down(DIK_LMENU))) {
  289. Do_Purchase_Screen (PurchaseSettingsDefClass::TYPE_SECRET_VEHICLES);
  290. } else {
  291. Do_Purchase_Screen (PurchaseSettingsDefClass::TYPE_VEHICLES);
  292. }
  293. #endif
  294. break;
  295. default:
  296. break;
  297. }
  298. MenuDialogClass::On_Command (ctrl_id, message_id, param);
  299. return ;
  300. }
  301. ////////////////////////////////////////////////////////////////
  302. //
  303. // Do_Purchase_Screen
  304. //
  305. ////////////////////////////////////////////////////////////////
  306. void
  307. CNCPurchaseMainMenuClass::Do_Purchase_Screen (PurchaseSettingsDefClass::TYPE type)
  308. {
  309. //
  310. // Lookup the definition based on the type and team
  311. //
  312. PurchaseSettingsDefClass *definition = NULL;
  313. definition = PurchaseSettingsDefClass::Find_Definition (type, Team);
  314. if (definition != NULL) {
  315. //
  316. // Show the purchase dialog
  317. //
  318. CNCPurchaseMenuClass *dialog = new CNCPurchaseMenuClass;
  319. dialog->Set_Definition (definition);
  320. dialog->Set_Type (type);
  321. //
  322. // Let the dialog know what "team" this purchase is for...
  323. //
  324. if (Team == PurchaseSettingsDefClass::TEAM_GDI) {
  325. dialog->Set_Team (PlayerTerminalClass::TYPE_GDI);
  326. } else if (Team == PurchaseSettingsDefClass::TEAM_NOD) {
  327. dialog->Set_Team (PlayerTerminalClass::TYPE_NOD);
  328. } else {
  329. dialog->Set_Team (PlayerTerminalClass::TYPE_MUTANT);
  330. }
  331. //
  332. // Examine the base for this player to decide what purchase options they have
  333. //
  334. BaseControllerClass *base = BaseControllerClass::Find_Base_For_Star ();
  335. if (base != NULL) {
  336. //
  337. // If the base is powered down then all prices double in cost
  338. //
  339. if (base->Is_Base_Powered () == false) {
  340. dialog->Set_Cost_Scaling_Factor (2.0F);
  341. }
  342. //
  343. // If the base can't generate new soldiers, then let the dialog know that
  344. // only "free" items are available
  345. //
  346. if (type == PurchaseSettingsDefClass::TYPE_CLASSES && base->Can_Generate_Soldiers () == false) {
  347. dialog->Enable_Production (false);
  348. }
  349. }
  350. //
  351. // Disable multiple purchases for vehicles and soldiers
  352. //
  353. if ( type == PurchaseSettingsDefClass::TYPE_CLASSES ||
  354. type == PurchaseSettingsDefClass::TYPE_VEHICLES)
  355. {
  356. dialog->Enable_Multiple_Purchases (false);
  357. }
  358. dialog->Start_Dialog ();
  359. REF_PTR_RELEASE (dialog);
  360. //
  361. // Reset any selections on this page
  362. //
  363. Clear_Selections ();
  364. }
  365. return ;
  366. }
  367. ////////////////////////////////////////////////////////////////
  368. //
  369. // Clear_Selections
  370. //
  371. ////////////////////////////////////////////////////////////////
  372. void
  373. CNCPurchaseMainMenuClass::Clear_Selections (void)
  374. {
  375. const int CTRL_IDS[] =
  376. {
  377. IDC_ENLISTED_PURCHASE_01,
  378. IDC_ENLISTED_PURCHASE_02,
  379. IDC_ENLISTED_PURCHASE_03,
  380. IDC_ENLISTED_PURCHASE_04,
  381. IDC_SUPPLY_PURCHASE,
  382. IDC_BEACON_PURCHASE
  383. };
  384. //
  385. // Find out which options are selected for purchase
  386. //
  387. for (int index = 0; index < 6; index ++) {
  388. MerchandiseCtrlClass *ctrl = (MerchandiseCtrlClass *)Get_Dlg_Item (CTRL_IDS[index]);
  389. if (ctrl != NULL && ctrl->Get_Purchase_Count () > 0) {
  390. ctrl->Reset_Purchase_Count ();
  391. }
  392. }
  393. return ;
  394. }
  395. ////////////////////////////////////////////////////////////////
  396. //
  397. // Purchase
  398. //
  399. ////////////////////////////////////////////////////////////////
  400. void
  401. CNCPurchaseMainMenuClass::Purchase (void)
  402. {
  403. const int CTRL_IDS[] =
  404. {
  405. IDC_ENLISTED_PURCHASE_01,
  406. IDC_ENLISTED_PURCHASE_02,
  407. IDC_ENLISTED_PURCHASE_03,
  408. IDC_ENLISTED_PURCHASE_04,
  409. IDC_SUPPLY_PURCHASE,
  410. IDC_BEACON_PURCHASE
  411. };
  412. //
  413. // Lookup the purchase settings for this team
  414. //
  415. TeamPurchaseSettingsDefClass *definition = NULL;
  416. definition = TeamPurchaseSettingsDefClass::Get_Definition ((TeamPurchaseSettingsDefClass::TEAM)Team);
  417. //
  418. // Find out which options are selected for purchase
  419. //
  420. for (int index = 0; index < 6; index ++) {
  421. MerchandiseCtrlClass *ctrl = (MerchandiseCtrlClass *)Get_Dlg_Item (CTRL_IDS[index]);
  422. if (ctrl != NULL && ctrl->Get_Purchase_Count () > 0) {
  423. switch (CTRL_IDS[index])
  424. {
  425. case IDC_ENLISTED_PURCHASE_01:
  426. case IDC_ENLISTED_PURCHASE_02:
  427. case IDC_ENLISTED_PURCHASE_03:
  428. case IDC_ENLISTED_PURCHASE_04:
  429. {
  430. VendorClass::Purchase_Item (COMBAT_STAR, VendorClass::TYPE_ENLISTED_CHARACTER, ctrl->Get_User_Data ());
  431. break;
  432. }
  433. case IDC_SUPPLY_PURCHASE:
  434. VendorClass::Purchase_Item (COMBAT_STAR, VendorClass::TYPE_SUPPLY, 0);
  435. break;
  436. case IDC_BEACON_PURCHASE:
  437. VendorClass::Purchase_Item (COMBAT_STAR, VendorClass::TYPE_BEACON, 0);
  438. break;
  439. }
  440. }
  441. }
  442. //
  443. // Resume play after a purchase
  444. //
  445. End_Dialog ();
  446. return ;
  447. }
  448. ////////////////////////////////////////////////////////////////
  449. //
  450. // On_Merchandise_Selected
  451. //
  452. ////////////////////////////////////////////////////////////////
  453. void
  454. CNCPurchaseMainMenuClass::On_Merchandise_Selected (MerchandiseCtrlClass *ctrl, int ctrl_id)
  455. {
  456. const int CTRL_IDS[] =
  457. {
  458. IDC_ENLISTED_PURCHASE_01,
  459. IDC_ENLISTED_PURCHASE_02,
  460. IDC_ENLISTED_PURCHASE_03,
  461. IDC_ENLISTED_PURCHASE_04
  462. };
  463. //
  464. // Update the counter on the merchandise control
  465. //
  466. if (ctrl != NULL) {
  467. if (ctrl->Get_Purchase_Count () == 0) {
  468. ctrl->Increment_Purchase_Count ();
  469. //
  470. // Check to ensure we don't select more then one of the
  471. // enlisted controls.
  472. //
  473. switch (ctrl_id)
  474. {
  475. case IDC_ENLISTED_PURCHASE_01:
  476. case IDC_ENLISTED_PURCHASE_02:
  477. case IDC_ENLISTED_PURCHASE_03:
  478. case IDC_ENLISTED_PURCHASE_04:
  479. {
  480. //
  481. // Make the enlisted purchases mutually exclusive
  482. //
  483. for (int index = 0; index < 4; index ++) {
  484. MerchandiseCtrlClass *other_ctrl = (MerchandiseCtrlClass *)Get_Dlg_Item (CTRL_IDS[index]);
  485. if (other_ctrl != NULL && other_ctrl != ctrl) {
  486. other_ctrl->Reset_Purchase_Count ();
  487. }
  488. }
  489. break;
  490. }
  491. }
  492. } else {
  493. ctrl->Reset_Purchase_Count ();
  494. }
  495. }
  496. return ;
  497. }
  498. ////////////////////////////////////////////////////////////////
  499. //
  500. // On_Merchandise_DblClk
  501. //
  502. ////////////////////////////////////////////////////////////////
  503. void
  504. CNCPurchaseMainMenuClass::On_Merchandise_DblClk (MerchandiseCtrlClass *ctrl, int ctrl_id)
  505. {
  506. Purchase_Item (ctrl_id);
  507. return ;
  508. }
  509. ////////////////////////////////////////////////////////////////
  510. //
  511. // Purchase_Item
  512. //
  513. ////////////////////////////////////////////////////////////////
  514. void
  515. CNCPurchaseMainMenuClass::Purchase_Item (int ctrl_id)
  516. {
  517. const int CTRL_IDS[] =
  518. {
  519. IDC_ENLISTED_PURCHASE_01,
  520. IDC_ENLISTED_PURCHASE_02,
  521. IDC_ENLISTED_PURCHASE_03,
  522. IDC_ENLISTED_PURCHASE_04,
  523. IDC_SUPPLY_PURCHASE,
  524. IDC_BEACON_PURCHASE
  525. };
  526. //
  527. // Reset all purchase controls
  528. //
  529. for (int index = 0; index < 6; index ++) {
  530. MerchandiseCtrlClass *ctrl = (MerchandiseCtrlClass *)Get_Dlg_Item (CTRL_IDS[index]);
  531. if (ctrl != NULL) {
  532. ctrl->Reset_Purchase_Count ();
  533. }
  534. }
  535. //
  536. // Purchase the item and close the dialog
  537. //
  538. MerchandiseCtrlClass *ctrl = (MerchandiseCtrlClass *)Get_Dlg_Item (ctrl_id);
  539. if (ctrl != NULL) {
  540. ctrl->Increment_Purchase_Count ();
  541. Purchase ();
  542. }
  543. return ;
  544. }
  545. ////////////////////////////////////////////////////////////////
  546. //
  547. // On_Frame_Update
  548. //
  549. ////////////////////////////////////////////////////////////////
  550. void
  551. CNCPurchaseMainMenuClass::On_Frame_Update (void)
  552. {
  553. if (COMBAT_STAR == NULL) {
  554. return ;
  555. }
  556. //
  557. // Update the player's money every frame
  558. // TSS120301 - I'm not sure how player data can be null here but we are crashing
  559. // with that, so let's test against it.
  560. //
  561. if (COMBAT_STAR->Get_Player_Data () != NULL) {
  562. int old_money = Get_Dlg_Item_Int (IDC_CREDITS_TEXT);
  563. int new_money = (int) COMBAT_STAR->Get_Player_Data ()->Get_Money ();
  564. if (new_money != old_money) {
  565. Set_Dlg_Item_Int (IDC_CREDITS_TEXT, new_money);
  566. }
  567. }
  568. //
  569. // Check to see if we should refresh the purchase button states
  570. //
  571. RefreshTimer -= DialogMgrClass::Get_Frame_Time ();
  572. if (RefreshTimer <= 0) {
  573. RefreshTimer = 0.5F;
  574. Refresh_Button_States ();
  575. Refresh_Beacon_State ();
  576. }
  577. //
  578. // Update the message log every frame
  579. //
  580. Refresh_Message_Log ();
  581. MenuDialogClass::On_Frame_Update ();
  582. return ;
  583. }
  584. ////////////////////////////////////////////////////////////////
  585. //
  586. // Refresh_Beacon_State
  587. //
  588. ////////////////////////////////////////////////////////////////
  589. void
  590. CNCPurchaseMainMenuClass::Refresh_Beacon_State (void)
  591. {
  592. if (COMBAT_STAR == NULL) {
  593. return ;
  594. }
  595. //
  596. // Lookup the purchase settings for this team
  597. //
  598. TeamPurchaseSettingsDefClass *definition = NULL;
  599. definition = TeamPurchaseSettingsDefClass::Get_Definition ((TeamPurchaseSettingsDefClass::TEAM)Team);
  600. //
  601. // Get the beacon cost and the player's current cash supply
  602. //
  603. float cost = definition->Get_Beacon_Cost ();
  604. int funds = 0;
  605. if (COMBAT_STAR->Get_Player_Data() != NULL) {
  606. funds = (int) COMBAT_STAR->Get_Player_Data ()->Get_Money ();
  607. }
  608. //
  609. // Enabled or disable the beacon ctrl as necessary
  610. //
  611. if (funds >= cost) {
  612. bool enable = true;
  613. //
  614. // Get the player's weapon bag
  615. //
  616. WeaponBagClass *weapon_bag = COMBAT_STAR->Get_Weapon_Bag ();
  617. if (weapon_bag != NULL) {
  618. //
  619. // Beacons are purchased via a powerup, so lookup the powerup
  620. // that grants the beacon weapon so we can check to ensure
  621. // the player isn't already maxed out.
  622. //
  623. PowerUpGameObjDef *powerup_def = (PowerUpGameObjDef *)DefinitionMgrClass::Find_Definition (definition->Get_Beacon_Definition ());
  624. if (powerup_def != NULL) {
  625. //
  626. // Loop over all the weapons in the bag
  627. //
  628. int beacon_id = powerup_def->Get_Grant_Weapon_ID ();
  629. int weapon_count = weapon_bag->Get_Count ();
  630. for (int index = 0; index < weapon_count; index ++) {
  631. WeaponClass *weapon = weapon_bag->Peek_Weapon (index);
  632. if (weapon != NULL && weapon->Get_ID () == beacon_id) {
  633. //
  634. // Don't allow the player to purchase more beacons then
  635. // they can hold.
  636. //
  637. if (weapon->Is_Ammo_Maxed ()) {
  638. enable = false;
  639. }
  640. break;
  641. }
  642. }
  643. }
  644. }
  645. Get_Dlg_Item (IDC_BEACON_PURCHASE)->Enable (enable);
  646. } else {
  647. Get_Dlg_Item (IDC_BEACON_PURCHASE)->Enable (false);
  648. }
  649. return ;
  650. }
  651. ////////////////////////////////////////////////////////////////
  652. //
  653. // Refresh_Button_States
  654. //
  655. ////////////////////////////////////////////////////////////////
  656. void
  657. CNCPurchaseMainMenuClass::Refresh_Button_States (void)
  658. {
  659. ButtonCtrlClass *chars_button = (ButtonCtrlClass *)Get_Dlg_Item (IDC_CHARACTERS_BUTTON);
  660. ButtonCtrlClass *vehicles_button = (ButtonCtrlClass *)Get_Dlg_Item (IDC_VEHICLES_BUTTON);
  661. //
  662. // Determine whether or not the player can purchase vehicles or characters
  663. //
  664. bool enable_vehicles = true;
  665. bool enable_chars = true;
  666. //
  667. // Check to see if the player can generate vehicles. If not, then disable
  668. // the vehicles button
  669. //
  670. BaseControllerClass *base_controller = BaseControllerClass::Find_Base_For_Star ();
  671. if (base_controller != NULL) {
  672. //
  673. // Try to find the vehicle factory for this level
  674. //
  675. BuildingGameObj *building = base_controller->Find_Building (BuildingConstants::TYPE_VEHICLE_FACTORY);
  676. if (building != NULL && building->As_VehicleFactoryGameObj () != NULL) {
  677. VehicleFactoryGameObj *factory = building->As_VehicleFactoryGameObj ();
  678. //
  679. // Determine if the factory is busy or destroyed
  680. //
  681. if (factory->Is_Busy ()) {
  682. Set_Dlg_Item_Text (IDC_VEHICLES_STATIC, TRANSLATE (IDS_CNC_PURCHASE_VB_BUSY));
  683. enable_vehicles = false;
  684. } else if (factory->Is_Destroyed ()) {
  685. Set_Dlg_Item_Text (IDC_VEHICLES_STATIC, TRANSLATE (IDS_CNC_PURCHASE_VB_DESTROYED));
  686. enable_vehicles = false;
  687. } else {
  688. Set_Dlg_Item_Text (IDC_VEHICLES_STATIC, TRANSLATE (IDS_MENU_VEHICLES));
  689. }
  690. } else {
  691. //
  692. // Let the user know that there is now vehicle factory
  693. //
  694. Set_Dlg_Item_Text (IDC_VEHICLES_STATIC, TRANSLATE (IDS_CNC_PURCHASE_VB_UNAVAILABLE));
  695. enable_vehicles = false;
  696. }
  697. //
  698. // Try to find the vehicle factory for this level
  699. //
  700. building = base_controller->Find_Building (BuildingConstants::TYPE_SOLDIER_FACTORY);
  701. if (building != NULL && building->As_SoldierFactoryGameObj () != NULL) {
  702. SoldierFactoryGameObj *factory = building->As_SoldierFactoryGameObj ();
  703. //
  704. // Determine if the factory is busy or destroyed
  705. //
  706. if (factory->Is_Destroyed ()) {
  707. Set_Dlg_Item_Text (IDC_SOLDIERS_STATIC, TRANSLATE (IDS_CNC_PURCHASE_VB_DESTROYED));
  708. enable_chars = false;
  709. } else {
  710. Set_Dlg_Item_Text (IDC_SOLDIERS_STATIC, TRANSLATE (IDS_MENU_CHARACTERS));
  711. }
  712. } else {
  713. //
  714. // Let the user know that there is no soldier factory
  715. //
  716. Set_Dlg_Item_Text (IDC_SOLDIERS_STATIC, TRANSLATE (IDS_CNC_PURCHASE_VB_UNAVAILABLE));
  717. enable_chars = false;
  718. }
  719. }
  720. //
  721. // Check to see if this team has reached its limit on vehicles.
  722. //
  723. if (enable_vehicles) {
  724. //
  725. // Count team vehicles.
  726. //
  727. BaseControllerClass *base = BaseControllerClass::Find_Base_For_Star ();
  728. if (base != NULL) {
  729. //
  730. // Find the vehicle factory
  731. //
  732. BuildingGameObj *building = base->Find_Building (BuildingConstants::TYPE_VEHICLE_FACTORY);
  733. if ((building != NULL) && (building->As_VehicleFactoryGameObj())) {
  734. //
  735. // See if the team already maxed out the number of vehicles
  736. //
  737. VehicleFactoryGameObj *factory = building->As_VehicleFactoryGameObj ();
  738. if (factory->Get_Team_Vehicle_Count() >= factory->Get_Max_Vehicles_Per_Team()) {
  739. Set_Dlg_Item_Text (IDC_VEHICLES_STATIC, TRANSLATE (IDS_MENU_LIMIT_REACHED));
  740. enable_vehicles = false;
  741. }
  742. }
  743. }
  744. }
  745. //
  746. // Enable or disable the vehicles and characters button
  747. //
  748. chars_button->Enable (enable_chars);
  749. vehicles_button->Enable (enable_vehicles);
  750. Get_Dlg_Item (IDC_SOLDIERS_STATIC)->Enable (enable_chars);
  751. Get_Dlg_Item (IDC_VEHICLES_STATIC)->Enable (enable_vehicles);
  752. Get_Dlg_Item (IDC_HOTKEY_TEXT_06)->Set_Text_Color (enable_chars ? Vector3 (1.0F, 1.0F, 1.0F) : Vector3 (0.5F, 0.5F, 0.5F));
  753. Get_Dlg_Item (IDC_HOTKEY_TEXT_07)->Set_Text_Color (enable_vehicles ? Vector3 (1.0F, 1.0F, 1.0F) : Vector3 (0.5F, 0.5F, 0.5F));
  754. return ;
  755. }
  756. ////////////////////////////////////////////////////////////////
  757. //
  758. // On_Key_Down
  759. //
  760. ////////////////////////////////////////////////////////////////
  761. bool
  762. CNCPurchaseMainMenuClass::On_Key_Down (uint32 key_id, uint32 key_data)
  763. {
  764. bool retval = false;
  765. //
  766. // Don't process hot keys if an edit control has the focus
  767. //
  768. DialogControlClass *focus_ctrl = DialogMgrClass::Get_Focus ();
  769. if (focus_ctrl == NULL || focus_ctrl->As_EditCtrlClass () == NULL) {
  770. //
  771. // Check to see if a hotkey was pressed
  772. //
  773. retval = true;
  774. switch (key_id)
  775. {
  776. case '1':
  777. Purchase_Item (IDC_ENLISTED_PURCHASE_01);
  778. break;
  779. case '2':
  780. Purchase_Item (IDC_ENLISTED_PURCHASE_02);
  781. break;
  782. case '3':
  783. Purchase_Item (IDC_ENLISTED_PURCHASE_03);
  784. break;
  785. case '4':
  786. Purchase_Item (IDC_ENLISTED_PURCHASE_04);
  787. break;
  788. case '5':
  789. Purchase_Item (IDC_SUPPLY_PURCHASE);
  790. break;
  791. case '6':
  792. if (Get_Dlg_Item (IDC_CHARACTERS_BUTTON)->Is_Enabled ()) {
  793. Do_Purchase_Screen (PurchaseSettingsDefClass::TYPE_CLASSES);
  794. }
  795. break;
  796. case '7':
  797. if (Get_Dlg_Item (IDC_VEHICLES_BUTTON)->Is_Enabled ()) {
  798. Do_Purchase_Screen (PurchaseSettingsDefClass::TYPE_VEHICLES);
  799. }
  800. break;
  801. case '8':
  802. if (Get_Dlg_Item (IDC_BEACON_PURCHASE)->Is_Enabled ()) {
  803. Purchase_Item (IDC_BEACON_PURCHASE);
  804. }
  805. break;
  806. default:
  807. retval = false;
  808. break;
  809. }
  810. }
  811. //
  812. // If we didn't process the key, then let the base class handle it
  813. //
  814. if (retval == false) {
  815. retval = MenuDialogClass::On_Key_Down (key_id, key_data);
  816. }
  817. return retval;
  818. }
  819. ////////////////////////////////////////////////////////////////
  820. //
  821. // Refresh_Message_Log
  822. //
  823. ////////////////////////////////////////////////////////////////
  824. void
  825. CNCPurchaseMainMenuClass::Refresh_Message_Log (void)
  826. {
  827. ListCtrlClass *list_ctrl = (ListCtrlClass *)Get_Dlg_Item (IDC_LIST_CTRL);
  828. MessageWindowClass *message_window = CombatManager::Get_Message_Window ();
  829. if (list_ctrl == NULL || message_window == NULL) {
  830. return ;
  831. }
  832. //
  833. // Don't do anything if the log hasn't changed size...
  834. //
  835. int count = message_window->Get_Log_Count ();
  836. if (count != MessageLogLength) {
  837. MessageLogLength = count;
  838. //
  839. // Start fresh
  840. //
  841. list_ctrl->Delete_All_Entries ();
  842. //
  843. // Add all the messages to the log...
  844. //
  845. for (int index = 0; index < count; index ++) {
  846. //
  847. // Get the message to display
  848. //
  849. const WCHAR *message = message_window->Get_Log_Entry (index);
  850. const Vector3 &color = message_window->Get_Log_Color (index);
  851. WideStringClass temp_string (message, true);
  852. int len = temp_string.Get_Length ();
  853. //
  854. // Strip off any unnecessary newlines
  855. //
  856. if (len > 0 && message[len - 1] == L'\n') {
  857. temp_string.Erase (len - 1, 1);
  858. }
  859. //
  860. // Add this message to the log
  861. //
  862. int item_index = list_ctrl->Insert_Entry (index, temp_string);
  863. if (item_index != -1) {
  864. list_ctrl->Set_Entry_Color (item_index, 0, color);
  865. }
  866. }
  867. //
  868. // Scroll to the end of the message log
  869. //.
  870. list_ctrl->Scroll_To_End ();
  871. }
  872. return ;
  873. }