bouy.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  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. // bouy.h
  19. // Project: Postal
  20. //
  21. // History:
  22. // 03/07/97 JMI Added an EditHotSpot() to make dragging smoother.
  23. //
  24. // 03/13/97 JMI Load now takes a version number.
  25. //
  26. // 04/15/97 BRH Taking out the old routing methods in favor of the new
  27. // BFS tree method.
  28. //
  29. // 06/06/97 BRH Freed m_paucRouteTable in the Destructor which had
  30. // previously been a source of memory leaks.
  31. //
  32. // 06/25/97 BRH Took out the STL set "linkset" because it was causing
  33. // sync problems with the game. Apparently, the set uses
  34. // a tree to store its data, and when building that tree,
  35. // uses some kind of random function to balance the tree, but
  36. // not the standard library rand() function, but a different
  37. // random function that we don't reset from realm to realm.
  38. // This caused the routing tables to be build differently
  39. // each time the game was played, and so the demo mode and
  40. // network mode were out of sync.
  41. //
  42. // 06/27/97 BRH Added a CTreeListNode to the bouys which the NavNet
  43. // will use to build a sorted list of nearest bouys when
  44. // someone asks for a the nearest bouy.
  45. //
  46. // 06/29/97 MJR Removed last trace of STL, replacing vector with RFList.
  47. //
  48. // 06/30/97 JMI Moved definitions of EditRect() and EditHotSpot() into
  49. // bouy.cpp.
  50. //
  51. // 07/21/97 JMI Added GetX(), GetY(), and GetZ().
  52. //
  53. // 07/30/97 BRH Added ms_bShowBouys flag and static functions to toggle
  54. // this flag.
  55. //
  56. // 08/08/97 BRH Added a Visible() function for the gameedit to be able
  57. // to determine when the bouy is hiding itself.
  58. //
  59. ////////////////////////////////////////////////////////////////////////////////
  60. #ifndef BOUY_H
  61. #define BOUY_H
  62. #include "RSPiX.h"
  63. #include "realm.h"
  64. // Template node class for linked lists
  65. template <class Owner, class K>
  66. class CTreeListNode
  67. {
  68. typedef CTreeListNode Node;
  69. typedef K SORTKEY, *PSORTKEY;
  70. // protected:
  71. public:
  72. CTreeListNode()
  73. {
  74. m_pnNext = m_pnPrev = m_pnRight = m_pnLeft = NULL;
  75. m_powner = NULL;
  76. } // Do not use.
  77. public:
  78. CTreeListNode(Owner* powner)
  79. { m_powner = powner;
  80. m_pnNext = m_pnPrev = m_pnRight = m_pnLeft = NULL; }
  81. // Note: This function can only be used with a list that has
  82. // dummy nodes for head and tail.
  83. Owner* GetNext(void)
  84. { return m_pnNext->m_powner; }
  85. // Note: This function can only be used with a list that has
  86. // dummy nodes for head and tail.
  87. Owner* GetPrev(void)
  88. { return m_pnPrev->m_powner; }
  89. // Note: This function can only be used with a list that has
  90. // dummy nodes for head and tail.
  91. void InsertBefore(
  92. Node* pn) // In: Node to insert before.
  93. {
  94. ASSERT(m_pnNext == NULL && m_pnPrev == NULL);
  95. m_pnNext = pn;
  96. m_pnPrev = pn->m_pnPrev;
  97. m_pnPrev->m_pnNext = this;
  98. pn->m_pnPrev = this;
  99. }
  100. // Note: This function can only be used with a list that has
  101. // dummy nodes for head and tail.
  102. void AddAfter(
  103. Node* pn) // In: Node to add after.
  104. {
  105. ASSERT(m_pnNext == NULL && m_pnPrev == NULL);
  106. m_pnNext = pn->m_pnNext;
  107. m_pnPrev = pn;
  108. m_pnNext->m_pnPrev = this;
  109. pn->m_pnNext = this;
  110. }
  111. // Note: This function can only be used with a list that has
  112. // dummy nodes for head and tail.
  113. // Note: Do not call, if already removed.
  114. void Remove(void)
  115. {
  116. m_pnNext->m_pnPrev = m_pnPrev;
  117. m_pnPrev->m_pnNext = m_pnNext;
  118. m_pnNext = NULL;
  119. m_pnPrev = NULL;
  120. }
  121. // Note: This function adds the item into the tree in its
  122. // proper place. It also puts it in the list in the proper place
  123. // This should usually be called by the root of the tree
  124. void Add
  125. (Node* pn) //In: Node to add in the tree and list
  126. {
  127. if (pn->m_sortkey >= m_sortkey)
  128. // go right
  129. {
  130. // If this is the end of the line, add it here
  131. if (m_pnRight == NULL)
  132. {
  133. m_pnRight = pn;
  134. //AddAfter(pn);
  135. pn->AddAfter(this);
  136. }
  137. else
  138. {
  139. m_pnRight->Add(pn);
  140. }
  141. }
  142. else
  143. // go left
  144. {
  145. // If this is the end of the line, add it here
  146. if (m_pnLeft == NULL)
  147. {
  148. m_pnLeft = pn;
  149. //InsertBefore(pn);
  150. pn->InsertBefore(this);
  151. }
  152. else
  153. {
  154. m_pnLeft->Add(pn);
  155. }
  156. }
  157. }
  158. // Note: This function is used to clear the tree - it will remove
  159. // all nodes. Call this from the root to delete the whole, or
  160. // from any other node to delete from there on down.
  161. // This can only be used if the list has dummy head and tail nodes.
  162. void DeleteTree(void)
  163. {
  164. // Delete left branches
  165. if (m_pnLeft)
  166. {
  167. m_pnLeft->DeleteTree();
  168. m_pnLeft = NULL;
  169. }
  170. // Delete right branches
  171. if (m_pnRight)
  172. {
  173. m_pnRight->DeleteTree();
  174. m_pnRight = NULL;
  175. }
  176. // Remove yourself from the list
  177. if (m_pnNext && m_pnPrev)
  178. Remove();
  179. }
  180. public:
  181. Node* m_pnNext;
  182. Node* m_pnPrev;
  183. Node* m_pnLeft;
  184. Node* m_pnRight;
  185. Owner* m_powner;
  186. SORTKEY m_sortkey;
  187. };
  188. // Forward declaration
  189. class CBouy;
  190. typedef CTreeListNode<CBouy, double> TreeListNode;
  191. // CBouy is the class for navigation
  192. class CBouy : public CThing
  193. {
  194. friend class CNavigationNet;
  195. //---------------------------------------------------------------------------
  196. // Types, enums, etc.
  197. //---------------------------------------------------------------------------
  198. public:
  199. typedef RFList<U16> linkinstanceid;
  200. typedef RList<CBouy> linklist;
  201. //---------------------------------------------------------------------------
  202. // Variables
  203. //---------------------------------------------------------------------------
  204. public:
  205. UCHAR m_ucID; // Bouy ID (or address)
  206. linklist m_aplDirectLinks;
  207. short m_sNumDirectLinks;
  208. TreeListNode m_TreeNode;
  209. protected:
  210. double m_dX; // x coord
  211. double m_dY; // y coord
  212. double m_dZ; // z coord
  213. CNavigationNet* m_pParentNavNet; // Pointer to its navigation network
  214. RImage* m_pImage; // Pointer to only image (replace with 3d anim, soon)
  215. CSprite2 m_sprite; // Sprite (replace with CSprite3, soon)
  216. short m_sSuspend; // Suspend flag
  217. UCHAR* m_paucRouteTable; // Routing table (new non-STL way)
  218. short m_sRouteTableSize;
  219. linkinstanceid m_LinkInstanceID; // Used to relink the network after a load
  220. U16 m_u16ParentInstanceID; // InstanceID used to relink to correct
  221. // Network after a load
  222. // Tracks file counter so we know when to load/save "common" data
  223. static short ms_sFileCount;
  224. static bool ms_bShowBouys;
  225. // "Constant" values that we want to be able to tune using the editor
  226. //---------------------------------------------------------------------------
  227. // Constructor(s) / destructor
  228. //---------------------------------------------------------------------------
  229. protected:
  230. // Constructor
  231. CBouy(CRealm* pRealm)
  232. : CThing(pRealm, CBouyID)
  233. {
  234. m_pImage = 0;
  235. m_sSuspend = 0;
  236. m_pParentNavNet = NULL;
  237. m_paucRouteTable = NULL;
  238. m_sRouteTableSize = 0;
  239. m_sNumDirectLinks = 0;
  240. }
  241. public:
  242. // Destructor
  243. ~CBouy()
  244. {
  245. // Remove sprite from scene (this is safe even if it was already removed!)
  246. m_pRealm->m_scene.RemoveSprite(&m_sprite);
  247. if (m_paucRouteTable != NULL)
  248. free(m_paucRouteTable);
  249. // Free resources
  250. FreeResources();
  251. }
  252. //---------------------------------------------------------------------------
  253. // Required static functions
  254. //---------------------------------------------------------------------------
  255. public:
  256. // Construct object
  257. static short Construct( // Returns 0 if successfull, non-zero otherwise
  258. CRealm* pRealm, // In: Pointer to realm this object belongs to
  259. CThing** ppNew) // Out: Pointer to new object
  260. {
  261. short sResult = 0;
  262. *ppNew = new CBouy(pRealm);
  263. if (*ppNew == 0)
  264. {
  265. sResult = -1;
  266. TRACE("CBouy::Construct(): Couldn't construct CBouy (that's a bad thing)\n");
  267. }
  268. return sResult;
  269. }
  270. //---------------------------------------------------------------------------
  271. // Required virtual functions (implimenting them as inlines doesn't pay!)
  272. //---------------------------------------------------------------------------
  273. public:
  274. // Load object (should call base class version!)
  275. short Load( // Returns 0 if successfull, non-zero otherwise
  276. RFile* pFile, // In: File to load from
  277. bool bEditMode, // In: True for edit mode, false otherwise
  278. short sFileCount, // In: File count (unique per file, never 0)
  279. ULONG ulFileVersion); // In: Version of file format to load.
  280. // Save object (should call base class version!)
  281. short Save( // Returns 0 if successfull, non-zero otherwise
  282. RFile* pFile, // In: File to save to
  283. short sFileCount); // In: File count (unique per file, never 0)
  284. // Startup object
  285. short Startup(void); // Returns 0 if successfull, non-zero otherwise
  286. // Shutdown object
  287. short Shutdown(void); // Returns 0 if successfull, non-zero otherwise
  288. // Suspend object
  289. void Suspend(void);
  290. // Resume object
  291. void Resume(void);
  292. // Update object
  293. void Update(void);
  294. // Render object
  295. void Render(void);
  296. // Called by editor to init new object at specified position
  297. short EditNew( // Returns 0 if successfull, non-zero otherwise
  298. short sX, // In: New x coord
  299. short sY, // In: New y coord
  300. short sZ); // In: New z coord
  301. // Called by editor to modify object
  302. short EditModify(void); // Returns 0 if successfull, non-zero otherwise
  303. // Called by editor to move object to specified position
  304. short EditMove( // Returns 0 if successfull, non-zero otherwise
  305. short sX, // In: New x coord
  306. short sY, // In: New y coord
  307. short sZ); // In: New z coord
  308. // Called by editor to update object
  309. void EditUpdate(void);
  310. // Called by editor to render object
  311. void EditRender(void);
  312. // Give Edit a rectangle around this object
  313. void EditRect(RRect* pRect);
  314. // Called by editor to get the hotspot of an object in 2D.
  315. void EditHotSpot( // Returns nothiing.
  316. short* psX, // Out: X coord of 2D hotspot relative to
  317. // EditRect() pos.
  318. short* psY); // Out: Y coord of 2D hotspot relative to
  319. // EditRect() pos.
  320. // Get the coordinates of this thing.
  321. virtual // Overriden here.
  322. double GetX(void) { return m_dX; }
  323. virtual // Overriden here.
  324. double GetY(void) { return m_dY; }
  325. virtual // Overriden here.
  326. double GetZ(void) { return m_dZ; }
  327. // Add a link to this bouy - it is directly connected, ie, 1 hop away
  328. short AddLink(CBouy* pBouy);
  329. // Get the next link to follow to get to this destination. This is
  330. // normally a routing table lookup unless the entry is not in the routing
  331. // table, then it is discovered and added as an entry to the routing table.
  332. UCHAR NextRouteNode(UCHAR dst);
  333. // Disconnect this node from the network. This will visit all of its
  334. // direct links and remove itself from their link list and then free
  335. // its own link list. This is called when a Bouy is deleted from the
  336. // editor.
  337. void Unlink(void);
  338. // Fill in all entries in the routing table.
  339. short BuildRoutingTable(void);
  340. // Print the routing table for this bouy - for debugging
  341. void PrintRouteTable(FILE* fp)
  342. {
  343. short i;
  344. char szLine[256];
  345. for (i = 0; i < m_sRouteTableSize; i++)
  346. {
  347. sprintf(szLine, "%d next %d\n", i, m_paucRouteTable[i]);
  348. fwrite(szLine, sizeof(char), strlen(szLine), fp);
  349. }
  350. }
  351. // Used by gameedit to know is this bouy is visible or hidden
  352. bool Visible(void)
  353. {
  354. return ((m_sprite.m_sInFlags & CSprite::InHidden) == 0);
  355. }
  356. // Toggle the show/hide flag
  357. static void Show(void)
  358. {
  359. ms_bShowBouys = true;
  360. }
  361. // Toggle the show/hide flag
  362. static void Hide(void)
  363. {
  364. ms_bShowBouys = false;
  365. }
  366. //---------------------------------------------------------------------------
  367. // Internal functions
  368. //---------------------------------------------------------------------------
  369. protected:
  370. // Get all required resources
  371. short GetResources(void); // Returns 0 if successfull, non-zero otherwise
  372. // Free all resources
  373. short FreeResources(void); // Returns 0 if successfull, non-zero otherwise
  374. };
  375. #endif //DOOFUS_H
  376. ////////////////////////////////////////////////////////////////////////////////
  377. // EOF
  378. ////////////////////////////////////////////////////////////////////////////////