/* ** 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 . */ /*********************************************************************************************** *** 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/DefinitionUtils.cpp $* * * * Author:: Patrick Smith * * * * $Modtime:: 8/24/01 12:15p $* * * * $Revision:: 11 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "StdAfx.h" #include "definition.h" #include "definitionmgr.h" #include "definitionfactorymgr.h" #include "definitionfactory.h" #include "phys.h" #include "Utils.h" #include "physicalgameobj.h" #include "tiledefinition.h" #include "combatchunkid.h" #include "dialogue.h" #include "soldier.h" #include "presetmgr.h" /////////////////////////////////////////////////////////////////////// // // Create_Physics_Definition // /////////////////////////////////////////////////////////////////////// DefinitionClass * Create_Physics_Definition (LPCTSTR base_class_name, bool is_temp) { DefinitionClass *definition = NULL; // // Loop over all the factories, until we've found one that matches // the base we are looking for // DefinitionFactoryClass *factory = NULL; for ( factory = DefinitionFactoryMgrClass::Get_First (CLASSID_PHYSICS); factory != NULL && definition == NULL; factory = DefinitionFactoryMgrClass::Get_Next (factory, CLASSID_PHYSICS)) { // // Instantiate a definition // definition = factory->Create (); if (definition != NULL) { // // Is this the definition 'type' we want? // if (((PhysDefClass *)definition)->Is_Type (base_class_name) == false) { SAFE_DELETE (definition); } else { if (is_temp) { definition->Set_ID (::Get_Next_Temp_ID ()); } else { definition->Set_ID (DefinitionMgrClass::Get_New_ID (definition->Get_Class_ID ())); } } } } return definition; } /////////////////////////////////////////////////////////////////////// // // Create_Definition // /////////////////////////////////////////////////////////////////////// DefinitionClass * Create_Definition (int class_id, bool is_temp) { DefinitionClass *definition = NULL; // // Attempt to find a factory for this definition // DefinitionFactoryClass *factory = DefinitionFactoryMgrClass::Find_Factory (class_id); if (factory != NULL) { // // Create a new instance of the definition // definition = factory->Create (); ASSERT (definition != NULL); // // Give the definition a new id // if (is_temp) { definition->Set_ID (::Get_Next_Temp_ID ()); } else { definition->Set_ID (DefinitionMgrClass::Get_New_ID (definition->Get_Class_ID ())); } } return definition; } /////////////////////////////////////////////////////////////////////// // // Copy_Definition // /////////////////////////////////////////////////////////////////////// void Copy_Definition (DefinitionClass *src_def, DefinitionClass *dest_def, bool is_temp) { SANITY_CHECK(src_def != NULL && dest_def != NULL) { return ; } // // Make sure the definitions are of the same type. // uint32 class_id1 = dest_def->Get_Class_ID (); uint32 class_id2 = src_def->Get_Class_ID (); if (class_id1 == class_id2) { // // Loop over all the parameters contained in the definitions // int count = dest_def->Get_Parameter_Count (); for (int index = 0; index < count; index ++) { ParameterClass *dest_param = dest_def->Lock_Parameter (index); ParameterClass *src_param = src_def->Lock_Parameter (index); if ((dest_param != NULL) && (src_param != NULL)) { // // Is this parameter type a 'phys-def' parameter? ///If it is, we need to make sure we don't copy the phys-def ID value, // we need to copy the properties of the phys-definition that the parameter // points to. // if (dest_param->Get_Type () == ParameterClass::TYPE_MODELDEFINITIONID) { int dest_def_id = ((ModelDefParameterClass *)dest_param)->Get_Value (); int src_def_id = ((ModelDefParameterClass *)src_param)->Get_Value (); DefinitionClass *dest_phys_def = DefinitionMgrClass::Find_Definition (dest_def_id, false); DefinitionClass *src_phys_def = DefinitionMgrClass::Find_Definition (src_def_id, false); // // Create a new phys-def for the destination param // if (dest_phys_def == NULL && src_phys_def != NULL) { dest_phys_def = ::Create_Definition (src_phys_def->Get_Class_ID (), is_temp); if (dest_phys_def != NULL) { ((ModelDefParameterClass *)dest_param)->Set_Value (dest_phys_def->Get_ID ()); DefinitionMgrClass::Register_Definition (dest_phys_def); } } // // If both the src and dest params point to valid physics-definitions, // then, copy the properties from the src to the dest (recursion) // if (dest_phys_def != NULL && src_phys_def != NULL) { ::Copy_Definition (src_phys_def, dest_phys_def, is_temp); } } else { // // Copy the parameter value // dest_param->Copy_Value (*src_param); } } dest_def->Unlock_Parameter (index); src_def->Unlock_Parameter (index); } // // Should we copy the dialogue list as well? // if (class_id1 == CLASSID_GAME_OBJECT_DEF_SOLDIER) { SoldierGameObjDef *src_soldier = reinterpret_cast (src_def); SoldierGameObjDef *dest_soldier = reinterpret_cast (dest_def); DialogueClass *src_list = src_soldier->Get_Dialog_List (); DialogueClass *dest_list = dest_soldier->Get_Dialog_List (); // // Copy the settings from the base to the derived... // for (int index = 0; index < DIALOG_MAX; index ++) { dest_list[index] = src_list[index]; } } } return ; } /////////////////////////////////////////////////////////////////////// // // Build_Embedded_Definition_List // /////////////////////////////////////////////////////////////////////// void Build_Embedded_Definition_List (DEFINITION_LIST &list, DefinitionClass *parent) { SANITY_CHECK(parent != NULL) { return ; } // // Loop over all the parameters of this definition // int count = parent->Get_Parameter_Count (); for (int index = 0; index < count; index ++) { ParameterClass *param = parent->Lock_Parameter (index); // // If this is the paramter type we are looking for, get the // definition pointer from it and return the pointer to the caller // if (param != NULL ) { if (param->Get_Type () == ParameterClass::TYPE_MODELDEFINITIONID) { int def_id = ((ModelDefParameterClass *)param)->Get_Value (); DefinitionClass *definition = DefinitionMgrClass::Find_Definition (def_id, false); if (definition != NULL) { list.Add (definition); // // Now recurse into the model definition // Build_Embedded_Definition_List (list, definition); } } else if (param->Get_Type () == ParameterClass::TYPE_PHYSDEFINITIONID) { int def_id = ((PhysDefParameterClass *)param)->Get_Value (); DefinitionClass *definition = DefinitionMgrClass::Find_Definition (def_id, false); if (definition != NULL) { list.Add (definition); } } } parent->Unlock_Parameter (index); } return ; } /////////////////////////////////////////////////////////////////////// // // Fix_Embedded_Definition_IDs // /////////////////////////////////////////////////////////////////////// void Fix_Embedded_Definition_IDs (DefinitionClass *parent) { SANITY_CHECK(parent != NULL) { return ; } // // Loop over all the parameters of this definition // int count = parent->Get_Parameter_Count (); for (int index = 0; index < count; index ++) { ParameterClass *param = parent->Lock_Parameter (index); // // If this is the paramter type we are looking for, get the // definition pointer from it and return the pointer to the caller // if (param != NULL ) { if (param->Get_Type () == ParameterClass::TYPE_MODELDEFINITIONID) { int def_id = ((ModelDefParameterClass *)param)->Get_Value (); DefinitionClass *definition = DefinitionMgrClass::Find_Definition (def_id, false); if (definition != NULL) { // // Give this definition a new ID if necessary // if (definition->Get_ID () >= TEMP_DEF_ID_START) { definition->Set_ID (DefinitionMgrClass::Get_New_ID (definition->Get_Class_ID ())); ((ModelDefParameterClass *)param)->Set_Value (definition->Get_ID ()); } // // Now recurse into the model definition // Fix_Embedded_Definition_IDs (definition); } } else if (param->Get_Type () == ParameterClass::TYPE_PHYSDEFINITIONID) { int def_id = ((PhysDefParameterClass *)param)->Get_Value (); DefinitionClass *definition = DefinitionMgrClass::Find_Definition (def_id, false); if (definition != NULL) { // // Give this definition a new ID if necessary // if (definition->Get_ID () >= TEMP_DEF_ID_START) { definition->Set_ID (DefinitionMgrClass::Get_New_ID (definition->Get_Class_ID ())); ((PhysDefParameterClass *)param)->Set_Value (definition->Get_ID ()); } } } } parent->Unlock_Parameter (index); } return ; } /////////////////////////////////////////////////////////////////////// // // Find_Physics_Definition // /////////////////////////////////////////////////////////////////////// DefinitionClass * Find_Physics_Definition (DefinitionClass *parent) { SANITY_CHECK(parent != NULL) { return NULL; } DefinitionClass *definition = NULL; // // Loop over all the parameters of this definition // int count = parent->Get_Parameter_Count (); for (int index = 0; index < count && definition == NULL; index ++) { ParameterClass *param = parent->Lock_Parameter (index); // // If this is the paramter type we are looking for, get the // definition pointer from it and return the pointer to the caller // if (param != NULL && param->Get_Type () == ParameterClass::TYPE_MODELDEFINITIONID) { int def_id = ((ModelDefParameterClass *)param)->Get_Value (); definition = DefinitionMgrClass::Find_Definition (def_id, false); } parent->Unlock_Parameter (index); } return definition; } /////////////////////////////////////////////////////////////////////// // // Get_Phys_Obj_From_Definition // /////////////////////////////////////////////////////////////////////// PhysClass * Get_Phys_Obj_From_Definition (DefinitionClass *definition) { SANITY_CHECK (definition != NULL) { return NULL; } PhysClass *retval = NULL; // // What type of object will this definition create? // int class_id = definition->Get_Class_ID (); switch (::SuperClassID_From_ClassID (class_id)) { /*case CLASSID_TERRAIN: { // // Create the terrain and pull out its physics object // TerrainNodeClass *node = (TerrainNodeClass *)definition->Create (); if (node != NULL) { MEMBER_ADD (retval, node->Peek_Physics_Obj ()); MEMBER_RELEASE (node); } } break;*/ case CLASSID_TILE: { // // Create the tile and pull out its physics object // int phys_def_id = ((TileDefinitionClass *)definition)->Get_Phys_Def_ID (); if (phys_def_id != 0) { DefinitionClass *phys_def = DefinitionMgrClass::Find_Definition (phys_def_id, false); if (phys_def != NULL) { retval = (PhysClass *)phys_def->Create (); } } } break; case CLASSID_GAME_OBJECTS: { // // Create the game object and pull out its physics object // BaseGameObj *game_obj = (BaseGameObj *)definition->Create (); if (game_obj != NULL) { PhysicalGameObj *phys_game_obj = game_obj->As_PhysicalGameObj (); if (phys_game_obj != NULL) { MEMBER_ADD (retval, phys_game_obj->Peek_Physical_Object ()); } game_obj->Set_Delete_Pending (); } } break; } return retval; }