goaltimer.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  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. // goaltimer.cpp
  19. // Project: Postal
  20. //
  21. // This module is a CThing that can be put in a level to keep track of a kill
  22. // goal or time limit goal. It can be set to keep the amount of time it takes
  23. // to kill a set number of people, or it can be set to count down to zero and
  24. // end the realm when the timer expires.
  25. //
  26. //
  27. // History:
  28. //
  29. // 06/30/97 BRH Started this file as part of the challenge levels.
  30. //
  31. // 07/09/97 JMI Now uses m_pRealm->Make2dResPath() to get the fullpath
  32. // for 2D image components.
  33. //
  34. // 08/05/97 JMI Changed priority to use Z position rather than 2D
  35. // projected Y position.
  36. //
  37. ////////////////////////////////////////////////////////////////////////////////
  38. #define GOALTIMER_CPP
  39. #include "RSPiX.h"
  40. #include "goaltimer.h"
  41. ////////////////////////////////////////////////////////////////////////////////
  42. // Macros/types/etc.
  43. ////////////////////////////////////////////////////////////////////////////////
  44. #define IMAGE_FILE "clock.bmp"
  45. #define TIMER_VALUE_GUI_ID 10
  46. #define KILL_VALUE_GUI_ID 11
  47. #define UPDOWN_GUI_ID 12
  48. ////////////////////////////////////////////////////////////////////////////////
  49. // Variables/data
  50. ////////////////////////////////////////////////////////////////////////////////
  51. // These are default values -- actually values are set using the editor!
  52. // Let this auto-init to 0
  53. short CGoalTimer::ms_sFileCount;
  54. ////////////////////////////////////////////////////////////////////////////////
  55. // Load object (should call base class version!)
  56. ////////////////////////////////////////////////////////////////////////////////
  57. short CGoalTimer::Load( // Returns 0 if successfull, non-zero otherwise
  58. RFile* pFile, // In: File to load from
  59. bool bEditMode, // In: True for edit mode, false otherwise
  60. short sFileCount, // In: File count (unique per file, never 0)
  61. ULONG ulFileVersion) // In: Version of file format to load.
  62. {
  63. // Call the base class load to get the instance ID
  64. short sResult = CThing::Load(pFile, bEditMode, sFileCount, ulFileVersion);
  65. if (sResult == 0)
  66. {
  67. // Load common data just once per file (not with each object)
  68. if (ms_sFileCount != sFileCount)
  69. {
  70. ms_sFileCount = sFileCount;
  71. // Load static data
  72. switch (ulFileVersion)
  73. {
  74. default:
  75. case 1:
  76. break;
  77. }
  78. }
  79. // Load object data
  80. switch (ulFileVersion)
  81. {
  82. default:
  83. case 1:
  84. pFile->Read(&m_dX);
  85. pFile->Read(&m_dY);
  86. pFile->Read(&m_dZ);
  87. pFile->Read(&m_lTimerMS);
  88. pFile->Read(&m_sKillGoal);
  89. pFile->Read(&m_sUpDown);
  90. break;
  91. }
  92. // Make sure there were no file errors or format errors . . .
  93. if (!pFile->Error() && sResult == 0)
  94. {
  95. // Get resources
  96. sResult = GetResources();
  97. }
  98. else
  99. {
  100. sResult = -1;
  101. TRACE("CGoalTimer::Load(): Error reading from file!\n");
  102. }
  103. }
  104. else
  105. {
  106. TRACE("CGoalTimer::Load(): CThing::Load() failed.\n");
  107. }
  108. return sResult;
  109. }
  110. ////////////////////////////////////////////////////////////////////////////////
  111. // Save object (should call base class version!)
  112. ////////////////////////////////////////////////////////////////////////////////
  113. short CGoalTimer::Save( // Returns 0 if successfull, non-zero otherwise
  114. RFile* pFile, // In: File to save to
  115. short sFileCount) // In: File count (unique per file, never 0)
  116. {
  117. // Call the base class save to save the instance ID
  118. CThing::Save(pFile, sFileCount);
  119. // Save common data just once per file (not with each object)
  120. if (ms_sFileCount != sFileCount)
  121. {
  122. ms_sFileCount = sFileCount;
  123. // Save static data
  124. }
  125. // Save object data
  126. pFile->Write(&m_dX);
  127. pFile->Write(&m_dY);
  128. pFile->Write(&m_dZ);
  129. pFile->Write(&m_lTimerMS);
  130. pFile->Write(&m_sKillGoal);
  131. pFile->Write(&m_sUpDown);
  132. return 0;
  133. }
  134. ////////////////////////////////////////////////////////////////////////////////
  135. // Startup object
  136. ////////////////////////////////////////////////////////////////////////////////
  137. short CGoalTimer::Startup(void) // Returns 0 if successfull, non-zero otherwise
  138. {
  139. short sReturn = 0;
  140. // At this point we can assume the CHood was loaded, so we init our height
  141. m_dY = m_pRealm->GetHeight((short) m_dX, (short) m_dZ);
  142. return sReturn;
  143. }
  144. ////////////////////////////////////////////////////////////////////////////////
  145. // Shutdown object
  146. ////////////////////////////////////////////////////////////////////////////////
  147. short CGoalTimer::Shutdown(void) // Returns 0 if successfull, non-zero otherwise
  148. {
  149. return 0;
  150. }
  151. ////////////////////////////////////////////////////////////////////////////////
  152. // Suspend object
  153. ////////////////////////////////////////////////////////////////////////////////
  154. void CGoalTimer::Suspend(void)
  155. {
  156. m_sSuspend++;
  157. }
  158. ////////////////////////////////////////////////////////////////////////////////
  159. // Resume object
  160. ////////////////////////////////////////////////////////////////////////////////
  161. void CGoalTimer::Resume(void)
  162. {
  163. m_sSuspend--;
  164. // If we're actually going to start updating again, we need to reset
  165. // the time so as to ignore any time that passed while we were suspended.
  166. // This method is far from precise, but I'm hoping it's good enough.
  167. }
  168. ////////////////////////////////////////////////////////////////////////////////
  169. // Update object
  170. ////////////////////////////////////////////////////////////////////////////////
  171. void CGoalTimer::Update(void)
  172. {
  173. }
  174. ////////////////////////////////////////////////////////////////////////////////
  175. // Render object
  176. ////////////////////////////////////////////////////////////////////////////////
  177. void CGoalTimer::Render(void)
  178. {
  179. }
  180. ////////////////////////////////////////////////////////////////////////////////
  181. // Called by editor to init new object at specified position
  182. ////////////////////////////////////////////////////////////////////////////////
  183. short CGoalTimer::EditNew( // Returns 0 if successfull, non-zero otherwise
  184. short sX, // In: New x coord
  185. short sY, // In: New y coord
  186. short sZ) // In: New z coord
  187. {
  188. short sResult = 0;
  189. // Use specified position
  190. m_dX = (double)sX;
  191. m_dY = (double)sY;
  192. m_dZ = (double)sZ;
  193. // Load resources
  194. sResult = GetResources();
  195. if (sResult == SUCCESS)
  196. {
  197. /*
  198. CListNode<CThing>* pEditorList = m_pRealm->m_aclassHeads[CThing::CGameEditThingID].m_pnNext;
  199. CGameEditThing* peditor = (CGameEditThing*) pEditorList->m_powner;
  200. RListBox* plb = peditor->m_plbNavNetList;
  201. if (plb != NULL)
  202. {
  203. RGuiItem* pgui = plb->AddString((char*) m_rstrNetName);
  204. pgui->m_lId = GetInstanceID();
  205. pgui->m_bcUser = NavNetListPressedCall;
  206. pgui->m_ulUserInstance = (unsigned long) this;
  207. plb->AdjustContents();
  208. plb->SetSel(pgui);
  209. }
  210. */
  211. }
  212. return sResult;
  213. }
  214. ////////////////////////////////////////////////////////////////////////////////
  215. // Helper inline to get a GUI, set its text to the value, and recompose it.
  216. ////////////////////////////////////////////////////////////////////////////////
  217. inline
  218. void SetText( // Returns nothing.
  219. RGuiItem* pguiRoot, // In: Root GUI.
  220. long lId, // In: ID of GUI to set text.
  221. long lVal) // In: Value to set text to.
  222. {
  223. RGuiItem* pgui = pguiRoot->GetItemFromId(lId);
  224. if (pgui != NULL)
  225. {
  226. pgui->SetText("%ld", lVal);
  227. pgui->Compose();
  228. }
  229. }
  230. ////////////////////////////////////////////////////////////////////////////////
  231. // Helper inline to get a RMultiBtn GUI, and set its state.
  232. ////////////////////////////////////////////////////////////////////////////////
  233. inline
  234. void CheckMultiBtn( // Returns nothing.
  235. RGuiItem* pguiRoot, // In: Root GUI.
  236. long lId, // In: ID of GUI to set text.
  237. short sChecked) // In: 1 to check, 0 to uncheck.
  238. {
  239. short sRes = 0; // Assume nothing;
  240. RMultiBtn* pmb = (RMultiBtn*)pguiRoot->GetItemFromId(lId);
  241. if (pmb != NULL)
  242. {
  243. ASSERT(pmb->m_type == RGuiItem::MultiBtn);
  244. pmb->m_sState = sChecked + 1;
  245. pmb->Compose();
  246. }
  247. }
  248. ////////////////////////////////////////////////////////////////////////////////
  249. // Helper inline to get a RMultiBtn GUI, and return its state.
  250. ////////////////////////////////////////////////////////////////////////////////
  251. inline
  252. short IsMultiBtnChecked( // Returns multibtn's state.
  253. RGuiItem* pguiRoot, // In: Root GUI.
  254. long lId) // In: ID of GUI to set text.
  255. {
  256. short sRes = 0; // Assume nothing;
  257. RMultiBtn* pmb = (RMultiBtn*)pguiRoot->GetItemFromId(lId);
  258. if (pmb != NULL)
  259. {
  260. ASSERT(pmb->m_type == RGuiItem::MultiBtn);
  261. sRes = (pmb->m_sState == 1) ? 0 : 1;
  262. }
  263. return sRes;
  264. }
  265. ////////////////////////////////////////////////////////////////////////////////
  266. // Edit Modify
  267. ////////////////////////////////////////////////////////////////////////////////
  268. short CGoalTimer::EditModify(void)
  269. {
  270. short sResult = 0;
  271. RGuiItem* pgui = RGuiItem::LoadInstantiate(FullPathVD("res/editor/clock.gui"));
  272. if (pgui)
  273. {
  274. SetText(pgui, TIMER_VALUE_GUI_ID, m_lTimerMS);
  275. SetText(pgui, KILL_VALUE_GUI_ID, m_sKillGoal);
  276. CheckMultiBtn(pgui, UPDOWN_GUI_ID, m_sUpDown);
  277. sResult = DoGui(pgui);
  278. if (sResult == 1)
  279. {
  280. m_lTimerMS = pgui->GetVal(TIMER_VALUE_GUI_ID);
  281. m_sKillGoal = pgui->GetVal(KILL_VALUE_GUI_ID);
  282. m_sUpDown = IsMultiBtnChecked(pgui, UPDOWN_GUI_ID);
  283. }
  284. delete pgui;
  285. }
  286. return 0;
  287. }
  288. ////////////////////////////////////////////////////////////////////////////////
  289. // Called by editor to move object to specified position
  290. ////////////////////////////////////////////////////////////////////////////////
  291. short CGoalTimer::EditMove( // Returns 0 if successfull, non-zero otherwise
  292. short sX, // In: New x coord
  293. short sY, // In: New y coord
  294. short sZ) // In: New z coord
  295. {
  296. m_dX = (double)sX;
  297. m_dY = (double)sY;
  298. m_dZ = (double)sZ;
  299. return 0;
  300. }
  301. ////////////////////////////////////////////////////////////////////////////////
  302. // Called by editor to update object
  303. ////////////////////////////////////////////////////////////////////////////////
  304. void CGoalTimer::EditUpdate(void)
  305. {
  306. }
  307. ////////////////////////////////////////////////////////////////////////////////
  308. // Called by editor to render object
  309. ////////////////////////////////////////////////////////////////////////////////
  310. void CGoalTimer::EditRender(void)
  311. {
  312. // No special flags
  313. m_sprite.m_sInFlags = 0;
  314. // Map from 3d to 2d coords
  315. Map3Dto2D(
  316. (short) m_dX,
  317. (short) m_dY,
  318. (short) m_dZ,
  319. &m_sprite.m_sX2,
  320. &m_sprite.m_sY2);
  321. // Priority is based on bottom edge of sprite
  322. m_sprite.m_sPriority = m_dZ;
  323. // Center on image.
  324. m_sprite.m_sX2 -= m_pImage->m_sWidth / 2;
  325. m_sprite.m_sY2 -= m_pImage->m_sHeight;
  326. // Layer should be based on info we get from attribute map.
  327. m_sprite.m_sLayer = CRealm::GetLayerViaAttrib(m_pRealm->GetLayer((short) m_dX, (short) m_dZ));
  328. // Image would normally animate, but doesn't for now
  329. m_sprite.m_pImage = m_pImage;
  330. // Update sprite in scene
  331. m_pRealm->m_scene.UpdateSprite(&m_sprite);
  332. }
  333. ////////////////////////////////////////////////////////////////////////////////
  334. // Give Edit a rectangle around this object
  335. ////////////////////////////////////////////////////////////////////////////////
  336. void CGoalTimer::EditRect(RRect* pRect)
  337. {
  338. Map3Dto2D(
  339. m_dX,
  340. m_dY,
  341. m_dZ,
  342. &(pRect->sX),
  343. &(pRect->sY) );
  344. pRect->sW = 10; // Safety.
  345. pRect->sH = 10; // Safety.
  346. if (m_pImage != NULL)
  347. {
  348. pRect->sW = m_pImage->m_sWidth;
  349. pRect->sH = m_pImage->m_sHeight;
  350. }
  351. pRect->sX -= pRect->sW / 2;
  352. pRect->sY -= pRect->sH;
  353. }
  354. ////////////////////////////////////////////////////////////////////////////////
  355. // Called by editor to get the hotspot of an object in 2D.
  356. ////////////////////////////////////////////////////////////////////////////////
  357. void CGoalTimer::EditHotSpot( // Returns nothiing.
  358. short* psX, // Out: X coord of 2D hotspot relative to
  359. // EditRect() pos.
  360. short* psY) // Out: Y coord of 2D hotspot relative to
  361. // EditRect() pos.
  362. {
  363. // Base of navnet is hotspot.
  364. *psX = (m_pImage->m_sWidth / 2);
  365. *psY = m_pImage->m_sHeight;
  366. }
  367. ////////////////////////////////////////////////////////////////////////////////
  368. // Get all required resources
  369. ////////////////////////////////////////////////////////////////////////////////
  370. short CGoalTimer::GetResources(void) // Returns 0 if successfull, non-zero otherwise
  371. {
  372. short sResult = 0;
  373. if (m_pImage == 0)
  374. {
  375. sResult = rspGetResource(&g_resmgrGame, m_pRealm->Make2dResPath(IMAGE_FILE), &m_pImage);
  376. if (sResult == 0)
  377. {
  378. // This is a questionable action on a resource managed item, but it's
  379. // okay if EVERYONE wants it to be an FSPR8.
  380. if (m_pImage->Convert(RImage::FSPR8) != RImage::FSPR8)
  381. {
  382. sResult = -1;
  383. TRACE("CGoalTimer::GetResource(): Couldn't convert to FSPR8!\n");
  384. }
  385. }
  386. }
  387. return sResult;
  388. }
  389. ////////////////////////////////////////////////////////////////////////////////
  390. // Free all resources
  391. ////////////////////////////////////////////////////////////////////////////////
  392. short CGoalTimer::FreeResources(void) // Returns 0 if successfull, non-zero otherwise
  393. {
  394. short sResult = 0;
  395. if (m_pImage != 0)
  396. {
  397. rspReleaseResource(&g_resmgrGame, &m_pImage);
  398. }
  399. return sResult;
  400. }
  401. ////////////////////////////////////////////////////////////////////////////////
  402. // EOF
  403. ////////////////////////////////////////////////////////////////////////////////