| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587 |
- /*
- ** Command & Conquer Renegade(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /***********************************************************************************************
- *** 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 ***
- ***********************************************************************************************
- * *
- * Project Name : LevelEdit *
- * *
- * $Archive:: /Commando/Code/Tools/LevelEdit/NodeMgr.cpp $*
- * *
- * Author:: Patrick Smith *
- * *
- * $Modtime:: 3/07/02 1:54p $*
- * *
- * $Revision:: 42 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "stdafx.h"
- #include "nodemgr.h"
- #include "node.h"
- #include "editorchunkids.h"
- #include "preset.h"
- #include "wwdebug.h"
- #include "chunkio.h"
- #include "persistfactory.h"
- #include "sceneeditor.h"
- #include "leveleditview.h"
- #include "instancespage.h"
- #include "gameobjmanager.h"
- #include "terrainnode.h"
- #include "leveledit.h"
- #include "regkeys.h"
- #include "presetmgr.h"
- #include "presetremapdialog.h"
- #include "heightfieldmgr.h"
- ///////////////////////////////////////////////////////////////////////
- // Singleton instance
- ///////////////////////////////////////////////////////////////////////
- NodeMgrClass _TheNodeMgr;
- ///////////////////////////////////////////////////////////////////////
- // Constants
- ///////////////////////////////////////////////////////////////////////
- enum
- {
- CHUNKID_VARIABLES = 0x00000100,
- CHUNKID_NODES
- };
- enum
- {
- XXX_VARID_NEXT_NODE_ID = 0x01,
- };
- enum
- {
- FIRST_OBJECT_NODE_ID = 100000,
- FIRST_STATIC_NODE_ID = 1100000000,
- FIRST_LIGHT_NODE_ID = 1200000000,
- FIRST_MISC_NODE_ID = 1300000000,
- };
- ///////////////////////////////////////////////////////////////////////
- // Static member initialization
- ///////////////////////////////////////////////////////////////////////
- NodeClass * NodeMgrClass::_NodeListHead = NULL;
- uint32 NodeMgrClass::_NextObjectNodeID = FIRST_OBJECT_NODE_ID;
- uint32 NodeMgrClass::_NextStaticNodeID = FIRST_STATIC_NODE_ID;
- uint32 NodeMgrClass::_NextLightNodeID = FIRST_LIGHT_NODE_ID;
- uint32 NodeMgrClass::_NextMiscNodeID = FIRST_MISC_NODE_ID;
- //////////////////////////////////////////////////////////////////////////////////////////
- //
- // ~NodeMgrClass
- //
- //////////////////////////////////////////////////////////////////////////////////////////
- NodeMgrClass::~NodeMgrClass (void)
- {
- return ;
- }
- //////////////////////////////////////////////////////////////////////////////////////////
- //
- // Chunk_ID
- //
- //////////////////////////////////////////////////////////////////////////////////////////
- uint32
- NodeMgrClass::Chunk_ID (void) const
- {
- return CHUNKID_NODEMGR;
- }
- //////////////////////////////////////////////////////////////////////////////////////////
- //
- // Setup_Node_Identity
- //
- //////////////////////////////////////////////////////////////////////////////////////////
- void
- NodeMgrClass::Setup_Node_Identity (NodeClass &node)
- {
- PresetClass *preset = node.Get_Preset ();
- int id = node.Get_ID ();
- //
- // Give the node an ID if it doesn't already
- // have one.
- //
- if (id == 0) {
- id = Get_Node_ID (node.Get_Type ());
- node.Set_ID (id);
- }
- //
- // Give the node a name
- //
- if (preset != NULL) {
- CString name;
- name.Format ("%s.%d", preset->Get_Name (), id);
- node.Set_Name (name);
- } else {
-
- RenderObjClass *model = node.Peek_Render_Obj ();
- if (model != NULL) {
- CString name;
- name.Format ("%s.%d", model->Get_Name (), id);
- node.Set_Name (name);
- } else {
- CString name;
- name.Format ("Unknown.%d", id);
- node.Set_Name (name);
- }
- }
- return ;
- }
- //////////////////////////////////////////////////////////////////////////////////////////
- //
- // Create_Node
- //
- //////////////////////////////////////////////////////////////////////////////////////////
- NodeClass *
- NodeMgrClass::Create_Node (PresetClass *preset, uint32 id)
- {
- NodeClass *node = preset->Create ();
- if (node != NULL) {
- //
- // Give the new node a unique id and name
- //
- node->Set_ID (id);
- Setup_Node_Identity (*node);
- //
- // Give the new node a chance to initialize its data
- //
- node->Initialize ();
- //
- // Keep track of this node
- //
- Add_Node (node);
- }
- return node;
- }
- //////////////////////////////////////////////////////////////////////////////////////////
- //
- // Add_Node
- //
- //////////////////////////////////////////////////////////////////////////////////////////
- void
- NodeMgrClass::Add_Node (NodeClass *node)
- {
- WWASSERT (node->m_NextNode == 0);
- WWASSERT (node->m_PrevNode == 0);
-
- //
- // Add the node to the the list and lock
- // a refcount on the node
- //
- if ( node->m_NextNode == NULL &&
- node->m_PrevNode == NULL &&
- node != _NodeListHead)
- {
- Link_Node (node);
- SAFE_ADD_REF (node);
- //
- // Update the UI
- //
- InstancesPageClass *instances_form = ::Get_Instances_Form ();
- if (instances_form != NULL) {
- instances_form->Add_Node (node);
- }
- }
- return ;
- }
- //////////////////////////////////////////////////////////////////////////////////////////
- //
- // Remove_Node
- //
- //////////////////////////////////////////////////////////////////////////////////////////
- void
- NodeMgrClass::Remove_Node (NodeClass *node)
- {
- WWASSERT (node != 0);
- if ( node->m_NextNode != NULL ||
- node->m_PrevNode != NULL ||
- node == _NodeListHead)
- {
- //
- // Remove the node from our list and
- // free our hold on the node
- //
- Unlink_Node (node);
- //
- // Update the UI
- //
- InstancesPageClass *instances_form = ::Get_Instances_Form ();
- if (instances_form != NULL) {
- instances_form->Remove_Node (node);
- }
- MEMBER_RELEASE (node);
- }
-
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // Link_Node
- //
- ////////////////////////////////////////////////////////////////////////////
- void
- NodeMgrClass::Link_Node (NodeClass *node)
- {
- WWASSERT (node->m_NextNode == 0);
- WWASSERT (node->m_PrevNode == 0);
- // Add this preset in front of the current head of the list
- node->m_NextNode = _NodeListHead;
-
- // If the list wasn't empty, link the next definiton back to this node
- if (node->m_NextNode != 0) {
- node->m_NextNode->m_PrevNode = node;
- }
- // Point the head of the list at this node now
- _NodeListHead = node;
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // Unlink_Node
- //
- ////////////////////////////////////////////////////////////////////////////
- void
- NodeMgrClass::Unlink_Node (NodeClass *node)
- {
- WWASSERT(node != 0);
- // Handle the node's prev pointer:
- if (node->m_PrevNode == 0) {
- // this node is the head
- WWASSERT (_NodeListHead == node);
- _NodeListHead = node->m_NextNode;
-
- } else {
- // link it's prev with it's next
- node->m_PrevNode->m_NextNode = node->m_NextNode;
- }
- // Handle the node's next pointer if its not at the end of the list:
- if (node->m_NextNode != 0) {
- node->m_NextNode->m_PrevNode = node->m_PrevNode;
- }
- // The node is now un-linked
- node->m_NextNode = 0;
- node->m_PrevNode = 0;
- return ;
- }
- //////////////////////////////////////////////////////////////////////////////////////////
- //
- // Free_Nodes
- //
- //////////////////////////////////////////////////////////////////////////////////////////
- void
- NodeMgrClass::Free_Nodes (void)
- {
- NodeClass *curr_node = NULL;
- NodeClass *next_node = NULL;
- InstancesPageClass *instances_form = ::Get_Instances_Form ();
- //
- // Unlink the nodes
- //
- DynamicVectorClass<NodeClass *> node_list;
- for (curr_node = _NodeListHead; curr_node != NULL; curr_node = next_node) {
- next_node = curr_node->m_NextNode;
- curr_node->m_PrevNode = NULL;
- curr_node->m_NextNode = NULL;
- node_list.Add (curr_node);
- }
- //
- // Free the nodes
- //
- _NodeListHead = NULL;
- for (int index = 0; index < node_list.Count (); index ++) {
- MEMBER_RELEASE (node_list[index]);
- }
-
- //
- // Reset the node ID ranges
- //
- uint32 foo = 0;
- Get_ID_Range (NODE_TYPE_OBJECT, &_NextObjectNodeID, &foo);
- Get_ID_Range (NODE_TYPE_TERRAIN, &_NextStaticNodeID, &foo);
- Get_ID_Range (NODE_TYPE_LIGHT, &_NextLightNodeID, &foo);
- Get_ID_Range (NODE_TYPE_VIS_POINT, &_NextMiscNodeID, &foo);
- //
- // Update the UI
- //
- if (instances_form != NULL) {
- instances_form->Reset_List ();
- }
- NetworkObjectMgrClass::Delete_Pending ();
- return ;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Find_Node
- //
- ///////////////////////////////////////////////////////////////////////
- NodeClass *
- NodeMgrClass::Find_Node (uint32 id)
- {
- NodeClass *req_node = NULL;
- for ( NodeClass *node = _NodeListHead;
- (req_node == NULL) && (node != NULL);
- node = node->m_NextNode)
- {
- //
- // Is this the node we are looking for?
- //
- if (node->Get_ID () == id) {
- req_node = node;
- }
- }
- return req_node;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Find_Node
- //
- ///////////////////////////////////////////////////////////////////////
- NodeClass *
- NodeMgrClass::Find_Node (const char *name)
- {
- NodeClass *req_node = NULL;
- for ( NodeClass *node = _NodeListHead;
- (req_node == NULL) && (node != NULL);
- node = node->m_NextNode)
- {
- //
- // Is this the node we are looking for?
- //
- if (::lstrcmpi (node->Get_Name (), name) == 0) {
- req_node = node;
- }
- }
- return req_node;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Get_Next
- //
- ///////////////////////////////////////////////////////////////////////
- NodeClass *
- NodeMgrClass::Get_Next (NodeClass *node)
- {
- return node->m_NextNode;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Get_First
- //
- ///////////////////////////////////////////////////////////////////////
- NodeClass *
- NodeMgrClass::Get_First (NODE_TYPE type)
- {
- NodeClass *req_node = NULL;
- //
- // Loop through all the nodes until we've found the
- // first one that matches the criteria
- //
- for ( NodeClass *node = _NodeListHead;
- (req_node == NULL) && (node != NULL);
- node = node->m_NextNode)
- {
- if (node->Get_Type () == type) {
- req_node = node;
- }
- }
- return req_node;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Get_Next
- //
- ///////////////////////////////////////////////////////////////////////
- NodeClass *
- NodeMgrClass::Get_Next (NodeClass *current, NODE_TYPE type)
- {
- NodeClass *req_node = NULL;
- //
- // Loop through all the nodes until we've found the
- // first one that matches the criteria
- //
- while ((req_node == NULL) && ((current = current->m_NextNode) != NULL))
- {
- if (current->Get_Type () == type) {
- req_node = current;
- }
- }
- return req_node;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Get_First
- //
- ///////////////////////////////////////////////////////////////////////
- NodeClass *
- NodeMgrClass::Get_First (PresetClass *preset)
- {
- NodeClass *req_node = NULL;
- //
- // Loop through all the nodes until we've found the
- // first one that matches the criteria
- //
- for ( NodeClass *node = _NodeListHead;
- (req_node == NULL) && (node != NULL);
- node = node->m_NextNode)
- {
- if (node->Get_Preset () == preset) {
- req_node = node;
- }
- }
- return req_node;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Find_First
- //
- ///////////////////////////////////////////////////////////////////////
- NodeClass *
- NodeMgrClass::Find_First (uint32 class_id)
- {
- NodeClass *req_node = NULL;
- //
- // Loop through all the nodes until we've found the
- // first one that matches the criteria
- //
- for ( NodeClass *node = _NodeListHead;
- (req_node == NULL) && (node != NULL);
- node = node->m_NextNode)
- {
- //
- // Get the preset this node was created from
- //
- PresetClass *preset = node->Get_Preset ();
- if (preset != NULL) {
- //
- // Is this preset belong to the requested class?
- //
- DefinitionClass *definition = preset->Get_Definition ();
- if (definition != NULL && definition->Get_Class_ID () == class_id) {
- req_node = node;
- }
- }
- }
- return req_node;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Find_Next
- //
- ///////////////////////////////////////////////////////////////////////
- NodeClass *
- NodeMgrClass::Find_Next (NodeClass *current, uint32 class_id)
- {
- NodeClass *req_node = NULL;
- //
- // Loop through all the nodes until we've found the
- // first one that matches the criteria
- //
- while ((req_node == NULL) && ((current = current->m_NextNode) != NULL))
- {
- //
- // Get the preset this node was created from
- //
- PresetClass *preset = current->Get_Preset ();
- if (preset != NULL) {
- //
- // Is this preset belong to the requested class?
- //
- DefinitionClass *definition = preset->Get_Definition ();
- if (definition != NULL && definition->Get_Class_ID () == class_id) {
- req_node = current;
- }
- }
- }
- return req_node;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Get_Next
- //
- ///////////////////////////////////////////////////////////////////////
- NodeClass *
- NodeMgrClass::Get_Next (NodeClass *current, PresetClass *preset)
- {
- NodeClass *req_node = NULL;
- //
- // Loop through all the nodes until we've found the
- // first one that matches the criteria
- //
- while ((req_node == NULL) && ((current = current->m_NextNode) != NULL))
- {
- if (current->Get_Preset () == preset) {
- req_node = current;
- }
- }
- return req_node;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Contains_Data
- //
- ///////////////////////////////////////////////////////////////////////
- bool
- NodeMgrClass::Contains_Data (void) const
- {
- return (_NodeListHead != NULL);
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Save
- //
- ///////////////////////////////////////////////////////////////////////
- bool
- NodeMgrClass::Save (ChunkSaveClass &csave)
- {
- bool retval = true;
- //
- // Save the variables to their own chunk
- //
- csave.Begin_Chunk (CHUNKID_VARIABLES);
- //WRITE_MICRO_CHUNK (csave, VARID_NEXT_NODE_ID, _NextNodeID);
- csave.End_Chunk ();
- //
- // Save the nodes to their own chunk
- //
- csave.Begin_Chunk (CHUNKID_NODES);
- retval &= Save_Nodes (csave);
- csave.End_Chunk ();
- return retval;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Load
- //
- // Note: It is the outside caller's responsibility to make sure
- // all nodes have been removed from the manager before a load. This
- // is done so we can import/export nodes without trashing the existing
- // node set.
- //
- ///////////////////////////////////////////////////////////////////////
- bool
- NodeMgrClass::Load (ChunkLoadClass &cload)
- {
- bool retval = true;
- while (cload.Open_Chunk ()) {
- switch (cload.Cur_Chunk_ID ()) {
-
- //
- // Load all the nodes from this chunk
- //
- case CHUNKID_NODES:
- retval &= Load_Nodes (cload);
- break;
- case CHUNKID_VARIABLES:
- retval &= Load_Variables (cload);
- break;
- }
- cload.Close_Chunk ();
- }
- SaveLoadSystemClass::Register_Post_Load_Callback (this);
- return retval;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Save_Node_List
- //
- ///////////////////////////////////////////////////////////////////////
- bool
- NodeMgrClass::Save_Node_List (ChunkSaveClass &csave, NODE_LIST &node_list)
- {
- //
- // Loop over all the nodes in the list
- //
- for (int index = 0; index < node_list.Count (); index ++) {
- NodeClass *node = node_list[index];
- if (node != NULL) {
-
- //
- // Save this node to its own chunk
- //
- csave.Begin_Chunk (node->Get_Factory ().Chunk_ID ());
- node->Get_Factory ().Save (csave, node);
- csave.End_Chunk ();
- }
- }
- return true;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Load_Node_List
- //
- ///////////////////////////////////////////////////////////////////////
- bool
- NodeMgrClass::Load_Node_List (ChunkLoadClass &cload, NODE_LIST &node_list)
- {
- while (cload.Open_Chunk ()) {
- //
- // Load this node from the chunk (if possible)
- //
- PersistFactoryClass *factory = SaveLoadSystemClass::Find_Persist_Factory (cload.Cur_Chunk_ID ());
- if (factory != NULL) {
- NodeClass *node = (NodeClass *)factory->Load (cload);
- if (node != NULL) {
-
- //
- // Does this node's preset still exist?
- //
- if (node->Get_Preset () != NULL || node->Get_Type () == NODE_TYPE_WAYPOINT) {
-
- //
- // Initialize the node
- //
- node->Initialize ();
- if (node->Needs_Save () == false) {
- node->Lock (true);
- }
- //
- // Add this node to the list
- //
- node->Add_Ref ();
- node_list.Add (node);
- } else {
- WWDEBUG_SAY (("No preset for linked node %s.\r\n", node->Get_Name ()));
- }
- MEMBER_RELEASE (node);
- }
- }
- cload.Close_Chunk ();
- }
- return true;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Save_Nodes
- //
- ///////////////////////////////////////////////////////////////////////
- bool
- NodeMgrClass::Save_Nodes (ChunkSaveClass &csave)
- {
- for ( NodeClass *node = _NodeListHead;
- node != NULL;
- node = node->m_NextNode)
- {
- if (node->Needs_Save ()) {
-
- //
- // Save this node to its own chunk
- //
- csave.Begin_Chunk (node->Get_Factory ().Chunk_ID ());
- node->Get_Factory ().Save (csave, node);
- csave.End_Chunk ();
- }
- }
- return true;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Load_Nodes
- //
- ///////////////////////////////////////////////////////////////////////
- bool
- NodeMgrClass::Load_Nodes (ChunkLoadClass &cload)
- {
- bool retval = true;
- DynamicVectorClass<NodeClass *> removed_node_list;
- while (cload.Open_Chunk ()) {
- //
- // Load this node from the chunk (if possible)
- //
- PersistFactoryClass *factory = SaveLoadSystemClass::Find_Persist_Factory (cload.Cur_Chunk_ID ());
- if (factory != NULL) {
- NodeClass *node = (NodeClass *)factory->Load (cload);
- if (node != NULL) {
-
- // Does this node's preset still exist?
- if (node->Get_Preset () != NULL || node->Get_Type () == NODE_TYPE_WAYPOINT) {
-
- //
- // Initialize the node
- //
- node->Initialize ();
- if (node->Needs_Save () == false) {
- node->Lock (true);
- }
- //
- // Put the node back into the world
- //
- Add_Node (node);
- } else {
- node->Add_Ref ();
- removed_node_list.Add (node);
- WWDEBUG_SAY (("No preset for %s, removing from level.\r\n", node->Get_Name ()));
- }
- MEMBER_RELEASE (node);
- }
- }
- cload.Close_Chunk ();
- }
- //
- // Display a dialog to the user allowing them to remap removed nodes
- // to other presets...
- //
- if (removed_node_list.Count () > 0) {
- PresetRemapDialogClass dialog (::AfxGetMainWnd ());
- dialog.Set_Node_list (removed_node_list);
- dialog.DoModal ();
- }
- return retval;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // On_Post_Load
- //
- ///////////////////////////////////////////////////////////////////////
- void
- NodeMgrClass::On_Post_Load (void)
- {
- SceneEditorClass *scene = ::Get_Scene_Editor ();
- //
- // Loop over all the nodes
- //
- for ( NodeClass *node = _NodeListHead;
- node != NULL;
- node = node->m_NextNode)
- {
- //
- // Add them to the scene...
- //
- node->Add_To_Scene ();
- scene->Update_File_Mgr (node);
- }
-
- Reset_New_ID ();
- return ;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Load_Variables
- //
- ///////////////////////////////////////////////////////////////////////
- bool
- NodeMgrClass::Load_Variables (ChunkLoadClass &cload)
- {
- bool retval = true;
- while (cload.Open_Micro_Chunk ()) {
- /*switch (cload.Cur_Micro_Chunk_ID ()) {
- }*/
- cload.Close_Micro_Chunk ();
- }
-
- return retval;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Reload_Nodes
- //
- ///////////////////////////////////////////////////////////////////////
- void
- NodeMgrClass::Reload_Nodes (void)
- {
- ::Get_Main_View ()->Allow_Repaint (false);
- //
- // First, make sure each node has the correct preset pointer
- //
- DynamicVectorClass<NodeClass *> node_list;
- Build_Full_Node_List (node_list);
- for (int index = 0; index < node_list.Count (); index ++) {
- NodeClass *node = node_list[index];
- if (node != NULL) {
- //
- // Lookup the preset and re-assign it to this node
- //
- uint32 preset_id = node->Get_Preset_ID ();
- PresetClass *preset = PresetMgrClass::Find_Preset (preset_id);
- node->Set_Preset (preset);
- }
- }
- //
- // Ask each node to recreate itself
- //
- for ( NodeClass *node = _NodeListHead; node != NULL; node = node->m_NextNode) {
- node->Reload ();
- }
- ::Get_Scene_Editor ()->Validate_Vis ();
- ::Get_Main_View ()->Allow_Repaint (true);
- return ;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Reload_Nodes
- //
- ///////////////////////////////////////////////////////////////////////
- void
- NodeMgrClass::Reload_Nodes (PresetClass *preset)
- {
- ::Get_Main_View ()->Allow_Repaint (false);
- //
- // Loop over all the nodes
- //
- for ( NodeClass *node = _NodeListHead;
- node != NULL;
- node = node->m_NextNode)
- {
- //
- // Simply ask the node to re-create itself
- //
- if (node->Get_Preset () == preset) {
- node->Reload ();
- }
- }
-
- ::Get_Scene_Editor ()->Validate_Vis ();
- ::Get_Main_View ()->Allow_Repaint (true);
- return ;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Put_Objects_Back
- //
- ///////////////////////////////////////////////////////////////////////
- void
- NodeMgrClass::Put_Objects_Back (const NODE_LIST &obj_list)
- {
- //
- // Insert the nodes back into the system
- //
- for (int index = 0; index < obj_list.Count (); index ++) {
- NodeClass *node = obj_list[index];
- NodeMgrClass::Add_Node (node);
- node->Release_Ref ();
- }
-
- return ;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Remove_Dynamic_Objects
- //
- ///////////////////////////////////////////////////////////////////////
- void
- NodeMgrClass::Remove_Dynamic_Objects (NODE_LIST &dynamic_obj_list)
- {
- //
- // Build a list of nodes to that are not dynamic
- //
- for ( NodeClass *node = NodeMgrClass::Get_First ();
- node != NULL;
- node = NodeMgrClass::Get_Next (node))
- {
- if (node->Is_Static () == false) {
- dynamic_obj_list.Add (node);
- }
- }
- //
- // Remove these nodes from the level
- //
- for (int index = 0; index < dynamic_obj_list.Count (); index ++) {
- NodeClass *node = dynamic_obj_list[index];
- if (node != NULL) {
- node->Add_Ref ();
- NodeMgrClass::Remove_Node (node);
- }
- }
-
- return ;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Remove_Static_Objects
- //
- ///////////////////////////////////////////////////////////////////////
- void
- NodeMgrClass::Remove_Static_Objects (NODE_LIST &static_obj_list)
- {
- //
- // Build a list of nodes to that are not dynamic
- //
- for ( NodeClass *node = NodeMgrClass::Get_First ();
- node != NULL;
- node = NodeMgrClass::Get_Next (node))
- {
- if (node->Is_Static ()) {
- static_obj_list.Add (node);
- }
- }
- //
- // Remove these nodes from the level
- //
- for (int index = 0; index < static_obj_list.Count (); index ++) {
- NodeClass *node = static_obj_list[index];
- if (node != NULL) {
- node->Add_Ref ();
- NodeMgrClass::Remove_Node (node);
- }
- }
-
- return ;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Get_Max_Used_ID
- //
- ///////////////////////////////////////////////////////////////////////
- uint32
- NodeMgrClass::Get_Max_Used_ID (void)
- {
- //
- // Build the full list of nodes
- //
- DynamicVectorClass<NodeClass *> full_node_list;
- Build_Full_Node_List (full_node_list);
- uint32 max_used = 0;
- //
- // Determine what the largest used ID is
- //
- for (int index = 0; index < full_node_list.Count (); index ++) {
- NodeClass *node = full_node_list[index];
- max_used = max (node->Get_ID (), max_used);
- }
- return max_used;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Verify_Unique_ID - Verify that given ID is unique.
- //
- ///////////////////////////////////////////////////////////////////////
- bool
- NodeMgrClass::Verify_Unique_ID(uint32 id)
- {
- NodeClass* node = Get_First();
- while (node != NULL) {
- if (node->Get_ID() == id) {
- return false;
- }
- node = Get_Next(node);
- }
- return true;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Make_Static_Anim_Phys_Collideable
- //
- ///////////////////////////////////////////////////////////////////////
- void
- NodeMgrClass::Make_Static_Anim_Phys_Collideable (bool onoff)
- {
- //
- // Loop over all the terrains in the level
- //
- for ( NodeClass *node = NodeMgrClass::Get_First (NODE_TYPE_TERRAIN);
- node != NULL;
- node = NodeMgrClass::Get_Next (node, NODE_TYPE_TERRAIN))
- {
- TerrainNodeClass *terrain = (TerrainNodeClass *)node;
- int count = terrain->Get_Sub_Node_Count ();
-
- //
- // Loop over all the sections of this terrain object
- //
- for (int index = 0; index < count; index ++) {
- NodeClass *sub_node = terrain->Get_Sub_Node (index);
- if (sub_node != NULL) {
- //
- // Check to make sure this is a static anim phys object
- //
- PhysClass *phys_obj = sub_node->Peek_Physics_Obj ();
- if (phys_obj != NULL && phys_obj->As_StaticAnimPhysClass () != NULL) {
- sub_node->Hide (onoff == false);
-
- //
- // Turn off collision on or off this object
- //
- if (onoff == false) {
- phys_obj->Inc_Ignore_Counter ();
- } else if (phys_obj->Is_Ignore_Me ()) {
- phys_obj->Dec_Ignore_Counter ();
- }
- }
- }
- }
- }
- //
- // Loop over all the tiles in the level
- //
- for ( node = NodeMgrClass::Get_First (NODE_TYPE_TILE);
- node != NULL;
- node = NodeMgrClass::Get_Next (node, NODE_TYPE_TILE))
- {
- //
- // Check to make sure this is a static anim phys object
- //
- PhysClass *phys_obj = node->Peek_Physics_Obj ();
- if (phys_obj != NULL && phys_obj->As_StaticAnimPhysClass () != NULL) {
- node->Hide (onoff);
-
- //
- // Turn off collision on or off this object
- //
- if (onoff == false) {
- phys_obj->Inc_Ignore_Counter ();
- } else if (phys_obj->Is_Ignore_Me ()) {
- phys_obj->Dec_Ignore_Counter ();
- }
- }
- }
-
- return ;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Build_ID_Collision_List
- //
- ///////////////////////////////////////////////////////////////////////
- void
- NodeMgrClass::Build_ID_Collision_List (NODE_LIST &node_list)
- {
- CWaitCursor wait_cursor;
- //
- // Build a flat list of nodes
- //
- DynamicVectorClass<NodeClass *> full_node_list;
- Build_Full_Node_List (full_node_list);
- //
- // Loop over all the nodes, checking every one against the other
- //
- for (int index1 = 0; index1 < full_node_list.Count (); index1 ++) {
- for (int index2 = 0; index2 < full_node_list.Count (); index2 ++) {
- NodeClass *node1 = full_node_list[index1];
- NodeClass *node2 = full_node_list[index2];
- //
- // Do these nodes share the same ID?
- //
- if (node1 != node2 && node1->Get_ID () == node2->Get_ID ()) {
- if (node_list.ID (node1) == -1) {
- node_list.Add (node1);
- }
- }
-
- }
- }
- return ;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Build_Unimportant_ID_Collision_List
- //
- ///////////////////////////////////////////////////////////////////////
- void
- NodeMgrClass::Build_Unimportant_ID_Collision_List (NODE_LIST &node_list)
- {
- CWaitCursor wait_cursor;
- //
- // Build a flat list of nodes
- //
- DynamicVectorClass<NodeClass *> full_node_list;
- Build_Full_Node_List (full_node_list);
- //
- // Loop over all the nodes, checking every one against the other
- //
- for (int index1 = 0; index1 < full_node_list.Count (); index1 ++) {
- for (int index2 = 0; index2 < full_node_list.Count (); index2 ++) {
- NodeClass *node1 = full_node_list[index1];
- NodeClass *node2 = full_node_list[index2];
- //
- // Do these nodes share the same ID?
- //
- if (node1 != node2 && node1->Get_ID () == node2->Get_ID ()) {
- if (node_list.ID (node1) == -1) {
- //
- // Check to make sure this isn't an important node type
- //
- if ( node1->As_ObjectNodeClass () == NULL &&
- node1->Get_Type () != NODE_TYPE_SPAWNER &&
- node1->Get_Type () != NODE_TYPE_TILE &&
- node1->Get_Type () != NODE_TYPE_WAYPATH &&
- node1->Get_Type () != NODE_TYPE_WAYPOINT &&
- node1->Get_Type () != NODE_TYPE_SOUND)
- {
- node_list.Add (node1);
- }
- }
- }
-
- }
- }
- return ;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Reset_New_ID
- //
- ///////////////////////////////////////////////////////////////////////
- void
- NodeMgrClass::Reset_New_ID (void)
- {
- //
- // Reset each of the id ranges
- //
- _NextObjectNodeID = Find_Max_Used_ID (NODE_TYPE_OBJECT) + 1;
- _NextStaticNodeID = Find_Max_Used_ID (NODE_TYPE_TERRAIN) + 1;
- _NextLightNodeID = Find_Max_Used_ID (NODE_TYPE_LIGHT) + 1;
- _NextMiscNodeID = Find_Max_Used_ID (NODE_TYPE_VIS_POINT) + 1;
- //
- // Update each heightfield with a guaranteed unique ID
- //
- HeightfieldMgrClass::Assign_Unique_IDs ();
- return ;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Find_Max_Used_ID
- //
- ///////////////////////////////////////////////////////////////////////
- uint32
- NodeMgrClass::Find_Max_Used_ID (NODE_TYPE type)
- {
- //
- // Determine what our minimum ID is
- //
- uint32 min_id = 0;
- uint32 max_id = 0;
- Get_ID_Range (type, &min_id, &max_id);
- //
- // First, build a complete list of all the nodes
- //
- DynamicVectorClass<NodeClass *> node_list;
- Build_Full_Node_List (node_list);
- //
- // Loop over all the nodes in the level and find the largest ID
- // in our range
- //
- uint32 largest_id = min_id;
- for (int index = 0; index < node_list.Count (); index ++) {
- NodeClass *node = node_list[index];
- if (node != NULL) {
- //
- // Is this the largest ID in our range?
- //
- uint32 curr_id = node->Get_ID ();
- if (curr_id >= min_id && curr_id < max_id) {
- largest_id = max (largest_id, curr_id);
- }
- }
- }
- return largest_id;
- }
- //////////////////////////////////////////////////////////////////////////////////////////
- //
- // Get_Node_ID
- //
- //////////////////////////////////////////////////////////////////////////////////////////
- uint32
- NodeMgrClass::Get_Node_ID (NODE_TYPE type)
- {
- uint32 new_id = 0;
- switch (type)
- {
- case NODE_TYPE_TERRAIN:
- case NODE_TYPE_TERRAIN_SECTION:
- case NODE_TYPE_TILE:
- case NODE_TYPE_BUILDING:
- new_id = _NextStaticNodeID ++;
- break;
- case NODE_TYPE_DAMAGE_ZONE:
- case NODE_TYPE_ZONE:
- new_id = _NextObjectNodeID ++;
- break;
- case NODE_TYPE_WAYPATH:
- case NODE_TYPE_WAYPOINT:
- new_id = _NextObjectNodeID ++;
- break;
-
- case NODE_TYPE_OBJECT:
- new_id = _NextObjectNodeID ++;
- break;
-
- case NODE_TYPE_COVER_SPOT:
- case NODE_TYPE_COVER_ATTACK_POINT:
- new_id = _NextObjectNodeID ++;
- break;
-
- case NODE_TYPE_SPAWNER:
- new_id = _NextObjectNodeID ++;
- break;
- case NODE_TYPE_SOUND:
- case NODE_TYPE_TRANSITION:
- case NODE_TYPE_TRANSITION_CHARACTER:
- case NODE_TYPE_DUMMY_OBJECT:
- new_id = _NextObjectNodeID ++;
- break;
- case NODE_TYPE_LIGHT:
- new_id = _NextLightNodeID ++;
- break;
- case NODE_TYPE_UNKNOWN:
- case NODE_TYPE_VIS:
- case NODE_TYPE_VIS_POINT:
- case NODE_TYPE_PATHFIND_START:
- default:
- new_id = _NextMiscNodeID ++;
- break;
- }
- return new_id;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Get_ID_Range
- //
- ///////////////////////////////////////////////////////////////////////
- void
- NodeMgrClass::Get_ID_Range (NODE_TYPE type, uint32 *min_id, uint32 *max_id)
- {
- switch (type)
- {
- case NODE_TYPE_TERRAIN:
- case NODE_TYPE_TERRAIN_SECTION:
- case NODE_TYPE_TILE:
- case NODE_TYPE_BUILDING:
- (*min_id) = theApp.GetProfileInt (CONFIG_KEY, NODE_ID_START_VALUE, FIRST_OBJECT_NODE_ID);
- (*min_id) += 50000;
- (*max_id) = (*min_id) + 50000;
- break;
- case NODE_TYPE_DAMAGE_ZONE:
- case NODE_TYPE_ZONE:
- case NODE_TYPE_WAYPATH:
- case NODE_TYPE_WAYPOINT:
- case NODE_TYPE_OBJECT:
- case NODE_TYPE_COVER_SPOT:
- case NODE_TYPE_COVER_ATTACK_POINT:
- case NODE_TYPE_SPAWNER:
- case NODE_TYPE_SOUND:
- case NODE_TYPE_TRANSITION:
- case NODE_TYPE_TRANSITION_CHARACTER:
- case NODE_TYPE_DUMMY_OBJECT:
- (*min_id) = theApp.GetProfileInt (CONFIG_KEY, NODE_ID_START_VALUE, FIRST_OBJECT_NODE_ID);
- (*max_id) = (*min_id) + 50000;
- break;
- case NODE_TYPE_LIGHT:
- (*min_id) = FIRST_LIGHT_NODE_ID;
- (*max_id) = (*min_id) + 100000;
- break;
- case NODE_TYPE_UNKNOWN:
- case NODE_TYPE_VIS:
- case NODE_TYPE_VIS_POINT:
- case NODE_TYPE_PATHFIND_START:
- (*min_id) = FIRST_MISC_NODE_ID;
- (*max_id) = (*min_id) + 100000;
- break;
- default:
- (*min_id) = FIRST_MISC_NODE_ID;
- break;
- }
- return ;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Build_Full_Node_List
- //
- ///////////////////////////////////////////////////////////////////////
- void
- NodeMgrClass::Build_Full_Node_List (DynamicVectorClass<NodeClass *> &node_list)
- {
- //
- // Add all nodes and sub-nodes to this list
- //
- for (NodeClass *node = ::Get_Node_Mgr ().Get_First ();
- node != NULL;
- node = ::Get_Node_Mgr ().Get_Next (node))
- {
- Add_Nodes_To_List (node_list, node);
- }
-
- return ;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Add_Nodes_To_List
- //
- ///////////////////////////////////////////////////////////////////////
- void
- NodeMgrClass::Add_Nodes_To_List
- (
- DynamicVectorClass<NodeClass *> &node_list,
- NodeClass *node
- )
- {
- node_list.Add (node);
- //
- // If the node is an aggregate (like a terrain), we are adding the
- // sub-nodes directly into the list
- //
- int sub_count = node->Get_Sub_Node_Count ();
- if (sub_count > 0) {
- for (int index = 0; index < sub_count; index ++) {
- NodeClass *sub_node = node->Get_Sub_Node (index);
-
- //
- // Recurse into this node
- //
- Add_Nodes_To_List (node_list, sub_node);
- }
- }
- return ;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Create_All_Embedded_Nodes
- //
- ///////////////////////////////////////////////////////////////////////
- void
- NodeMgrClass::Create_All_Embedded_Nodes (void)
- {
- //
- // Generate a list of nodes
- //
- DynamicVectorClass<NodeClass *> node_list;
- Build_Full_Node_List (node_list);
- //
- // Loop over all the nodes
- //
- for (int index = 0; index < node_list.Count (); index ++) {
- if (node_list[index]->Is_Proxied () == false) {
- PresetClass *preset = node_list[index]->Get_Preset ();
- if (preset != NULL) {
-
- //
- // Create the nodes that are embedded inside this preset
- //
- preset->Create_Linked_Nodes (node_list[index]);
- }
- }
- }
- return ;
- }
|