StockPile.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2016 RWS Inc, All Rights Reserved
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of version 2 of the GNU General Public License as published by
  7. // the Free Software Foundation
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License along
  15. // with this program; if not, write to the Free Software Foundation, Inc.,
  16. // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. //
  18. // Stockpile.cpp
  19. // Project: Nostril (aka Postal)
  20. //
  21. // History:
  22. // 06/03/97 JMI Started.
  23. //
  24. // 06/06/97 JMI Added Add(), Union(), Intersect(), and Copy() functions.
  25. //
  26. // 06/11/97 JMI Added Zero().
  27. //
  28. // 06/12/97 JMI Added weapon values.
  29. //
  30. // 06/14/97 JMI Added m_sKevlarLayers.
  31. //
  32. // 06/15/97 JMI Added m_sBackpack and maximums.
  33. //
  34. // 06/15/97 JMI Added m_sBackpack, maximums, and Truncate().
  35. //
  36. // 07/10/97 JMI Increased maximums on fuel.
  37. //
  38. // 07/14/97 JMI Can now edit fuel via dialog.
  39. //
  40. // 07/15/97 JMI Added Sub().
  41. //
  42. // 07/15/97 JMI Transferred powerup index enums into CStockPile.
  43. // Also, added GetItem(). See proto for details.
  44. //
  45. // 07/16/97 JMI Moved IsEmpty() from powerup to stockpile.
  46. //
  47. // 07/19/97 JMI Added optional child GUI param to UserEdit().
  48. //
  49. // 07/23/97 JMI Added separate launcher for napalm.
  50. // Also, made all functions like Add(), Sub(), etc. use
  51. // iterative technique for accessing members so I don't
  52. // have to keep updating every one to have new members.
  53. //
  54. // 07/30/97 JMI Added DeathWadLauncher.
  55. // Made pstockpile inputs to functions const. This caused
  56. // some silly stupidity in GetItem() calls but I just casted
  57. // it away b/c the stockpile was not being modified.
  58. //
  59. // 08/02/97 JMI Upgraded kevlar maximums from 50 to 32767.
  60. //
  61. // 08/07/97 JMI Added DoubleBarrel.
  62. //
  63. // 08/13/97 JMI Decreased maxes on m_sKevlarLayers to 100 (was 32767).
  64. //
  65. // 08/21/97 JMI Set maximums for hitpoints to 1000.
  66. //
  67. // 08/24/97 JMI Decreased the max carry with backpack on grenades,
  68. // firebombs, missiles, heatseekers, napalms, and mines.
  69. //
  70. // 12/08/97 JMI Added GetWeapon() that takes a CDude::WeaponType enum
  71. // to index into the stockpile.
  72. //
  73. //////////////////////////////////////////////////////////////////////////////
  74. //
  75. // This represents a character's stockpile of weapons and health.
  76. //
  77. //////////////////////////////////////////////////////////////////////////////
  78. //////////////////////////////////////////////////////////////////////////////
  79. // C Headers -- Must be included before RSPiX.h b/c RSPiX utilizes SHMalloc.
  80. //////////////////////////////////////////////////////////////////////////////
  81. ///////////////////////////////////////////////////////////////////////////////
  82. // RSPiX Headers.
  83. ///////////////////////////////////////////////////////////////////////////////
  84. #include "RSPiX.h"
  85. //////////////////////////////////////////////////////////////////////////////
  86. // Postal Headers.
  87. //////////////////////////////////////////////////////////////////////////////
  88. #include "StockPile.h"
  89. #include "game.h"
  90. #include "thing.h"
  91. #include "dude.h" // For GetWeapon().
  92. //////////////////////////////////////////////////////////////////////////////
  93. // Module specific macros.
  94. //////////////////////////////////////////////////////////////////////////////
  95. #define GUI_FILE_NAME "res/editor/EditPile.gui"
  96. // IDs for GUIs.
  97. #define HITPOINTS_GUI_ID 3
  98. #define GRENADES_GUI_ID 4
  99. #define FIREBOMB_GUI_ID 5
  100. #define MISSILE_GUI_ID 6
  101. #define NAPALM_GUI_ID 7
  102. #define BULLETS_GUI_ID 8
  103. #define SHELLS_GUI_ID 9
  104. #define MINES_GUI_ID 10
  105. #define HEATSEEKERS_GUI_ID 11
  106. #define FUEL_GUI_ID 12
  107. #define MACHINEGUN_GUI_ID 20
  108. #define MISSILELAUNCHER_GUI_ID 21
  109. #define SHOTGUN_GUI_ID 22
  110. #define SPRAYCANNON_GUI_ID 23
  111. #define FLAMETHROWER_GUI_ID 24
  112. #define NAPALMLAUNCHER_GUI_ID 25
  113. #define DEATHWADLAUNCHER_GUI_ID 26
  114. #define DOUBLEBARREL_GUI_ID 27
  115. #define ARMOR_GUI_ID 30
  116. #define BACKPACK_GUI_ID 40
  117. #define DEATHWADLAUNCHER_TXT_ID 100
  118. #define DOUBLEBARREL_TXT_ID 101
  119. // Space above, below, to the left, and right of optional
  120. // user's GUI on stockpile's GUI.
  121. #define GUI_SPACING 5
  122. //////////////////////////////////////////////////////////////////////////////
  123. // Module specific typedefs.
  124. //////////////////////////////////////////////////////////////////////////////
  125. //////////////////////////////////////////////////////////////////////////////
  126. // Exported (extern) variables.
  127. //////////////////////////////////////////////////////////////////////////////
  128. //////////////////////////////////////////////////////////////////////////////
  129. // Module specific (static) variables / Instantiate class statics.
  130. //////////////////////////////////////////////////////////////////////////////
  131. CStockPile CStockPile::ms_stockpileMax = // Maximum one can carry
  132. // w/o a backpack.
  133. {
  134. 1000, // m_sHitPoints
  135. 10, // m_sNumGrenades
  136. 10, // m_sNumFireBombs
  137. 5, // m_sNumMissiles
  138. 5, // m_sNumNapalms
  139. 100, // m_sNumBullets
  140. 50, // m_sNumShells
  141. 250, // m_sNumFuel
  142. 5, // m_sNumMines
  143. 5, // m_sNumHeatseekers
  144. 1, // m_sMachineGun
  145. 1, // m_sMissileLauncher
  146. 1, // m_sShotGun
  147. 1, // m_sSprayCannon
  148. 1, // m_sFlameThrower
  149. 1, // m_sNapalmLauncher
  150. 1, // m_sDeathWadLauncher
  151. 1, // m_sDoubleBarrel
  152. 100, // m_sKevlarLayers
  153. 1, // m_sBackpack
  154. };
  155. CStockPile CStockPile::ms_stockpileBackPackMax = // Maximum one can carry
  156. // with a backpack.
  157. {
  158. 1000, // m_sHitPoints
  159. 20, // m_sNumGrenades
  160. 20, // m_sNumFireBombs
  161. 15, // m_sNumMissiles
  162. 15, // m_sNumNapalms
  163. 100, // m_sNumBullets
  164. 100, // m_sNumShells
  165. 500, // m_sNumFuel
  166. 10, // m_sNumMines
  167. 15, // m_sNumHeatseekers
  168. 1, // m_sMachineGun
  169. 1, // m_sMissileLauncher
  170. 1, // m_sShotGun
  171. 1, // m_sSprayCannon
  172. 1, // m_sFlameThrower
  173. 1, // m_sNapalmLauncher
  174. 1, // m_sDeathWadLauncher
  175. 1, // m_sDoubleBarrel
  176. 100, // m_sKevlarLayers
  177. 1, // m_sBackpack
  178. };
  179. short CStockPile::ms_sEnableDeathWad = FALSE; // Enable the death wad
  180. // check box.
  181. short CStockPile::ms_sEnableDoubleBarrel = FALSE; // Enable the double barrel
  182. // check box.
  183. //////////////////////////////////////////////////////////////////////////////
  184. // Module specific (static) protos.
  185. //////////////////////////////////////////////////////////////////////////////
  186. //////////////////////////////////////////////////////////////////////////////
  187. // Functions.
  188. //////////////////////////////////////////////////////////////////////////////
  189. ////////////////////////////////////////////////////////////////////////////////
  190. // Helper inline to get a GUI, set its text to the value, and recompose it.
  191. ////////////////////////////////////////////////////////////////////////////////
  192. inline
  193. void SetText( // Returns nothing.
  194. RGuiItem* pguiRoot, // In: Root GUI.
  195. long lId, // In: ID of GUI to set text.
  196. long lVal) // In: Value to set text to.
  197. {
  198. RGuiItem* pgui = pguiRoot->GetItemFromId(lId);
  199. if (pgui != NULL)
  200. {
  201. pgui->SetText("%ld", lVal);
  202. pgui->Compose();
  203. }
  204. }
  205. ////////////////////////////////////////////////////////////////////////////////
  206. // Helper inline to get a RMultiBtn GUI, and set its state.
  207. ////////////////////////////////////////////////////////////////////////////////
  208. inline
  209. void CheckMultiBtn( // Returns nothing.
  210. RGuiItem* pguiRoot, // In: Root GUI.
  211. long lId, // In: ID of GUI to set text.
  212. short sChecked) // In: 1 to check, 0 to uncheck.
  213. {
  214. short sRes = 0; // Assume nothing;
  215. RMultiBtn* pmb = (RMultiBtn*)pguiRoot->GetItemFromId(lId);
  216. if (pmb != NULL)
  217. {
  218. ASSERT(pmb->m_type == RGuiItem::MultiBtn);
  219. pmb->m_sState = sChecked + 1;
  220. pmb->Compose();
  221. }
  222. }
  223. ////////////////////////////////////////////////////////////////////////////////
  224. // Helper inline to get a RMultiBtn GUI, and return its state.
  225. ////////////////////////////////////////////////////////////////////////////////
  226. inline
  227. short IsMultiBtnChecked( // Returns multibtn's state.
  228. RGuiItem* pguiRoot, // In: Root GUI.
  229. long lId) // In: ID of GUI to set text.
  230. {
  231. short sRes = 0; // Assume nothing;
  232. RMultiBtn* pmb = (RMultiBtn*)pguiRoot->GetItemFromId(lId);
  233. if (pmb != NULL)
  234. {
  235. ASSERT(pmb->m_type == RGuiItem::MultiBtn);
  236. sRes = (pmb->m_sState == 1) ? 0 : 1;
  237. }
  238. return sRes;
  239. }
  240. //////////////////////////////////////////////////////////////////////////////
  241. // Allow user to edit members.
  242. //////////////////////////////////////////////////////////////////////////////
  243. short CStockPile::UserEdit( // Returns 0 on success.
  244. RGuiItem* pguiChild /*= NULL*/) // In: Optional child GUI to be placed at
  245. // botom of Stockpile GUI.
  246. {
  247. short sResult = 0;
  248. RGuiItem* pgui = RGuiItem::LoadInstantiate(FullPathVD(GUI_FILE_NAME));
  249. if (pgui)
  250. {
  251. // If there is a user specified GUI . . .
  252. if (pguiChild)
  253. {
  254. short sChildPosX;
  255. short sChildPosY;
  256. short sOkHeight;
  257. // Get the position of the OK button.
  258. RGuiItem* pguiOk = pgui->GetItemFromId(1);
  259. RGuiItem* pguiCancel = pgui->GetItemFromId(2);
  260. if (pguiOk)
  261. {
  262. sChildPosY = pguiOk->m_sY;
  263. sOkHeight = pguiOk->m_im.m_sHeight;
  264. }
  265. else
  266. {
  267. sChildPosY = pgui->m_im.m_sHeight;
  268. sOkHeight = 0;
  269. }
  270. sChildPosX = GUI_SPACING;
  271. // Expand stockpile's GUI as necessary allowing space between
  272. // stockpile's stuff and user's stuff and the bottom.
  273. short sOldHeight = pgui->m_im.m_sHeight;
  274. short sNewWidth = MAX(short(sChildPosX + pguiChild->m_im.m_sWidth + GUI_SPACING), pgui->m_im.m_sWidth);
  275. short sNewHeight = sChildPosY + pguiChild->m_im.m_sHeight + GUI_SPACING + sOkHeight;
  276. if (pgui->Create( // Returns 0 on success.
  277. pgui->m_sX,
  278. pgui->m_sY,
  279. sNewWidth,
  280. sNewHeight,
  281. pgui->m_im.m_sDepth) == 0)
  282. {
  283. // Parent and move the child GUI.
  284. pguiChild->Move(
  285. pgui->m_im.m_sWidth / 2 - pguiChild->m_im.m_sWidth / 2,
  286. sChildPosY);
  287. pguiChild->SetParent(pgui);
  288. // Reposition OK and Cancel.
  289. RSP_SAFE_GUI_REF_VOID(pguiOk, Move(pguiOk->m_sX, pguiOk->m_sY + (pgui->m_im.m_sHeight - sOldHeight) ) );
  290. RSP_SAFE_GUI_REF_VOID(pguiCancel, Move(pguiCancel->m_sX, pguiCancel->m_sY + (pgui->m_im.m_sHeight - sOldHeight) ) );
  291. }
  292. else
  293. {
  294. TRACE("UserEdit(): Failed to resize Stockpile GUI to accommodate "
  295. "user's GUI.\n");
  296. }
  297. }
  298. SetText(pgui, HITPOINTS_GUI_ID, m_sHitPoints );
  299. SetText(pgui, BULLETS_GUI_ID, m_sNumBullets );
  300. SetText(pgui, GRENADES_GUI_ID, m_sNumGrenades );
  301. SetText(pgui, FIREBOMB_GUI_ID, m_sNumFireBombs );
  302. SetText(pgui, MISSILE_GUI_ID, m_sNumMissiles );
  303. SetText(pgui, NAPALM_GUI_ID, m_sNumNapalms );
  304. SetText(pgui, SHELLS_GUI_ID, m_sNumShells );
  305. SetText(pgui, MINES_GUI_ID, m_sNumMines );
  306. SetText(pgui, HEATSEEKERS_GUI_ID, m_sNumHeatseekers );
  307. SetText(pgui, FUEL_GUI_ID, m_sNumFuel );
  308. SetText(pgui, ARMOR_GUI_ID, m_sKevlarLayers );
  309. CheckMultiBtn(pgui, MACHINEGUN_GUI_ID, m_sMachineGun );
  310. CheckMultiBtn(pgui, MISSILELAUNCHER_GUI_ID, m_sMissileLauncher );
  311. CheckMultiBtn(pgui, SHOTGUN_GUI_ID, m_sShotGun );
  312. CheckMultiBtn(pgui, SPRAYCANNON_GUI_ID, m_sSprayCannon );
  313. CheckMultiBtn(pgui, FLAMETHROWER_GUI_ID, m_sFlameThrower );
  314. CheckMultiBtn(pgui, NAPALMLAUNCHER_GUI_ID, m_sNapalmLauncher );
  315. CheckMultiBtn(pgui, DEATHWADLAUNCHER_GUI_ID, m_sDeathWadLauncher );
  316. CheckMultiBtn(pgui, DOUBLEBARREL_GUI_ID, m_sDoubleBarrel );
  317. // If available . . .
  318. RSP_SAFE_GUI_REF_VOID(pgui->GetItemFromId(DEATHWADLAUNCHER_GUI_ID), SetVisible(ms_sEnableDeathWad) );
  319. RSP_SAFE_GUI_REF_VOID(pgui->GetItemFromId(DEATHWADLAUNCHER_TXT_ID), SetVisible(ms_sEnableDeathWad) );
  320. // If available . . .
  321. RSP_SAFE_GUI_REF_VOID(pgui->GetItemFromId(DOUBLEBARREL_GUI_ID), SetVisible(ms_sEnableDoubleBarrel) );
  322. RSP_SAFE_GUI_REF_VOID(pgui->GetItemFromId(DOUBLEBARREL_TXT_ID), SetVisible(ms_sEnableDoubleBarrel) );
  323. CheckMultiBtn(pgui, BACKPACK_GUI_ID, m_sBackpack );
  324. sResult = CThing::DoGui(pgui);
  325. if (sResult == 1)
  326. {
  327. // Get new values.
  328. m_sHitPoints = pgui->GetVal(HITPOINTS_GUI_ID );
  329. m_sNumBullets = pgui->GetVal(BULLETS_GUI_ID );
  330. m_sNumGrenades = pgui->GetVal(GRENADES_GUI_ID );
  331. m_sNumFireBombs = pgui->GetVal(FIREBOMB_GUI_ID );
  332. m_sNumMissiles = pgui->GetVal(MISSILE_GUI_ID );
  333. m_sNumNapalms = pgui->GetVal(NAPALM_GUI_ID );
  334. m_sNumShells = pgui->GetVal(SHELLS_GUI_ID );
  335. m_sNumMines = pgui->GetVal(MINES_GUI_ID );
  336. m_sNumHeatseekers = pgui->GetVal(HEATSEEKERS_GUI_ID );
  337. m_sNumFuel = pgui->GetVal(FUEL_GUI_ID );
  338. m_sKevlarLayers = pgui->GetVal(ARMOR_GUI_ID );
  339. m_sMachineGun = IsMultiBtnChecked(pgui, MACHINEGUN_GUI_ID );
  340. m_sMissileLauncher = IsMultiBtnChecked(pgui, MISSILELAUNCHER_GUI_ID );
  341. m_sShotGun = IsMultiBtnChecked(pgui, SHOTGUN_GUI_ID );
  342. m_sSprayCannon = IsMultiBtnChecked(pgui, SPRAYCANNON_GUI_ID );
  343. m_sFlameThrower = IsMultiBtnChecked(pgui, FLAMETHROWER_GUI_ID );
  344. m_sNapalmLauncher = IsMultiBtnChecked(pgui, NAPALMLAUNCHER_GUI_ID );
  345. m_sDeathWadLauncher = IsMultiBtnChecked(pgui, DEATHWADLAUNCHER_GUI_ID );
  346. m_sDoubleBarrel = IsMultiBtnChecked(pgui, DOUBLEBARREL_GUI_ID );
  347. m_sBackpack = IsMultiBtnChecked(pgui, BACKPACK_GUI_ID );
  348. // Success.
  349. sResult = 0;
  350. }
  351. // If there is a user specified GUI . . .
  352. if (pguiChild)
  353. {
  354. // Get it outta there before we delete the tree.
  355. pguiChild->SetParent(NULL);
  356. }
  357. delete pgui;
  358. }
  359. return sResult;
  360. }
  361. ///////////////////////////////////////////////////////////////////////////////
  362. // Save stockpile to the specified file.
  363. ///////////////////////////////////////////////////////////////////////////////
  364. short CStockPile::Save( // Returns 0 on success.
  365. RFile* pfile) // In: File to save to.
  366. {
  367. pfile->Write(m_sDoubleBarrel );
  368. pfile->Write(m_sDeathWadLauncher );
  369. pfile->Write(m_sNapalmLauncher );
  370. pfile->Write(m_sBackpack );
  371. pfile->Write(m_sKevlarLayers );
  372. pfile->Write(m_sMachineGun );
  373. pfile->Write(m_sMissileLauncher );
  374. pfile->Write(m_sShotGun );
  375. pfile->Write(m_sSprayCannon );
  376. pfile->Write(m_sFlameThrower );
  377. pfile->Write(m_sHitPoints );
  378. pfile->Write(m_sNumGrenades );
  379. pfile->Write(m_sNumFireBombs );
  380. pfile->Write(m_sNumMissiles );
  381. pfile->Write(m_sNumNapalms );
  382. pfile->Write(m_sNumBullets );
  383. pfile->Write(m_sNumShells );
  384. pfile->Write(m_sNumFuel );
  385. pfile->Write(m_sNumMines );
  386. pfile->Write(m_sNumHeatseekers );
  387. return pfile->Error();
  388. }
  389. ///////////////////////////////////////////////////////////////////////////////
  390. // Load stockpile from the specified file.
  391. ///////////////////////////////////////////////////////////////////////////////
  392. short CStockPile::Load( // Returns 0 on success.
  393. RFile* pfile, // In: File to load from.
  394. ULONG ulVersion) // In: File version to load.
  395. {
  396. // Zero() out first in case file version doesn't support a value.
  397. Zero();
  398. switch (ulVersion)
  399. {
  400. default:
  401. case 41:
  402. pfile->Read(&m_sDoubleBarrel );
  403. case 40:
  404. case 39:
  405. case 38:
  406. case 37:
  407. case 36:
  408. pfile->Read(&m_sDeathWadLauncher );
  409. case 35:
  410. case 34:
  411. case 33:
  412. pfile->Read(&m_sNapalmLauncher );
  413. case 32:
  414. case 31:
  415. case 30:
  416. case 29:
  417. case 28:
  418. case 27:
  419. case 26:
  420. case 25:
  421. case 24:
  422. case 23:
  423. case 22:
  424. pfile->Read(&m_sBackpack );
  425. case 21:
  426. pfile->Read(&m_sKevlarLayers );
  427. case 20:
  428. case 19:
  429. pfile->Read(&m_sMachineGun );
  430. pfile->Read(&m_sMissileLauncher );
  431. pfile->Read(&m_sShotGun );
  432. pfile->Read(&m_sSprayCannon );
  433. pfile->Read(&m_sFlameThrower );
  434. case 18:
  435. case 17:
  436. case 16:
  437. case 15:
  438. case 14:
  439. case 13:
  440. case 12:
  441. case 11:
  442. case 10:
  443. case 9:
  444. case 8:
  445. case 7:
  446. case 6:
  447. case 5:
  448. case 4:
  449. case 3:
  450. case 2:
  451. case 1:
  452. pfile->Read(&m_sHitPoints );
  453. pfile->Read(&m_sNumGrenades );
  454. pfile->Read(&m_sNumFireBombs );
  455. pfile->Read(&m_sNumMissiles );
  456. pfile->Read(&m_sNumNapalms );
  457. pfile->Read(&m_sNumBullets );
  458. pfile->Read(&m_sNumShells );
  459. pfile->Read(&m_sNumFuel );
  460. pfile->Read(&m_sNumMines );
  461. pfile->Read(&m_sNumHeatseekers );
  462. break;
  463. }
  464. return pfile->Error();
  465. }
  466. ///////////////////////////////////////////////////////////////////////////////
  467. // Add another stockpile to this one.
  468. ///////////////////////////////////////////////////////////////////////////////
  469. void CStockPile::Add( // Returns nothing.
  470. const CStockPile* pstockpile) // In: Stockpile to add to this one.
  471. {
  472. short sTypeIndex;
  473. for (sTypeIndex = 0; sTypeIndex < NumStockPileItems; sTypeIndex++)
  474. {
  475. GetItem(sTypeIndex) += ((CStockPile*)pstockpile)->GetItem(sTypeIndex);
  476. }
  477. }
  478. ///////////////////////////////////////////////////////////////////////////////
  479. // Subtract another stockpile from this one.
  480. ///////////////////////////////////////////////////////////////////////////////
  481. void CStockPile::Sub( // Returns nothing.
  482. const CStockPile* pstockpile) // In: Stockpile to sub from this one.
  483. {
  484. short sTypeIndex;
  485. for (sTypeIndex = 0; sTypeIndex < NumStockPileItems; sTypeIndex++)
  486. {
  487. GetItem(sTypeIndex) -= ((CStockPile*)pstockpile)->GetItem(sTypeIndex);
  488. }
  489. }
  490. ///////////////////////////////////////////////////////////////////////////////
  491. // Combine specified stockpile and this stockpile into this one
  492. // using maximum extents from either.
  493. ///////////////////////////////////////////////////////////////////////////////
  494. void CStockPile::Union( // Returns nothing.
  495. const CStockPile* pstockpile) // In: Stockpile to combine into this one.
  496. {
  497. short sTypeIndex;
  498. for (sTypeIndex = 0; sTypeIndex < NumStockPileItems; sTypeIndex++)
  499. {
  500. GetItem(sTypeIndex) = MAX(GetItem(sTypeIndex), ((CStockPile*)pstockpile)->GetItem(sTypeIndex) );
  501. }
  502. }
  503. ///////////////////////////////////////////////////////////////////////////////
  504. // Combine specified stockpile and this stockpile into this one
  505. // using minimum extents from either.
  506. ///////////////////////////////////////////////////////////////////////////////
  507. void CStockPile::Intersect( // Returns nothing.
  508. const CStockPile* pstockpile) // In: Stockpile to combine into this one.
  509. {
  510. short sTypeIndex;
  511. for (sTypeIndex = 0; sTypeIndex < NumStockPileItems; sTypeIndex++)
  512. {
  513. GetItem(sTypeIndex) = MIN(GetItem(sTypeIndex), ((CStockPile*)pstockpile)->GetItem(sTypeIndex) );
  514. }
  515. }
  516. ///////////////////////////////////////////////////////////////////////////////
  517. // Copy the specified stockpile over this one.
  518. ///////////////////////////////////////////////////////////////////////////////
  519. void CStockPile::Copy( // Returns nothing.
  520. const CStockPile* pstockpile) // In: Stockpile to copy from.
  521. {
  522. short sTypeIndex;
  523. for (sTypeIndex = 0; sTypeIndex < NumStockPileItems; sTypeIndex++)
  524. {
  525. GetItem(sTypeIndex) = ((CStockPile*)pstockpile)->GetItem(sTypeIndex);
  526. }
  527. }
  528. ///////////////////////////////////////////////////////////////////////////////
  529. // Zero the stockpile.
  530. ///////////////////////////////////////////////////////////////////////////////
  531. void CStockPile::Zero(void) // Returns nothing.
  532. {
  533. short sTypeIndex;
  534. for (sTypeIndex = 0; sTypeIndex < NumStockPileItems; sTypeIndex++)
  535. {
  536. GetItem(sTypeIndex) = 0;
  537. }
  538. }
  539. ///////////////////////////////////////////////////////////////////////////////
  540. // Truncate based on maximums that can be carried.
  541. // Note that this varies based on m_sBackpack.
  542. ///////////////////////////////////////////////////////////////////////////////
  543. void CStockPile::Truncate(void) // Returns nothing.
  544. {
  545. // If we have a backpack . . .
  546. if (m_sBackpack != 0)
  547. {
  548. Intersect(&ms_stockpileBackPackMax);
  549. }
  550. else
  551. {
  552. Intersect(&ms_stockpileMax);
  553. }
  554. }
  555. ///////////////////////////////////////////////////////////////////////////////
  556. // Index by the StockPileItem you are interested in.
  557. ///////////////////////////////////////////////////////////////////////////////
  558. short& CStockPile::GetItem( // Returns a reference to the indexed item.
  559. short sIndex) // In: The item index.
  560. {
  561. // KEEP THIS SWITCH STATEMENT IN ORDER OF SMALLEST TO LARGEST LEAVING OUT
  562. // NO INTERMEDIATE VALUES.
  563. // This allows the compiler, when optimizing for speed, to make a jump table.
  564. switch (sIndex)
  565. {
  566. case Bullets:
  567. return m_sNumBullets;
  568. case Grenades:
  569. return m_sNumGrenades;
  570. case Cocktails:
  571. return m_sNumFireBombs;
  572. case Rockets:
  573. return m_sNumMissiles;
  574. case Napalm:
  575. return m_sNumNapalms;
  576. case Shells:
  577. return m_sNumShells;
  578. case Fuel:
  579. return m_sNumFuel;
  580. case Mines:
  581. return m_sNumMines;
  582. case Health:
  583. return m_sHitPoints;
  584. case Heatseekers:
  585. return m_sNumHeatseekers;
  586. case MachineGun:
  587. return m_sMachineGun;
  588. case MissileLauncher:
  589. return m_sMissileLauncher;
  590. case ShotGun:
  591. return m_sShotGun;
  592. case SprayCannon:
  593. return m_sSprayCannon;
  594. case FlameThrower:
  595. return m_sFlameThrower;
  596. case NapalmLauncher:
  597. return m_sNapalmLauncher;
  598. case DeathWadLauncher:
  599. return m_sDeathWadLauncher;
  600. case DoubleBarrel:
  601. return m_sDoubleBarrel;
  602. case KevlarVest:
  603. return m_sKevlarLayers;
  604. case Backpack:
  605. return m_sBackpack;
  606. default:
  607. {
  608. TRACE("GetItem(): Unknown type passed.\n");
  609. ASSERT(0);
  610. // This should never happen.
  611. // Try to save the day in release mode.
  612. static short sUnknown;
  613. sUnknown = 0;
  614. return sUnknown;
  615. }
  616. }
  617. }
  618. ///////////////////////////////////////////////////////////////////////////////
  619. // Index by the CDude::WeaponType you are interested in.
  620. ///////////////////////////////////////////////////////////////////////////////
  621. short& CStockPile::GetWeapon( // Returns a reference to the indexed item.
  622. short sIndex) // In: The item index.
  623. {
  624. static short sNoWeapon;
  625. // KEEP THIS SWITCH STATEMENT IN ORDER OF SMALLEST TO LARGEST LEAVING OUT
  626. // NO INTERMEDIATE VALUES.
  627. // This allows the compiler, when optimizing for speed, to make a jump table.
  628. switch (sIndex)
  629. {
  630. case CDude::SemiAutomatic:
  631. return m_sMachineGun;
  632. case CDude::ShotGun:
  633. return m_sShotGun;
  634. case CDude::SprayCannon:
  635. return m_sSprayCannon;
  636. case CDude::Grenade:
  637. sNoWeapon = 0;
  638. return sNoWeapon;
  639. case CDude::Rocket:
  640. return m_sMissileLauncher;
  641. case CDude::Heatseeker:
  642. return m_sMissileLauncher;
  643. case CDude::FireBomb:
  644. sNoWeapon = 0;
  645. return sNoWeapon;
  646. case CDude::Napalm:
  647. return m_sNapalmLauncher;
  648. case CDude::FlameThrower:
  649. return m_sFlameThrower;
  650. case CDude::ProximityMine:
  651. case CDude::TimedMine:
  652. case CDude::RemoteMine:
  653. case CDude::BouncingBettyMine:
  654. sNoWeapon = 0;
  655. return sNoWeapon;
  656. case CDude::DeathWad:
  657. return m_sDeathWadLauncher;
  658. case CDude::DoubleBarrel:
  659. return m_sDoubleBarrel;
  660. default:
  661. {
  662. TRACE("GetWeapon(): Unknown type passed.\n");
  663. ASSERT(0);
  664. // This should never happen.
  665. // Try to save the day in release mode.
  666. sNoWeapon = 0;
  667. return sNoWeapon;
  668. }
  669. }
  670. }
  671. ////////////////////////////////////////////////////////////////////////////////
  672. // Determine if this stockpile is empty.
  673. ////////////////////////////////////////////////////////////////////////////////
  674. bool CStockPile::IsEmpty(void) // Returns true, if the stockpile is
  675. // empty.
  676. {
  677. // Inventory.
  678. short sTypeIndex;
  679. bool bEmpty = true;
  680. for (sTypeIndex = 0; sTypeIndex < NumStockPileItems; sTypeIndex++)
  681. {
  682. if (GetItem(sTypeIndex) > 0)
  683. {
  684. bEmpty = false;
  685. break;
  686. }
  687. }
  688. return bEmpty;
  689. }
  690. ///////////////////////////////////////////////////////////////////////////////
  691. // EOF
  692. ///////////////////////////////////////////////////////////////////////////////