NodeMgr.cpp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : LevelEdit *
  23. * *
  24. * $Archive:: /Commando/Code/Tools/LevelEdit/NodeMgr.cpp $*
  25. * *
  26. * Author:: Patrick Smith *
  27. * *
  28. * $Modtime:: 3/07/02 1:54p $*
  29. * *
  30. * $Revision:: 42 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "stdafx.h"
  36. #include "nodemgr.h"
  37. #include "node.h"
  38. #include "editorchunkids.h"
  39. #include "preset.h"
  40. #include "wwdebug.h"
  41. #include "chunkio.h"
  42. #include "persistfactory.h"
  43. #include "sceneeditor.h"
  44. #include "leveleditview.h"
  45. #include "instancespage.h"
  46. #include "gameobjmanager.h"
  47. #include "terrainnode.h"
  48. #include "leveledit.h"
  49. #include "regkeys.h"
  50. #include "presetmgr.h"
  51. #include "presetremapdialog.h"
  52. #include "heightfieldmgr.h"
  53. ///////////////////////////////////////////////////////////////////////
  54. // Singleton instance
  55. ///////////////////////////////////////////////////////////////////////
  56. NodeMgrClass _TheNodeMgr;
  57. ///////////////////////////////////////////////////////////////////////
  58. // Constants
  59. ///////////////////////////////////////////////////////////////////////
  60. enum
  61. {
  62. CHUNKID_VARIABLES = 0x00000100,
  63. CHUNKID_NODES
  64. };
  65. enum
  66. {
  67. XXX_VARID_NEXT_NODE_ID = 0x01,
  68. };
  69. enum
  70. {
  71. FIRST_OBJECT_NODE_ID = 100000,
  72. FIRST_STATIC_NODE_ID = 1100000000,
  73. FIRST_LIGHT_NODE_ID = 1200000000,
  74. FIRST_MISC_NODE_ID = 1300000000,
  75. };
  76. ///////////////////////////////////////////////////////////////////////
  77. // Static member initialization
  78. ///////////////////////////////////////////////////////////////////////
  79. NodeClass * NodeMgrClass::_NodeListHead = NULL;
  80. uint32 NodeMgrClass::_NextObjectNodeID = FIRST_OBJECT_NODE_ID;
  81. uint32 NodeMgrClass::_NextStaticNodeID = FIRST_STATIC_NODE_ID;
  82. uint32 NodeMgrClass::_NextLightNodeID = FIRST_LIGHT_NODE_ID;
  83. uint32 NodeMgrClass::_NextMiscNodeID = FIRST_MISC_NODE_ID;
  84. //////////////////////////////////////////////////////////////////////////////////////////
  85. //
  86. // ~NodeMgrClass
  87. //
  88. //////////////////////////////////////////////////////////////////////////////////////////
  89. NodeMgrClass::~NodeMgrClass (void)
  90. {
  91. return ;
  92. }
  93. //////////////////////////////////////////////////////////////////////////////////////////
  94. //
  95. // Chunk_ID
  96. //
  97. //////////////////////////////////////////////////////////////////////////////////////////
  98. uint32
  99. NodeMgrClass::Chunk_ID (void) const
  100. {
  101. return CHUNKID_NODEMGR;
  102. }
  103. //////////////////////////////////////////////////////////////////////////////////////////
  104. //
  105. // Setup_Node_Identity
  106. //
  107. //////////////////////////////////////////////////////////////////////////////////////////
  108. void
  109. NodeMgrClass::Setup_Node_Identity (NodeClass &node)
  110. {
  111. PresetClass *preset = node.Get_Preset ();
  112. int id = node.Get_ID ();
  113. //
  114. // Give the node an ID if it doesn't already
  115. // have one.
  116. //
  117. if (id == 0) {
  118. id = Get_Node_ID (node.Get_Type ());
  119. node.Set_ID (id);
  120. }
  121. //
  122. // Give the node a name
  123. //
  124. if (preset != NULL) {
  125. CString name;
  126. name.Format ("%s.%d", preset->Get_Name (), id);
  127. node.Set_Name (name);
  128. } else {
  129. RenderObjClass *model = node.Peek_Render_Obj ();
  130. if (model != NULL) {
  131. CString name;
  132. name.Format ("%s.%d", model->Get_Name (), id);
  133. node.Set_Name (name);
  134. } else {
  135. CString name;
  136. name.Format ("Unknown.%d", id);
  137. node.Set_Name (name);
  138. }
  139. }
  140. return ;
  141. }
  142. //////////////////////////////////////////////////////////////////////////////////////////
  143. //
  144. // Create_Node
  145. //
  146. //////////////////////////////////////////////////////////////////////////////////////////
  147. NodeClass *
  148. NodeMgrClass::Create_Node (PresetClass *preset, uint32 id)
  149. {
  150. NodeClass *node = preset->Create ();
  151. if (node != NULL) {
  152. //
  153. // Give the new node a unique id and name
  154. //
  155. node->Set_ID (id);
  156. Setup_Node_Identity (*node);
  157. //
  158. // Give the new node a chance to initialize its data
  159. //
  160. node->Initialize ();
  161. //
  162. // Keep track of this node
  163. //
  164. Add_Node (node);
  165. }
  166. return node;
  167. }
  168. //////////////////////////////////////////////////////////////////////////////////////////
  169. //
  170. // Add_Node
  171. //
  172. //////////////////////////////////////////////////////////////////////////////////////////
  173. void
  174. NodeMgrClass::Add_Node (NodeClass *node)
  175. {
  176. WWASSERT (node->m_NextNode == 0);
  177. WWASSERT (node->m_PrevNode == 0);
  178. //
  179. // Add the node to the the list and lock
  180. // a refcount on the node
  181. //
  182. if ( node->m_NextNode == NULL &&
  183. node->m_PrevNode == NULL &&
  184. node != _NodeListHead)
  185. {
  186. Link_Node (node);
  187. SAFE_ADD_REF (node);
  188. //
  189. // Update the UI
  190. //
  191. InstancesPageClass *instances_form = ::Get_Instances_Form ();
  192. if (instances_form != NULL) {
  193. instances_form->Add_Node (node);
  194. }
  195. }
  196. return ;
  197. }
  198. //////////////////////////////////////////////////////////////////////////////////////////
  199. //
  200. // Remove_Node
  201. //
  202. //////////////////////////////////////////////////////////////////////////////////////////
  203. void
  204. NodeMgrClass::Remove_Node (NodeClass *node)
  205. {
  206. WWASSERT (node != 0);
  207. if ( node->m_NextNode != NULL ||
  208. node->m_PrevNode != NULL ||
  209. node == _NodeListHead)
  210. {
  211. //
  212. // Remove the node from our list and
  213. // free our hold on the node
  214. //
  215. Unlink_Node (node);
  216. //
  217. // Update the UI
  218. //
  219. InstancesPageClass *instances_form = ::Get_Instances_Form ();
  220. if (instances_form != NULL) {
  221. instances_form->Remove_Node (node);
  222. }
  223. MEMBER_RELEASE (node);
  224. }
  225. return ;
  226. }
  227. ////////////////////////////////////////////////////////////////////////////
  228. //
  229. // Link_Node
  230. //
  231. ////////////////////////////////////////////////////////////////////////////
  232. void
  233. NodeMgrClass::Link_Node (NodeClass *node)
  234. {
  235. WWASSERT (node->m_NextNode == 0);
  236. WWASSERT (node->m_PrevNode == 0);
  237. // Add this preset in front of the current head of the list
  238. node->m_NextNode = _NodeListHead;
  239. // If the list wasn't empty, link the next definiton back to this node
  240. if (node->m_NextNode != 0) {
  241. node->m_NextNode->m_PrevNode = node;
  242. }
  243. // Point the head of the list at this node now
  244. _NodeListHead = node;
  245. return ;
  246. }
  247. ////////////////////////////////////////////////////////////////////////////
  248. //
  249. // Unlink_Node
  250. //
  251. ////////////////////////////////////////////////////////////////////////////
  252. void
  253. NodeMgrClass::Unlink_Node (NodeClass *node)
  254. {
  255. WWASSERT(node != 0);
  256. // Handle the node's prev pointer:
  257. if (node->m_PrevNode == 0) {
  258. // this node is the head
  259. WWASSERT (_NodeListHead == node);
  260. _NodeListHead = node->m_NextNode;
  261. } else {
  262. // link it's prev with it's next
  263. node->m_PrevNode->m_NextNode = node->m_NextNode;
  264. }
  265. // Handle the node's next pointer if its not at the end of the list:
  266. if (node->m_NextNode != 0) {
  267. node->m_NextNode->m_PrevNode = node->m_PrevNode;
  268. }
  269. // The node is now un-linked
  270. node->m_NextNode = 0;
  271. node->m_PrevNode = 0;
  272. return ;
  273. }
  274. //////////////////////////////////////////////////////////////////////////////////////////
  275. //
  276. // Free_Nodes
  277. //
  278. //////////////////////////////////////////////////////////////////////////////////////////
  279. void
  280. NodeMgrClass::Free_Nodes (void)
  281. {
  282. NodeClass *curr_node = NULL;
  283. NodeClass *next_node = NULL;
  284. InstancesPageClass *instances_form = ::Get_Instances_Form ();
  285. //
  286. // Unlink the nodes
  287. //
  288. DynamicVectorClass<NodeClass *> node_list;
  289. for (curr_node = _NodeListHead; curr_node != NULL; curr_node = next_node) {
  290. next_node = curr_node->m_NextNode;
  291. curr_node->m_PrevNode = NULL;
  292. curr_node->m_NextNode = NULL;
  293. node_list.Add (curr_node);
  294. }
  295. //
  296. // Free the nodes
  297. //
  298. _NodeListHead = NULL;
  299. for (int index = 0; index < node_list.Count (); index ++) {
  300. MEMBER_RELEASE (node_list[index]);
  301. }
  302. //
  303. // Reset the node ID ranges
  304. //
  305. uint32 foo = 0;
  306. Get_ID_Range (NODE_TYPE_OBJECT, &_NextObjectNodeID, &foo);
  307. Get_ID_Range (NODE_TYPE_TERRAIN, &_NextStaticNodeID, &foo);
  308. Get_ID_Range (NODE_TYPE_LIGHT, &_NextLightNodeID, &foo);
  309. Get_ID_Range (NODE_TYPE_VIS_POINT, &_NextMiscNodeID, &foo);
  310. //
  311. // Update the UI
  312. //
  313. if (instances_form != NULL) {
  314. instances_form->Reset_List ();
  315. }
  316. NetworkObjectMgrClass::Delete_Pending ();
  317. return ;
  318. }
  319. ///////////////////////////////////////////////////////////////////////
  320. //
  321. // Find_Node
  322. //
  323. ///////////////////////////////////////////////////////////////////////
  324. NodeClass *
  325. NodeMgrClass::Find_Node (uint32 id)
  326. {
  327. NodeClass *req_node = NULL;
  328. for ( NodeClass *node = _NodeListHead;
  329. (req_node == NULL) && (node != NULL);
  330. node = node->m_NextNode)
  331. {
  332. //
  333. // Is this the node we are looking for?
  334. //
  335. if (node->Get_ID () == id) {
  336. req_node = node;
  337. }
  338. }
  339. return req_node;
  340. }
  341. ///////////////////////////////////////////////////////////////////////
  342. //
  343. // Find_Node
  344. //
  345. ///////////////////////////////////////////////////////////////////////
  346. NodeClass *
  347. NodeMgrClass::Find_Node (const char *name)
  348. {
  349. NodeClass *req_node = NULL;
  350. for ( NodeClass *node = _NodeListHead;
  351. (req_node == NULL) && (node != NULL);
  352. node = node->m_NextNode)
  353. {
  354. //
  355. // Is this the node we are looking for?
  356. //
  357. if (::lstrcmpi (node->Get_Name (), name) == 0) {
  358. req_node = node;
  359. }
  360. }
  361. return req_node;
  362. }
  363. ///////////////////////////////////////////////////////////////////////
  364. //
  365. // Get_Next
  366. //
  367. ///////////////////////////////////////////////////////////////////////
  368. NodeClass *
  369. NodeMgrClass::Get_Next (NodeClass *node)
  370. {
  371. return node->m_NextNode;
  372. }
  373. ///////////////////////////////////////////////////////////////////////
  374. //
  375. // Get_First
  376. //
  377. ///////////////////////////////////////////////////////////////////////
  378. NodeClass *
  379. NodeMgrClass::Get_First (NODE_TYPE type)
  380. {
  381. NodeClass *req_node = NULL;
  382. //
  383. // Loop through all the nodes until we've found the
  384. // first one that matches the criteria
  385. //
  386. for ( NodeClass *node = _NodeListHead;
  387. (req_node == NULL) && (node != NULL);
  388. node = node->m_NextNode)
  389. {
  390. if (node->Get_Type () == type) {
  391. req_node = node;
  392. }
  393. }
  394. return req_node;
  395. }
  396. ///////////////////////////////////////////////////////////////////////
  397. //
  398. // Get_Next
  399. //
  400. ///////////////////////////////////////////////////////////////////////
  401. NodeClass *
  402. NodeMgrClass::Get_Next (NodeClass *current, NODE_TYPE type)
  403. {
  404. NodeClass *req_node = NULL;
  405. //
  406. // Loop through all the nodes until we've found the
  407. // first one that matches the criteria
  408. //
  409. while ((req_node == NULL) && ((current = current->m_NextNode) != NULL))
  410. {
  411. if (current->Get_Type () == type) {
  412. req_node = current;
  413. }
  414. }
  415. return req_node;
  416. }
  417. ///////////////////////////////////////////////////////////////////////
  418. //
  419. // Get_First
  420. //
  421. ///////////////////////////////////////////////////////////////////////
  422. NodeClass *
  423. NodeMgrClass::Get_First (PresetClass *preset)
  424. {
  425. NodeClass *req_node = NULL;
  426. //
  427. // Loop through all the nodes until we've found the
  428. // first one that matches the criteria
  429. //
  430. for ( NodeClass *node = _NodeListHead;
  431. (req_node == NULL) && (node != NULL);
  432. node = node->m_NextNode)
  433. {
  434. if (node->Get_Preset () == preset) {
  435. req_node = node;
  436. }
  437. }
  438. return req_node;
  439. }
  440. ///////////////////////////////////////////////////////////////////////
  441. //
  442. // Find_First
  443. //
  444. ///////////////////////////////////////////////////////////////////////
  445. NodeClass *
  446. NodeMgrClass::Find_First (uint32 class_id)
  447. {
  448. NodeClass *req_node = NULL;
  449. //
  450. // Loop through all the nodes until we've found the
  451. // first one that matches the criteria
  452. //
  453. for ( NodeClass *node = _NodeListHead;
  454. (req_node == NULL) && (node != NULL);
  455. node = node->m_NextNode)
  456. {
  457. //
  458. // Get the preset this node was created from
  459. //
  460. PresetClass *preset = node->Get_Preset ();
  461. if (preset != NULL) {
  462. //
  463. // Is this preset belong to the requested class?
  464. //
  465. DefinitionClass *definition = preset->Get_Definition ();
  466. if (definition != NULL && definition->Get_Class_ID () == class_id) {
  467. req_node = node;
  468. }
  469. }
  470. }
  471. return req_node;
  472. }
  473. ///////////////////////////////////////////////////////////////////////
  474. //
  475. // Find_Next
  476. //
  477. ///////////////////////////////////////////////////////////////////////
  478. NodeClass *
  479. NodeMgrClass::Find_Next (NodeClass *current, uint32 class_id)
  480. {
  481. NodeClass *req_node = NULL;
  482. //
  483. // Loop through all the nodes until we've found the
  484. // first one that matches the criteria
  485. //
  486. while ((req_node == NULL) && ((current = current->m_NextNode) != NULL))
  487. {
  488. //
  489. // Get the preset this node was created from
  490. //
  491. PresetClass *preset = current->Get_Preset ();
  492. if (preset != NULL) {
  493. //
  494. // Is this preset belong to the requested class?
  495. //
  496. DefinitionClass *definition = preset->Get_Definition ();
  497. if (definition != NULL && definition->Get_Class_ID () == class_id) {
  498. req_node = current;
  499. }
  500. }
  501. }
  502. return req_node;
  503. }
  504. ///////////////////////////////////////////////////////////////////////
  505. //
  506. // Get_Next
  507. //
  508. ///////////////////////////////////////////////////////////////////////
  509. NodeClass *
  510. NodeMgrClass::Get_Next (NodeClass *current, PresetClass *preset)
  511. {
  512. NodeClass *req_node = NULL;
  513. //
  514. // Loop through all the nodes until we've found the
  515. // first one that matches the criteria
  516. //
  517. while ((req_node == NULL) && ((current = current->m_NextNode) != NULL))
  518. {
  519. if (current->Get_Preset () == preset) {
  520. req_node = current;
  521. }
  522. }
  523. return req_node;
  524. }
  525. ///////////////////////////////////////////////////////////////////////
  526. //
  527. // Contains_Data
  528. //
  529. ///////////////////////////////////////////////////////////////////////
  530. bool
  531. NodeMgrClass::Contains_Data (void) const
  532. {
  533. return (_NodeListHead != NULL);
  534. }
  535. ///////////////////////////////////////////////////////////////////////
  536. //
  537. // Save
  538. //
  539. ///////////////////////////////////////////////////////////////////////
  540. bool
  541. NodeMgrClass::Save (ChunkSaveClass &csave)
  542. {
  543. bool retval = true;
  544. //
  545. // Save the variables to their own chunk
  546. //
  547. csave.Begin_Chunk (CHUNKID_VARIABLES);
  548. //WRITE_MICRO_CHUNK (csave, VARID_NEXT_NODE_ID, _NextNodeID);
  549. csave.End_Chunk ();
  550. //
  551. // Save the nodes to their own chunk
  552. //
  553. csave.Begin_Chunk (CHUNKID_NODES);
  554. retval &= Save_Nodes (csave);
  555. csave.End_Chunk ();
  556. return retval;
  557. }
  558. ///////////////////////////////////////////////////////////////////////
  559. //
  560. // Load
  561. //
  562. // Note: It is the outside caller's responsibility to make sure
  563. // all nodes have been removed from the manager before a load. This
  564. // is done so we can import/export nodes without trashing the existing
  565. // node set.
  566. //
  567. ///////////////////////////////////////////////////////////////////////
  568. bool
  569. NodeMgrClass::Load (ChunkLoadClass &cload)
  570. {
  571. bool retval = true;
  572. while (cload.Open_Chunk ()) {
  573. switch (cload.Cur_Chunk_ID ()) {
  574. //
  575. // Load all the nodes from this chunk
  576. //
  577. case CHUNKID_NODES:
  578. retval &= Load_Nodes (cload);
  579. break;
  580. case CHUNKID_VARIABLES:
  581. retval &= Load_Variables (cload);
  582. break;
  583. }
  584. cload.Close_Chunk ();
  585. }
  586. SaveLoadSystemClass::Register_Post_Load_Callback (this);
  587. return retval;
  588. }
  589. ///////////////////////////////////////////////////////////////////////
  590. //
  591. // Save_Node_List
  592. //
  593. ///////////////////////////////////////////////////////////////////////
  594. bool
  595. NodeMgrClass::Save_Node_List (ChunkSaveClass &csave, NODE_LIST &node_list)
  596. {
  597. //
  598. // Loop over all the nodes in the list
  599. //
  600. for (int index = 0; index < node_list.Count (); index ++) {
  601. NodeClass *node = node_list[index];
  602. if (node != NULL) {
  603. //
  604. // Save this node to its own chunk
  605. //
  606. csave.Begin_Chunk (node->Get_Factory ().Chunk_ID ());
  607. node->Get_Factory ().Save (csave, node);
  608. csave.End_Chunk ();
  609. }
  610. }
  611. return true;
  612. }
  613. ///////////////////////////////////////////////////////////////////////
  614. //
  615. // Load_Node_List
  616. //
  617. ///////////////////////////////////////////////////////////////////////
  618. bool
  619. NodeMgrClass::Load_Node_List (ChunkLoadClass &cload, NODE_LIST &node_list)
  620. {
  621. while (cload.Open_Chunk ()) {
  622. //
  623. // Load this node from the chunk (if possible)
  624. //
  625. PersistFactoryClass *factory = SaveLoadSystemClass::Find_Persist_Factory (cload.Cur_Chunk_ID ());
  626. if (factory != NULL) {
  627. NodeClass *node = (NodeClass *)factory->Load (cload);
  628. if (node != NULL) {
  629. //
  630. // Does this node's preset still exist?
  631. //
  632. if (node->Get_Preset () != NULL || node->Get_Type () == NODE_TYPE_WAYPOINT) {
  633. //
  634. // Initialize the node
  635. //
  636. node->Initialize ();
  637. if (node->Needs_Save () == false) {
  638. node->Lock (true);
  639. }
  640. //
  641. // Add this node to the list
  642. //
  643. node->Add_Ref ();
  644. node_list.Add (node);
  645. } else {
  646. WWDEBUG_SAY (("No preset for linked node %s.\r\n", node->Get_Name ()));
  647. }
  648. MEMBER_RELEASE (node);
  649. }
  650. }
  651. cload.Close_Chunk ();
  652. }
  653. return true;
  654. }
  655. ///////////////////////////////////////////////////////////////////////
  656. //
  657. // Save_Nodes
  658. //
  659. ///////////////////////////////////////////////////////////////////////
  660. bool
  661. NodeMgrClass::Save_Nodes (ChunkSaveClass &csave)
  662. {
  663. for ( NodeClass *node = _NodeListHead;
  664. node != NULL;
  665. node = node->m_NextNode)
  666. {
  667. if (node->Needs_Save ()) {
  668. //
  669. // Save this node to its own chunk
  670. //
  671. csave.Begin_Chunk (node->Get_Factory ().Chunk_ID ());
  672. node->Get_Factory ().Save (csave, node);
  673. csave.End_Chunk ();
  674. }
  675. }
  676. return true;
  677. }
  678. ///////////////////////////////////////////////////////////////////////
  679. //
  680. // Load_Nodes
  681. //
  682. ///////////////////////////////////////////////////////////////////////
  683. bool
  684. NodeMgrClass::Load_Nodes (ChunkLoadClass &cload)
  685. {
  686. bool retval = true;
  687. DynamicVectorClass<NodeClass *> removed_node_list;
  688. while (cload.Open_Chunk ()) {
  689. //
  690. // Load this node from the chunk (if possible)
  691. //
  692. PersistFactoryClass *factory = SaveLoadSystemClass::Find_Persist_Factory (cload.Cur_Chunk_ID ());
  693. if (factory != NULL) {
  694. NodeClass *node = (NodeClass *)factory->Load (cload);
  695. if (node != NULL) {
  696. // Does this node's preset still exist?
  697. if (node->Get_Preset () != NULL || node->Get_Type () == NODE_TYPE_WAYPOINT) {
  698. //
  699. // Initialize the node
  700. //
  701. node->Initialize ();
  702. if (node->Needs_Save () == false) {
  703. node->Lock (true);
  704. }
  705. //
  706. // Put the node back into the world
  707. //
  708. Add_Node (node);
  709. } else {
  710. node->Add_Ref ();
  711. removed_node_list.Add (node);
  712. WWDEBUG_SAY (("No preset for %s, removing from level.\r\n", node->Get_Name ()));
  713. }
  714. MEMBER_RELEASE (node);
  715. }
  716. }
  717. cload.Close_Chunk ();
  718. }
  719. //
  720. // Display a dialog to the user allowing them to remap removed nodes
  721. // to other presets...
  722. //
  723. if (removed_node_list.Count () > 0) {
  724. PresetRemapDialogClass dialog (::AfxGetMainWnd ());
  725. dialog.Set_Node_list (removed_node_list);
  726. dialog.DoModal ();
  727. }
  728. return retval;
  729. }
  730. ///////////////////////////////////////////////////////////////////////
  731. //
  732. // On_Post_Load
  733. //
  734. ///////////////////////////////////////////////////////////////////////
  735. void
  736. NodeMgrClass::On_Post_Load (void)
  737. {
  738. SceneEditorClass *scene = ::Get_Scene_Editor ();
  739. //
  740. // Loop over all the nodes
  741. //
  742. for ( NodeClass *node = _NodeListHead;
  743. node != NULL;
  744. node = node->m_NextNode)
  745. {
  746. //
  747. // Add them to the scene...
  748. //
  749. node->Add_To_Scene ();
  750. scene->Update_File_Mgr (node);
  751. }
  752. Reset_New_ID ();
  753. return ;
  754. }
  755. ///////////////////////////////////////////////////////////////////////
  756. //
  757. // Load_Variables
  758. //
  759. ///////////////////////////////////////////////////////////////////////
  760. bool
  761. NodeMgrClass::Load_Variables (ChunkLoadClass &cload)
  762. {
  763. bool retval = true;
  764. while (cload.Open_Micro_Chunk ()) {
  765. /*switch (cload.Cur_Micro_Chunk_ID ()) {
  766. }*/
  767. cload.Close_Micro_Chunk ();
  768. }
  769. return retval;
  770. }
  771. ///////////////////////////////////////////////////////////////////////
  772. //
  773. // Reload_Nodes
  774. //
  775. ///////////////////////////////////////////////////////////////////////
  776. void
  777. NodeMgrClass::Reload_Nodes (void)
  778. {
  779. ::Get_Main_View ()->Allow_Repaint (false);
  780. //
  781. // First, make sure each node has the correct preset pointer
  782. //
  783. DynamicVectorClass<NodeClass *> node_list;
  784. Build_Full_Node_List (node_list);
  785. for (int index = 0; index < node_list.Count (); index ++) {
  786. NodeClass *node = node_list[index];
  787. if (node != NULL) {
  788. //
  789. // Lookup the preset and re-assign it to this node
  790. //
  791. uint32 preset_id = node->Get_Preset_ID ();
  792. PresetClass *preset = PresetMgrClass::Find_Preset (preset_id);
  793. node->Set_Preset (preset);
  794. }
  795. }
  796. //
  797. // Ask each node to recreate itself
  798. //
  799. for ( NodeClass *node = _NodeListHead; node != NULL; node = node->m_NextNode) {
  800. node->Reload ();
  801. }
  802. ::Get_Scene_Editor ()->Validate_Vis ();
  803. ::Get_Main_View ()->Allow_Repaint (true);
  804. return ;
  805. }
  806. ///////////////////////////////////////////////////////////////////////
  807. //
  808. // Reload_Nodes
  809. //
  810. ///////////////////////////////////////////////////////////////////////
  811. void
  812. NodeMgrClass::Reload_Nodes (PresetClass *preset)
  813. {
  814. ::Get_Main_View ()->Allow_Repaint (false);
  815. //
  816. // Loop over all the nodes
  817. //
  818. for ( NodeClass *node = _NodeListHead;
  819. node != NULL;
  820. node = node->m_NextNode)
  821. {
  822. //
  823. // Simply ask the node to re-create itself
  824. //
  825. if (node->Get_Preset () == preset) {
  826. node->Reload ();
  827. }
  828. }
  829. ::Get_Scene_Editor ()->Validate_Vis ();
  830. ::Get_Main_View ()->Allow_Repaint (true);
  831. return ;
  832. }
  833. ///////////////////////////////////////////////////////////////////////
  834. //
  835. // Put_Objects_Back
  836. //
  837. ///////////////////////////////////////////////////////////////////////
  838. void
  839. NodeMgrClass::Put_Objects_Back (const NODE_LIST &obj_list)
  840. {
  841. //
  842. // Insert the nodes back into the system
  843. //
  844. for (int index = 0; index < obj_list.Count (); index ++) {
  845. NodeClass *node = obj_list[index];
  846. NodeMgrClass::Add_Node (node);
  847. node->Release_Ref ();
  848. }
  849. return ;
  850. }
  851. ///////////////////////////////////////////////////////////////////////
  852. //
  853. // Remove_Dynamic_Objects
  854. //
  855. ///////////////////////////////////////////////////////////////////////
  856. void
  857. NodeMgrClass::Remove_Dynamic_Objects (NODE_LIST &dynamic_obj_list)
  858. {
  859. //
  860. // Build a list of nodes to that are not dynamic
  861. //
  862. for ( NodeClass *node = NodeMgrClass::Get_First ();
  863. node != NULL;
  864. node = NodeMgrClass::Get_Next (node))
  865. {
  866. if (node->Is_Static () == false) {
  867. dynamic_obj_list.Add (node);
  868. }
  869. }
  870. //
  871. // Remove these nodes from the level
  872. //
  873. for (int index = 0; index < dynamic_obj_list.Count (); index ++) {
  874. NodeClass *node = dynamic_obj_list[index];
  875. if (node != NULL) {
  876. node->Add_Ref ();
  877. NodeMgrClass::Remove_Node (node);
  878. }
  879. }
  880. return ;
  881. }
  882. ///////////////////////////////////////////////////////////////////////
  883. //
  884. // Remove_Static_Objects
  885. //
  886. ///////////////////////////////////////////////////////////////////////
  887. void
  888. NodeMgrClass::Remove_Static_Objects (NODE_LIST &static_obj_list)
  889. {
  890. //
  891. // Build a list of nodes to that are not dynamic
  892. //
  893. for ( NodeClass *node = NodeMgrClass::Get_First ();
  894. node != NULL;
  895. node = NodeMgrClass::Get_Next (node))
  896. {
  897. if (node->Is_Static ()) {
  898. static_obj_list.Add (node);
  899. }
  900. }
  901. //
  902. // Remove these nodes from the level
  903. //
  904. for (int index = 0; index < static_obj_list.Count (); index ++) {
  905. NodeClass *node = static_obj_list[index];
  906. if (node != NULL) {
  907. node->Add_Ref ();
  908. NodeMgrClass::Remove_Node (node);
  909. }
  910. }
  911. return ;
  912. }
  913. ///////////////////////////////////////////////////////////////////////
  914. //
  915. // Get_Max_Used_ID
  916. //
  917. ///////////////////////////////////////////////////////////////////////
  918. uint32
  919. NodeMgrClass::Get_Max_Used_ID (void)
  920. {
  921. //
  922. // Build the full list of nodes
  923. //
  924. DynamicVectorClass<NodeClass *> full_node_list;
  925. Build_Full_Node_List (full_node_list);
  926. uint32 max_used = 0;
  927. //
  928. // Determine what the largest used ID is
  929. //
  930. for (int index = 0; index < full_node_list.Count (); index ++) {
  931. NodeClass *node = full_node_list[index];
  932. max_used = max (node->Get_ID (), max_used);
  933. }
  934. return max_used;
  935. }
  936. ///////////////////////////////////////////////////////////////////////
  937. //
  938. // Verify_Unique_ID - Verify that given ID is unique.
  939. //
  940. ///////////////////////////////////////////////////////////////////////
  941. bool
  942. NodeMgrClass::Verify_Unique_ID(uint32 id)
  943. {
  944. NodeClass* node = Get_First();
  945. while (node != NULL) {
  946. if (node->Get_ID() == id) {
  947. return false;
  948. }
  949. node = Get_Next(node);
  950. }
  951. return true;
  952. }
  953. ///////////////////////////////////////////////////////////////////////
  954. //
  955. // Make_Static_Anim_Phys_Collideable
  956. //
  957. ///////////////////////////////////////////////////////////////////////
  958. void
  959. NodeMgrClass::Make_Static_Anim_Phys_Collideable (bool onoff)
  960. {
  961. //
  962. // Loop over all the terrains in the level
  963. //
  964. for ( NodeClass *node = NodeMgrClass::Get_First (NODE_TYPE_TERRAIN);
  965. node != NULL;
  966. node = NodeMgrClass::Get_Next (node, NODE_TYPE_TERRAIN))
  967. {
  968. TerrainNodeClass *terrain = (TerrainNodeClass *)node;
  969. int count = terrain->Get_Sub_Node_Count ();
  970. //
  971. // Loop over all the sections of this terrain object
  972. //
  973. for (int index = 0; index < count; index ++) {
  974. NodeClass *sub_node = terrain->Get_Sub_Node (index);
  975. if (sub_node != NULL) {
  976. //
  977. // Check to make sure this is a static anim phys object
  978. //
  979. PhysClass *phys_obj = sub_node->Peek_Physics_Obj ();
  980. if (phys_obj != NULL && phys_obj->As_StaticAnimPhysClass () != NULL) {
  981. sub_node->Hide (onoff == false);
  982. //
  983. // Turn off collision on or off this object
  984. //
  985. if (onoff == false) {
  986. phys_obj->Inc_Ignore_Counter ();
  987. } else if (phys_obj->Is_Ignore_Me ()) {
  988. phys_obj->Dec_Ignore_Counter ();
  989. }
  990. }
  991. }
  992. }
  993. }
  994. //
  995. // Loop over all the tiles in the level
  996. //
  997. for ( node = NodeMgrClass::Get_First (NODE_TYPE_TILE);
  998. node != NULL;
  999. node = NodeMgrClass::Get_Next (node, NODE_TYPE_TILE))
  1000. {
  1001. //
  1002. // Check to make sure this is a static anim phys object
  1003. //
  1004. PhysClass *phys_obj = node->Peek_Physics_Obj ();
  1005. if (phys_obj != NULL && phys_obj->As_StaticAnimPhysClass () != NULL) {
  1006. node->Hide (onoff);
  1007. //
  1008. // Turn off collision on or off this object
  1009. //
  1010. if (onoff == false) {
  1011. phys_obj->Inc_Ignore_Counter ();
  1012. } else if (phys_obj->Is_Ignore_Me ()) {
  1013. phys_obj->Dec_Ignore_Counter ();
  1014. }
  1015. }
  1016. }
  1017. return ;
  1018. }
  1019. ///////////////////////////////////////////////////////////////////////
  1020. //
  1021. // Build_ID_Collision_List
  1022. //
  1023. ///////////////////////////////////////////////////////////////////////
  1024. void
  1025. NodeMgrClass::Build_ID_Collision_List (NODE_LIST &node_list)
  1026. {
  1027. CWaitCursor wait_cursor;
  1028. //
  1029. // Build a flat list of nodes
  1030. //
  1031. DynamicVectorClass<NodeClass *> full_node_list;
  1032. Build_Full_Node_List (full_node_list);
  1033. //
  1034. // Loop over all the nodes, checking every one against the other
  1035. //
  1036. for (int index1 = 0; index1 < full_node_list.Count (); index1 ++) {
  1037. for (int index2 = 0; index2 < full_node_list.Count (); index2 ++) {
  1038. NodeClass *node1 = full_node_list[index1];
  1039. NodeClass *node2 = full_node_list[index2];
  1040. //
  1041. // Do these nodes share the same ID?
  1042. //
  1043. if (node1 != node2 && node1->Get_ID () == node2->Get_ID ()) {
  1044. if (node_list.ID (node1) == -1) {
  1045. node_list.Add (node1);
  1046. }
  1047. }
  1048. }
  1049. }
  1050. return ;
  1051. }
  1052. ///////////////////////////////////////////////////////////////////////
  1053. //
  1054. // Build_Unimportant_ID_Collision_List
  1055. //
  1056. ///////////////////////////////////////////////////////////////////////
  1057. void
  1058. NodeMgrClass::Build_Unimportant_ID_Collision_List (NODE_LIST &node_list)
  1059. {
  1060. CWaitCursor wait_cursor;
  1061. //
  1062. // Build a flat list of nodes
  1063. //
  1064. DynamicVectorClass<NodeClass *> full_node_list;
  1065. Build_Full_Node_List (full_node_list);
  1066. //
  1067. // Loop over all the nodes, checking every one against the other
  1068. //
  1069. for (int index1 = 0; index1 < full_node_list.Count (); index1 ++) {
  1070. for (int index2 = 0; index2 < full_node_list.Count (); index2 ++) {
  1071. NodeClass *node1 = full_node_list[index1];
  1072. NodeClass *node2 = full_node_list[index2];
  1073. //
  1074. // Do these nodes share the same ID?
  1075. //
  1076. if (node1 != node2 && node1->Get_ID () == node2->Get_ID ()) {
  1077. if (node_list.ID (node1) == -1) {
  1078. //
  1079. // Check to make sure this isn't an important node type
  1080. //
  1081. if ( node1->As_ObjectNodeClass () == NULL &&
  1082. node1->Get_Type () != NODE_TYPE_SPAWNER &&
  1083. node1->Get_Type () != NODE_TYPE_TILE &&
  1084. node1->Get_Type () != NODE_TYPE_WAYPATH &&
  1085. node1->Get_Type () != NODE_TYPE_WAYPOINT &&
  1086. node1->Get_Type () != NODE_TYPE_SOUND)
  1087. {
  1088. node_list.Add (node1);
  1089. }
  1090. }
  1091. }
  1092. }
  1093. }
  1094. return ;
  1095. }
  1096. ///////////////////////////////////////////////////////////////////////
  1097. //
  1098. // Reset_New_ID
  1099. //
  1100. ///////////////////////////////////////////////////////////////////////
  1101. void
  1102. NodeMgrClass::Reset_New_ID (void)
  1103. {
  1104. //
  1105. // Reset each of the id ranges
  1106. //
  1107. _NextObjectNodeID = Find_Max_Used_ID (NODE_TYPE_OBJECT) + 1;
  1108. _NextStaticNodeID = Find_Max_Used_ID (NODE_TYPE_TERRAIN) + 1;
  1109. _NextLightNodeID = Find_Max_Used_ID (NODE_TYPE_LIGHT) + 1;
  1110. _NextMiscNodeID = Find_Max_Used_ID (NODE_TYPE_VIS_POINT) + 1;
  1111. //
  1112. // Update each heightfield with a guaranteed unique ID
  1113. //
  1114. HeightfieldMgrClass::Assign_Unique_IDs ();
  1115. return ;
  1116. }
  1117. ///////////////////////////////////////////////////////////////////////
  1118. //
  1119. // Find_Max_Used_ID
  1120. //
  1121. ///////////////////////////////////////////////////////////////////////
  1122. uint32
  1123. NodeMgrClass::Find_Max_Used_ID (NODE_TYPE type)
  1124. {
  1125. //
  1126. // Determine what our minimum ID is
  1127. //
  1128. uint32 min_id = 0;
  1129. uint32 max_id = 0;
  1130. Get_ID_Range (type, &min_id, &max_id);
  1131. //
  1132. // First, build a complete list of all the nodes
  1133. //
  1134. DynamicVectorClass<NodeClass *> node_list;
  1135. Build_Full_Node_List (node_list);
  1136. //
  1137. // Loop over all the nodes in the level and find the largest ID
  1138. // in our range
  1139. //
  1140. uint32 largest_id = min_id;
  1141. for (int index = 0; index < node_list.Count (); index ++) {
  1142. NodeClass *node = node_list[index];
  1143. if (node != NULL) {
  1144. //
  1145. // Is this the largest ID in our range?
  1146. //
  1147. uint32 curr_id = node->Get_ID ();
  1148. if (curr_id >= min_id && curr_id < max_id) {
  1149. largest_id = max (largest_id, curr_id);
  1150. }
  1151. }
  1152. }
  1153. return largest_id;
  1154. }
  1155. //////////////////////////////////////////////////////////////////////////////////////////
  1156. //
  1157. // Get_Node_ID
  1158. //
  1159. //////////////////////////////////////////////////////////////////////////////////////////
  1160. uint32
  1161. NodeMgrClass::Get_Node_ID (NODE_TYPE type)
  1162. {
  1163. uint32 new_id = 0;
  1164. switch (type)
  1165. {
  1166. case NODE_TYPE_TERRAIN:
  1167. case NODE_TYPE_TERRAIN_SECTION:
  1168. case NODE_TYPE_TILE:
  1169. case NODE_TYPE_BUILDING:
  1170. new_id = _NextStaticNodeID ++;
  1171. break;
  1172. case NODE_TYPE_DAMAGE_ZONE:
  1173. case NODE_TYPE_ZONE:
  1174. new_id = _NextObjectNodeID ++;
  1175. break;
  1176. case NODE_TYPE_WAYPATH:
  1177. case NODE_TYPE_WAYPOINT:
  1178. new_id = _NextObjectNodeID ++;
  1179. break;
  1180. case NODE_TYPE_OBJECT:
  1181. new_id = _NextObjectNodeID ++;
  1182. break;
  1183. case NODE_TYPE_COVER_SPOT:
  1184. case NODE_TYPE_COVER_ATTACK_POINT:
  1185. new_id = _NextObjectNodeID ++;
  1186. break;
  1187. case NODE_TYPE_SPAWNER:
  1188. new_id = _NextObjectNodeID ++;
  1189. break;
  1190. case NODE_TYPE_SOUND:
  1191. case NODE_TYPE_TRANSITION:
  1192. case NODE_TYPE_TRANSITION_CHARACTER:
  1193. case NODE_TYPE_DUMMY_OBJECT:
  1194. new_id = _NextObjectNodeID ++;
  1195. break;
  1196. case NODE_TYPE_LIGHT:
  1197. new_id = _NextLightNodeID ++;
  1198. break;
  1199. case NODE_TYPE_UNKNOWN:
  1200. case NODE_TYPE_VIS:
  1201. case NODE_TYPE_VIS_POINT:
  1202. case NODE_TYPE_PATHFIND_START:
  1203. default:
  1204. new_id = _NextMiscNodeID ++;
  1205. break;
  1206. }
  1207. return new_id;
  1208. }
  1209. ///////////////////////////////////////////////////////////////////////
  1210. //
  1211. // Get_ID_Range
  1212. //
  1213. ///////////////////////////////////////////////////////////////////////
  1214. void
  1215. NodeMgrClass::Get_ID_Range (NODE_TYPE type, uint32 *min_id, uint32 *max_id)
  1216. {
  1217. switch (type)
  1218. {
  1219. case NODE_TYPE_TERRAIN:
  1220. case NODE_TYPE_TERRAIN_SECTION:
  1221. case NODE_TYPE_TILE:
  1222. case NODE_TYPE_BUILDING:
  1223. (*min_id) = theApp.GetProfileInt (CONFIG_KEY, NODE_ID_START_VALUE, FIRST_OBJECT_NODE_ID);
  1224. (*min_id) += 50000;
  1225. (*max_id) = (*min_id) + 50000;
  1226. break;
  1227. case NODE_TYPE_DAMAGE_ZONE:
  1228. case NODE_TYPE_ZONE:
  1229. case NODE_TYPE_WAYPATH:
  1230. case NODE_TYPE_WAYPOINT:
  1231. case NODE_TYPE_OBJECT:
  1232. case NODE_TYPE_COVER_SPOT:
  1233. case NODE_TYPE_COVER_ATTACK_POINT:
  1234. case NODE_TYPE_SPAWNER:
  1235. case NODE_TYPE_SOUND:
  1236. case NODE_TYPE_TRANSITION:
  1237. case NODE_TYPE_TRANSITION_CHARACTER:
  1238. case NODE_TYPE_DUMMY_OBJECT:
  1239. (*min_id) = theApp.GetProfileInt (CONFIG_KEY, NODE_ID_START_VALUE, FIRST_OBJECT_NODE_ID);
  1240. (*max_id) = (*min_id) + 50000;
  1241. break;
  1242. case NODE_TYPE_LIGHT:
  1243. (*min_id) = FIRST_LIGHT_NODE_ID;
  1244. (*max_id) = (*min_id) + 100000;
  1245. break;
  1246. case NODE_TYPE_UNKNOWN:
  1247. case NODE_TYPE_VIS:
  1248. case NODE_TYPE_VIS_POINT:
  1249. case NODE_TYPE_PATHFIND_START:
  1250. (*min_id) = FIRST_MISC_NODE_ID;
  1251. (*max_id) = (*min_id) + 100000;
  1252. break;
  1253. default:
  1254. (*min_id) = FIRST_MISC_NODE_ID;
  1255. break;
  1256. }
  1257. return ;
  1258. }
  1259. ///////////////////////////////////////////////////////////////////////
  1260. //
  1261. // Build_Full_Node_List
  1262. //
  1263. ///////////////////////////////////////////////////////////////////////
  1264. void
  1265. NodeMgrClass::Build_Full_Node_List (DynamicVectorClass<NodeClass *> &node_list)
  1266. {
  1267. //
  1268. // Add all nodes and sub-nodes to this list
  1269. //
  1270. for (NodeClass *node = ::Get_Node_Mgr ().Get_First ();
  1271. node != NULL;
  1272. node = ::Get_Node_Mgr ().Get_Next (node))
  1273. {
  1274. Add_Nodes_To_List (node_list, node);
  1275. }
  1276. return ;
  1277. }
  1278. ///////////////////////////////////////////////////////////////////////
  1279. //
  1280. // Add_Nodes_To_List
  1281. //
  1282. ///////////////////////////////////////////////////////////////////////
  1283. void
  1284. NodeMgrClass::Add_Nodes_To_List
  1285. (
  1286. DynamicVectorClass<NodeClass *> &node_list,
  1287. NodeClass *node
  1288. )
  1289. {
  1290. node_list.Add (node);
  1291. //
  1292. // If the node is an aggregate (like a terrain), we are adding the
  1293. // sub-nodes directly into the list
  1294. //
  1295. int sub_count = node->Get_Sub_Node_Count ();
  1296. if (sub_count > 0) {
  1297. for (int index = 0; index < sub_count; index ++) {
  1298. NodeClass *sub_node = node->Get_Sub_Node (index);
  1299. //
  1300. // Recurse into this node
  1301. //
  1302. Add_Nodes_To_List (node_list, sub_node);
  1303. }
  1304. }
  1305. return ;
  1306. }
  1307. ///////////////////////////////////////////////////////////////////////
  1308. //
  1309. // Create_All_Embedded_Nodes
  1310. //
  1311. ///////////////////////////////////////////////////////////////////////
  1312. void
  1313. NodeMgrClass::Create_All_Embedded_Nodes (void)
  1314. {
  1315. //
  1316. // Generate a list of nodes
  1317. //
  1318. DynamicVectorClass<NodeClass *> node_list;
  1319. Build_Full_Node_List (node_list);
  1320. //
  1321. // Loop over all the nodes
  1322. //
  1323. for (int index = 0; index < node_list.Count (); index ++) {
  1324. if (node_list[index]->Is_Proxied () == false) {
  1325. PresetClass *preset = node_list[index]->Get_Preset ();
  1326. if (preset != NULL) {
  1327. //
  1328. // Create the nodes that are embedded inside this preset
  1329. //
  1330. preset->Create_Linked_Nodes (node_list[index]);
  1331. }
  1332. }
  1333. }
  1334. return ;
  1335. }