Preset.cpp 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389
  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/Preset.cpp $*
  25. * *
  26. * Author:: Patrick Smith *
  27. * *
  28. * $Modtime:: 1/29/02 4:04p $*
  29. * *
  30. * $Revision:: 49 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "stdafx.h"
  36. #include "preset.h"
  37. #include "presetgeneraltab.h"
  38. #include "presetsettingstab.h"
  39. #include "presetpropsheet.h"
  40. #include "chunkio.h"
  41. #include "persistfactory.h"
  42. #include "editorchunkids.h"
  43. #include "definition.h"
  44. #include "definitionmgr.h"
  45. #include "filemgr.h"
  46. #include "parameter.h"
  47. #include "terrainnode.h"
  48. #include "terraindefinition.h"
  49. #include "tilenode.h"
  50. #include "objectnode.h"
  51. #include "assetmgr.h"
  52. #include "wwstring.h"
  53. #include "combatchunkid.h"
  54. #include "spawnernode.h"
  55. #include "soundnode.h"
  56. #include "vispointnode.h"
  57. #include "presettransitiontab.h"
  58. #include "vehicle.h"
  59. #include "zonenode.h"
  60. #include "damagezonenode.h"
  61. #include "transitionnode.h"
  62. #include "pathfindstartnode.h"
  63. #include "dummyobjectnode.h"
  64. #include "editoronlyobjectnode.h"
  65. #include "presetmgr.h"
  66. #include "lightnode.h"
  67. #include "physobjedittab.h"
  68. #include "definitionutils.h"
  69. #include "waypathnode.h"
  70. #include "utils.h"
  71. #include "coverspotnode.h"
  72. #include "presetdependencytab.h"
  73. #include "presetzonetab.h"
  74. #include "presetdialoguetab.h"
  75. #include "buildingnode.h"
  76. #include "nodescriptsproppage.h"
  77. #include "nodemgr.h"
  78. #include "sceneeditor.h"
  79. #include "editorbuild.h"
  80. ///////////////////////////////////////////////////////////////////////
  81. //
  82. // Global persist factory for presets
  83. //
  84. ///////////////////////////////////////////////////////////////////////
  85. SimplePersistFactoryClass<PresetClass, CHUNKID_PRESET> _PresetPersistFactory;
  86. //////////////////////////////////////////////////////////////////////////////////
  87. // Constants
  88. //////////////////////////////////////////////////////////////////////////////////
  89. enum
  90. {
  91. CHUNKID_VARIABLES = 0x00000100,
  92. CHUNKID_COMMENTS,
  93. XXX_CHUNKID_NODES
  94. };
  95. enum
  96. {
  97. VARID_DEFINITIONID = 0x01,
  98. VARID_ISTEMPORARY,
  99. VARID_COMMENTS,
  100. VARID_PARENTPTR,
  101. VARID_THISPTR,
  102. XXX_VARID_FILEDEPENDENCY,
  103. VARID_PARENT_ID,
  104. VARID_MANUALDEPENDENCY
  105. };
  106. ///////////////////////////////////////////////////////////////////////
  107. //
  108. // PresetClass
  109. //
  110. ///////////////////////////////////////////////////////////////////////
  111. PresetClass::PresetClass (void)
  112. : m_Definition (NULL),
  113. m_DefinitionID (0),
  114. m_Parent (NULL),
  115. m_ParentID (0),
  116. m_NextPreset (NULL),
  117. m_PrevPreset (NULL),
  118. m_IsTemporary (false),
  119. m_IsValid (true)
  120. {
  121. return ;
  122. }
  123. ///////////////////////////////////////////////////////////////////////
  124. //
  125. // ~PresetClass
  126. //
  127. ///////////////////////////////////////////////////////////////////////
  128. PresetClass::~PresetClass (void)
  129. {
  130. //
  131. // Remove this preset from its parent (if possible or necessary)
  132. //
  133. PresetClass *parent = PresetMgrClass::Find_Preset (m_ParentID);
  134. if (parent != NULL) {
  135. parent->Remove_Child_Preset (m_DefinitionID);
  136. }
  137. //
  138. // Unlink this definition from its preset (if possible or necessary)
  139. //
  140. DefinitionClass *definition = DefinitionMgrClass::Find_Definition (m_DefinitionID, false);
  141. if (definition != NULL && (definition->Get_User_Data () == (uint32)this)) {
  142. definition->Set_User_Data (NULL);
  143. }
  144. Free_Node_List ();
  145. return ;
  146. }
  147. ///////////////////////////////////////////////////////////////////////
  148. //
  149. // Show_Properties
  150. //
  151. ///////////////////////////////////////////////////////////////////////
  152. bool
  153. PresetClass::Show_Properties (bool read_only)
  154. {
  155. PresetGeneralTabClass general_tab (this);
  156. PhysObjEditTabClass phys_model_tab;
  157. PresetSettingsTabClass settings_tab (this);
  158. PresetDependencyTabClass dependencies_tab (this);
  159. PresetTransitionTabClass transition_tab (this);
  160. PresetZoneTabClass zone_tab (this);
  161. PresetDialogueTabClass dialogue_tab (this);
  162. NodeScriptsPropPage scripts_tab;
  163. //
  164. // Add the general page first
  165. //
  166. PresetPropSheetClass prop_sheet;
  167. prop_sheet.Set_Preset (this);
  168. prop_sheet.Add_Page (&general_tab);
  169. //
  170. // Should we add a physics-definition page?
  171. //
  172. ModelDefParameterClass *phys_def_param = Get_Phys_Def_Param ();
  173. if (phys_def_param != NULL) {
  174. phys_model_tab.Set_PhysDef_Param (phys_def_param);
  175. phys_model_tab.Set_Filter (phys_def_param->Get_Base_Class ());
  176. phys_model_tab.Set_Is_Temp (m_IsTemporary);
  177. phys_model_tab.Set_Definition_ID (phys_def_param->Get_Value ());
  178. prop_sheet.Add_Page (&phys_model_tab);
  179. }
  180. //
  181. // Add the settings and file dependencies page
  182. //
  183. prop_sheet.Add_Page (&settings_tab);
  184. prop_sheet.Add_Page (&dependencies_tab);
  185. //
  186. // Should we add a scripts page?
  187. //
  188. ScriptListParameterClass *script_list_param = Get_Script_List_Param ();
  189. if (script_list_param != NULL) {
  190. scripts_tab.Set_Script_List_Parameter (script_list_param);
  191. prop_sheet.Add_Page (&scripts_tab);
  192. }
  193. //
  194. // Add a dialogue tab to the property sheet if this preset represents a human.
  195. //
  196. if (Is_Soldier_Preset ()) {
  197. prop_sheet.Add_Page (&dialogue_tab);
  198. }
  199. //
  200. // Should we add a transition-list page?
  201. //
  202. TRANSITION_DATA_LIST *transition_list = Get_Transition_List ();
  203. if (transition_list != NULL && read_only == false) {
  204. transition_tab.Set_Transition_List (transition_list);
  205. prop_sheet.Add_Page (&transition_tab);
  206. }
  207. //
  208. // Should we add a zone-list page?
  209. //
  210. ZONE_PARAM_LIST zone_list;
  211. Build_Zone_List (m_Definition, zone_list);
  212. if (zone_list.Count () > 0 && read_only == false) {
  213. zone_tab.Set_Zone_Param_List (&zone_list);
  214. prop_sheet.Add_Page (&zone_tab);
  215. }
  216. //
  217. // Make sure things are read-only if needs be
  218. //
  219. prop_sheet.Set_Read_Only (read_only);
  220. general_tab.Set_Read_Only (read_only);
  221. settings_tab.Set_Read_Only (read_only);
  222. dependencies_tab.Set_Read_Only (read_only);
  223. phys_model_tab.Set_Read_Only (read_only);
  224. dialogue_tab.Set_Read_Only (read_only);
  225. //
  226. // Show the property sheet
  227. //
  228. UINT ret_code = prop_sheet.DoModal ();
  229. // Return true if the user clicked OK
  230. return (ret_code == IDOK);
  231. }
  232. ///////////////////////////////////////////////////////////////////////
  233. //
  234. // Get_Factory
  235. //
  236. ///////////////////////////////////////////////////////////////////////
  237. const PersistFactoryClass &
  238. PresetClass::Get_Factory (void) const
  239. {
  240. return _PresetPersistFactory;
  241. }
  242. ///////////////////////////////////////////////////////////////////////
  243. //
  244. // Save
  245. //
  246. ///////////////////////////////////////////////////////////////////////
  247. bool
  248. PresetClass::Save (ChunkSaveClass &csave)
  249. {
  250. bool retval = true;
  251. //
  252. // Save the comments to their own chunk
  253. //
  254. WRITE_WWSTRING_CHUNK (csave, CHUNKID_COMMENTS, m_Comments);
  255. //
  256. // Save the other variables to a micro chunk
  257. //
  258. csave.Begin_Chunk (CHUNKID_VARIABLES);
  259. retval &= Save_Variables (csave);
  260. csave.End_Chunk ();
  261. return retval;
  262. }
  263. ///////////////////////////////////////////////////////////////////////
  264. //
  265. // Save_Variables
  266. //
  267. ///////////////////////////////////////////////////////////////////////
  268. bool
  269. PresetClass::Save_Variables (ChunkSaveClass &csave)
  270. {
  271. bool retval = true;
  272. //
  273. // Write the ID of the definition to the chunk
  274. //
  275. ASSERT (m_Definition != NULL);
  276. if (m_Definition != NULL) {
  277. m_DefinitionID = m_Definition->Get_ID ();
  278. WRITE_MICRO_CHUNK (csave, VARID_DEFINITIONID, m_DefinitionID);
  279. }
  280. WRITE_MICRO_CHUNK (csave, VARID_ISTEMPORARY, m_IsTemporary);
  281. //
  282. // Write the file dependencies to their own micro-chunks
  283. //
  284. for (int index = 0; index < m_ManualDependencies.Count (); index ++) {
  285. StringClass filename = (LPCTSTR)m_ManualDependencies[index];
  286. WRITE_MICRO_CHUNK_WWSTRING (csave, VARID_MANUALDEPENDENCY, filename);
  287. }
  288. //
  289. // For pointer remapping
  290. //
  291. PresetClass *this_ptr = this;
  292. WRITE_MICRO_CHUNK (csave, VARID_THISPTR, this_ptr);
  293. if (m_Parent != NULL) {
  294. m_ParentID = m_Parent->Get_ID ();
  295. WRITE_MICRO_CHUNK (csave, VARID_PARENT_ID, m_ParentID);
  296. }
  297. return retval;
  298. }
  299. ///////////////////////////////////////////////////////////////////////
  300. //
  301. // Load
  302. //
  303. ///////////////////////////////////////////////////////////////////////
  304. bool
  305. PresetClass::Load (ChunkLoadClass &cload)
  306. {
  307. bool retval = true;
  308. while (cload.Open_Chunk ()) {
  309. switch (cload.Cur_Chunk_ID ())
  310. {
  311. READ_WWSTRING_CHUNK (cload, CHUNKID_COMMENTS, m_Comments);
  312. case CHUNKID_VARIABLES:
  313. retval &= Load_Variables (cload);
  314. break;
  315. }
  316. cload.Close_Chunk ();
  317. }
  318. SaveLoadSystemClass::Register_Post_Load_Callback (this);
  319. return retval;
  320. }
  321. ///////////////////////////////////////////////////////////////////////
  322. //
  323. // Load_Variables
  324. //
  325. ///////////////////////////////////////////////////////////////////////
  326. bool
  327. PresetClass::Load_Variables (ChunkLoadClass &cload)
  328. {
  329. m_DefinitionID = 0;
  330. PresetClass *old_this_ptr = NULL;
  331. m_ManualDependencies.Delete_All ();
  332. //
  333. // Loop through all the microchunks that define the variables
  334. //
  335. while (cload.Open_Micro_Chunk ()) {
  336. switch (cload.Cur_Micro_Chunk_ID ()) {
  337. READ_MICRO_CHUNK (cload, VARID_DEFINITIONID, m_DefinitionID)
  338. READ_MICRO_CHUNK (cload, VARID_ISTEMPORARY, m_IsTemporary)
  339. READ_MICRO_CHUNK_WWSTRING (cload, VARID_COMMENTS, m_Comments);
  340. READ_MICRO_CHUNK (cload, VARID_PARENTPTR, m_Parent)
  341. READ_MICRO_CHUNK (cload, VARID_THISPTR, old_this_ptr)
  342. READ_MICRO_CHUNK (cload, VARID_PARENT_ID, m_ParentID);
  343. case VARID_MANUALDEPENDENCY:
  344. {
  345. StringClass filename;
  346. cload.Read(filename.Get_Buffer(cload.Cur_Micro_Chunk_Length()),cload.Cur_Micro_Chunk_Length());
  347. m_ManualDependencies.Add ((LPCTSTR)filename);
  348. }
  349. break;
  350. }
  351. cload.Close_Micro_Chunk ();
  352. }
  353. //
  354. // Check for a recursive linkage (could happen with temp presets if the
  355. // user deletes his registry)...
  356. //
  357. if (m_ParentID == Get_ID ()) {
  358. m_IsValid = false;
  359. }
  360. //
  361. // Handle pointer remapping. LEGACY CODE -- IS NOW OBSOLETE.
  362. //
  363. WWASSERT (old_this_ptr != NULL);
  364. SaveLoadSystemClass::Register_Pointer (old_this_ptr, this);
  365. if (m_Parent != NULL) {
  366. REQUEST_POINTER_REMAP ((void **)&m_Parent);
  367. }
  368. //
  369. // Lookup the definition pointer from the definition id
  370. //
  371. WWASSERT (m_DefinitionID != 0);
  372. m_Definition = DefinitionMgrClass::Find_Definition (m_DefinitionID, false);
  373. //
  374. // Associate this preset with the definition
  375. //
  376. if (m_Definition != NULL) {
  377. m_Definition->Set_User_Data ((uint32)this);
  378. }
  379. if (m_DefinitionID == 0 || m_Definition == NULL) {
  380. int test = 0;
  381. }
  382. return true;
  383. }
  384. ///////////////////////////////////////////////////////////////////////
  385. //
  386. // On_Post_Load
  387. //
  388. ///////////////////////////////////////////////////////////////////////
  389. void
  390. PresetClass::On_Post_Load (void)
  391. {
  392. PersistClass::On_Post_Load ();
  393. //
  394. // Lookup the parent based on its ID (instead of its pointer)
  395. //
  396. if (m_ParentID != 0) {
  397. m_Parent = PresetMgrClass::Find_Preset (m_ParentID);
  398. ASSERT (m_Parent != NULL);
  399. //
  400. // Add ourselves as a child of our parent
  401. //
  402. if (m_Parent != NULL) {
  403. m_Parent->Add_Child_Preset (Get_ID ());
  404. }
  405. #ifdef _DEBUG
  406. if (m_Parent == this || m_ParentID == Get_ID ()) {
  407. CString message;
  408. message.Format ("Preset %s is recursively linked to itself.\r\n", Get_Name ());
  409. ::Output_Message (message);
  410. }
  411. #endif // _DEBUG
  412. }
  413. return ;
  414. }
  415. ///////////////////////////////////////////////////////////////////////
  416. //
  417. // Create
  418. //
  419. ///////////////////////////////////////////////////////////////////////
  420. NodeClass *
  421. PresetClass::Create (void)
  422. {
  423. NodeClass *node = NULL;
  424. StringClass error_message;
  425. if (m_Definition != NULL && m_Definition->Is_Valid_Config (error_message)) {
  426. uint32 class_id = m_Definition->Get_Class_ID ();
  427. switch (::SuperClassID_From_ClassID (class_id))
  428. {
  429. case CLASSID_TERRAIN:
  430. node = new TerrainNodeClass (this);
  431. break;
  432. case CLASSID_TILE:
  433. node = new TileNodeClass (this);
  434. break;
  435. case CLASSID_BUILDINGS:
  436. node = new BuildingNodeClass (this);
  437. break;
  438. case CLASSID_GAME_OBJECTS:
  439. if (class_id == CLASSID_SPAWNER_DEF) {
  440. node = new SpawnerNodeClass (this);
  441. } else if (class_id == CLASSID_GAME_OBJECT_DEF_BUILDING) {
  442. node = new BuildingNodeClass (this);
  443. } else if (class_id == CLASSID_GAME_OBJECT_DEF_SCRIPT_ZONE) {
  444. node = new ZoneNodeClass (this);
  445. } else if (class_id == CLASSID_GAME_OBJECT_DEF_DAMAGE_ZONE) {
  446. node = new DamageZoneNodeClass (this);
  447. } else if (class_id == CLASSID_GAME_OBJECT_DEF_TRANSITION) {
  448. node = new TransitionNodeClass (this);
  449. } else if (class_id == CLASSID_GAME_OBJECT_DEF_C4) {
  450. ::AfxGetMainWnd ()->MessageBox ("You cannot place C4 objects in the editor.", "Non-Placeable Object", MB_ICONEXCLAMATION | MB_OK);
  451. } else {
  452. node = new ObjectNodeClass (this);
  453. }
  454. break;
  455. case CLASSID_LIGHT:
  456. node = new LightNodeClass (this);
  457. break;
  458. case CLASSID_SOUND:
  459. node = new SoundNodeClass (this);
  460. break;
  461. case CLASSID_WAYPATH:
  462. node = new WaypathNodeClass (this);
  463. break;
  464. case CLASSID_DUMMY_OBJECTS:
  465. node = new DummyObjectNodeClass (this);
  466. break;
  467. default:
  468. if (class_id == CLASSID_VIS_POINT_DEF) {
  469. node = new VisPointNodeClass (this);
  470. } else if (class_id == CLASSID_PATHFIND_START_DEF) {
  471. node = new PathfindStartNodeClass (this);
  472. } else if (class_id == CLASSID_COVERSPOT) {
  473. node = new CoverSpotNodeClass (this);
  474. } else if (class_id == CLASSID_EDITOR_ONLY_OBJECTS) {
  475. node = new EditorOnlyObjectNodeClass (this);
  476. }
  477. break;
  478. }
  479. } else if (m_Definition != NULL) {
  480. //
  481. // Warn the user
  482. //
  483. StringClass msg ("Unable to instantiate preset!\nReason: preset not configured correctly.\n\n");
  484. msg += error_message;
  485. ::AfxGetMainWnd ()->MessageBox (msg, "Preset Error", MB_ICONEXCLAMATION | MB_OK);
  486. }
  487. return node;
  488. }
  489. ///////////////////////////////////////////////////////////////////////
  490. //
  491. // Copy_Properties
  492. //
  493. ///////////////////////////////////////////////////////////////////////
  494. void
  495. PresetClass::Copy_Properties (const PresetClass &preset)
  496. {
  497. DefinitionClass *src_def = preset.Get_Definition ();
  498. if ((m_Definition != NULL) && (src_def != NULL)) {
  499. //
  500. // Simply copy the parameters from one definition to the other...
  501. //
  502. ::Copy_Definition (src_def, m_Definition, m_IsTemporary);
  503. //
  504. // Copy the transitions as well
  505. //
  506. const TRANSITION_DATA_LIST *src_list = preset.Get_Transition_List ();
  507. TRANSITION_DATA_LIST *dest_list = Get_Transition_List ();
  508. if (src_list != NULL && dest_list != NULL) {
  509. //
  510. // Free any existing transitions
  511. //
  512. for (int index = 0; index < dest_list->Count (); index ++) {
  513. TransitionDataClass *data = (*dest_list)[index];
  514. SAFE_DELETE (data);
  515. }
  516. dest_list->Delete_All ();
  517. //
  518. // Now copy each of the transitions from the source list
  519. //
  520. for (index = 0; index < src_list->Count (); index ++) {
  521. const TransitionDataClass *data = (*src_list)[index];
  522. //
  523. // Create a new transition object and copy the src's settings
  524. //
  525. TransitionDataClass *new_data = new TransitionDataClass;
  526. new_data->Set_Type (data->Get_Type ());
  527. new_data->Set_Zone (data->Get_Zone ());
  528. new_data->Set_Animation_Name (data->Get_Animation_Name ());
  529. new_data->Set_Ending_TM (data->Get_Ending_TM ());
  530. //
  531. // Add this new transition to our list
  532. //
  533. dest_list->Add (new_data);
  534. }
  535. }
  536. }
  537. return ;
  538. }
  539. ///////////////////////////////////////////////////////////////////////
  540. //
  541. // Load_All_Assets
  542. //
  543. ///////////////////////////////////////////////////////////////////////
  544. void
  545. PresetClass::Load_All_Assets (void)
  546. {
  547. STRING_LIST dependencies;
  548. Get_All_Dependencies (dependencies);
  549. for (int index = 0; index < dependencies.Count (); index ++) {
  550. CString filename = dependencies[index];
  551. CString full_path = ::Get_File_Mgr ()->Make_Full_Path (filename);
  552. CString path = ::Strip_Filename_From_Path (full_path);
  553. //
  554. // Load all the assets contained in this file
  555. //
  556. ::Set_Current_Directory (path);
  557. if (::Is_W3D_Filename (filename)) {
  558. WW3DAssetManager::Get_Instance ()->Load_3D_Assets (full_path);
  559. RenderObjClass *model = ::Create_Render_Obj (::Asset_Name_From_Filename (full_path));
  560. REF_PTR_RELEASE (model);
  561. } else {
  562. #ifndef PUBLIC_EDITOR_VER
  563. if (::GetFileAttributes (full_path) == 0xFFFFFFFF) {
  564. ::Get_File_Mgr ()->Update_File (full_path);
  565. }
  566. #endif //!PUBLIC_EDITOR_VER
  567. }
  568. }
  569. return ;
  570. }
  571. ///////////////////////////////////////////////////////////////////////
  572. //
  573. // Get_All_Dependencies
  574. //
  575. ///////////////////////////////////////////////////////////////////////
  576. void
  577. PresetClass::Get_All_Dependencies (STRING_LIST &list) const
  578. {
  579. //
  580. // Start fresh
  581. //
  582. list.Delete_All ();
  583. //
  584. // Copy the manual dependencies to the list
  585. //
  586. list = m_ManualDependencies;
  587. //
  588. // Add the implicit dependencies to the list
  589. //
  590. Add_Definition_Dependencies (m_Definition, list);
  591. return ;
  592. }
  593. ///////////////////////////////////////////////////////////////////////
  594. //
  595. // Get_Implicit_Dependencies
  596. //
  597. ///////////////////////////////////////////////////////////////////////
  598. void
  599. PresetClass::Get_Implicit_Dependencies (STRING_LIST &list) const
  600. {
  601. //
  602. // Start fresh
  603. //
  604. list.Delete_All ();
  605. //
  606. // Add the implicit dependencies to the list
  607. //
  608. Add_Definition_Dependencies (m_Definition, list);
  609. return ;
  610. }
  611. ///////////////////////////////////////////////////////////////////////
  612. //
  613. // Add_Definition_Dependencies
  614. //
  615. ///////////////////////////////////////////////////////////////////////
  616. void
  617. PresetClass::Add_Definition_Dependencies (DefinitionClass *definition, STRING_LIST &list)
  618. {
  619. if (definition != NULL) {
  620. //
  621. // Find all 'filename' parameters to this definition.
  622. //
  623. int count = definition->Get_Parameter_Count ();
  624. for (int index = 0; index < count; index ++) {
  625. ParameterClass *parameter = definition->Lock_Parameter (index);
  626. if ( parameter->Get_Type () == ParameterClass::TYPE_FILENAME ||
  627. parameter->Get_Type () == ParameterClass::TYPE_SOUND_FILENAME) {
  628. //
  629. // Add this filename dependency to the list
  630. //
  631. CString filename = ((FilenameParameterClass *)parameter)->Get_String ();
  632. CString full_path = ::Get_File_Mgr ()->Make_Full_Path (filename);
  633. if ( ::Get_File_Mgr ()->Is_Path_Valid (full_path) &&
  634. ::Get_File_Mgr ()->Is_Empty_Path (full_path) == false)
  635. {
  636. list.Add (::Get_File_Mgr ()->Make_Relative_Path (full_path));
  637. }
  638. } else if (parameter->Get_Type () == ParameterClass::TYPE_MODELDEFINITIONID) {
  639. //
  640. // If this is param references a physics-definition, then add all its dependencies as well..
  641. //
  642. DefinitionClass *phys_def = NULL;
  643. phys_def = DefinitionMgrClass::Find_Definition (((ModelDefParameterClass *)parameter)->Get_Value (), false);
  644. Add_Definition_Dependencies (phys_def, list);
  645. }
  646. }
  647. }
  648. return ;
  649. }
  650. ///////////////////////////////////////////////////////////////////////
  651. //
  652. // Get_Script_List_Param
  653. //
  654. ///////////////////////////////////////////////////////////////////////
  655. ScriptListParameterClass *
  656. PresetClass::Get_Script_List_Param (void)
  657. {
  658. ScriptListParameterClass *param = NULL;
  659. //
  660. // Try to find a script list parameter somewhere in the preset...
  661. //
  662. int index = m_Definition->Get_Parameter_Count ();
  663. while ((index --) && (param == NULL)) {
  664. ParameterClass *parameter = m_Definition->Lock_Parameter (index);
  665. //
  666. // Is this the parameter we are looking for?
  667. //
  668. if (parameter->Get_Type () == ParameterClass::TYPE_SCRIPTLIST) {
  669. param = (ScriptListParameterClass *)parameter;
  670. }
  671. m_Definition->Unlock_Parameter (index);
  672. }
  673. return param;
  674. }
  675. ///////////////////////////////////////////////////////////////////////
  676. //
  677. // Get_Phys_Def_Param
  678. //
  679. ///////////////////////////////////////////////////////////////////////
  680. ModelDefParameterClass *
  681. PresetClass::Get_Phys_Def_Param (void)
  682. {
  683. ModelDefParameterClass *param = NULL;
  684. //
  685. // Try to find a physics-def parameter somewhere in the preset...
  686. //
  687. int index = m_Definition->Get_Parameter_Count ();
  688. while ((index --) && (param == NULL)) {
  689. ParameterClass *parameter = m_Definition->Lock_Parameter (index);
  690. //
  691. // Is this the parameter we are looking for?
  692. //
  693. if (parameter->Get_Type () == ParameterClass::TYPE_MODELDEFINITIONID) {
  694. param = (ModelDefParameterClass *)parameter;
  695. }
  696. m_Definition->Unlock_Parameter (index);
  697. }
  698. return param;
  699. }
  700. ///////////////////////////////////////////////////////////////////////
  701. //
  702. // Get_Transition_List
  703. //
  704. ///////////////////////////////////////////////////////////////////////
  705. TRANSITION_DATA_LIST *
  706. PresetClass::Get_Transition_List (void) const
  707. {
  708. TRANSITION_DATA_LIST *list = NULL;
  709. if (m_Definition != NULL) {
  710. switch (m_Definition->Get_Class_ID ()) {
  711. //
  712. // Vehicles from Combat Lib
  713. //
  714. case CLASSID_GAME_OBJECT_DEF_VEHICLE:
  715. {
  716. VehicleGameObjDef *vehicle_def = (VehicleGameObjDef *)m_Definition;
  717. list = vehicle_def->Get_Transition_List ();
  718. }
  719. break;
  720. case CLASSID_GAME_OBJECT_DEF_TRANSITION:
  721. {
  722. TransitionGameObjDef *trans_def = (TransitionGameObjDef *)m_Definition;
  723. list = trans_def->Get_Transition_List ();
  724. }
  725. break;
  726. }
  727. }
  728. return list;
  729. }
  730. ///////////////////////////////////////////////////////////////////////
  731. //
  732. // Build_Zone_List
  733. //
  734. ///////////////////////////////////////////////////////////////////////
  735. void
  736. PresetClass::Build_Zone_List (DefinitionClass *definition, ZONE_PARAM_LIST &zone_list) const
  737. {
  738. if (definition == NULL) {
  739. definition = m_Definition;
  740. }
  741. if (definition != NULL) {
  742. //
  743. // Loop over all the parameters
  744. //
  745. int count = definition->Get_Parameter_Count ();
  746. for (int index = 0; index < count; index ++) {
  747. ParameterClass *parameter = definition->Lock_Parameter (index);
  748. //
  749. // If this is a zone parameter, then add it to the list
  750. //
  751. if (parameter->Get_Type () == ParameterClass::TYPE_ZONE) {
  752. ZoneParameterClass *zone_param = (ZoneParameterClass *)parameter;
  753. zone_list.Add (zone_param);
  754. } else if (parameter->Get_Type () == ParameterClass::TYPE_MODELDEFINITIONID) {
  755. //
  756. // Recurse into the physics definition (if necessary)
  757. //
  758. int def_id = ((ModelDefParameterClass *)parameter)->Get_Value ();
  759. DefinitionClass *model_def= DefinitionMgrClass::Find_Definition (def_id, false);
  760. if (model_def != NULL) {
  761. Build_Zone_List (model_def, zone_list);
  762. }
  763. }
  764. definition->Unlock_Parameter (index);
  765. }
  766. }
  767. return ;
  768. }
  769. ///////////////////////////////////////////////////////////////////////
  770. //
  771. // Add_Files_To_VSS
  772. //
  773. ///////////////////////////////////////////////////////////////////////
  774. void
  775. PresetClass::Add_Files_To_VSS (void)
  776. {
  777. if (::Get_File_Mgr ()->Is_VSS_Read_Only () == false) {
  778. HWND hdlg = Show_VSS_Update_Dialog (::AfxGetMainWnd ()->m_hWnd);
  779. //
  780. // Build a list of dependencies
  781. //
  782. STRING_LIST dependencies;
  783. Get_All_Dependencies (dependencies);
  784. //
  785. // Loop over all the files and add them to VSS
  786. //
  787. for (int index = 0; index < dependencies.Count (); index ++) {
  788. CString filename = dependencies[index];
  789. CString full_path = ::Get_File_Mgr ()->Make_Full_Path (filename);
  790. ::Get_File_Mgr ()->Add_Files_To_Database (full_path);
  791. }
  792. ::Kill_VSS_Update_Dialog (hdlg);
  793. }
  794. return ;
  795. }
  796. ///////////////////////////////////////////////////////////////////////
  797. //
  798. // Is_Valid_Sound_Preset
  799. //
  800. ///////////////////////////////////////////////////////////////////////
  801. bool
  802. PresetClass::Is_Valid_Sound_Preset (void)
  803. {
  804. bool retval = false;
  805. //
  806. // First off, is this a sound preset at all?
  807. //
  808. if ( m_Definition != NULL &&
  809. m_Definition->Get_Class_ID () == CLASSID_SOUND)
  810. {
  811. AudibleSoundDefinitionClass *definition = (AudibleSoundDefinitionClass *)m_Definition;
  812. //
  813. // Does this preset point to a file?
  814. //
  815. CString filename = definition->Get_Filename ();
  816. DWORD file_attrs = ::GetFileAttributes (definition->Get_Filename ());
  817. if ( filename.GetLength () > 0 &&
  818. (file_attrs == 0xFFFFFFFF ||
  819. file_attrs != FILE_ATTRIBUTE_DIRECTORY))
  820. {
  821. retval = true;
  822. }
  823. }
  824. return retval;
  825. }
  826. ///////////////////////////////////////////////////////////////////////
  827. //
  828. // Is_A_Parent
  829. //
  830. ///////////////////////////////////////////////////////////////////////
  831. bool
  832. PresetClass::Is_A_Parent (PresetClass *preset)
  833. {
  834. bool retval = false;
  835. //
  836. // Look over all the parents
  837. //
  838. for ( PresetClass *parent = this;
  839. parent != NULL && !retval;
  840. parent = parent->Get_Parent ())
  841. {
  842. retval = (parent == preset);
  843. }
  844. return retval;
  845. }
  846. ///////////////////////////////////////////////////////////////////////
  847. //
  848. // Is_A_Parent
  849. //
  850. ///////////////////////////////////////////////////////////////////////
  851. bool
  852. PresetClass::Is_A_Parent (LPCTSTR parent_name)
  853. {
  854. bool retval = false;
  855. //
  856. // Look over all the parents
  857. //
  858. for ( PresetClass *parent = this;
  859. parent != NULL && !retval;
  860. parent = parent->Get_Parent ())
  861. {
  862. retval = (::lstrcmpi (parent->Get_Name (), parent_name) == 0);
  863. }
  864. return retval;
  865. }
  866. ///////////////////////////////////////////////////////////////////////
  867. //
  868. // Get_Icon_Index
  869. //
  870. ///////////////////////////////////////////////////////////////////////
  871. int
  872. PresetClass::Get_Icon_Index (void) const
  873. {
  874. int index = 0;
  875. //
  876. // What type is it?
  877. //
  878. uint32 class_id = m_Definition->Get_Class_ID ();
  879. switch (::SuperClassID_From_ClassID (class_id))
  880. {
  881. case CLASSID_TERRAIN:
  882. index = TERRAIN_ICON;
  883. break;
  884. case CLASSID_TILE:
  885. index = TILE_ICON;
  886. break;
  887. case CLASSID_MUNITIONS:
  888. case CLASSID_DUMMY_OBJECTS:
  889. case CLASSID_GAME_OBJECTS:
  890. index = OBJECT_ICON;
  891. break;
  892. case CLASSID_LIGHT:
  893. index = LIGHT_ICON;
  894. break;
  895. case CLASSID_SOUND:
  896. index = SOUND_ICON;
  897. break;
  898. case CLASSID_WAYPATH:
  899. index = WAYPATH_ICON;
  900. break;
  901. case CLASSID_ZONE:
  902. index = ZONE_ICON;
  903. break;
  904. case CLASSID_TRANSITION:
  905. index = TRANSITION_ICON;
  906. break;
  907. case CLASSID_BUILDINGS:
  908. index = BUILDING_ICON;
  909. break;
  910. case CLASSID_TWIDDLERS:
  911. index = RAND_ICON;
  912. break;
  913. default:
  914. if (class_id == CLASSID_VIS_POINT_DEF) {
  915. index = VIS_ICON;
  916. } else if (class_id == CLASSID_PATHFIND_START_DEF) {
  917. index = PATHFIND_ICON;
  918. } else if (class_id == CLASSID_COVERSPOT) {
  919. index = OBJECT_ICON;
  920. }
  921. break;
  922. }
  923. return index;
  924. }
  925. ///////////////////////////////////////////////////////////////////////
  926. //
  927. // Collect_Definitions
  928. //
  929. ///////////////////////////////////////////////////////////////////////
  930. void
  931. PresetClass::Collect_Definitions (DEFINITION_LIST &list)
  932. {
  933. if (m_Definition != NULL) {
  934. list.Add (m_Definition);
  935. //
  936. // Get the physics definition that this definition embeds (if any)
  937. //
  938. ::Build_Embedded_Definition_List (list, m_Definition);
  939. }
  940. return ;
  941. }
  942. ////////////////////////////////////////////////////////////////////
  943. //
  944. // Is_Soldier_Preset
  945. //
  946. ////////////////////////////////////////////////////////////////////
  947. bool
  948. PresetClass::Is_Soldier_Preset (void)
  949. {
  950. bool is_soldier = false;
  951. if (m_Definition != NULL) {
  952. is_soldier = (m_Definition->Get_Class_ID () == CLASSID_GAME_OBJECT_DEF_SOLDIER);
  953. }
  954. return is_soldier;
  955. }
  956. ////////////////////////////////////////////////////////////////////
  957. //
  958. // Build_Node_List
  959. //
  960. ////////////////////////////////////////////////////////////////////
  961. void
  962. PresetClass::Build_Node_List (NodeClass *parent_node)
  963. {
  964. Free_Node_List ();
  965. //
  966. // Build a matrix that we can use to transform each
  967. // node into the coordinate system of the parent node
  968. //
  969. Matrix3D parent_tm = parent_node->Get_Transform ();
  970. Matrix3D world_to_parent_tm;
  971. parent_tm.Get_Orthogonal_Inverse (world_to_parent_tm);
  972. //
  973. // Loop over all the nodes in the scene
  974. //
  975. for ( NodeClass *node = NodeMgrClass::Get_First ();
  976. node != NULL;
  977. node = NodeMgrClass::Get_Next (node))
  978. {
  979. //
  980. // Is this a node we want to bind to this preset?
  981. //
  982. if ( node != parent_node &&
  983. node->Is_Proxied () == false &&
  984. node->Get_Parent_Node () == NULL &&
  985. node->Get_Type () != NODE_TYPE_WAYPOINT)
  986. {
  987. //
  988. // Make a copy of the node
  989. //
  990. NodeClass *new_node = node->Clone ();
  991. if (new_node != NULL) {
  992. //
  993. // Transform the new node into the coordinate system
  994. // of the parent node
  995. //
  996. Matrix3D curr_tm = node->Get_Transform ();
  997. Matrix3D rel_tm = world_to_parent_tm * curr_tm;
  998. new_node->Set_Transform (rel_tm);
  999. new_node->Set_Needs_Save (false);
  1000. new_node->Set_Container_Preset_ID (Get_ID ());
  1001. //
  1002. // Add this node to our list
  1003. //
  1004. m_NodeList.Add (new_node);
  1005. }
  1006. }
  1007. }
  1008. return ;
  1009. }
  1010. ////////////////////////////////////////////////////////////////////
  1011. //
  1012. // Free_Node_List
  1013. //
  1014. ////////////////////////////////////////////////////////////////////
  1015. void
  1016. PresetClass::Free_Node_List (void)
  1017. {
  1018. for (int index = 0; index < m_NodeList.Count (); index ++) {
  1019. REF_PTR_RELEASE (m_NodeList[index]);
  1020. }
  1021. m_NodeList.Delete_All ();
  1022. return ;
  1023. }
  1024. ////////////////////////////////////////////////////////////////////
  1025. //
  1026. // Create_Linked_Nodes
  1027. //
  1028. ////////////////////////////////////////////////////////////////////
  1029. void
  1030. PresetClass::Create_Linked_Nodes (NodeClass *parent_node)
  1031. {
  1032. //
  1033. // Build a matrix that we can use to transform each
  1034. // node into the coordinate system of the parent node
  1035. //
  1036. Matrix3D parent_tm = parent_node->Get_Transform ();
  1037. for (int index = 0; index < m_NodeList.Count (); index ++) {
  1038. //
  1039. // Clone this node via the scene so it will get installed into
  1040. // all the appropriate systems
  1041. //
  1042. NodeClass *new_node = ::Get_Scene_Editor ()->Clone_Node (m_NodeList[index]);
  1043. //
  1044. // Transform the node into world space
  1045. //
  1046. Matrix3D rel_tm = m_NodeList[index]->Get_Transform ();
  1047. Matrix3D new_tm = parent_tm * rel_tm;
  1048. new_node->Set_Transform (new_tm);
  1049. new_node->Lock (true);
  1050. new_node->Set_Is_Proxied (true);
  1051. new_node->Set_Needs_Save (false);
  1052. new_node->Set_Container_Preset_ID (Get_ID ());
  1053. //
  1054. // Release our hold on the node
  1055. //
  1056. REF_PTR_RELEASE (new_node);
  1057. }
  1058. return ;
  1059. }
  1060. ////////////////////////////////////////////////////////////////////
  1061. //
  1062. // Get_Child_Preset
  1063. //
  1064. ////////////////////////////////////////////////////////////////////
  1065. PresetClass *
  1066. PresetClass::Get_Child_Preset (int index)
  1067. {
  1068. PresetClass *retval = NULL;
  1069. if (index >= 0 && index < m_ChildIDList.Count ()) {
  1070. retval = PresetMgrClass::Find_Preset (m_ChildIDList[index]);
  1071. }
  1072. return retval;
  1073. }
  1074. ////////////////////////////////////////////////////////////////////
  1075. //
  1076. // Set_Definition
  1077. //
  1078. ////////////////////////////////////////////////////////////////////
  1079. void
  1080. PresetClass::Set_Definition (DefinitionClass *definition)
  1081. {
  1082. if (m_Definition != NULL) {
  1083. m_Definition->Set_User_Data (NULL);
  1084. }
  1085. m_Definition = definition;
  1086. m_DefinitionID = 0;
  1087. //
  1088. // Store our "this" pointer in the definition so we can
  1089. // quickly find the preset given its definition
  1090. //
  1091. if (m_Definition != NULL) {
  1092. m_Definition->Set_User_Data ((uint32)this);
  1093. m_DefinitionID = m_Definition->Get_ID ();
  1094. }
  1095. return ;
  1096. }
  1097. ////////////////////////////////////////////////////////////////////
  1098. //
  1099. // Add_Child_Preset
  1100. //
  1101. ////////////////////////////////////////////////////////////////////
  1102. void
  1103. PresetClass::Add_Child_Preset (int child_id)
  1104. {
  1105. //
  1106. // Don't allow ourselves to become recursively linked
  1107. //
  1108. if (child_id == (int)Get_ID ()) {
  1109. return ;
  1110. }
  1111. //
  1112. // Make sure the child isn't already in our list
  1113. //
  1114. int index = m_ChildIDList.ID (child_id);
  1115. WWASSERT (index == -1);
  1116. //
  1117. // Add the child to the list
  1118. //
  1119. if (index == -1) {
  1120. m_ChildIDList.Add (child_id);
  1121. }
  1122. return ;
  1123. }
  1124. ////////////////////////////////////////////////////////////////////
  1125. //
  1126. // Remove_Child_Preset
  1127. //
  1128. ////////////////////////////////////////////////////////////////////
  1129. void
  1130. PresetClass::Remove_Child_Preset (int child_id)
  1131. {
  1132. int index = m_ChildIDList.ID (child_id);
  1133. if (index != -1) {
  1134. m_ChildIDList.Delete (index);
  1135. }
  1136. return ;
  1137. }
  1138. ////////////////////////////////////////////////////////////////////
  1139. //
  1140. // Set_Parent
  1141. //
  1142. ////////////////////////////////////////////////////////////////////
  1143. void
  1144. PresetClass::Set_Parent (PresetClass *parent)
  1145. {
  1146. //
  1147. // If changing parents, unlink ourselves from our old parent
  1148. //
  1149. if (m_Parent != NULL) {
  1150. m_Parent->Remove_Child_Preset (Get_ID ());
  1151. }
  1152. m_Parent = parent;
  1153. //
  1154. // Cache the parent's ID
  1155. //
  1156. if (m_Parent != NULL) {
  1157. m_ParentID = m_Parent->Get_ID ();
  1158. } else {
  1159. m_ParentID = 0;
  1160. }
  1161. return ;
  1162. }