DefinitionUtils.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  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/DefinitionUtils.cpp $*
  25. * *
  26. * Author:: Patrick Smith *
  27. * *
  28. * $Modtime:: 8/24/01 12:15p $*
  29. * *
  30. * $Revision:: 11 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "StdAfx.h"
  36. #include "definition.h"
  37. #include "definitionmgr.h"
  38. #include "definitionfactorymgr.h"
  39. #include "definitionfactory.h"
  40. #include "phys.h"
  41. #include "Utils.h"
  42. #include "physicalgameobj.h"
  43. #include "tiledefinition.h"
  44. #include "combatchunkid.h"
  45. #include "dialogue.h"
  46. #include "soldier.h"
  47. #include "presetmgr.h"
  48. ///////////////////////////////////////////////////////////////////////
  49. //
  50. // Create_Physics_Definition
  51. //
  52. ///////////////////////////////////////////////////////////////////////
  53. DefinitionClass *
  54. Create_Physics_Definition (LPCTSTR base_class_name, bool is_temp)
  55. {
  56. DefinitionClass *definition = NULL;
  57. //
  58. // Loop over all the factories, until we've found one that matches
  59. // the base we are looking for
  60. //
  61. DefinitionFactoryClass *factory = NULL;
  62. for ( factory = DefinitionFactoryMgrClass::Get_First (CLASSID_PHYSICS);
  63. factory != NULL && definition == NULL;
  64. factory = DefinitionFactoryMgrClass::Get_Next (factory, CLASSID_PHYSICS))
  65. {
  66. //
  67. // Instantiate a definition
  68. //
  69. definition = factory->Create ();
  70. if (definition != NULL) {
  71. //
  72. // Is this the definition 'type' we want?
  73. //
  74. if (((PhysDefClass *)definition)->Is_Type (base_class_name) == false) {
  75. SAFE_DELETE (definition);
  76. } else {
  77. if (is_temp) {
  78. definition->Set_ID (::Get_Next_Temp_ID ());
  79. } else {
  80. definition->Set_ID (DefinitionMgrClass::Get_New_ID (definition->Get_Class_ID ()));
  81. }
  82. }
  83. }
  84. }
  85. return definition;
  86. }
  87. ///////////////////////////////////////////////////////////////////////
  88. //
  89. // Create_Definition
  90. //
  91. ///////////////////////////////////////////////////////////////////////
  92. DefinitionClass *
  93. Create_Definition (int class_id, bool is_temp)
  94. {
  95. DefinitionClass *definition = NULL;
  96. //
  97. // Attempt to find a factory for this definition
  98. //
  99. DefinitionFactoryClass *factory = DefinitionFactoryMgrClass::Find_Factory (class_id);
  100. if (factory != NULL) {
  101. //
  102. // Create a new instance of the definition
  103. //
  104. definition = factory->Create ();
  105. ASSERT (definition != NULL);
  106. //
  107. // Give the definition a new id
  108. //
  109. if (is_temp) {
  110. definition->Set_ID (::Get_Next_Temp_ID ());
  111. } else {
  112. definition->Set_ID (DefinitionMgrClass::Get_New_ID (definition->Get_Class_ID ()));
  113. }
  114. }
  115. return definition;
  116. }
  117. ///////////////////////////////////////////////////////////////////////
  118. //
  119. // Copy_Definition
  120. //
  121. ///////////////////////////////////////////////////////////////////////
  122. void
  123. Copy_Definition (DefinitionClass *src_def, DefinitionClass *dest_def, bool is_temp)
  124. {
  125. SANITY_CHECK(src_def != NULL && dest_def != NULL) {
  126. return ;
  127. }
  128. //
  129. // Make sure the definitions are of the same type.
  130. //
  131. uint32 class_id1 = dest_def->Get_Class_ID ();
  132. uint32 class_id2 = src_def->Get_Class_ID ();
  133. if (class_id1 == class_id2) {
  134. //
  135. // Loop over all the parameters contained in the definitions
  136. //
  137. int count = dest_def->Get_Parameter_Count ();
  138. for (int index = 0; index < count; index ++) {
  139. ParameterClass *dest_param = dest_def->Lock_Parameter (index);
  140. ParameterClass *src_param = src_def->Lock_Parameter (index);
  141. if ((dest_param != NULL) && (src_param != NULL)) {
  142. //
  143. // Is this parameter type a 'phys-def' parameter?
  144. ///If it is, we need to make sure we don't copy the phys-def ID value,
  145. // we need to copy the properties of the phys-definition that the parameter
  146. // points to.
  147. //
  148. if (dest_param->Get_Type () == ParameterClass::TYPE_MODELDEFINITIONID) {
  149. int dest_def_id = ((ModelDefParameterClass *)dest_param)->Get_Value ();
  150. int src_def_id = ((ModelDefParameterClass *)src_param)->Get_Value ();
  151. DefinitionClass *dest_phys_def = DefinitionMgrClass::Find_Definition (dest_def_id, false);
  152. DefinitionClass *src_phys_def = DefinitionMgrClass::Find_Definition (src_def_id, false);
  153. //
  154. // Create a new phys-def for the destination param
  155. //
  156. if (dest_phys_def == NULL && src_phys_def != NULL) {
  157. dest_phys_def = ::Create_Definition (src_phys_def->Get_Class_ID (), is_temp);
  158. if (dest_phys_def != NULL) {
  159. ((ModelDefParameterClass *)dest_param)->Set_Value (dest_phys_def->Get_ID ());
  160. DefinitionMgrClass::Register_Definition (dest_phys_def);
  161. }
  162. }
  163. //
  164. // If both the src and dest params point to valid physics-definitions,
  165. // then, copy the properties from the src to the dest (recursion)
  166. //
  167. if (dest_phys_def != NULL && src_phys_def != NULL) {
  168. ::Copy_Definition (src_phys_def, dest_phys_def, is_temp);
  169. }
  170. } else {
  171. //
  172. // Copy the parameter value
  173. //
  174. dest_param->Copy_Value (*src_param);
  175. }
  176. }
  177. dest_def->Unlock_Parameter (index);
  178. src_def->Unlock_Parameter (index);
  179. }
  180. //
  181. // Should we copy the dialogue list as well?
  182. //
  183. if (class_id1 == CLASSID_GAME_OBJECT_DEF_SOLDIER) {
  184. SoldierGameObjDef *src_soldier = reinterpret_cast<SoldierGameObjDef *> (src_def);
  185. SoldierGameObjDef *dest_soldier = reinterpret_cast<SoldierGameObjDef *> (dest_def);
  186. DialogueClass *src_list = src_soldier->Get_Dialog_List ();
  187. DialogueClass *dest_list = dest_soldier->Get_Dialog_List ();
  188. //
  189. // Copy the settings from the base to the derived...
  190. //
  191. for (int index = 0; index < DIALOG_MAX; index ++) {
  192. dest_list[index] = src_list[index];
  193. }
  194. }
  195. }
  196. return ;
  197. }
  198. ///////////////////////////////////////////////////////////////////////
  199. //
  200. // Build_Embedded_Definition_List
  201. //
  202. ///////////////////////////////////////////////////////////////////////
  203. void
  204. Build_Embedded_Definition_List (DEFINITION_LIST &list, DefinitionClass *parent)
  205. {
  206. SANITY_CHECK(parent != NULL) {
  207. return ;
  208. }
  209. //
  210. // Loop over all the parameters of this definition
  211. //
  212. int count = parent->Get_Parameter_Count ();
  213. for (int index = 0; index < count; index ++) {
  214. ParameterClass *param = parent->Lock_Parameter (index);
  215. //
  216. // If this is the paramter type we are looking for, get the
  217. // definition pointer from it and return the pointer to the caller
  218. //
  219. if (param != NULL ) {
  220. if (param->Get_Type () == ParameterClass::TYPE_MODELDEFINITIONID) {
  221. int def_id = ((ModelDefParameterClass *)param)->Get_Value ();
  222. DefinitionClass *definition = DefinitionMgrClass::Find_Definition (def_id, false);
  223. if (definition != NULL) {
  224. list.Add (definition);
  225. //
  226. // Now recurse into the model definition
  227. //
  228. Build_Embedded_Definition_List (list, definition);
  229. }
  230. } else if (param->Get_Type () == ParameterClass::TYPE_PHYSDEFINITIONID) {
  231. int def_id = ((PhysDefParameterClass *)param)->Get_Value ();
  232. DefinitionClass *definition = DefinitionMgrClass::Find_Definition (def_id, false);
  233. if (definition != NULL) {
  234. list.Add (definition);
  235. }
  236. }
  237. }
  238. parent->Unlock_Parameter (index);
  239. }
  240. return ;
  241. }
  242. ///////////////////////////////////////////////////////////////////////
  243. //
  244. // Fix_Embedded_Definition_IDs
  245. //
  246. ///////////////////////////////////////////////////////////////////////
  247. void
  248. Fix_Embedded_Definition_IDs (DefinitionClass *parent)
  249. {
  250. SANITY_CHECK(parent != NULL) {
  251. return ;
  252. }
  253. //
  254. // Loop over all the parameters of this definition
  255. //
  256. int count = parent->Get_Parameter_Count ();
  257. for (int index = 0; index < count; index ++) {
  258. ParameterClass *param = parent->Lock_Parameter (index);
  259. //
  260. // If this is the paramter type we are looking for, get the
  261. // definition pointer from it and return the pointer to the caller
  262. //
  263. if (param != NULL ) {
  264. if (param->Get_Type () == ParameterClass::TYPE_MODELDEFINITIONID) {
  265. int def_id = ((ModelDefParameterClass *)param)->Get_Value ();
  266. DefinitionClass *definition = DefinitionMgrClass::Find_Definition (def_id, false);
  267. if (definition != NULL) {
  268. //
  269. // Give this definition a new ID if necessary
  270. //
  271. if (definition->Get_ID () >= TEMP_DEF_ID_START) {
  272. definition->Set_ID (DefinitionMgrClass::Get_New_ID (definition->Get_Class_ID ()));
  273. ((ModelDefParameterClass *)param)->Set_Value (definition->Get_ID ());
  274. }
  275. //
  276. // Now recurse into the model definition
  277. //
  278. Fix_Embedded_Definition_IDs (definition);
  279. }
  280. } else if (param->Get_Type () == ParameterClass::TYPE_PHYSDEFINITIONID) {
  281. int def_id = ((PhysDefParameterClass *)param)->Get_Value ();
  282. DefinitionClass *definition = DefinitionMgrClass::Find_Definition (def_id, false);
  283. if (definition != NULL) {
  284. //
  285. // Give this definition a new ID if necessary
  286. //
  287. if (definition->Get_ID () >= TEMP_DEF_ID_START) {
  288. definition->Set_ID (DefinitionMgrClass::Get_New_ID (definition->Get_Class_ID ()));
  289. ((PhysDefParameterClass *)param)->Set_Value (definition->Get_ID ());
  290. }
  291. }
  292. }
  293. }
  294. parent->Unlock_Parameter (index);
  295. }
  296. return ;
  297. }
  298. ///////////////////////////////////////////////////////////////////////
  299. //
  300. // Find_Physics_Definition
  301. //
  302. ///////////////////////////////////////////////////////////////////////
  303. DefinitionClass *
  304. Find_Physics_Definition (DefinitionClass *parent)
  305. {
  306. SANITY_CHECK(parent != NULL) {
  307. return NULL;
  308. }
  309. DefinitionClass *definition = NULL;
  310. //
  311. // Loop over all the parameters of this definition
  312. //
  313. int count = parent->Get_Parameter_Count ();
  314. for (int index = 0; index < count && definition == NULL; index ++) {
  315. ParameterClass *param = parent->Lock_Parameter (index);
  316. //
  317. // If this is the paramter type we are looking for, get the
  318. // definition pointer from it and return the pointer to the caller
  319. //
  320. if (param != NULL && param->Get_Type () == ParameterClass::TYPE_MODELDEFINITIONID) {
  321. int def_id = ((ModelDefParameterClass *)param)->Get_Value ();
  322. definition = DefinitionMgrClass::Find_Definition (def_id, false);
  323. }
  324. parent->Unlock_Parameter (index);
  325. }
  326. return definition;
  327. }
  328. ///////////////////////////////////////////////////////////////////////
  329. //
  330. // Get_Phys_Obj_From_Definition
  331. //
  332. ///////////////////////////////////////////////////////////////////////
  333. PhysClass *
  334. Get_Phys_Obj_From_Definition (DefinitionClass *definition)
  335. {
  336. SANITY_CHECK (definition != NULL) {
  337. return NULL;
  338. }
  339. PhysClass *retval = NULL;
  340. //
  341. // What type of object will this definition create?
  342. //
  343. int class_id = definition->Get_Class_ID ();
  344. switch (::SuperClassID_From_ClassID (class_id))
  345. {
  346. /*case CLASSID_TERRAIN:
  347. {
  348. //
  349. // Create the terrain and pull out its physics object
  350. //
  351. TerrainNodeClass *node = (TerrainNodeClass *)definition->Create ();
  352. if (node != NULL) {
  353. MEMBER_ADD (retval, node->Peek_Physics_Obj ());
  354. MEMBER_RELEASE (node);
  355. }
  356. }
  357. break;*/
  358. case CLASSID_TILE:
  359. {
  360. //
  361. // Create the tile and pull out its physics object
  362. //
  363. int phys_def_id = ((TileDefinitionClass *)definition)->Get_Phys_Def_ID ();
  364. if (phys_def_id != 0) {
  365. DefinitionClass *phys_def = DefinitionMgrClass::Find_Definition (phys_def_id, false);
  366. if (phys_def != NULL) {
  367. retval = (PhysClass *)phys_def->Create ();
  368. }
  369. }
  370. }
  371. break;
  372. case CLASSID_GAME_OBJECTS:
  373. {
  374. //
  375. // Create the game object and pull out its physics object
  376. //
  377. BaseGameObj *game_obj = (BaseGameObj *)definition->Create ();
  378. if (game_obj != NULL) {
  379. PhysicalGameObj *phys_game_obj = game_obj->As_PhysicalGameObj ();
  380. if (phys_game_obj != NULL) {
  381. MEMBER_ADD (retval, phys_game_obj->Peek_Physical_Object ());
  382. }
  383. game_obj->Set_Delete_Pending ();
  384. }
  385. }
  386. break;
  387. }
  388. return retval;
  389. }