thing.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  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. // thing.cpp
  19. // Project: Nostril (aka Postal)
  20. //
  21. // This module impliments the CThing class.
  22. //
  23. // History:
  24. // 12/09/96 MJR Started.
  25. //
  26. // 01/17/97 JMI Started DoGui(). Checked in so can work at home. Compiles.
  27. //
  28. // 01/19/97 JMI Finished DoGui().
  29. //
  30. // 01/22/97 JMI Added initialization of bEditorCreatable member of
  31. // ms_aClassInfo[] elements.
  32. //
  33. // 01/23/97 JMI DoGui() now calls functions in GUIs and hots via the this
  34. // instead of the namespace.
  35. // Also, now first item in list of children is given the focus
  36. // instead of OK item.
  37. // Also, also, RDirtyRect is given a clip rect so we don't
  38. // have to hear Blue complain about it.
  39. //
  40. // 01/29/97 CMI Added m_u16InstanceId, an identifier unique to each instance
  41. // of CThing within its Realm. Also, added the initialization
  42. // of this ID in the constructor, the release of the ID in the
  43. // destructor, and the saving and loading of the ID in Save()
  44. // and Load(). Note that this value is either created by the
  45. // editor, loaded from the .rlm file, or assigned by the
  46. // server (dynamically created CThings (one's not loaded from
  47. // the .rlm file) will get their IDs assigned somehow at run-
  48. // time).
  49. //
  50. // 01/30/97 JMI Forgot to reserve the instance ID on load. Now calls
  51. // pRealm->m_idbank.Take(this, m_u16InstanceId).
  52. // Also, added SetInstanceID().
  53. //
  54. // 02/07/97 JMI Added support for new CGameEditThing.
  55. //
  56. // 02/10/97 BRH Added CNapalm and CFire as things to construct
  57. //
  58. // 02/16/97 BRH Added message.h and the message queue along with the
  59. // SendThingMessage function to allow CThings to communicate.
  60. // Also set the thing base class version of Update to
  61. // empty the queue each time. If you aren't dealing with
  62. // messages, call the base class Update after yours to
  63. // get rid of unused messages. There should be a better way
  64. // to have the base class automatically clear the queue
  65. // so that CThings that aren't aware of message queues at all
  66. // won't have message queues fill up.
  67. //
  68. // 02/17/97 JMI CThing() now puts an allocated CThing into the proper set
  69. // list based on it's ID. If you want a CThing to be in a
  70. // particular set list, you must change or add the case in
  71. // the switch statements in both CThing() (to Add) and
  72. // ~CThing() (to Remove).
  73. //
  74. // 02/17/97 BRH Changed the message queue to take the new message structure
  75. // which contains a union of the other message types.
  76. //
  77. // 02/18/97 JMI SendThingMessage() now passes a ptr to a GameMessage to
  78. // EnQ() instead of a ptr to a ptr to a GameMessage.
  79. //
  80. // 02/19/97 JMI Added CAnimThingID entry to ms_aClassInfo.
  81. // Also, removed monstrous switch states in con/destructor
  82. // having to do with old collision detection sets.
  83. //
  84. // 02/20/97 JMI Now initializes m_sCallStartup and m_sCallShutdown in the
  85. // CThing constructor.
  86. //
  87. // 02/23/97 MJR Added Preload members to classinfo struct for those classes
  88. // that have one, and 0 for those that don't.
  89. //
  90. // 02/24/97 MJR Added CSoundThing stuff.
  91. //
  92. // 02/25/97 JMI Added CGunner stuff.
  93. //
  94. // 03/04/97 BRH Added CBand stuff.
  95. //
  96. // 03/05/97 JMI Added ConstructWidthID() to construct an object and assign
  97. // it an ID, if it does not already have one.
  98. //
  99. // 03/06/97 BRH Fixed SendThingMessage (id) to make sure the thing
  100. // exists before sending the message.
  101. //
  102. // 03/06/97 JMI Added CItem3d stuff.
  103. //
  104. // 03/13/97 JMI Load now takes a version number.
  105. //
  106. // 03/17/97 BRH Added CBarrel.
  107. //
  108. // 03/19/97 BRH Added CMine.
  109. //
  110. // 03/19/97 JMI Added CDispenser stuff.
  111. //
  112. // 03/20/97 JMI SetInstanceID() no longer whines about already having an
  113. // ID before releasing it.
  114. //
  115. // 04/04/97 JMI Load() now checks to make sure no one else has claimed the
  116. // loaded ID before taking it.
  117. //
  118. // 04/16/97 BRH Added Jon's template CListNode that replaces the old STL
  119. // lists in CRealm. The CListNode contains next and previous
  120. // pointers rather than having the CThing being put into an
  121. // STL container in CRealm.
  122. //
  123. // 04/25/97 BRH Added CFireball.
  124. // Added CCop.
  125. //
  126. // 04/28/97 BRH Added fake classes CPistol, CMachineGun, CShotGun so that
  127. // the PrepareWeapon() and ShootWeapon() functions could
  128. // be made more generic by using the class ID's to identify
  129. // weapons.
  130. //
  131. // 04/28/97 BRH Added CPerson.
  132. //
  133. // 04/30/97 JMI Changed CMine::Construct to CMine::ConstructProximityMine
  134. // and added CMine::ConstructTimed,
  135. // CMine::ConstructBouncingBetty, and
  136. // CMine::ConstructRemoteControl.
  137. //
  138. // 05/01/97 BRH Added CPylon::Construct
  139. //
  140. // 05/04/97 BRH Took Tkachuk out of the project.
  141. //
  142. // 05/05/97 BRH Had to put Tkachuk placeholder back in to avoid screwing
  143. // up all of the realm files.
  144. //
  145. // 05/08/97 JMI Added schtuff for CPowerUp.
  146. //
  147. // 05/09/97 BRH Added COstrich
  148. //
  149. // 05/12/97 JRD Added CTrigger
  150. //
  151. // 05/13/97 BRH Added CHeatseeker.
  152. //
  153. // 05/08/97 JMI Added schtuff for CChunk.
  154. //
  155. // 05/26/97 BRH Changed the editor placement flag for several enemies so
  156. // CPerson will be used instead.
  157. //
  158. // 05/26/97 JMI Finally broke down and added an RHot* so the editor can
  159. // quickly from CThing* to RHot*.
  160. //
  161. // 05/26/97 BRH Added CAssault which is the Shot Gun fired rapidly.
  162. // This is just another dummy ID like the rest of the guns.
  163. //
  164. // 06/02/97 JMI Added schtuff for CLadder.
  165. //
  166. // 06/02/97 BRH Added CSentry and CSentryGun
  167. //
  168. // 06/02/97 JMI Removed CLadder stuff.
  169. //
  170. // 06/03/97 JMI Made DoGui() static.
  171. // Also, added CWarpID.
  172. //
  173. // 06/03/97 JMI Removed references to CGrenader, CRocketMan, CCop, CGunner,
  174. // CImbecile.
  175. //
  176. // 06/05/97 JMI Added m_lDoGuiPressedId and GuiPressed() statics.
  177. // Also, made sure DoGui() cleans up the display before
  178. // exitting.
  179. //
  180. // 06/09/97 BRH Added CDemon.
  181. //
  182. // 06/11/97 JMI Added CCharacter stuff.
  183. //
  184. // 06/15/97 MJR Now calls Update() instead of rspDoSystem().
  185. //
  186. // 06/24/97 JMI Now SendThingMessage() ASSERTs that the message priority
  187. // has been initialized by ASSERTing it's not 0xebeb.
  188. //
  189. // 06/26/97 JMI Added inline aliases to CRealm's Map3DTo2D()s.
  190. //
  191. // 06/30/97 MJR Replaced SAFE_GUI_REF with new GuiItem.h-defined macro.
  192. //
  193. // 06/30/97 BRH Added CGoalTimer, CFlag, and CFlagbase
  194. //
  195. // 07/02/97 BRH Added CFirestream as a better fire for the flamethrower.
  196. //
  197. // 07/03/97 JMI Removed GuiPressed() and added an RProcessGui which is a
  198. // simple way to process a GUI. It is nearly the same as the
  199. // RMsgBox interface but is for Load()ed or otherwise
  200. // preprepared GUIs where RMsgBox is a more dynamic method
  201. // of using a dialog box. Also, the RProcessGui works for
  202. // any GUI (not just RDlg).
  203. //
  204. // 07/03/97 JMI Added callback for RProcessGui so we can use ::Update()
  205. // instead of its internal update stuff.
  206. //
  207. // 07/14/97 JMI Moved Construct() definition into thing.cpp.
  208. // Now checks to make sure id is bounds.
  209. //
  210. // 07/14/97 BRH Removed CGoalTimer from the project since the realm
  211. // is handling this duty.
  212. //
  213. // 07/19/97 JMI Removed all the 'C's preceding the thing names.
  214. //
  215. // 07/30/97 JMI Added CDeathWad entry in ms_aClassInfo[].
  216. //
  217. // 08/06/97 JMI Added CDoubleBarrel entry in ms_aClassInfo[].
  218. //
  219. // 08/08/97 JMI Added more weapons for doofuses:
  220. // CUziID, CAutoRifleID, CSmallPistolID, CDynamiteID.
  221. //
  222. // 08/10/97 JMI Added entries for CSndRelay in ms_aClassInfo.
  223. //
  224. // 08/17/97 JMI Now sets the Update() call for the GUI processor.
  225. //
  226. // 08/21/97 JMI Changed call to Update() to UpdateSystem().
  227. //
  228. // 08/25/97 JMI Now the editor cannot create CDudes or CBalls.
  229. //
  230. // 08/28/97 BRH Added Preload for PowerUps and Mines to the table of
  231. // preload functions to call.
  232. //
  233. // 09/03/97 BRH Fixed spelling of Bouy in editor, according to Webster,
  234. // it really is buoy.
  235. //
  236. ////////////////////////////////////////////////////////////////////////////////
  237. #define THING_CPP
  238. #include "RSPiX.h"
  239. #include "thing.h"
  240. #include "realm.h"
  241. #include "IdBank.h"
  242. // Need these to initialize array of class info (until better method is developed)
  243. #include "ball.h"
  244. #include "hood.h"
  245. #include "dude.h"
  246. #include "doofus.h"
  247. #include "rocket.h"
  248. #include "grenade.h"
  249. #include "explode.h"
  250. #include "bouy.h"
  251. #include "navnet.h"
  252. #include "gameedit.h"
  253. #include "napalm.h"
  254. #include "fire.h"
  255. #include "firebomb.h"
  256. #include "AnimThing.h"
  257. #include "SoundThing.h"
  258. #include "band.h"
  259. #include "item3d.h"
  260. #include "barrel.h"
  261. #include "mine.h"
  262. #include "dispenser.h"
  263. #include "fireball.h"
  264. #include "person.h"
  265. #include "pylon.h"
  266. #include "PowerUp.h"
  267. #include "ostrich.h"
  268. #include "trigger.h"
  269. #include "heatseeker.h"
  270. #include "chunk.h"
  271. #include "sentry.h"
  272. #include "warp.h"
  273. #include "demon.h"
  274. #include "update.h"
  275. #include "flag.h"
  276. #include "flagbase.h"
  277. #include "deathWad.h"
  278. #include "SndRelay.h"
  279. ////////////////////////////////////////////////////////////////////////////////
  280. // Macros/types/etc.
  281. ////////////////////////////////////////////////////////////////////////////////
  282. ////////////////////////////////////////////////////////////////////////////////
  283. // Variables/data
  284. ////////////////////////////////////////////////////////////////////////////////
  285. // Init this flag to a non-zero value so we can detect whether a CThing is
  286. // created before these static member variables are initialized.
  287. short CThing::ms_sDetectStaticInits = 1;
  288. // This is used by DoGui() to perform GUI processing.
  289. RProcessGui CThing::ms_pgDoGui;
  290. // Array of class info
  291. // This sucks right now. I need to add the info for each class into this
  292. // array, but I don't like this method because it means this file has to
  293. // include the headers for each class. Sounds like an RImage-style solution
  294. // might work, but I'm not sure exactly how.
  295. CThing::ClassInfo CThing::ms_aClassInfo[CThing::TotalIDs] =
  296. { // Object Allocator Preload function Object Name User can create in Editor
  297. // ===================== ===================== ================
  298. { CHood::Construct, 0, "Hood", false },
  299. { CDude::Construct, 0, "Dude", false },
  300. { CDoofus::Construct, 0, "Doofus", false },
  301. { NULL, /* Tkachuk */ 0, "Tkachuk", false },
  302. { NULL, /* CRocketMan */ 0, "RocketMan", false },
  303. { NULL, /* CGrenader */ 0, "Grenader", false },
  304. { CRocket::Construct, CRocket::Preload, "Rocket", false },
  305. { CGrenade::Construct, CGrenade::Preload, "Grenade", false },
  306. { CBall::Construct, 0, "Ball", false },
  307. { CExplode::Construct, CExplode::Preload, "Explode", false },
  308. { CBouy::Construct, 0, "Buoy", true },
  309. { CNavigationNet::Construct, 0, "NavNet", true },
  310. { CGameEditThing::Construct, 0, "GameEditThing", false },
  311. { CNapalm::Construct, CNapalm::Preload, "Napalm", false },
  312. { CFire::Construct, CFire::Preload, "Fire", false },
  313. { NULL, /* CImbecile */ 0, "Imbecile", false },
  314. { CFirebomb::Construct, CFirebomb::Preload, "Firebomb", false },
  315. { CFirefrag::Construct, 0, "Firefrag", false },
  316. { CAnimThing::Construct, 0, "AnimThing", true },
  317. { CSoundThing::Construct, 0, "SoundThing", true },
  318. { NULL, /* CGunner */ 0, "Gunner", false },
  319. { CBand::Construct, 0, "Band", true },
  320. { CItem3d::Construct, 0, "Item3d", true },
  321. { CBarrel::Construct, 0, "Barrel", true },
  322. { CMine::ConstructProximity, 0, "ProximityMine", true },
  323. { CDispenser::Construct, 0, "Dispenser", true },
  324. { CFireball::Construct, CFireball::Preload, "Fireball", false },
  325. { NULL, /* CCop */ 0, "Cop", false },
  326. { NULL, /* CPistol */ 0, "Pistol", false },
  327. { NULL, /* CMachineGun */ 0, "MachineGun", false },
  328. { NULL, /* CShotGun */ 0, "ShotGun", false },
  329. { CPerson::Construct, 0, "Person", true },
  330. { CMine::ConstructTimed, CMine::Preload, "TimedMine", true },
  331. { CMine::ConstructBouncingBetty, 0,/*CMine::Preload*/ "BouncingBettyMine", true },
  332. { CMine::ConstructRemoteControl, 0,/*CMine::Preload*/ "RemoteControlMine", false },
  333. { CPylon::Construct, 0, "Pylon", true },
  334. { CPowerUp::Construct, CPowerUp::Preload, "PowerUp", true },
  335. { COstrich::Construct, 0, "Ostrich", true },
  336. { CTrigger::Construct, 0, "Trigger", false },
  337. { CHeatseeker::Construct, CHeatseeker::Preload, "Heatseeker", false },
  338. { CChunk::Construct, 0, "Chunk", false },
  339. { NULL, /* CAssault */ 0, "AssaultWeapon", false },
  340. { CSentry::Construct, 0, "Sentry", true },
  341. { NULL, /* CSentryGun */ 0, "CentryGun", false },
  342. { CWarp::Construct, 0, "Warp", true },
  343. { CDemon::Construct, CDemon::Preload, "Demon", true },
  344. { NULL, /* CCharacter */ CCharacter::Preload, "Character", false },
  345. { NULL, /*CGoalTimer */ 0, "GoalTimer", false },
  346. { CFlag::Construct, 0, "Flag", true },
  347. { CFlagbase::Construct, 0, "Flagbase", true },
  348. { CFirestream::Construct, 0, "Firestream", false },
  349. { CDeathWad::Construct, CDeathWad::Preload, "DeathWad", false },
  350. { NULL, /*CDoubleBarrel */ 0, "DoubleBarrel", false },
  351. { NULL, /*CUziID */ 0, "Uzi", false },
  352. { NULL, /*CAutoRifleID */ 0, "AutoRifle", false },
  353. { NULL, /*CSmallPistolID */ 0, "SmallPistol", false },
  354. { CGrenade::ConstructDynamite, 0, "Dynamite", false },
  355. { CSndRelay::Construct, 0, "SndRelay", true },
  356. };
  357. ////////////////////////////////////////////////////////////////////////////////
  358. // Function prototypes
  359. ////////////////////////////////////////////////////////////////////////////////
  360. ////////////////////////////////////////////////////////////////////////////////
  361. // Default (and only) constructor
  362. ////////////////////////////////////////////////////////////////////////////////
  363. CThing::CThing(
  364. CRealm* pRealm, // In: Pointer to realm
  365. ClassIDType id) // In: Class ID
  366. {
  367. // Make sure CThing static's have been initialized by C++ runtime
  368. if (ms_sDetectStaticInits != 1)
  369. TRACE("CThing::CThing(): Can't create global/static objects based on CThing!\n");
  370. // Save class id so we have it quickly avaiable in destructor
  371. m_id = id;
  372. // Default to calling startup and shutdown. What could be the harm?!
  373. m_sCallStartup = TRUE;
  374. m_sCallShutdown = TRUE;
  375. // Save realm
  376. m_pRealm = pRealm;
  377. m_everything.m_powner = this;
  378. m_everything.m_pnNext = NULL;
  379. m_everything.m_pnPrev = NULL;
  380. m_nodeClass.m_powner = this;
  381. m_nodeClass.m_pnNext = NULL;
  382. m_nodeClass.m_pnPrev = NULL;
  383. // Add this object to realm and save its assigned position in realm's container
  384. // pRealm->AddThing(this, id, &m_iterEvery, &m_iterClass);
  385. pRealm->AddThing(this, id);
  386. // Start out with no ID.
  387. m_u16InstanceId = CIdBank::IdNil;
  388. // Clear editor's RHot*.
  389. m_phot = NULL;
  390. }
  391. ////////////////////////////////////////////////////////////////////////////////
  392. // Destructor
  393. ////////////////////////////////////////////////////////////////////////////////
  394. CThing::~CThing()
  395. {
  396. // Remove this object from realm
  397. // m_pRealm->RemoveThing(m_id, m_iterEvery, m_iterClass);
  398. m_pRealm->RemoveThing(this);
  399. // Release this fellow's ID.
  400. m_pRealm->m_idbank.Release(m_u16InstanceId);
  401. }
  402. ////////////////////////////////////////////////////////////////////////////////
  403. //
  404. // Call this for any GUIs besides the standard OK (ID 1) and Cancel (ID 2)
  405. // to set the callback (for on 'pressed') for any GUI you want to end
  406. // a DoGui().
  407. // (static).
  408. //
  409. ////////////////////////////////////////////////////////////////////////////////
  410. // static
  411. void CThing::SetGuiToNotify( // Returns nothing.
  412. RGuiItem* pguiNotifier) // In: The pressed GUI.
  413. {
  414. ms_pgDoGui.SetGuiToNotify(pguiNotifier);
  415. }
  416. ////////////////////////////////////////////////////////////////////////////////
  417. //
  418. // Callback from ms_pgDoGui for system update.
  419. //
  420. ////////////////////////////////////////////////////////////////////////////////
  421. // static // Static for use as a callback.
  422. long CThing::SysUpdate( // Returns a non-zero ID to abort or zero
  423. // to continue.
  424. RInputEvent* pie) // Out: Next input event to process.
  425. {
  426. UpdateSystem();
  427. rspGetNextInputEvent(pie);
  428. return 0;
  429. }
  430. ////////////////////////////////////////////////////////////////////////////////
  431. //
  432. // Helper for processing your GUIs.
  433. // Will be made visible by calling pguiRoot->SetVisible(TRUE).
  434. // GUI will be run with focus-awareness until a GUI with ID 1 or 2 is
  435. // clicked. Typically, 1 should be an 'OK' equivalent and 2 'Cancel'.
  436. // Return value indicates which item was clicked (1, 2, or by the ID
  437. // of a GUI that was previously passed to SetGuiToNotify() ).
  438. // Processing involves using queued RSPiX user input via
  439. // rspGetNextInputEvent().
  440. // (static).
  441. //
  442. ////////////////////////////////////////////////////////////////////////////////
  443. long CThing::DoGui( // Returns ID of item that terminated looping.
  444. // Returns 0 if rspGetQuitStatus() is nonzero.
  445. // Returns negative on error.
  446. RGuiItem* pguiRoot) // Root of GUI items to process through user.
  447. {
  448. // Get two controls that can end the processing.
  449. RGuiItem* pguiOk = pguiRoot->GetItemFromId(1);
  450. RGuiItem* pguiCancel = pguiRoot->GetItemFromId(2);
  451. // Use the update function.
  452. ms_pgDoGui.m_fnUpdate = SysUpdate;
  453. return ms_pgDoGui.DoModal(pguiRoot, pguiOk, pguiCancel);
  454. }
  455. ////////////////////////////////////////////////////////////////////////////////
  456. //
  457. // Load object (should call base class version!)
  458. // (virtual).
  459. //
  460. ////////////////////////////////////////////////////////////////////////////////
  461. short CThing::Load( // Returns 0 if successfull, non-zero otherwise
  462. RFile* pFile, // In: File to load from
  463. bool bEditMode, // In: True for edit mode, false otherwise
  464. short sFileCount, // In: File count (unique per file, never 0)
  465. ULONG ulFileVersion) // In: File version being loaded.
  466. {
  467. // Switch on the file version.
  468. switch (ulFileVersion)
  469. {
  470. default: // Newer versions where this format has not changed.
  471. case 1:
  472. // Load this thing's ID. The ID is unique to this 'thing' within its realm
  473. // (i.e., no other CThing or derived class has this same ID within this realm).
  474. // This is assigned by the editor via a call to the realm's m_idbank.Get().
  475. pFile->Read(&m_u16InstanceId);
  476. break;
  477. }
  478. // If this ID is not yet claimed . . .
  479. CThing* pthing;
  480. if (m_pRealm->m_idbank.GetThingByID(&pthing, m_u16InstanceId) != 0)
  481. {
  482. // Reserve ID.
  483. m_pRealm->m_idbank.Take(this, m_u16InstanceId);
  484. }
  485. else
  486. {
  487. // No ID for you! Currently the only way I know this happens is via the
  488. // dispenser. In that case, this is fine b/c the dispenser never uses the
  489. // id from the file.
  490. m_u16InstanceId = CIdBank::IdNil;
  491. }
  492. return pFile->Error();
  493. }
  494. ////////////////////////////////////////////////////////////////////////////////
  495. //
  496. // Set object instance's unique ID.
  497. //
  498. ////////////////////////////////////////////////////////////////////////////////
  499. void CThing::SetInstanceID( // Returns nothing.
  500. U16 u16Id) // New id for this instance.
  501. {
  502. // Safety.
  503. if (m_u16InstanceId != CIdBank::IdNil)
  504. {
  505. // TRACE("SetInstanceID(): This thing already had an ID!\n");
  506. // Release existing ID.
  507. m_pRealm->m_idbank.Release(m_u16InstanceId);
  508. }
  509. m_u16InstanceId = u16Id;
  510. }
  511. ////////////////////////////////////////////////////////////////////////////////
  512. //
  513. // Put a message in another CThing's message queue
  514. //
  515. ////////////////////////////////////////////////////////////////////////////////
  516. short CThing::SendThingMessage(pGameMessage pMessage, short sPriority, U16 u16ID)
  517. {
  518. short sResult = SUCCESS;
  519. CThing* pThing = NULL;
  520. m_pRealm->m_idbank.GetThingByID(&pThing, u16ID);
  521. if (pThing)
  522. return SendThingMessage(pMessage, sPriority, pThing);
  523. else
  524. return -1;
  525. }
  526. short CThing::SendThingMessage(pGameMessage pMessage, short sPriority, CThing* pThing)
  527. {
  528. short sResult = SUCCESS;
  529. // Make sure this has been initialized.
  530. // If you were using 0xebeb as your priority, stop that.
  531. ASSERT(sPriority != 0xebeb);
  532. if (pThing != NULL)
  533. pThing->m_MessageQueue.EnQ(pMessage, &sPriority);
  534. else
  535. sResult = -1;
  536. return sResult;
  537. }
  538. ////////////////////////////////////////////////////////////////////////////////
  539. // Maps a 3D coordinate onto the viewing plane.
  540. ////////////////////////////////////////////////////////////////////////////////
  541. void CThing::Map3Dto2D( // Returns nothing.
  542. short sX, // In.
  543. short sY, // In.
  544. short sZ, // In.
  545. short* psX, // Out.
  546. short* psY) // Out.
  547. {
  548. m_pRealm->Map3Dto2D(sX, sY, sZ, psX, psY);
  549. }
  550. ////////////////////////////////////////////////////////////////////////////////
  551. // Maps a 3D coordinate onto the viewing plane.
  552. ////////////////////////////////////////////////////////////////////////////////
  553. void CThing::Map3Dto2D( // Returns nothing.
  554. double dX, // In.
  555. double dY, // In.
  556. double dZ, // In.
  557. double* pdX, // Out.
  558. double* pdY) // Out.
  559. {
  560. m_pRealm->Map3Dto2D(dX, dY, dZ, pdX, pdY);
  561. }
  562. ////////////////////////////////////////////////////////////////////////////////
  563. // Construct object
  564. // (static).
  565. ////////////////////////////////////////////////////////////////////////////////
  566. short CThing::Construct( // Returns 0 if successfull, non-zero otherwise
  567. ClassIDType id, // In: Class ID
  568. CRealm* pRealm, // In: Pointer to realm this object belongs to
  569. CThing** ppNew) // Out: Pointer to new object
  570. {
  571. // If in bounds (note ClassIDType is unsigned) . . .
  572. if (id < TotalIDs)
  573. {
  574. // If there is a Construct func . . .
  575. if (ms_aClassInfo[id].funcConstruct)
  576. return (*(ms_aClassInfo[id].funcConstruct))(pRealm, ppNew);
  577. else
  578. return -1;
  579. }
  580. else
  581. {
  582. TRACE("Construct(): id %d is out of bounds.\n", id);
  583. return -2;
  584. }
  585. }
  586. ////////////////////////////////////////////////////////////////////////////////
  587. // Construct object and assign it an ID from the Realm's ID bank,
  588. // if it does not already have one.
  589. // (static).
  590. ////////////////////////////////////////////////////////////////////////////////
  591. short CThing::ConstructWithID( // Returns 0 if successfull, non-zero otherwise
  592. ClassIDType id, // In: Class ID
  593. CRealm* pRealm, // In: Pointer to realm this object belongs to
  594. CThing** ppNew) // Out: Pointer to new object
  595. {
  596. short sResult = Construct(id, pRealm, ppNew);
  597. if (sResult == 0)
  598. {
  599. // If new thing has no ID . . .
  600. if ((*ppNew)->m_u16InstanceId == CIdBank::IdNil)
  601. {
  602. sResult = pRealm->m_idbank.Get(*ppNew, &((*ppNew)->m_u16InstanceId) );
  603. if (sResult != 0)
  604. {
  605. delete *ppNew;
  606. *ppNew = NULL;
  607. }
  608. }
  609. }
  610. return sResult;
  611. }
  612. ////////////////////////////////////////////////////////////////////////////////
  613. // EOF
  614. ////////////////////////////////////////////////////////////////////////////////