flag.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784
  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. // flag.cpp
  19. // Project: Postal
  20. //
  21. // This module implements the flag object for capture the flag gameplay.
  22. //
  23. // History:
  24. //
  25. // 06/30/97 BRH Started this file for the challenge levels.
  26. //
  27. // 07/06/97 BRH Added time bonus.
  28. //
  29. // 07/12/97 BRH Added EditModify dialog for bonus time and flag ID.
  30. // Added Flag ID and loading/saving thereof so that
  31. // a flag can be matched with a base. Also adds bonus time
  32. // to realm timer.
  33. //
  34. // 07/14/97 BRH Changed smash bits to CSmash::Flag. Incremented
  35. // the flag captured count in the realm.
  36. //
  37. // 08/03/97 JMI Init() was setting the looping parms on a phot which no
  38. // longer exists. Now the looping parms are passed via the
  39. // Get() call in GetResources() instead so they will get set
  40. // via the CAnim3D which should know which ones are okay to
  41. // use.
  42. //
  43. // 08/10/97 JMI Once blown up, the returns to the guard state but never
  44. // restored its smash bits (they were changed when it left
  45. // guard mode so, I think, the flag could search for the base).
  46. // Now the bits are restored to looking for dude mode. Maybe
  47. // we should have two sets of bits, one set for each state.
  48. // Also, was only updating the smash in State_Wait. Changed
  49. // so it always does it which may not be necessary. Have to
  50. // ask.
  51. //
  52. // 08/11/97 BRH Added a flag color variable which is loaded and saved
  53. // and can be changed in the EditModify dialog box.
  54. //
  55. // 08/18/97 JMI Changed State_Dead to call DeadRender3D() (which used to be
  56. // known/called as just another Render() overload).
  57. //
  58. // 08/24/97 BRH Processes the OnBurnMsg so that it can set its state
  59. // back to guard mode. The Cdude drops the flag when he
  60. // is burned, and then forwards the mesage to the flag so
  61. // it can go back to the mode where it looks for someone
  62. // to pick it up. Previously, when the dude dropped it in
  63. // this state, it was only looking for a flag base and so
  64. // could not be picked up again. Added the State_Burning
  65. // to Update() so that the Dude couldn't pick up the flag
  66. // instantly after being burned. Otherwise he kept picking
  67. // it up and dropping it.
  68. //
  69. // 08/25/97 BRH Fixed bug where flags incremented the flag score when
  70. // picked up but didn't decrement the count when dropped.
  71. //
  72. // 08/28/97 BRH Set the correct bits to detect the flag base. Finished
  73. // the code for capturing the flagbase.
  74. //
  75. // 08/30/97 JMI Since CDude no longer contains an m_idFlagItem, this object
  76. // no longer sets it. Simply adding a CFlag's sprite to the
  77. // dude's sprite children is sufficient for him to handle the
  78. // flag.
  79. //
  80. ////////////////////////////////////////////////////////////////////////////////
  81. #define FLAG_CPP
  82. #include "RSPiX.h"
  83. #include "flag.h"
  84. #include "flagbase.h"
  85. #include "SampleMaster.h"
  86. #include "dude.h"
  87. #include "reality.h"
  88. ////////////////////////////////////////////////////////////////////////////////
  89. // Macros/types/etc.
  90. ////////////////////////////////////////////////////////////////////////////////
  91. #define GUI_MINUTES_EDIT_ID 101
  92. #define GUI_SECONDS_EDIT_ID 102
  93. #define GUI_FLAGID_EDIT_ID 103
  94. #define GUI_COLOR_EDIT_ID 104
  95. #define FLAG_BURNED_TIMEOUT 1500
  96. ////////////////////////////////////////////////////////////////////////////////
  97. // Variables/data
  98. ////////////////////////////////////////////////////////////////////////////////
  99. // These are default values -- actually values are set using the editor!
  100. double CFlag::ms_dInRange = 30 * 30; // Sq distance to base
  101. // Let this auto-init to 0
  102. short CFlag::ms_sFileCount;
  103. /// Throwing Animation Files ////////////////////////////////////////////////////
  104. // An array of pointers to resource names (one for each channel of the animation)
  105. static char* ms_apszRedResNames[] =
  106. {
  107. "3d/rflag.sop",
  108. "3d/rflag.mesh",
  109. "3d/rflag.tex",
  110. "3d/rflag.hot",
  111. "3d/rflag.bounds",
  112. "3d/rflag.floor",
  113. NULL,
  114. NULL
  115. };
  116. static char* ms_apszBlueResNames[] =
  117. {
  118. "3d/bflag.sop",
  119. "3d/bflag.mesh",
  120. "3d/bflag.tex",
  121. "3d/bflag.hot",
  122. "3d/bflag.bounds",
  123. "3d/bflag.floor",
  124. NULL,
  125. NULL
  126. };
  127. ////////////////////////////////////////////////////////////////////////////////
  128. // Load object (should call base class version!)
  129. ////////////////////////////////////////////////////////////////////////////////
  130. short CFlag::Load( // Returns 0 if successfull, non-zero otherwise
  131. RFile* pFile, // In: File to load from
  132. bool bEditMode, // In: True for edit mode, false otherwise
  133. short sFileCount, // In: File count (unique per file, never 0)
  134. ULONG ulFileVersion) // In: Version of file format to load.
  135. {
  136. short sResult = 0;
  137. // Call the base load function to get ID, position, etc.
  138. sResult = CThing3d::Load(pFile, bEditMode, sFileCount, ulFileVersion);
  139. if (sResult == 0)
  140. {
  141. // Load common data just once per file (not with each object)
  142. if (ms_sFileCount != sFileCount)
  143. {
  144. ms_sFileCount = sFileCount;
  145. // Load static data
  146. switch (ulFileVersion)
  147. {
  148. default:
  149. case 1:
  150. pFile->Read(&ms_dInRange);
  151. break;
  152. }
  153. }
  154. // Load other values
  155. switch (ulFileVersion)
  156. {
  157. default:
  158. case 45:
  159. pFile->Read(&m_u16FlagColor);
  160. case 44:
  161. case 43:
  162. case 42:
  163. case 41:
  164. case 40:
  165. case 39:
  166. case 38:
  167. case 37:
  168. case 36:
  169. case 35:
  170. case 34:
  171. case 33:
  172. case 32:
  173. case 31:
  174. case 30:
  175. case 29:
  176. case 28:
  177. case 27:
  178. case 26:
  179. case 25:
  180. case 24:
  181. case 23:
  182. case 22:
  183. case 21:
  184. case 20:
  185. case 19:
  186. case 18:
  187. case 17:
  188. case 16:
  189. case 15:
  190. case 14:
  191. case 13:
  192. case 12:
  193. case 11:
  194. case 10:
  195. case 9:
  196. case 8:
  197. case 7:
  198. case 6:
  199. case 5:
  200. case 4:
  201. case 3:
  202. case 2:
  203. case 1:
  204. case 0:
  205. pFile->Read(&m_lTimeBonus);
  206. pFile->Read(&m_u16FlagID);
  207. break;
  208. }
  209. // Make sure there were no file errors or format errors . . .
  210. if (!pFile->Error() && sResult == 0)
  211. {
  212. // Get resources
  213. sResult = GetResources();
  214. }
  215. else
  216. {
  217. sResult = -1;
  218. TRACE("CFlag::Load(): Error reading from file!\n");
  219. }
  220. }
  221. else
  222. {
  223. TRACE("CFlag::Load(): CDoofus::Load() failed.\n");
  224. }
  225. return sResult;
  226. }
  227. ////////////////////////////////////////////////////////////////////////////////
  228. // Save object (should call base class version!)
  229. ////////////////////////////////////////////////////////////////////////////////
  230. short CFlag::Save( // Returns 0 if successfull, non-zero otherwise
  231. RFile* pFile, // In: File to save to
  232. short sFileCount) // In: File count (unique per file, never 0)
  233. {
  234. // Swap the hotspot we want to save in.
  235. short sResult;
  236. // Call the base class save to save the instance ID, position, etc
  237. CThing3d::Save(pFile, sFileCount);
  238. // Save common data just once per file (not with each object)
  239. if (ms_sFileCount != sFileCount)
  240. {
  241. ms_sFileCount = sFileCount;
  242. // Save static data
  243. pFile->Write(&ms_dInRange);
  244. }
  245. // Save additinal stuff here.
  246. pFile->Write(&m_u16FlagColor);
  247. pFile->Write(&m_lTimeBonus);
  248. pFile->Write(&m_u16FlagID);
  249. if (!pFile->Error())
  250. {
  251. sResult = SUCCESS;
  252. }
  253. else
  254. {
  255. TRACE("CFlag::Save() - Error writing to file\n");
  256. sResult = -1;
  257. }
  258. return sResult;
  259. }
  260. ////////////////////////////////////////////////////////////////////////////////
  261. // Init - Call this after the resources are in place
  262. ////////////////////////////////////////////////////////////////////////////////
  263. short CFlag::Init(void)
  264. {
  265. short sResult = 0;
  266. // Prepare shadow (get resources and setup sprite).
  267. sResult = PrepareShadow();
  268. // Init other stuff
  269. m_dVel = 0.0;
  270. m_dRot = 0.0;
  271. // Set to different starting state based on the design of the animation, but
  272. // for now, ok. Then also set his current animation.
  273. m_state = CFlag::State_Wait;
  274. m_panimCur = &m_animFlagWave;
  275. m_lAnimTime = 0;
  276. m_lTimer = m_pRealm->m_time.GetGameTime() + 500;
  277. m_smash.m_bits = CSmash::Flag;
  278. m_smash.m_pThing = this;
  279. m_u32IncludeBits = CSmash::Good | CSmash::Character;
  280. m_u32DontcareBits = 0;
  281. m_u32ExcludeBits = CSmash::Dead;
  282. m_sBrightness = 0; // Default Brightness level
  283. return sResult;
  284. }
  285. ////////////////////////////////////////////////////////////////////////////////
  286. // Startup object
  287. ////////////////////////////////////////////////////////////////////////////////
  288. short CFlag::Startup(void) // Returns 0 if successfull, non-zero otherwise
  289. {
  290. short sResult = 0;
  291. // Set the current height, previous time, and Nav Net
  292. CThing3d::Startup();
  293. // Init other stuff
  294. Init();
  295. return sResult;
  296. }
  297. ////////////////////////////////////////////////////////////////////////////////
  298. // Shutdown object
  299. ////////////////////////////////////////////////////////////////////////////////
  300. short CFlag::Shutdown(void) // Returns 0 if successfull, non-zero otherwise
  301. {
  302. short sResult = 0;
  303. m_trans.Make1();
  304. return sResult;
  305. }
  306. ////////////////////////////////////////////////////////////////////////////////
  307. // Update object
  308. ////////////////////////////////////////////////////////////////////////////////
  309. void CFlag::Update(void)
  310. {
  311. short sHeight = m_sPrevHeight;
  312. long lThisTime;
  313. long lTimeDifference;
  314. CSmash* pSmashed = NULL;
  315. if (!m_sSuspend)
  316. {
  317. // Get new time
  318. lThisTime = m_pRealm->m_time.GetGameTime();
  319. lTimeDifference = lThisTime - m_lPrevTime;
  320. m_lAnimTime += lTimeDifference;
  321. // Calculate elapsed time in seconds
  322. double dSeconds = (double)(lThisTime - m_lPrevTime) / 1000.0;
  323. // Check for new messages that may change the state
  324. ProcessMessages();
  325. switch(m_state)
  326. {
  327. case CFlag::State_Wait:
  328. if (lThisTime > m_lTimer)
  329. {
  330. m_state = CFlag::State_Guard;
  331. }
  332. break;
  333. //-----------------------------------------------------------------------
  334. // Guard - normal operation
  335. //-----------------------------------------------------------------------
  336. case CFlag::State_Guard:
  337. if (m_pRealm->m_smashatorium.QuickCheckClosest(&m_smash,
  338. m_u32IncludeBits,
  339. m_u32DontcareBits,
  340. m_u32ExcludeBits, &pSmashed))
  341. {
  342. // Add child to smashed
  343. if (pSmashed->m_pThing->GetClassID() == CDudeID)
  344. {
  345. ((CDude*) pSmashed->m_pThing)->m_sprite.AddChild(&m_sprite);
  346. m_u16IdParent = pSmashed->m_pThing->GetInstanceID();
  347. m_pRealm->m_scene.RemoveSprite(&m_sprite);
  348. m_state = State_Patrol;
  349. //m_u32IncludeBits = CSmash::Flagbase;
  350. m_u32IncludeBits = CSmash::FlagBase;
  351. m_u32DontcareBits = CSmash::Good | CSmash::Bad;
  352. m_u32ExcludeBits = 0;
  353. // Add bonus time (if any) to realm timer
  354. m_pRealm->m_lScoreTimeDisplay += m_lTimeBonus;
  355. m_pRealm->m_sFlagsCaptured++;
  356. // Feedback.
  357. PlaySample(
  358. g_smidDemonYes2,
  359. SampleMaster::Demon,
  360. DistanceToVolume(m_dX, m_dY, m_dZ, 250) );
  361. }
  362. }
  363. // QuickCheckClosest (CDudeID);
  364. break;
  365. //-----------------------------------------------------------------------
  366. // Patrol - look for base while being carried
  367. //-----------------------------------------------------------------------
  368. case CFlag::State_Patrol:
  369. if (m_pRealm->m_smashatorium.QuickCheckClosest(&m_smash,
  370. m_u32IncludeBits,
  371. m_u32DontcareBits,
  372. m_u32ExcludeBits, &pSmashed))
  373. {
  374. if (pSmashed)
  375. {
  376. if (((CFlagbase*) pSmashed->m_pThing)->m_u16FlagID == m_u16FlagID)
  377. {
  378. m_sSavedX = pSmashed->m_sphere.sphere.X;
  379. m_sSavedY = pSmashed->m_sphere.sphere.Y + 15;
  380. m_sSavedZ = pSmashed->m_sphere.sphere.Z;
  381. m_pRealm->m_sFlagbaseCaptured++;
  382. CThing3d* pParent = NULL;
  383. GameMessage msg;
  384. msg.msg_PutMeDown.eType = typePutMeDown;
  385. msg.msg_PutMeDown.sPriority = 0;
  386. msg.msg_PutMeDown.u16FlagInstanceID = GetInstanceID();
  387. if (m_pRealm->m_idbank.GetThingByID((CThing**)&pParent, m_u16IdParent) == 0)
  388. {
  389. SendThingMessage(&msg, pParent);
  390. }
  391. }
  392. }
  393. }
  394. break;
  395. //-----------------------------------------------------------------------
  396. // Die - You collided with the flag base, so just set your position
  397. // to the base position and then go to dead.
  398. //-----------------------------------------------------------------------
  399. case CFlag::State_Die:
  400. m_dX = m_sSavedX;
  401. m_dY = m_sSavedY;
  402. m_dZ = m_sSavedZ;
  403. m_smash.m_bits = 0;
  404. m_state = State_Dead;
  405. break;
  406. //-----------------------------------------------------------------------
  407. // Blownup - You were blown up so pop up into the air and come down
  408. //-----------------------------------------------------------------------
  409. case CFlag::State_BlownUp:
  410. // Make her animate
  411. m_lAnimTime += lTimeDifference;
  412. if (!WhileBlownUp())
  413. {
  414. m_state = State_Guard;
  415. // Stop the spinning.
  416. m_dExtRotVelY = 0;
  417. m_dExtRotVelZ = 0;
  418. // Return the smash bits to guard mode (i.e., looking
  419. // for dude).
  420. m_u32IncludeBits = CSmash::Good | CSmash::Character;
  421. m_u32DontcareBits = 0;
  422. m_u32ExcludeBits = CSmash::Dead;
  423. m_pRealm->m_sFlagsCaptured--;
  424. }
  425. else
  426. {
  427. UpdateFirePosition();
  428. }
  429. break;
  430. //-----------------------------------------------------------------------
  431. // Burning - The CDude carrying you got burnt, and dropped you so wait
  432. // a while before going active again so he separates from you.
  433. //-----------------------------------------------------------------------
  434. case CFlag::State_Burning:
  435. if (lThisTime > m_lTimer)
  436. {
  437. m_state = State_Guard;
  438. // Return the smash bits to guard mode (i.e., looking
  439. // for dude).
  440. m_u32IncludeBits = CSmash::Good | CSmash::Character;
  441. m_u32DontcareBits = 0;
  442. m_u32ExcludeBits = CSmash::Dead;
  443. m_pRealm->m_sFlagsCaptured--;
  444. }
  445. break;
  446. //-----------------------------------------------------------------------
  447. // Dead - You are dead, so lay there and decompose, then go away
  448. //-----------------------------------------------------------------------
  449. case CFlag::State_Dead:
  450. CHood* phood = m_pRealm->m_phood;
  451. // Render current dead frame into background to stay.
  452. m_pRealm->m_scene.DeadRender3D(
  453. phood->m_pimBackground, // Destination image.
  454. &m_sprite, // Tree of 3D sprites to render.
  455. phood); // Dst clip rect.
  456. delete this;
  457. return;
  458. break;
  459. }
  460. // Update sphere.
  461. m_smash.m_sphere.sphere.X = m_dX;
  462. m_smash.m_sphere.sphere.Y = m_dY;
  463. m_smash.m_sphere.sphere.Z = m_dZ;
  464. m_smash.m_sphere.sphere.lRadius = 30; //m_spriteBase.m_sRadius;
  465. // Update the smash.
  466. m_pRealm->m_smashatorium.Update(&m_smash);
  467. // Save time for next time
  468. m_lPrevTime = lThisTime;
  469. m_lAnimPrevUpdateTime = m_lAnimTime;
  470. }
  471. }
  472. ////////////////////////////////////////////////////////////////////////////////
  473. // Called by editor to init new object at specified position
  474. ////////////////////////////////////////////////////////////////////////////////
  475. short CFlag::EditNew( // Returns 0 if successfull, non-zero otherwise
  476. short sX, // In: New x coord
  477. short sY, // In: New y coord
  478. short sZ) // In: New z coord
  479. {
  480. short sResult = 0;
  481. sResult = CThing3d::EditNew(sX, sY, sZ);
  482. if (sResult == SUCCESS)
  483. {
  484. // Load resources
  485. sResult = GetResources();
  486. if (sResult == SUCCESS)
  487. {
  488. sResult = Init();
  489. }
  490. }
  491. else
  492. {
  493. sResult = -1;
  494. }
  495. return sResult;
  496. }
  497. ////////////////////////////////////////////////////////////////////////////////
  498. // Edit Move
  499. ////////////////////////////////////////////////////////////////////////////////
  500. short CFlag::EditMove(short sX, short sY, short sZ)
  501. {
  502. short sResult = CThing3d::EditMove(sX, sY, sZ);
  503. return sResult;
  504. }
  505. ////////////////////////////////////////////////////////////////////////////////
  506. // Give Edit a rectangle around this object
  507. ////////////////////////////////////////////////////////////////////////////////
  508. void CFlag::EditRect(RRect* pRect)
  509. {
  510. // Call base class.
  511. CThing3d::EditRect(pRect);
  512. }
  513. ////////////////////////////////////////////////////////////////////////////////
  514. // Called by editor to get the hotspot of an object in 2D.
  515. // (virtual (Overridden here)).
  516. ////////////////////////////////////////////////////////////////////////////////
  517. void CFlag::EditHotSpot( // Returns nothiing.
  518. short* psX, // Out: X coord of 2D hotspot relative to
  519. // EditRect() pos.
  520. short* psY) // Out: Y coord of 2D hotspot relative to
  521. // EditRect() pos.
  522. {
  523. // Get rectangle.
  524. RRect rc;
  525. EditRect(&rc);
  526. // Get 2D hotspot.
  527. short sX;
  528. short sY;
  529. Map3Dto2D(
  530. m_dX,
  531. m_dY,
  532. m_dZ,
  533. &sX,
  534. &sY);
  535. // Get relation.
  536. *psX = sX - rc.sX;
  537. *psY = sY - rc.sY;
  538. }
  539. ////////////////////////////////////////////////////////////////////////////////
  540. // Called by editor to modify object
  541. ////////////////////////////////////////////////////////////////////////////////
  542. short CFlag::EditModify(void)
  543. {
  544. short sResult = 0;
  545. U16 u16OrigColor = m_u16FlagColor;
  546. RGuiItem* pGuiItem = NULL;
  547. RGuiItem* pguiRoot = RGuiItem::LoadInstantiate(FullPathVD("res/editor/flag.gui"));
  548. if (pguiRoot != NULL)
  549. {
  550. REdit* peditMinutes = (REdit*) pguiRoot->GetItemFromId(GUI_MINUTES_EDIT_ID);
  551. REdit* peditSeconds = (REdit*) pguiRoot->GetItemFromId(GUI_SECONDS_EDIT_ID);
  552. REdit* peditFlagID = (REdit*) pguiRoot->GetItemFromId(GUI_FLAGID_EDIT_ID);
  553. REdit* peditColor = (REdit*) pguiRoot->GetItemFromId(GUI_COLOR_EDIT_ID);
  554. long lMinutes;
  555. long lSeconds;
  556. if (peditMinutes != NULL && peditSeconds != NULL && peditFlagID != NULL && peditColor != NULL)
  557. {
  558. ASSERT(peditMinutes->m_type == RGuiItem::Edit);
  559. ASSERT(peditSeconds->m_type == RGuiItem::Edit);
  560. ASSERT(peditFlagID->m_type == RGuiItem::Edit);
  561. ASSERT(peditColor->m_type == RGuiItem::Edit);
  562. lMinutes = m_lTimeBonus / 60000;
  563. lSeconds = (m_lTimeBonus / 1000) % 60;
  564. peditMinutes->SetText("%ld", lMinutes);
  565. peditSeconds->SetText("%2.2ld", lSeconds);
  566. peditFlagID->SetText("%d", m_u16FlagID);
  567. peditColor->SetText("%d", m_u16FlagColor);
  568. peditMinutes->Compose();
  569. peditSeconds->Compose();
  570. peditFlagID->Compose();
  571. peditColor->Compose();
  572. sResult = DoGui(pguiRoot);
  573. if (sResult == 1)
  574. {
  575. lMinutes = peditMinutes->GetVal();
  576. lSeconds = peditSeconds->GetVal() % 60;
  577. m_lTimeBonus = (lMinutes * 60000) + (lSeconds * 1000);
  578. m_u16FlagID = peditFlagID->GetVal();
  579. m_u16FlagColor = MIN((long) (EndOfColors-1), peditColor->GetVal());
  580. }
  581. }
  582. }
  583. delete pguiRoot;
  584. // If they changed the flag apperance, load new assets.
  585. if (m_u16FlagColor != u16OrigColor)
  586. {
  587. FreeResources();
  588. GetResources();
  589. }
  590. return 0;
  591. }
  592. ////////////////////////////////////////////////////////////////////////////////
  593. // Get all required resources
  594. ////////////////////////////////////////////////////////////////////////////////
  595. short CFlag::GetResources(void) // Returns 0 if successfull, non-zero otherwise
  596. {
  597. short sResult = 0;
  598. switch (m_u16FlagColor)
  599. {
  600. default:
  601. case Red:
  602. sResult = m_animFlagWave.Get(ms_apszRedResNames, RChannel_LoopAtStart | RChannel_LoopAtEnd);
  603. break;
  604. case Blue:
  605. sResult = m_animFlagWave.Get(ms_apszBlueResNames, RChannel_LoopAtStart | RChannel_LoopAtEnd);
  606. break;
  607. }
  608. if (sResult == 0)
  609. {
  610. // Add new animation loads here
  611. }
  612. else
  613. {
  614. TRACE("CFlag::GetResources - Failed to open 3D flag waving animation\n");
  615. }
  616. return sResult;
  617. }
  618. ////////////////////////////////////////////////////////////////////////////////
  619. // Free all resources
  620. ////////////////////////////////////////////////////////////////////////////////
  621. short CFlag::FreeResources(void) // Returns 0 if successfull, non-zero otherwise
  622. {
  623. m_animFlagWave.Release();
  624. return 0;
  625. }
  626. ////////////////////////////////////////////////////////////////////////////////
  627. // Message handlers
  628. ////////////////////////////////////////////////////////////////////////////////
  629. ////////////////////////////////////////////////////////////////////////////////
  630. // Shot Message
  631. ////////////////////////////////////////////////////////////////////////////////
  632. ////////////////////////////////////////////////////////////////////////////////
  633. // Explosion message
  634. ////////////////////////////////////////////////////////////////////////////////
  635. void CFlag::OnExplosionMsg(Explosion_Message* pMessage)
  636. {
  637. if (
  638. m_state != State_BlownUp &&
  639. m_state != State_Die &&
  640. m_state != State_Dead)
  641. {
  642. CThing3d::OnExplosionMsg(pMessage);
  643. m_state = State_BlownUp;
  644. m_lAnimTime = 0;
  645. m_lTimer = m_pRealm->m_time.GetGameTime();
  646. m_dExtHorzVel *= -1.4; //2.5;
  647. m_dExtVertVel *= 1.1; //1.4;
  648. // Send it spinning.
  649. m_dExtRotVelY = GetRandom() % 720;
  650. m_dExtRotVelZ = GetRandom() % 720;
  651. // m_panimCur = &m_animDie;
  652. }
  653. }
  654. ////////////////////////////////////////////////////////////////////////////////
  655. // Burning message
  656. ////////////////////////////////////////////////////////////////////////////////
  657. void CFlag::OnBurnMsg(Burn_Message* pMessage)
  658. {
  659. // For now we made the sentry fireproof, the only
  660. // way it can be destroyed is by blowing it up.
  661. m_state = State_Burning;
  662. m_lTimer = m_pRealm->m_time.GetGameTime() + FLAG_BURNED_TIMEOUT;
  663. }
  664. ////////////////////////////////////////////////////////////////////////////////
  665. // EOF
  666. ////////////////////////////////////////////////////////////////////////////////