PowerUp.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778
  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. // PowerUp.cpp
  19. // Project: Nostril (aka Postal)
  20. //
  21. // History:
  22. // 05/08/97 JMI Started.
  23. //
  24. // 05/09/97 JMI Added m_smash and Init().
  25. //
  26. // 05/14/97 JMI Added Grab() and Drop().
  27. // Also, Update() will not update collision sphere unless
  28. // there's no parent.
  29. // Also, increased COLLISION_RADIUS from 5 to 10.
  30. //
  31. // 05/29/97 JMI Removed ASSERT on m_pRealm->m_pAttribMap which no longer
  32. // exists.
  33. //
  34. // 06/06/97 JMI Now hotspot is bottom center of image (was center of
  35. // image).
  36. // Increased COLLISION_RADIUS to 20 (was 10).
  37. // Got rid of the whole type thing. Now uses a CStockPile
  38. // and can contain any combination of powerups w/i one
  39. // instance. Types are still used for loading old powerup
  40. // files.
  41. // Now EditModify() simply invokes m_stockpile.UserEdit().
  42. //
  43. // 06/09/97 JMI Changed RES_NAME from "2d/box.bmp" to "2d/box.img".
  44. //
  45. // 06/10/97 JMI Changed "First Aid Kit" to "Health".
  46. //
  47. // 06/12/97 JMI Added support for new weapon members of CStockPile.
  48. //
  49. // 06/12/97 JMI Added sHitPointMax parameter to GetDescription().
  50. //
  51. // 06/12/97 JMI Drop was not checking that we had a parent before trying
  52. // to call RemoveChild() in the parent.
  53. //
  54. // 06/13/97 JMI Moved priority spot to center of image vertically.
  55. //
  56. // 06/14/97 JMI Decreased COLLISION_RADIUS to 10 (was 20).
  57. //
  58. // 06/14/97 JMI Changed to a descendant of CItem3d instead of CThing.
  59. // Removed 2D bullshit.
  60. //
  61. // 06/14/97 JMI Changed SCALE from 3.0 to 2.0. Note that once Randy
  62. // makes larger powerup specific animations, this should be
  63. // changed to 1.0.
  64. // Seems that the BoundingSphereToScreen() function does not
  65. // take scaling into account.
  66. //
  67. // 06/14/97 JMI Added KevlarVest (CStockPile::m_sArmorLayers).
  68. //
  69. // 06/15/97 JMI Added Backpack (CStockPile::m_sBackpack).
  70. // Now returns to normal spinning after blown up state is
  71. // complete.
  72. //
  73. // 06/15/97 JMI Reduced SCALE to 1.0 (was 2.0) and added some of the
  74. // real powerup filenames.
  75. //
  76. // 06/16/97 JMI Added more real powerup names.
  77. //
  78. // JMI Added a user (audible) feedback function, PickUpFeedback().
  79. //
  80. // 06/17/97 JMI Changed the 'no items' and 'multiple items' anim to
  81. // the mine crate.
  82. //
  83. // 06/25/97 JMI Now calls PrepareShadow() in Init() which loads and sets up
  84. // a shadow sprite.
  85. //
  86. // 06/30/97 BRH Caches the sample it uses in the Load function so that
  87. // the sound effect will be ready in any level that the
  88. // powerups are in.
  89. //
  90. // 07/15/97 JMI Made GetDescription() and TypeToStockPile() static and
  91. // added stockpiles as parms so they can be used more
  92. // generically.
  93. // Also, added RepaginateNow().
  94. // Also, added IsEmpty().
  95. //
  96. // 07/15/97 JMI Added some message handling functions.
  97. // Transferred powerup index enums into CStockPile.
  98. // Now boxes of multiple powerups explode into many when
  99. // blown up.
  100. //
  101. // 07/16/97 JMI Now Setup() automatically calls Startup().
  102. // Moved IsEmpty() from powerup to stockpile.
  103. //
  104. // 07/18/97 JMI Got rid of bogus immitation PlaySample functions.
  105. // Now there is one PlaySample() function. Also, you now
  106. // MUST specify a category and you don't have to specify a
  107. // SoundInstance ptr to specify a volume.
  108. //
  109. // 07/23/97 JMI Added separate launcher for napalm and icons for napalm
  110. // launcher, flame thrower, and fuel.
  111. //
  112. // 07/28/97 JMI Changed "nplmlauncher" to "napalmer" for res name.
  113. //
  114. // 07/30/97 JMI Added DeathWadLauncher to array of powerup names and
  115. // res names.
  116. //
  117. // 08/07/97 JMI Added DoubleBarrel to array of powerup names and res
  118. // names.
  119. //
  120. // 08/07/97 JMI Added additional parameter to CAnim3D::Get() call.
  121. //
  122. // 08/07/97 JMI Changed backpack resname from "3d/backpack" to
  123. // "3d/backpackicon".
  124. //
  125. // 08/17/97 JMI Got rid of m_szMessages and all message related functions
  126. // and variables from CDude since we are now using the toolbar
  127. // for dude status feedback to the user. This includes:
  128. // MsgTypeInfo, m_lNextStatusUpdateTime, m_lMsgUpdateDoneTime,
  129. // m_print, m_bClearedStatus, m_szMessages[], m_sDeadMsgNum,
  130. // ms_amtfMessages[], ms_u8FontForeIndex, ms_u8FontBackIndex,
  131. // ms_u8FontShadowIndex, DrawStatus(), StatusChange(),
  132. // MessageChange(), Message(), UpdateFontColors(),
  133. // CPowerUp::ms_apszPowerUpTypeNames[],
  134. // CPowerUp::GetDescription(), and some strings and a string
  135. // array in localize.*.
  136. //
  137. // 08/28/97 BRH Added a Preload function for the powerups since they
  138. // may pop up during gameplay, we want to have their assets
  139. // ready.
  140. //
  141. //////////////////////////////////////////////////////////////////////////////
  142. //
  143. // This CItem3d-derived class will represent power ups that the player can
  144. // pick up.
  145. //
  146. //////////////////////////////////////////////////////////////////////////////
  147. #define POWERUP_CPP
  148. #include "RSPiX.h"
  149. #include <math.h>
  150. #include "PowerUp.h"
  151. #include "dude.h"
  152. #include "game.h"
  153. ////////////////////////////////////////////////////////////////////////////////
  154. // Macros/types/etc.
  155. ////////////////////////////////////////////////////////////////////////////////
  156. #define GUI_FILE_NAME "res/editor/PowerUp.gui"
  157. #define GUI_ID_STOCKPILE 3
  158. #define Y_AXIS_ROTATION_RATE 240.0
  159. #define SCALE 1.0
  160. ////////////////////////////////////////////////////////////////////////////////
  161. // Variables/data
  162. ////////////////////////////////////////////////////////////////////////////////
  163. // Animations.
  164. char* CPowerUp::ms_apszPowerUpResNames[CStockPile::NumStockPileItems + 2] =
  165. {
  166. "3d/ammo", // Bullets.
  167. "3d/grenadeicon", // Grenades.
  168. "3d/cocktail", // Cocktails.
  169. "3d/missileicon", // Rockets.
  170. "3d/napalmicon", // Napalm.
  171. "3d/shotshells", // Shells.
  172. "3d/fuel", // Fuel.
  173. "3d/minecrate", // Mines.
  174. "3d/health", // Health.
  175. "3d/gmissileicon", // Heatseekers.
  176. "3d/machinegun", // MachineGun.
  177. "3d/launcher", // MissileLauncher.
  178. "3d/shotgun", // ShotGun.
  179. "3d/spraygun", // SprayCannon.
  180. "3d/flmthrower", // FlameThrower.
  181. "3d/napalmer", // NapalmLauncher.
  182. "3d/napalmer", // DeathWadLauncher.
  183. "3d/shotgun", // DoubleBarrel.
  184. "3d/kevlarvest", // KevlarVest.
  185. "3d/backpackicon", // Backpack.
  186. // Insert new items above this item.
  187. "3d/minecrate", // Multiple items.
  188. "3d/minecrate", // No items.
  189. };
  190. ////////////////////////////////////////////////////////////////////////////////
  191. // Load object (should call base class version!)
  192. ////////////////////////////////////////////////////////////////////////////////
  193. short CPowerUp::Load( // Returns 0 if successfull, non-zero otherwise
  194. RFile* pFile, // In: File to load from
  195. bool bEditMode, // In: True for edit mode, false otherwise
  196. short sFileCount, // In: File count (unique per file, never 0)
  197. ULONG ulFileVersion) // In: Version of file format to load.
  198. {
  199. short sResult = 0;
  200. if (ulFileVersion < 20)
  201. {
  202. sResult = CThing::Load(pFile, bEditMode, sFileCount, ulFileVersion);
  203. }
  204. else
  205. {
  206. // Note that we bypass CItem3d::Load() cuz I think that would be wierd.
  207. sResult = CThing3d::Load(pFile, bEditMode, sFileCount, ulFileVersion);
  208. }
  209. if (sResult == 0)
  210. {
  211. CacheSample(g_smidPickedUpWeapon);
  212. switch (ulFileVersion)
  213. {
  214. default:
  215. case 31:
  216. case 30:
  217. case 29:
  218. case 28:
  219. case 27:
  220. case 26:
  221. case 25:
  222. case 24:
  223. case 23:
  224. case 22:
  225. case 21:
  226. case 20:
  227. // Base class gets it all.
  228. break;
  229. case 19:
  230. case 18:
  231. case 17:
  232. pFile->Read(&m_dX);
  233. pFile->Read(&m_dY);
  234. pFile->Read(&m_dZ);
  235. sResult = m_stockpile.Load(pFile, ulFileVersion);
  236. break;
  237. case 16:
  238. case 15:
  239. case 14:
  240. case 13:
  241. case 12:
  242. case 11:
  243. case 10:
  244. case 9:
  245. case 8:
  246. case 7:
  247. case 6:
  248. case 5:
  249. case 4:
  250. case 3:
  251. case 2:
  252. case 1:
  253. {
  254. pFile->Read(&m_dX);
  255. pFile->Read(&m_dY);
  256. pFile->Read(&m_dZ);
  257. U8 u8Type = (U8)CStockPile::Bullets;
  258. pFile->Read(&u8Type);
  259. long lPowerVal;
  260. pFile->Read(&lPowerVal);
  261. switch (u8Type)
  262. {
  263. case 0://Bullets:
  264. m_stockpile.m_sNumBullets = lPowerVal;
  265. break;
  266. case 1://Grenades:
  267. m_stockpile.m_sNumGrenades = lPowerVal;
  268. break;
  269. case 2://Cocktails:
  270. m_stockpile.m_sNumFireBombs = lPowerVal;
  271. break;
  272. case 3://Rockets:
  273. m_stockpile.m_sNumMissiles = lPowerVal;
  274. break;
  275. case 4://Napalm:
  276. m_stockpile.m_sNumNapalms = lPowerVal;
  277. break;
  278. case 5://Shells:
  279. m_stockpile.m_sNumShells = lPowerVal;
  280. break;
  281. case 6://Fuel:
  282. m_stockpile.m_sNumFuel = lPowerVal;
  283. break;
  284. case 7://ProximityMine:
  285. case 8://TimedMine:
  286. case 9://RemoteMine:
  287. case 10://BouncingBettyMine:
  288. m_stockpile.m_sNumMines = lPowerVal;
  289. break;
  290. case 11://Health:
  291. m_stockpile.m_sHitPoints = lPowerVal;
  292. break;
  293. case 12://Heatseekers:
  294. m_stockpile.m_sNumHeatseekers = lPowerVal;
  295. break;
  296. }
  297. break;
  298. }
  299. }
  300. // Make sure there were no file errors or format errors . . .
  301. if (!pFile->Error() && sResult == 0)
  302. {
  303. // Get resources and initialize.
  304. sResult = Init();
  305. }
  306. else
  307. {
  308. sResult = -1;
  309. TRACE("CPowerUp::Load(): Error reading from file!\n");
  310. }
  311. }
  312. return sResult;
  313. }
  314. ////////////////////////////////////////////////////////////////////////////////
  315. // Save object (should call base class version!)
  316. ////////////////////////////////////////////////////////////////////////////////
  317. short CPowerUp::Save( // Returns 0 if successfull, non-zero otherwise
  318. RFile* pFile, // In: File to save to
  319. short sFileCount) // In: File count (unique per file, never 0)
  320. {
  321. // Note that we bypass CItem3d::Save() cuz I think that would be wierd.
  322. short sResult = CThing3d::Save(pFile, sFileCount);
  323. if (sResult == 0)
  324. {
  325. // Base class does it all.
  326. }
  327. return sResult;
  328. }
  329. ////////////////////////////////////////////////////////////////////////////////
  330. // Update object
  331. ////////////////////////////////////////////////////////////////////////////////
  332. void CPowerUp::Update(void)
  333. {
  334. if (!m_sSuspend)
  335. {
  336. // Get new time
  337. long lThisTime = m_pRealm->m_time.GetGameTime();
  338. // Advance the animation timer.
  339. long lDifTime = lThisTime - m_lAnimPrevUpdateTime;
  340. m_lAnimTime += lDifTime;
  341. // Update prev time.
  342. m_lAnimPrevUpdateTime = lThisTime;
  343. // Service message queue.
  344. ProcessMessages();
  345. // Switch on state.
  346. switch (m_state)
  347. {
  348. case State_BlownUp:
  349. // Handle state. If done . . .
  350. if (WhileBlownUp() == false)
  351. {
  352. m_state = State_Idle;
  353. // Restore powerup cheese spin.
  354. m_dExtRotVelY = Y_AXIS_ROTATION_RATE;
  355. m_dExtRotVelZ = 0.0;
  356. m_dRotZ = 0.0;
  357. }
  358. break;
  359. default:
  360. if (m_u16IdParent == CIdBank::IdNil)
  361. {
  362. // Get time from last call in seconds.
  363. double dSeconds = double(lThisTime - m_lPrevTime) / 1000.0;
  364. DeluxeUpdatePosVel(dSeconds);
  365. }
  366. break;
  367. }
  368. // Update sphere.
  369. m_smash.m_sphere.sphere.X = m_dX;
  370. m_smash.m_sphere.sphere.Y = m_dY;
  371. m_smash.m_sphere.sphere.Z = m_dZ;
  372. m_smash.m_sphere.sphere.lRadius = m_sprite.m_sRadius;
  373. // Update the smash.
  374. m_pRealm->m_smashatorium.Update(&m_smash);
  375. // Save time for next time
  376. m_lPrevTime = lThisTime;
  377. }
  378. }
  379. ////////////////////////////////////////////////////////////////////////////////
  380. // Render object
  381. ////////////////////////////////////////////////////////////////////////////////
  382. void CPowerUp::Render(void)
  383. {
  384. CItem3d::Render();
  385. // Make larger.
  386. m_trans.Scale(SCALE, SCALE, SCALE);
  387. }
  388. ////////////////////////////////////////////////////////////////////////////////
  389. // Setup object.
  390. ////////////////////////////////////////////////////////////////////////////////
  391. short CPowerUp::Setup( // Returns 0 if successfull, non-zero otherwise
  392. short sX, // In: New x coord
  393. short sY, // In: New y coord
  394. short sZ) // In: New z coord
  395. {
  396. short sResult = 0;
  397. // Use specified position
  398. m_dX = (double)sX;
  399. m_dY = (double)sY;
  400. m_dZ = (double)sZ;
  401. // Load resources and initialize.
  402. sResult = Init();
  403. if (sResult == 0)
  404. {
  405. sResult = Startup();
  406. }
  407. return sResult;
  408. }
  409. ////////////////////////////////////////////////////////////////////////////////
  410. // Called by editor to init new object at specified position
  411. ////////////////////////////////////////////////////////////////////////////////
  412. short CPowerUp::EditNew( // Returns 0 if successfull, non-zero otherwise
  413. short sX, // In: New x coord
  414. short sY, // In: New y coord
  415. short sZ) // In: New z coord
  416. {
  417. short sResult = 0;
  418. // Use specified position
  419. m_dX = (double)sX;
  420. m_dY = (double)sY;
  421. m_dZ = (double)sZ;
  422. sResult = EditModify();
  423. return sResult;
  424. }
  425. ////////////////////////////////////////////////////////////////////////////////
  426. // Called by editor to modify object
  427. ////////////////////////////////////////////////////////////////////////////////
  428. short CPowerUp::EditModify(void)
  429. {
  430. short sResult = m_stockpile.UserEdit();
  431. // If successful so far . . .
  432. if (sResult == 0)
  433. {
  434. // Load resources and initialize.
  435. sResult = Init();
  436. }
  437. return sResult;
  438. }
  439. ////////////////////////////////////////////////////////////////////////////////
  440. // Initialize object.
  441. ////////////////////////////////////////////////////////////////////////////////
  442. short CPowerUp::Init(void) // Returns 0 on success.
  443. {
  444. short sRes = GetResources();
  445. // Prepare shadow (get resources and setup sprite).
  446. sRes |= PrepareShadow();
  447. m_dExtRotVelY = Y_AXIS_ROTATION_RATE;
  448. m_lAnimTime = 0;
  449. // Set up collision object
  450. m_smash.m_bits = CSmash::PowerUp | CSmash::Misc;
  451. return sRes;
  452. }
  453. ////////////////////////////////////////////////////////////////////////////////
  454. // Get resource name for this item.
  455. ////////////////////////////////////////////////////////////////////////////////
  456. void CPowerUp::GetResName( // Returns nothing.
  457. char* pszResName) // Out: Resource base name.
  458. {
  459. short sTypeIndex;
  460. short sTypeInPowerUp = CStockPile::NumStockPileItems;
  461. for (sTypeIndex = 0; sTypeIndex < CStockPile::NumStockPileItems; sTypeIndex++)
  462. {
  463. if (m_stockpile.GetItem(sTypeIndex) > 0)
  464. {
  465. // If no type yet . . .
  466. if (sTypeInPowerUp == CStockPile::NumStockPileItems)
  467. {
  468. sTypeInPowerUp = sTypeIndex;
  469. }
  470. else
  471. {
  472. sTypeInPowerUp = CStockPile::NumStockPileItems + 1;
  473. break;
  474. }
  475. }
  476. }
  477. strcpy(pszResName, ms_apszPowerUpResNames[sTypeInPowerUp]);
  478. }
  479. ////////////////////////////////////////////////////////////////////////////////
  480. // Get all required resources
  481. ////////////////////////////////////////////////////////////////////////////////
  482. short CPowerUp::GetResources(void) // Returns 0 if successfull, non-zero otherwise
  483. {
  484. short sResult = 0;
  485. // Safe to call even if no resource.
  486. FreeResources();
  487. char szResName[RSP_MAX_PATH];
  488. GetResName(szResName);
  489. sResult = m_anim.Get(
  490. szResName,
  491. NULL,
  492. NULL,
  493. NULL,
  494. RChannel_LoopAtStart | RChannel_LoopAtEnd);
  495. return sResult;
  496. }
  497. ////////////////////////////////////////////////////////////////////////////////
  498. // Free all resources
  499. ////////////////////////////////////////////////////////////////////////////////
  500. short CPowerUp::FreeResources(void) // Returns 0 if successfull, non-zero otherwise
  501. {
  502. short sResult = 0;
  503. if (m_anim.m_psops != NULL)
  504. {
  505. m_anim.Release();
  506. }
  507. return sResult;
  508. }
  509. ////////////////////////////////////////////////////////////////////////////////
  510. // Preload - Preload assets needed so they can be cached and don't have to load
  511. // during the game
  512. ////////////////////////////////////////////////////////////////////////////////
  513. short CPowerUp::Preload(CRealm* /*prealm*/)
  514. {
  515. short sResult = 0;
  516. short i;
  517. CAnim3D anim;
  518. for (i = 0; i < CStockPile::NumStockPileItems + 2; i++)
  519. {
  520. sResult |= anim.Get(ms_apszPowerUpResNames[i], NULL, NULL, NULL, 0);
  521. anim.Release();
  522. }
  523. return sResult;
  524. }
  525. ////////////////////////////////////////////////////////////////////////////////
  526. // Call to grab this item.
  527. ////////////////////////////////////////////////////////////////////////////////
  528. short CPowerUp::Grab( // Returns 0 on success..
  529. CSprite* psprParent) // In: Parent's sprite.
  530. {
  531. short sRes = 0; // Assume success.
  532. // If we are not already grabbed . . .
  533. if (m_sprite.m_psprParent == NULL)
  534. {
  535. m_dX = 0.0;
  536. m_dY = 0.0;
  537. m_dZ = 0.0;
  538. psprParent->AddChild(&m_sprite);
  539. // Don't use this for now b/c the next line that removes the
  540. // smash from the smashatorium will be ineffective b/c the
  541. // base class will put it right back.
  542. ASSERT(0);
  543. // Remove collision thinger.
  544. m_pRealm->m_smashatorium.Remove(&m_smash);
  545. }
  546. else
  547. {
  548. // Already have a parent.
  549. sRes = -1;
  550. }
  551. return sRes;
  552. }
  553. ////////////////////////////////////////////////////////////////////////////////
  554. // Call to release this item.
  555. ////////////////////////////////////////////////////////////////////////////////
  556. void CPowerUp::Drop( // Returns nothing.
  557. short sX, // In: Position from which to release.
  558. short sY, // In: Position from which to release.
  559. short sZ) // In: Position from which to release.
  560. {
  561. m_dX = sX;
  562. m_dY = sY;
  563. m_dZ = sZ;
  564. // If we have a parent . . .
  565. if (m_sprite.m_psprParent != NULL)
  566. {
  567. // Remove from parent.
  568. m_sprite.m_psprParent->RemoveChild(&m_sprite);
  569. }
  570. }
  571. ////////////////////////////////////////////////////////////////////////////////
  572. // Plays a sample corresponding to the type of powerup indicating it
  573. // was picked up.
  574. ////////////////////////////////////////////////////////////////////////////////
  575. void CPowerUp::PickUpFeedback(void) // Returns nothing.
  576. {
  577. PlaySample(g_smidPickedUpWeapon, SampleMaster::UserFeedBack);
  578. }
  579. ////////////////////////////////////////////////////////////////////////////////
  580. // If this powerup has nothing left, destroys itself. Otherwise, chooses
  581. // a new resource to represent its current contents.
  582. // NOTE: This function can cause this item to be destroyed. Don't use
  583. // a ptr to this object after calling this function.
  584. ////////////////////////////////////////////////////////////////////////////////
  585. void CPowerUp::RepaginateNow(void)
  586. {
  587. // If not empty . . .
  588. if (IsEmpty() == false)
  589. {
  590. // If this fails, we'd better go away . . .
  591. if (GetResources() != 0)
  592. {
  593. delete this;
  594. }
  595. }
  596. else
  597. {
  598. // Done then.
  599. delete this;
  600. }
  601. }
  602. ////////////////////////////////////////////////////////////////////////////////
  603. // Message Handlers.
  604. ////////////////////////////////////////////////////////////////////////////////
  605. ////////////////////////////////////////////////////////////////////////////////
  606. // Handles a Shot_Message.
  607. // (virtual).
  608. ////////////////////////////////////////////////////////////////////////////////
  609. void CPowerUp::OnShotMsg( // Returns nothing.
  610. Shot_Message* pshotmsg) // In: Message to handle.
  611. {
  612. // Eventually, it'd be cool to have the ammos respond to bullets.
  613. // Invoke base class implementation.
  614. CItem3d::OnShotMsg(pshotmsg);
  615. }
  616. ////////////////////////////////////////////////////////////////////////////////
  617. // Handles an Explosion_Message.
  618. // (virtual).
  619. ////////////////////////////////////////////////////////////////////////////////
  620. void CPowerUp::OnExplosionMsg( // Returns nothing.
  621. Explosion_Message* pexplosionmsg) // In: Message to handle.
  622. {
  623. // Break into smaller pieces and pass the message on . . .
  624. // Inventory.
  625. short sTypeIndex;
  626. bool bFirst = true;
  627. short sNumGenerated = 0;
  628. for (sTypeIndex = 0; sTypeIndex < CStockPile::NumStockPileItems; sTypeIndex++)
  629. {
  630. if (m_stockpile.GetItem(sTypeIndex) > 0)
  631. {
  632. if (bFirst == false)
  633. {
  634. CPowerUp* ppowerup;
  635. if (ConstructWithID(CPowerUpID, m_pRealm, (CThing**)&ppowerup) == 0)
  636. {
  637. // Transfer item.
  638. ppowerup->m_stockpile.GetItem(sTypeIndex) = m_stockpile.GetItem(sTypeIndex);
  639. // Clear local item.
  640. m_stockpile.GetItem(sTypeIndex) = 0;
  641. // Prepare for the cold, cruel, fire-infested realm.
  642. ppowerup->Setup(m_dX, m_dY, m_dZ);
  643. // Slap it some (bypass this function, though..that'd be a waste to
  644. // do again).
  645. ppowerup->CItem3d::OnExplosionMsg(pexplosionmsg);
  646. // Note that another was created.
  647. sNumGenerated++;
  648. // Choose random trajectory.
  649. ppowerup->m_dExtHorzRot = GetRandom() % 360;
  650. }
  651. else
  652. {
  653. TRACE("OnExplosionMsg(): Failed to create powerup.\n");
  654. }
  655. }
  656. else
  657. {
  658. bFirst = false;
  659. }
  660. }
  661. }
  662. // If we created any new powerups . . .
  663. if (sNumGenerated)
  664. {
  665. // This one was altered.
  666. if (GetResources() != 0)
  667. {
  668. // Doh!
  669. delete this;
  670. return;
  671. }
  672. }
  673. // Invoke base class implementation.
  674. CItem3d::OnExplosionMsg(pexplosionmsg);
  675. }
  676. ////////////////////////////////////////////////////////////////////////////////
  677. // Handles a Burn_Message.
  678. // (virtual).
  679. ////////////////////////////////////////////////////////////////////////////////
  680. void CPowerUp::OnBurnMsg( // Returns nothing.
  681. Burn_Message* pburnmsg) // In: Message to handle.
  682. {
  683. // Eventually, it'd be cool to have the ammos respond to fire.
  684. // Invoke base class implementation.
  685. CItem3d::OnBurnMsg(pburnmsg);
  686. }
  687. ////////////////////////////////////////////////////////////////////////////////
  688. // EOF
  689. ////////////////////////////////////////////////////////////////////////////////