// EditorApplication.cpp: implementation of the EditorApplication class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "MW4GameEd2.h" #include "EditorApplication.h" #include #include #include #include #include #include #include ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// //############################################################################# //######################## EditorApplication ###################### //############################################################################# //############################################################################# // Message Support // const Receiver::MessageEntry EditorApplication::MessageEntries[]= { MESSAGE_ENTRY(EditorApplication, PauseGame) }; EditorApplication::ClassData* EditorApplication::DefaultData = NULL; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void EditorApplication::InitializeClass() { Verify(!DefaultData); DefaultData = new ClassData( EditorApplicationClassID, "EditorApplication", MWApplication::DefaultData, ELEMENTS(MessageEntries), MessageEntries ); Check_Object(DefaultData); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void EditorApplication::TerminateClass() { Check_Object(DefaultData); delete DefaultData; DefaultData = NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // EditorApplication* EditorApplication::Make() { return new EditorApplication; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // EditorApplication::EditorApplication(): MWApplication(DefaultData,false) { applicationMode = EditorMode; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // EditorApplication::~EditorApplication() { } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void EditorApplication::LoadGameMessageHandler(int connection, Stuff::MemoryStream *message) { Check_Object(this); MWApplication::LoadGameMessageHandler(connection, message); // //------------------------------------------------------- //We need to create a drop zone with the name PlayerStart //------------------------------------------------------- // if(NameTable::GetInstance()->FindID("PlayerStart") == NameTable::NullObjectID) { Adept::Resource model_resource((LPCSTR)"Content\\Misc\\DropZone\\DropZone.instance"); Check_Object(&model_resource); model_resource.LoadData(); Verify(model_resource.DoesResourceExist()); Adept::Entity *entity; Check_Object(Connection::Local); ReplicatorID base_id = Connection::Local->GetNextReplicatorID(); entity = Entity::CreateEntity(&model_resource,&base_id); Check_Object(entity); entity->instanceName = "PlayerStart"; Check_Object(Map::GetInstance()); Map::GetInstance()->AddChild(entity); entity->SetPropType(Entity::MissionPropType); entity->SyncMatrices(true); NameTable::GetInstance()->AddEntry(entity, NameTable::DropZoneArray); Verify(NameTable::GetInstance()->IsValid()); Map::GetInstance()->UpdateZone(entity); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void EditorApplication::EnterRunningGameState(void* data) { Check_Object(this); MWApplication::EnterRunningGameState(data); } void EditorApplication::PauseGameMessageHandler(const PauseGameMessage *message) { Check_Object(this); Check_Object(message); Verify(message->messageID == PauseGameMessageID); } void EditorApplication::LoadMissionResources(const char *mission_name) { // //--------------------------------------------------------- // Get the mission instance name and the resource file name //--------------------------------------------------------- // Stuff::MString mission_instance = mission_name; // [editor data fix] Derive the mission's compiled resource (.mw4) so BOTH user missions // (Resource\UserMissions\.mw4) AND stock missions can be opened. Stock missions // compile to Resource\Missions\.mw4 where is an abbreviated, lowercase name // declared in the mission's .build (e.g. CentralPark -> cpark.mw4), so it can't be derived // by a simple transform. The original code hardcoded "Resource\\User" + (name after first // '\\'), which only ever found the few user missions and produced a garbage path (and STOP) // for any name lacking a '\\'. Now: extract the bare mission name, prefer the user-mission // package, else read the resource path straight out of .build. char _bare[256]; { const char* _s = strrchr( (const char*)mission_instance, '\\' ); _s = _s ? _s + 1 : (const char*)mission_instance; Str_Copy( _bare, _s, sizeof(_bare) ); char* _dot = strrchr( _bare, '.' ); if( _dot ) *_dot = 0; } Stuff::MString res_name = "Resource\\UserMissions\\"; res_name += _bare; res_name += ".mw4"; if( GetFileAttributes( (const char*)res_name ) == 0xFFFFFFFF ) // no user-mission package -> stock mission { char _bp[512]; sprintf( _bp, "Content\\Missions\\%s\\%s.build", _bare, _bare ); FILE* _bf = fopen( _bp, "r" ); if( _bf ) { char _ln[512]; while( fgets( _ln, sizeof(_ln), _bf ) ) { char* _lb = strchr( _ln, '[' ); char* _rb = _lb ? strchr( _lb, ']' ) : 0; if( _lb && _rb && _rb > _lb && strstr( _lb, ".mw4" ) ) { *_rb = 0; res_name = _lb + 1; // e.g. resource\missions\cpark.mw4 break; } } fclose( _bf ); } } // // Since databases override the file hooking I have to specifically // make sure we do or don't need to translate the name at this point. // TranslateMissionNameIfNecessary(res_name); // //------------------------------------------------------------------- // Open up the resource file as a database and access record 0. This // will contain the list of resource files this one is dependant on //------------------------------------------------------------------- // Stuff::DatabaseHandle *database = new Stuff::DatabaseHandle(res_name, false, VER_CONTENTVERSION); Stuff::RecordHandle record; record.m_databaseHandle = database; record.m_ID = ResourceID::BuildDependenciesRecordID; #if defined(_ARMOR) bool result = #endif record.FindID(true); Verify(result); // //------------------------- // Load up the core effects //------------------------- // Verify(!gosFX::EffectLibrary::Instance); gosFX::EffectLibrary::Instance = new ResourceEffectLibrary; Resource core_libraries("{effects}"); Verify(core_libraries.DoesResourceExist()); core_libraries.LoadData(); ResourceID *lib = Cast_Pointer(ResourceID*, core_libraries.GetPointer()); for (unsigned i=0; iLoad(&library); } // //---------------------------------------------------------------------- // The data points to a series of null terminated strings. Step through // them until done //---------------------------------------------------------------------- // const char* data = reinterpret_cast(record.m_data); short level=MapResourceFileID; for (DWORD count=0; countOpenResourceFile( data+count, NULL, level, VER_CONTENTVERSION, false, false ); // //---------------------------- // Load up this file's effects //---------------------------- // Resource libraries("{effects}"); libraries.LoadData(); if (libraries.DoesResourceExist() && libraries.GetResourceID().GetFileID() == level) { ResourceID *lib = Cast_Pointer(ResourceID*, libraries.GetPointer()); for (unsigned i=0; iLoad(&library); } } count += strlen(data+count)+1; } // //--------------------------------- // Now create our own resource file //--------------------------------- // // MString depstr=res_name; // strcpy(strrchr(depstr,'.')+1,"dep"); ResourceManager::Instance->OpenResourceFile(database, level, false); Resource libraries("{effects}"); libraries.LoadData(); if (libraries.DoesResourceExist() && libraries.GetResourceID().GetFileID() == level) { ResourceID *lib = Cast_Pointer(ResourceID*, libraries.GetPointer()); for (unsigned i=0; iLoad(&library); } } } Entity::CreateMessage * EditorApplication::MakePlayerCreationMessage(int player_id) { Resource vehicle_instance("Content\\Vehicles\\ObservationVehicle\\ObservationVehicle.instance"); vehicle_instance.LoadData(); MString interface_name = "Interfaces\\SimpleInterface\\SimpleInterface.instance"; Resource interface_instance(interface_name); interface_instance.LoadData(); Resource player_data("Players\\TestPlayer\\TestPlayer.data"); player_data.LoadData(); MWPlayer::CreateMessage *player_message = new MWPlayer::CreateMessage( sizeof(MWPlayer::CreateMessage), DefaultEventPriority, MWPlayer::CreateMessage::DefaultFlags, MWPlayerClassID, 0, player_data.GetResourceID(), LinearMatrix4D::Identity, 0.0f, MWPlayer::ExecutionStateEngine::AlwaysExecuteState, NameTableEntry::BuildObjectID(NameTable::PlayerArray, 0), Entity::Player, vehicle_instance.GetResourceID(), interface_instance.GetResourceID(), NameTable::NullObjectID, 0, DefaultSkinPrefix, 0, 0 ); Check_Object(player_message); return player_message; }