dlgcncpurchasemenu.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856
  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/dlgcncpurchasemenu.cpp $*
  25. * *
  26. * Author:: Patrick Smith *
  27. * *
  28. * $Modtime:: 2/15/02 12:00p $*
  29. * *
  30. * $Revision:: 22 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "dlgcncpurchasemenu.h"
  36. #include "dlgcncpurchasemainmenu.h"
  37. #include "resource.h"
  38. #include "purchasesettings.h"
  39. #include "vendor.h"
  40. #include "merchandisectrl.h"
  41. #include "playerdata.h"
  42. #include "combat.h"
  43. #include "soldier.h"
  44. #include "translatedb.h"
  45. #include "combatchunkid.h"
  46. #include "weaponmanager.h"
  47. #include "powerup.h"
  48. #include "gdcnc.h"
  49. #include "gdskirmish.h"
  50. #include "weapons.h"
  51. #include "vehiclefactorygameobj.h"
  52. #include "string_ids.h"
  53. #include "dlgmessagebox.h"
  54. #include "gameinitmgr.h"
  55. #include "healthbarctrl.h"
  56. #include "imagectrl.h"
  57. #include "hud.h"
  58. #include "mpsettingsmgr.h"
  59. #include "mapmgr.h"
  60. #include "wwphysids.h"
  61. ////////////////////////////////////////////////////////////////
  62. // Local constants
  63. ////////////////////////////////////////////////////////////////
  64. static const int PURCHASE_ITEMS = 10;
  65. static const int PURCHASE_ALTERNATES = 3;
  66. const int ITEM_CTRL_IDS[PURCHASE_ITEMS] =
  67. {
  68. IDC_ITEM_1, IDC_ITEM_2, IDC_ITEM_3, IDC_ITEM_4, IDC_ITEM_5,
  69. IDC_ITEM_6, IDC_ITEM_7, IDC_ITEM_8, IDC_ITEM_9, IDC_ITEM_10
  70. };
  71. const int HOTKEY_CTRL_IDS[PURCHASE_ITEMS] =
  72. {
  73. IDC_HOTKEY_TEXT_01, IDC_HOTKEY_TEXT_02, IDC_HOTKEY_TEXT_03, IDC_HOTKEY_TEXT_04,
  74. IDC_HOTKEY_TEXT_05, IDC_HOTKEY_TEXT_06, IDC_HOTKEY_TEXT_07, IDC_HOTKEY_TEXT_08,
  75. IDC_HOTKEY_TEXT_09, IDC_HOTKEY_TEXT_10
  76. };
  77. ////////////////////////////////////////////////////////////////
  78. //
  79. // CNCPurchaseMenuClass
  80. //
  81. ////////////////////////////////////////////////////////////////
  82. CNCPurchaseMenuClass::CNCPurchaseMenuClass (void) :
  83. TotalCost (0),
  84. IsProductionDisabled (false),
  85. CostScalingFactor (1.0F),
  86. EnableMultiplePurchases (true),
  87. Team (PlayerTerminalClass::TYPE_NONE),
  88. PurchaseType (PurchaseSettingsDefClass::TYPE_CLASSES),
  89. HealthUpdateTimer (0),
  90. EnabledStateUpdateTimer (0),
  91. MenuDialogClass (IDD_CNC_PURCHASE_SCREEN)
  92. {
  93. return ;
  94. }
  95. ////////////////////////////////////////////////////////////////
  96. //
  97. // On_Init_Dialog
  98. //
  99. ////////////////////////////////////////////////////////////////
  100. void
  101. CNCPurchaseMenuClass::On_Init_Dialog (void)
  102. {
  103. MenuDialogClass::On_Init_Dialog ();
  104. WWASSERT(COMBAT_STAR != NULL);
  105. WWASSERT(COMBAT_STAR->Get_Player_Data() != NULL);
  106. //
  107. // Get the player's current money
  108. //
  109. PlayerDataClass *player_data = COMBAT_STAR->Get_Player_Data ();
  110. //
  111. // Force the hot-key colors to be white
  112. //
  113. Get_Dlg_Item (IDC_HOTKEY_TEXT_01)->Set_Text_Color (Vector3 (1.0F, 1.0F, 1.0F));
  114. Get_Dlg_Item (IDC_HOTKEY_TEXT_02)->Set_Text_Color (Vector3 (1.0F, 1.0F, 1.0F));
  115. Get_Dlg_Item (IDC_HOTKEY_TEXT_03)->Set_Text_Color (Vector3 (1.0F, 1.0F, 1.0F));
  116. Get_Dlg_Item (IDC_HOTKEY_TEXT_04)->Set_Text_Color (Vector3 (1.0F, 1.0F, 1.0F));
  117. Get_Dlg_Item (IDC_HOTKEY_TEXT_05)->Set_Text_Color (Vector3 (1.0F, 1.0F, 1.0F));
  118. Get_Dlg_Item (IDC_HOTKEY_TEXT_06)->Set_Text_Color (Vector3 (1.0F, 1.0F, 1.0F));
  119. Get_Dlg_Item (IDC_HOTKEY_TEXT_07)->Set_Text_Color (Vector3 (1.0F, 1.0F, 1.0F));
  120. Get_Dlg_Item (IDC_HOTKEY_TEXT_08)->Set_Text_Color (Vector3 (1.0F, 1.0F, 1.0F));
  121. Get_Dlg_Item (IDC_HOTKEY_TEXT_09)->Set_Text_Color (Vector3 (1.0F, 1.0F, 1.0F));
  122. Get_Dlg_Item (IDC_HOTKEY_TEXT_10)->Set_Text_Color (Vector3 (1.0F, 1.0F, 1.0F));
  123. //
  124. // Initialize the purchase controls
  125. //
  126. for (int index = 0; index < PURCHASE_ITEMS; index ++) {
  127. //
  128. // Get the control for this entry
  129. //
  130. MerchandiseCtrlClass *ctrl = (MerchandiseCtrlClass *)Get_Dlg_Item (ITEM_CTRL_IDS[index]);
  131. if (ctrl != NULL) {
  132. //
  133. // Is this slot available?
  134. //
  135. int definition_id = Definition->Get_Definition (index);
  136. DefinitionClass *definition = DefinitionMgrClass::Find_Definition (definition_id);
  137. if (Is_Definition_OK (definition)) {
  138. //
  139. // Configure the merchandise settings
  140. //
  141. int cost = Definition->Get_Cost (index) * CostScalingFactor;
  142. ctrl->Set_Text (Definition->Get_Name (index));
  143. ctrl->Set_Cost (cost);
  144. ctrl->Set_Texture (Definition->Get_Texture (index));
  145. ctrl->Set_User_Data (index);
  146. //
  147. // Load in the alternate skins (as necessary)
  148. //
  149. if (MPSettingsMgrClass::Are_Alternate_Skins_Unlocked ()) {
  150. for (int alt_index = 0; alt_index < PURCHASE_ALTERNATES; alt_index ++) {
  151. int alt_def_id = Definition->Get_Alt_Definition (index, alt_index);
  152. if (alt_def_id != 0) {
  153. ctrl->Add_Alternate_Texture (Definition->Get_Alt_Texture (index, alt_index));
  154. }
  155. }
  156. }
  157. //
  158. // Disable any options that cost money if production is disabled
  159. //
  160. if ((IsProductionDisabled && (cost > 0)) || (player_data->Get_Money () < cost)) {
  161. ctrl->Enable (false);
  162. }
  163. } else {
  164. //
  165. // Remove and free the control if we aren't going to use it
  166. //
  167. Remove_Control (ctrl);
  168. delete ctrl;
  169. //
  170. // Remove the hotkey control as well
  171. //
  172. DialogControlClass *hotkey_ctrl = Get_Dlg_Item (HOTKEY_CTRL_IDS[index]);
  173. Remove_Control (hotkey_ctrl);
  174. delete hotkey_ctrl;
  175. }
  176. }
  177. }
  178. //
  179. // Initialize the current credits and total cost
  180. //
  181. Set_Dlg_Item_Int (IDC_CREDITS, (int) player_data->Get_Money ());
  182. //
  183. // Setup the images for the building health icons
  184. //
  185. Configure_Building_Icons ();
  186. return ;
  187. }
  188. ////////////////////////////////////////////////////////////////
  189. //
  190. // On_Command
  191. //
  192. ////////////////////////////////////////////////////////////////
  193. void
  194. CNCPurchaseMenuClass::On_Command (int ctrl_id, int message_id, DWORD param)
  195. {
  196. switch (ctrl_id)
  197. {
  198. case IDC_PURCHASE_BUTTON:
  199. Purchase ();
  200. break;
  201. case IDC_CLEAR_BUTTON:
  202. Clear_Shopping_Cart ();
  203. break;
  204. default:
  205. break;
  206. }
  207. MenuDialogClass::On_Command (ctrl_id, message_id, param);
  208. return ;
  209. }
  210. ////////////////////////////////////////////////////////////////
  211. //
  212. // Render
  213. //
  214. ////////////////////////////////////////////////////////////////
  215. void
  216. CNCPurchaseMenuClass::Render (void)
  217. {
  218. MenuDialogClass::Render ();
  219. HUDClass::Damage_Render ();
  220. return ;
  221. }
  222. ////////////////////////////////////////////////////////////////
  223. //
  224. // On_Merchandise_DblClk
  225. //
  226. ////////////////////////////////////////////////////////////////
  227. void
  228. CNCPurchaseMenuClass::On_Merchandise_DblClk (MerchandiseCtrlClass *ctrl, int ctrl_id)
  229. {
  230. Purchase_Item (ctrl_id);
  231. return ;
  232. }
  233. ////////////////////////////////////////////////////////////////
  234. //
  235. // Purchase_Item
  236. //
  237. ////////////////////////////////////////////////////////////////
  238. void
  239. CNCPurchaseMenuClass::Purchase_Item (int ctrl_id)
  240. {
  241. //
  242. // Reset the shopping list to include just this one purchase
  243. //
  244. Clear_Shopping_Cart ();
  245. Add_Item_To_Shopping_Cart (ctrl_id);
  246. //
  247. // Buy the item and return to the game
  248. //
  249. Purchase ();
  250. GameInitMgrClass::Continue_Game ();
  251. return ;
  252. }
  253. ////////////////////////////////////////////////////////////////
  254. //
  255. // On_Merchandise_Selected
  256. //
  257. ////////////////////////////////////////////////////////////////
  258. void
  259. CNCPurchaseMenuClass::On_Merchandise_Selected (MerchandiseCtrlClass *ctrl, int ctrl_id)
  260. {
  261. //
  262. // Reset the shopping list to include just this one purchase
  263. //
  264. Clear_Shopping_Cart ();
  265. Add_Item_To_Shopping_Cart (ctrl_id);
  266. return ;
  267. }
  268. ////////////////////////////////////////////////////////////////
  269. //
  270. // Add_Item_To_Shopping_Cart
  271. //
  272. ////////////////////////////////////////////////////////////////
  273. void
  274. CNCPurchaseMenuClass::Add_Item_To_Shopping_Cart (int ctrl_id)
  275. {
  276. MerchandiseCtrlClass *ctrl = (MerchandiseCtrlClass *)Get_Dlg_Item (ctrl_id);
  277. if (ctrl == NULL) {
  278. return ;
  279. }
  280. int item_index = (int)ctrl->Get_User_Data ();
  281. //
  282. // Can the player afford this item?
  283. //
  284. WWASSERT(COMBAT_STAR != NULL);
  285. WWASSERT(COMBAT_STAR->Get_Player_Data() != NULL);
  286. int funds = (int) COMBAT_STAR->Get_Player_Data ()->Get_Money ();
  287. int cost = Definition->Get_Cost (item_index) * CostScalingFactor;
  288. if ((TotalCost + cost) <= funds) {
  289. //
  290. // Add this cost into our grand total
  291. //
  292. TotalCost += cost;
  293. //
  294. // Add this to item to our list
  295. //
  296. ShoppingList.Add (ctrl_id);
  297. //
  298. // Update the UI
  299. //
  300. Set_Dlg_Item_Int (IDC_CREDITS, funds - TotalCost);
  301. //
  302. // Update the counter on the merchandise control
  303. //
  304. MerchandiseCtrlClass *ctrl = (MerchandiseCtrlClass *)Get_Dlg_Item (ITEM_CTRL_IDS[item_index]);
  305. if (ctrl != NULL) {
  306. ctrl->Increment_Purchase_Count ();
  307. }
  308. }
  309. return ;
  310. }
  311. ////////////////////////////////////////////////////////////////
  312. //
  313. // Clear_Shopping_Cart
  314. //
  315. ////////////////////////////////////////////////////////////////
  316. void
  317. CNCPurchaseMenuClass::Clear_Shopping_Cart (void)
  318. {
  319. //
  320. // Reset our data
  321. //
  322. TotalCost = 0;
  323. WWASSERT(COMBAT_STAR != NULL);
  324. WWASSERT(COMBAT_STAR->Get_Player_Data() != NULL);
  325. int funds = (int) COMBAT_STAR->Get_Player_Data ()->Get_Money ();
  326. ShoppingList.Delete_All ();
  327. //
  328. // Update the UI
  329. //
  330. Set_Dlg_Item_Int (IDC_CREDITS, funds);
  331. //
  332. // Reset the purchase counts
  333. //
  334. for (int index = 0; index < PURCHASE_ITEMS; index ++) {
  335. //
  336. // Get the control for this entry
  337. //
  338. MerchandiseCtrlClass *ctrl = (MerchandiseCtrlClass *)Get_Dlg_Item (ITEM_CTRL_IDS[index]);
  339. if (ctrl != NULL) {
  340. ctrl->Reset_Purchase_Count ();
  341. }
  342. }
  343. return ;
  344. }
  345. ////////////////////////////////////////////////////////////////
  346. //
  347. // Purchase
  348. //
  349. ////////////////////////////////////////////////////////////////
  350. void
  351. CNCPurchaseMenuClass::Purchase (void)
  352. {
  353. bool allow_purchase = true;
  354. VendorClass::PURCHASE_TYPE vendor_purchase_type = VendorClass::TYPE_CHARACTER;
  355. switch (PurchaseType)
  356. {
  357. case PurchaseSettingsDefClass::TYPE_CLASSES:
  358. vendor_purchase_type = VendorClass::TYPE_CHARACTER;
  359. allow_purchase = true;
  360. break;
  361. case PurchaseSettingsDefClass::TYPE_SECRET_CLASSES:
  362. vendor_purchase_type = VendorClass::TYPE_SECRET_CHARACTER;
  363. allow_purchase = true;
  364. break;
  365. case PurchaseSettingsDefClass::TYPE_VEHICLES:
  366. allow_purchase = Verify_Vehicle_Purchase();
  367. vendor_purchase_type = VendorClass::TYPE_VEHICLE;
  368. break;
  369. case PurchaseSettingsDefClass::TYPE_SECRET_VEHICLES:
  370. allow_purchase = Verify_Vehicle_Purchase();
  371. vendor_purchase_type = VendorClass::TYPE_SECRET_VEHICLE;
  372. break;
  373. };
  374. //
  375. // Puchase each item
  376. //
  377. if (allow_purchase) {
  378. for (int index = 0; index < ShoppingList.Count (); index ++) {
  379. WWASSERT (COMBAT_STAR != NULL);
  380. //
  381. // Lookup the merchandise control we'll be purchasing
  382. //
  383. MerchandiseCtrlClass *ctrl = (MerchandiseCtrlClass *)Get_Dlg_Item (ShoppingList[index]);
  384. if (ctrl != NULL) {
  385. int item_index = (int)ctrl->Get_User_Data ();
  386. int alt_index = ctrl->Get_Selected_Alternate ();
  387. VendorClass::Purchase_Item (COMBAT_STAR, vendor_purchase_type, item_index, alt_index);
  388. }
  389. }
  390. }
  391. //
  392. // Close the dialog
  393. //
  394. End_Dialog ();
  395. return ;
  396. }
  397. ////////////////////////////////////////////////////////////////
  398. //
  399. // Verify_Vehicle_Purchase
  400. // Checks whether the vehicle factory is available and able
  401. // to build. Pops up dialogs if anything goes wrong.
  402. //
  403. ////////////////////////////////////////////////////////////////
  404. bool
  405. CNCPurchaseMenuClass::Verify_Vehicle_Purchase (void)
  406. {
  407. bool allow_purchase = true;
  408. //
  409. // Find the base for this user
  410. //
  411. BaseControllerClass *base = BaseControllerClass::Find_Base_For_Star ();
  412. if (base != NULL) {
  413. //
  414. // Find the vehicle factory
  415. //
  416. BuildingGameObj *building = base->Find_Building (BuildingConstants::TYPE_VEHICLE_FACTORY);
  417. if (building != NULL && building->As_VehicleFactoryGameObj () != NULL) {
  418. VehicleFactoryGameObj *factory = building->As_VehicleFactoryGameObj ();
  419. //
  420. // Determine if the factory is busy or destroyed
  421. //
  422. if (factory->Is_Busy ()) {
  423. DlgMsgBox::DoDialog (IDS_CNC_CANT_PURCHASE_TITLE, IDS_CNC_VEHICLE_FACTORY_BUSY_MSG, DlgMsgBox::Okay, NULL, 0);
  424. allow_purchase = false;
  425. } else if (factory->Is_Destroyed ()) {
  426. DlgMsgBox::DoDialog (IDS_CNC_CANT_PURCHASE_TITLE, IDS_CNC_VEHICLE_FACTORY_DESTROYED_MSG, DlgMsgBox::Okay, NULL, 0);
  427. allow_purchase = false;
  428. } else if (factory->Get_Team_Vehicle_Count() >= factory->Get_Max_Vehicles_Per_Team()) {
  429. DlgMsgBox::DoDialog (IDS_CNC_CANT_PURCHASE_TITLE, IDS_CNC_VEHICLE_FACTORY_LIMIT_REACHED, DlgMsgBox::Okay, NULL, 0);
  430. allow_purchase = false;
  431. }
  432. }
  433. }
  434. return allow_purchase;
  435. }
  436. ////////////////////////////////////////////////////////////////
  437. //
  438. // Is_Definition_OK
  439. //
  440. ////////////////////////////////////////////////////////////////
  441. bool
  442. CNCPurchaseMenuClass::Is_Definition_OK (DefinitionClass *definition)
  443. {
  444. bool retval = false;
  445. if (definition != NULL) {
  446. retval = true;
  447. //
  448. // Are we purchasing equipment?
  449. //
  450. if (PurchaseType == PurchaseSettingsDefClass::TYPE_EQUIPMENT) {
  451. int weapon_id = ((PowerUpGameObjDef *)definition)->Get_Grant_Weapon_ID ();
  452. //
  453. // Is this a weapon we're purchasing?
  454. //
  455. DefinitionClass *weapon_def = DefinitionMgrClass::Find_Definition (weapon_id);
  456. if (weapon_def != NULL && weapon_def->Get_Class_ID () == CLASSID_DEF_WEAPON) {
  457. //
  458. // Is this a beacon?
  459. //
  460. if (((WeaponDefinitionClass *)weapon_def)->Style == WEAPON_HOLD_STYLE_BEACON) {
  461. //
  462. // Is this CnC mode?
  463. //
  464. /*
  465. if (The_Game () != NULL && The_Game ()->As_Cnc () != NULL) {
  466. cGameDataCnc *game_data = The_Game ()->As_Cnc ();
  467. //
  468. // Don't allow the player to purchase beacons unless the
  469. // server settings allow it.
  470. //
  471. if ( game_data->BaseDestructionEndsGame.Is_False () ||
  472. game_data->BeaconPlacementEndsGame.Is_False ())
  473. {
  474. retval = false;
  475. }
  476. }
  477. */
  478. if (The_Game () != NULL) {
  479. //
  480. // Don't allow the player to purchase beacons unless the
  481. // server settings allow it.
  482. //
  483. cGameDataCnc * game_cnc = The_Game ()->As_Cnc ();
  484. if ( game_cnc != NULL &&
  485. (game_cnc->BaseDestructionEndsGame.Is_False () ||
  486. game_cnc->BeaconPlacementEndsGame.Is_False ()))
  487. {
  488. retval = false;
  489. }
  490. cGameDataSkirmish * game_skirmish = The_Game ()->As_Skirmish ();
  491. if ( game_skirmish != NULL &&
  492. (game_skirmish->BaseDestructionEndsGame.Is_False () ||
  493. game_skirmish->BeaconPlacementEndsGame.Is_False ()))
  494. {
  495. retval = false;
  496. }
  497. }
  498. }
  499. }
  500. } else if ( PurchaseType == PurchaseSettingsDefClass::TYPE_VEHICLES ||
  501. PurchaseType == PurchaseSettingsDefClass::TYPE_SECRET_VEHICLES)
  502. {
  503. //
  504. // Lookup the physics object to determine if its valid to purchase
  505. // this type of object on this map
  506. //
  507. int phys_def_id = ((PhysicalGameObjDef *)definition)->Get_Phys_Def_ID ();
  508. PhysDefClass *phys_def = (PhysDefClass *)DefinitionMgrClass::Find_Definition (phys_def_id);
  509. if (phys_def != NULL) {
  510. //
  511. // Don't allow flying vehicles on maps that aren't geared towards
  512. // flying vehicles...
  513. //
  514. if ( MapMgrClass::Are_VTOL_Vehicles_Enabled () == false &&
  515. phys_def->Get_Class_ID () == CLASSID_VTOLVEHICLEDEF)
  516. {
  517. retval = false;
  518. }
  519. }
  520. }
  521. }
  522. return retval;
  523. }
  524. ////////////////////////////////////////////////////////////////
  525. //
  526. // On_Frame_Update
  527. //
  528. ////////////////////////////////////////////////////////////////
  529. void
  530. CNCPurchaseMenuClass::On_Frame_Update (void)
  531. {
  532. if (COMBAT_STAR == NULL) {
  533. return ;
  534. }
  535. WWASSERT(COMBAT_STAR != NULL);
  536. WWASSERT(COMBAT_STAR->Get_Player_Data() != NULL);
  537. //
  538. // Update the player's money every frame
  539. //
  540. int old_money = Get_Dlg_Item_Int (IDC_CREDITS);
  541. int new_money = (int) COMBAT_STAR->Get_Player_Data ()->Get_Money ();
  542. if (new_money != old_money) {
  543. Set_Dlg_Item_Int (IDC_CREDITS, new_money);
  544. }
  545. //
  546. // Update each building's health once per second
  547. //
  548. HealthUpdateTimer -= TimeManager::Get_Frame_Seconds ();
  549. if (HealthUpdateTimer <= 0) {
  550. HealthUpdateTimer = 1.0F;
  551. Update_Building_Health ();
  552. }
  553. //
  554. // Update the enabled state of each purchase control every half second
  555. //
  556. EnabledStateUpdateTimer -= TimeManager::Get_Frame_Seconds ();
  557. if (EnabledStateUpdateTimer <= 0) {
  558. EnabledStateUpdateTimer = 0.5F;
  559. Update_Enabled_Status ();
  560. }
  561. MenuDialogClass::On_Frame_Update ();
  562. return ;
  563. }
  564. ////////////////////////////////////////////////////////////////
  565. //
  566. // On_Key_Down
  567. //
  568. ////////////////////////////////////////////////////////////////
  569. bool
  570. CNCPurchaseMenuClass::On_Key_Down (uint32 key_id, uint32 key_data)
  571. {
  572. bool retval = true;
  573. //
  574. // Check to see if a hotkey was pressed
  575. //
  576. switch (key_id)
  577. {
  578. case '1':
  579. case '2':
  580. case '3':
  581. case '4':
  582. case '5':
  583. case '6':
  584. case '7':
  585. case '8':
  586. case '9':
  587. Purchase_Item (int(ITEM_CTRL_IDS[key_id - '1']));
  588. break;
  589. case '0':
  590. Purchase_Item (IDC_ITEM_10);
  591. break;
  592. default:
  593. retval = false;
  594. break;
  595. }
  596. //
  597. // If we didn't process the key, then let the base class handle it
  598. //
  599. if (retval == false) {
  600. retval = MenuDialogClass::On_Key_Down (key_id, key_data);
  601. }
  602. return retval;
  603. }
  604. ////////////////////////////////////////////////////////////////
  605. //
  606. // Update_Building_Health
  607. //
  608. ////////////////////////////////////////////////////////////////
  609. void
  610. CNCPurchaseMenuClass::Update_Building_Health (void)
  611. {
  612. BaseControllerClass *base = BaseControllerClass::Find_Base_For_Star ();
  613. if (base == NULL) {
  614. return ;
  615. }
  616. //
  617. // Find the building for the requested factory
  618. //
  619. BuildingGameObj *building = NULL;
  620. if (PurchaseType == PurchaseSettingsDefClass::TYPE_CLASSES) {
  621. building = base->Find_Building (BuildingConstants::TYPE_SOLDIER_FACTORY);
  622. } else if (PurchaseType == PurchaseSettingsDefClass::TYPE_VEHICLES) {
  623. building = base->Find_Building (BuildingConstants::TYPE_VEHICLE_FACTORY);
  624. }
  625. //
  626. // Update the factory
  627. //
  628. if (building != NULL) {
  629. float life = building->Get_Defense_Object ()->Get_Health () / building->Get_Defense_Object ()->Get_Health_Max ();
  630. ((HealthBarCtrlClass *)Get_Dlg_Item (IDC_BUILDING01_HEALTHBAR))->Set_Life (life);
  631. }
  632. //
  633. // Update the poweruplant
  634. //
  635. building = base->Find_Building (BuildingConstants::TYPE_POWER_PLANT);
  636. if (building != NULL) {
  637. float life = building->Get_Defense_Object ()->Get_Health () / building->Get_Defense_Object ()->Get_Health_Max ();
  638. ((HealthBarCtrlClass *)Get_Dlg_Item (IDC_BUILDING02_HEALTHBAR))->Set_Life (life);
  639. //
  640. // Show the cost doubled text
  641. //
  642. if (life <= 0) {
  643. Get_Dlg_Item (IDC_COST_X2_TEXT)->Show (true);
  644. }
  645. }
  646. return ;
  647. }
  648. ////////////////////////////////////////////////////////////////
  649. //
  650. // Configure_Building_Icons
  651. //
  652. ////////////////////////////////////////////////////////////////
  653. void
  654. CNCPurchaseMenuClass::Configure_Building_Icons (void)
  655. {
  656. StringClass fact_icon_name;
  657. StringClass pplant_icon_name ("HUD_C&C_G_POWER.TGA");
  658. if (Team == PlayerTerminalClass::TYPE_NOD) {
  659. pplant_icon_name = "HUD_C&C_N_POWER.TGA";
  660. //
  661. // Determine which building icon to use...
  662. //
  663. if (PurchaseType == PurchaseSettingsDefClass::TYPE_CLASSES) {
  664. fact_icon_name = "HUD_C&C_N_HANDOF.TGA";
  665. } else if (PurchaseType == PurchaseSettingsDefClass::TYPE_VEHICLES) {
  666. fact_icon_name = "HUD_C&C_N_AIRSTRIP.TGA";
  667. }
  668. } else {
  669. //
  670. // Determine which building icon to use...
  671. //
  672. if (PurchaseType == PurchaseSettingsDefClass::TYPE_CLASSES) {
  673. fact_icon_name = "HUD_C&C_G_BARRACKS.TGA";
  674. } else if (PurchaseType == PurchaseSettingsDefClass::TYPE_VEHICLES) {
  675. fact_icon_name = "HUD_C&C_G_WARFACT.TGA";
  676. }
  677. }
  678. //
  679. // Assign immages to the building icons
  680. //
  681. ((ImageCtrlClass *)Get_Dlg_Item (IDC_BUILDING01_ICON))->Set_Texture (fact_icon_name);
  682. ((ImageCtrlClass *)Get_Dlg_Item (IDC_BUILDING02_ICON))->Set_Texture (pplant_icon_name);
  683. //
  684. // Hide the cost doubled text
  685. //
  686. Get_Dlg_Item (IDC_COST_X2_TEXT)->Show (false);
  687. Update_Building_Health ();
  688. return ;
  689. }
  690. ////////////////////////////////////////////////////////////////
  691. //
  692. // Update_Enabled_Status
  693. //
  694. ////////////////////////////////////////////////////////////////
  695. void
  696. CNCPurchaseMenuClass::Update_Enabled_Status (void)
  697. {
  698. if (COMBAT_STAR == NULL || COMBAT_STAR->Get_Player_Data () == NULL) {
  699. return ;
  700. }
  701. PlayerDataClass *player_data = COMBAT_STAR->Get_Player_Data ();
  702. //
  703. // Initialize the purchase controls
  704. //
  705. for (int index = 0; index < PURCHASE_ITEMS; index ++) {
  706. //
  707. // Get the control for this entry
  708. //
  709. MerchandiseCtrlClass *ctrl = (MerchandiseCtrlClass *)Get_Dlg_Item (ITEM_CTRL_IDS[index]);
  710. if (ctrl != NULL) {
  711. //
  712. // Is this slot available?
  713. //
  714. int definition_id = Definition->Get_Definition (index);
  715. DefinitionClass *definition = DefinitionMgrClass::Find_Definition (definition_id);
  716. if (definition != NULL) {
  717. //
  718. // Configure the merchandise settings
  719. //
  720. int cost = Definition->Get_Cost (index) * CostScalingFactor;
  721. //
  722. // Disable any options that cost money if production is disabled
  723. //
  724. if ((IsProductionDisabled && (cost > 0)) || (player_data->Get_Money () < cost)) {
  725. ctrl->Enable (false);
  726. } else {
  727. ctrl->Enable (true);
  728. }
  729. }
  730. }
  731. }
  732. return ;
  733. }