diff --git a/Engine/source/T3D/Scene.cpp b/Engine/source/T3D/Scene.cpp index e2494743b..f762b160f 100644 --- a/Engine/source/T3D/Scene.cpp +++ b/Engine/source/T3D/Scene.cpp @@ -1,4 +1,5 @@ #include "Scene.h" +#include "T3D/assets/LevelAsset.h" Scene * Scene::smRootScene = nullptr; Vector Scene::smSceneList; @@ -180,6 +181,93 @@ void Scene::unpackUpdate(NetConnection *conn, BitStream *stream) } +void Scene::dumpUtilizedAssets() +{ + Con::printf("Dumping utilized assets in scene!"); + + Vector utilizedAssetsList; + for (U32 i = 0; i < mPermanentObjects.size(); i++) + { + mPermanentObjects[i]->getUtilizedAssets(&utilizedAssetsList); + } + + for (U32 i = 0; i < mDynamicObjects.size(); i++) + { + mDynamicObjects[i]->getUtilizedAssets(&utilizedAssetsList); + } + + for (U32 i = 0; i < utilizedAssetsList.size(); i++) + { + Con::printf("Utilized Asset: %s", utilizedAssetsList[i]); + } + + Con::printf("Utilized Asset dump complete!"); +} + +StringTableEntry Scene::getOriginatingFile() +{ + return getFilename(); +} + +StringTableEntry Scene::getLevelAsset() +{ + StringTableEntry levelFile = getFilename(); + + if (levelFile == StringTable->EmptyString()) + return StringTable->EmptyString(); + + AssetQuery* query = new AssetQuery(); + query->registerObject(); + + S32 foundAssetcount = AssetDatabase.findAssetLooseFile(query, levelFile); + if (foundAssetcount == 0) + return StringTable->EmptyString(); + else + return query->mAssetList[0]; +} + +bool Scene::saveScene(StringTableEntry fileName) +{ + //So, we ultimately want to not only save out the level, but also collate all the assets utilized + //by the static objects in the scene so we can have those before we parse the level file itself + //Useful for preloading or stat tracking + + //First, save the level file + if (fileName == StringTable->EmptyString()) + { + fileName = getOriginatingFile(); + } + + bool saveSuccess = save(fileName); + + if (!saveSuccess) + return false; + + //Get the level asset + StringTableEntry levelAsset = getLevelAsset(); + if (levelAsset == StringTable->EmptyString()) + return saveSuccess; + + LevelAsset* levelAssetDef = AssetDatabase.acquireAsset(levelAsset); + levelAssetDef->clearAssetDependencyFields("staticObjectAssetDependency"); + + //Next, lets build out our + Vector utilizedAssetsList; + for (U32 i = 0; i < mPermanentObjects.size(); i++) + { + mPermanentObjects[i]->getUtilizedAssets(&utilizedAssetsList); + } + + for (U32 i = 0; i < utilizedAssetsList.size(); i++) + { + levelAssetDef->addAssetDependencyField("staticObjectAssetDependency", utilizedAssetsList[i]); + } + + saveSuccess = levelAssetDef->saveAsset(); + + return saveSuccess; +} + // Vector Scene::getObjectsByClass(String className, bool checkSubscenes) { @@ -251,3 +339,34 @@ DefineEngineMethod(Scene, getObjectsByClass, String, (String className), (""), //return object->getObjectsByClass(className); return ""; } + +DefineEngineMethod(Scene, dumpUtilizedAssets, void, (), , + "Get the root Scene object that is loaded.\n" + "@return The id of the Root Scene. Will be 0 if no root scene is loaded") +{ + object->dumpUtilizedAssets(); +} + +DefineEngineMethod(Scene, getOriginatingFile, const char*, (), , + "Get the root Scene object that is loaded.\n" + "@return The id of the Root Scene. Will be 0 if no root scene is loaded") +{ + return object->getOriginatingFile(); +} + +DefineEngineMethod(Scene, getLevelAsset, const char*, (), , + "Get the root Scene object that is loaded.\n" + "@return The id of the Root Scene. Will be 0 if no root scene is loaded") +{ + return object->getLevelAsset(); +} + +DefineEngineMethod(Scene, save, bool, (const char* fileName), (""), + "Save out the object to the given file.\n" + "@param fileName The name of the file to save to." + "@param selectedOnly If true, only objects marked as selected will be saved out.\n" + "@param preAppendString Text which will be preprended directly to the object serialization.\n" + "@param True on success, false on failure.") +{ + return object->saveScene(StringTable->insert(fileName)); +} diff --git a/Engine/source/T3D/Scene.h b/Engine/source/T3D/Scene.h index f75d29ce9..ca2238be6 100644 --- a/Engine/source/T3D/Scene.h +++ b/Engine/source/T3D/Scene.h @@ -62,6 +62,13 @@ public: void addDynamicObject(SceneObject* object); void removeDynamicObject(SceneObject* object); + void dumpUtilizedAssets(); + + StringTableEntry getOriginatingFile(); + StringTableEntry getLevelAsset(); + + bool saveScene(StringTableEntry fileName); + // //Networking U32 packUpdate(NetConnection *conn, U32 mask, BitStream *stream); diff --git a/Engine/source/T3D/assets/LevelAsset.cpp b/Engine/source/T3D/assets/LevelAsset.cpp index b8f83f94c..770c94f53 100644 --- a/Engine/source/T3D/assets/LevelAsset.cpp +++ b/Engine/source/T3D/assets/LevelAsset.cpp @@ -330,9 +330,52 @@ void LevelAsset::setNavmeshFile(const char* pNavmeshFile) refreshAsset(); } +void LevelAsset::loadDependencies() +{ + //First, load any material, animation, etc assets we may be referencing in our asset + // Find any asset dependencies. + AssetManager::typeAssetDependsOnHash::Iterator assetDependenciesItr = mpOwningAssetManager->getDependedOnAssets()->find(mpAssetDefinition->mAssetId); + + // Does the asset have any dependencies? + if (assetDependenciesItr != mpOwningAssetManager->getDependedOnAssets()->end()) + { + // Iterate all dependencies. + while (assetDependenciesItr != mpOwningAssetManager->getDependedOnAssets()->end() && assetDependenciesItr->key == mpAssetDefinition->mAssetId) + { + //Force it to be loaded by acquiring it + StringTableEntry assetId = assetDependenciesItr->value; + mAssetDependencies.push_back(AssetDatabase.acquireAsset(assetId)); + + // Next dependency. + assetDependenciesItr++; + } + } +} + +void LevelAsset::unloadDependencies() +{ + for (U32 i = 0; i < mAssetDependencies.size(); i++) + { + AssetBase* assetDef = mAssetDependencies[i]; + AssetDatabase.releaseAsset(assetDef->getAssetId()); + } +} + DefineEngineMethod(LevelAsset, getLevelFile, const char*, (),, "Creates a new script asset using the targetFilePath.\n" "@return The bool result of calling exec") { return object->getLevelPath(); } + +DefineEngineMethod(LevelAsset, loadDependencies, void, (), , + "Initiates the loading of asset dependencies for this level.") +{ + return object->loadDependencies(); +} + +DefineEngineMethod(LevelAsset, unloadDependencies, void, (), , + "Initiates the unloading of previously loaded asset dependencies for this level.") +{ + return object->unloadDependencies(); +} diff --git a/Engine/source/T3D/assets/LevelAsset.h b/Engine/source/T3D/assets/LevelAsset.h index 2199d476c..eb91f3142 100644 --- a/Engine/source/T3D/assets/LevelAsset.h +++ b/Engine/source/T3D/assets/LevelAsset.h @@ -67,6 +67,8 @@ class LevelAsset : public AssetBase StringTableEntry mGamemodeName; + Vector mAssetDependencies; + public: LevelAsset(); virtual ~LevelAsset(); @@ -78,6 +80,9 @@ public: /// Declare Console Object. DECLARE_CONOBJECT(LevelAsset); + void loadDependencies(); + void unloadDependencies(); + void setLevelFile(const char* pImageFile); inline StringTableEntry getLevelFile(void) const { return mLevelFile; }; void setPostFXPresetFile(const char* pPostFXPresetFile); diff --git a/Engine/source/T3D/assets/TerrainAsset.cpp b/Engine/source/T3D/assets/TerrainAsset.cpp index 32223580b..52d81ccc8 100644 --- a/Engine/source/T3D/assets/TerrainAsset.cpp +++ b/Engine/source/T3D/assets/TerrainAsset.cpp @@ -221,7 +221,6 @@ bool TerrainAsset::loadTerrain() //Force the asset to become initialized if it hasn't been already AssetPtr matAsset = assetId; - mTerrMaterialAssets.push_front(matAsset); } diff --git a/Engine/source/T3D/tsStatic.cpp b/Engine/source/T3D/tsStatic.cpp index 96ad599b3..3689a12b7 100644 --- a/Engine/source/T3D/tsStatic.cpp +++ b/Engine/source/T3D/tsStatic.cpp @@ -1691,6 +1691,12 @@ void TSStatic::updateMaterials() mShapeInstance->initMaterialList(); } +void TSStatic::getUtilizedAssets(Vector* usedAssetsList) +{ + if(!mShapeAsset.isNull()) + usedAssetsList->push_back_unique(mShapeAssetId); +} + //------------------------------------------------------------------------ //These functions are duplicated in tsStatic and shapeBase. //They each function a little differently; but achieve the same purpose of gathering diff --git a/Engine/source/T3D/tsStatic.h b/Engine/source/T3D/tsStatic.h index 1d1ff0673..c08986b9c 100644 --- a/Engine/source/T3D/tsStatic.h +++ b/Engine/source/T3D/tsStatic.h @@ -286,6 +286,8 @@ public: bool isAnimated() { return mPlayAmbient; } + virtual void getUtilizedAssets(Vector* usedAssetsList); + private: virtual void onStaticModified(const char* slotName, const char* newValue = NULL); protected: diff --git a/Engine/source/assets/assetManager.cpp b/Engine/source/assets/assetManager.cpp index 9a710febe..5293fdc55 100644 --- a/Engine/source/assets/assetManager.cpp +++ b/Engine/source/assets/assetManager.cpp @@ -253,30 +253,22 @@ bool AssetManager::loadModuleAutoLoadAssets(ModuleDefinition* pModuleDefinition) if (assetDef->mAssetType == pAutoloadAssets->getAssetType()) { - //TODO: this is stupid and ugly, need to properly automagically parse the class for registration - AssetBase* assetBase = nullptr; + String assetPath = assetDef->mAssetBaseFilePath; + assetPath.replace("//", "/"); - if (assetDef->mAssetType == StringTable->insert("GUIAsset")) - { - assetBase = mTaml.read(assetDef->mAssetBaseFilePath); - } - else if (assetDef->mAssetType == StringTable->insert("ScriptAsset")) - { - assetBase = mTaml.read(assetDef->mAssetBaseFilePath); - } - else if (assetDef->mAssetType == StringTable->insert("MaterialAsset")) - { - assetBase = mTaml.read(assetDef->mAssetBaseFilePath); - } - else if (assetDef->mAssetType == StringTable->insert("GameObjectAsset")) - { - assetBase = mTaml.read(assetDef->mAssetBaseFilePath); - } + String autoLoadPath = pModuleDefinition->getModulePath(); + autoLoadPath += "/"; + autoLoadPath += pAutoloadAssets->getPath(); - //load the asset now if valid - if (assetBase) + if (pAutoloadAssets->getPath() == StringTable->EmptyString() || assetPath.startsWith(autoLoadPath.c_str())) { - assetBase->setOwned(this, assetDef); + AssetBase* assetBase = dynamic_cast(mTaml.read(assetDef->mAssetBaseFilePath)); + + //load the asset now if valid + if (assetBase) + { + assetBase->setOwned(this, assetDef); + } } } } diff --git a/Engine/source/scene/sceneObject.h b/Engine/source/scene/sceneObject.h index 36c8e1cad..a3140156a 100644 --- a/Engine/source/scene/sceneObject.h +++ b/Engine/source/scene/sceneObject.h @@ -942,6 +942,8 @@ class SceneObject : public NetObject, private SceneContainer::Link, public Proce /// notification that a direct child object has been detached virtual void onLostChild(SceneObject *subObject); // PATHSHAPE END + + virtual void getUtilizedAssets(Vector* usedAssetsList) {} }; #endif // _SCENEOBJECT_H_ diff --git a/Engine/source/terrain/terrData.cpp b/Engine/source/terrain/terrData.cpp index d96a9e41e..d6b2dd7d2 100644 --- a/Engine/source/terrain/terrData.cpp +++ b/Engine/source/terrain/terrData.cpp @@ -1420,6 +1420,11 @@ void TerrainBlock::getMinMaxHeight( F32 *minHeight, F32 *maxHeight ) const *maxHeight = fixedToFloat( sq->maxHeight ); } +void TerrainBlock::getUtilizedAssets(Vector* usedAssetsList) +{ + if (!mTerrainAsset.isNull()) + usedAssetsList->push_back_unique(mTerrainAssetId); +} //----------------------------------------------------------------------------- // Console Methods //----------------------------------------------------------------------------- diff --git a/Engine/source/terrain/terrData.h b/Engine/source/terrain/terrData.h index 15b02bee5..fac5dd940 100644 --- a/Engine/source/terrain/terrData.h +++ b/Engine/source/terrain/terrData.h @@ -474,6 +474,8 @@ public: U32 packUpdate (NetConnection *conn, U32 mask, BitStream *stream); void unpackUpdate(NetConnection *conn, BitStream *stream); void inspectPostApply(); + + virtual void getUtilizedAssets(Vector* usedAssetsList); protected: bool mIgnoreZodiacs; diff --git a/Templates/BaseGame/game/core/clientServer/Core_ClientServer.cs b/Templates/BaseGame/game/core/clientServer/Core_ClientServer.cs index 9f774c465..578db7523 100644 --- a/Templates/BaseGame/game/core/clientServer/Core_ClientServer.cs +++ b/Templates/BaseGame/game/core/clientServer/Core_ClientServer.cs @@ -60,11 +60,11 @@ function Core_ClientServer::onDestroy( %this ) } //----------------------------------------------------------------------------- -function StartGame( %mission, %hostingType ) +function StartGame( %levelAsset, %hostingType ) { - if( %mission $= "" ) + if( %levelAsset $= "" ) { - %mission = $selectedLevelFile; + %levelAsset = $selectedLevelAsset; } if (%hostingType !$= "") @@ -88,7 +88,7 @@ function StartGame( %mission, %hostingType ) Canvas.repaint(); } - createAndConnectToLocalServer( %serverType, %mission ); + createAndConnectToLocalServer( %serverType, %levelAsset ); } function JoinGame( %serverIndex ) diff --git a/Templates/BaseGame/game/core/clientServer/scripts/server/levelLoad.cs b/Templates/BaseGame/game/core/clientServer/scripts/server/levelLoad.cs index f6585aa84..340ea5fe5 100644 --- a/Templates/BaseGame/game/core/clientServer/scripts/server/levelLoad.cs +++ b/Templates/BaseGame/game/core/clientServer/scripts/server/levelLoad.cs @@ -33,22 +33,26 @@ $MissionLoadPause = 5000; //----------------------------------------------------------------------------- //This is the first call made by the server to kick the loading process off -function loadMission( %missionName, %isFirstMission ) +function loadMission( %levelAsset, %isFirstMission ) { endMission(); - echo("*** LOADING MISSION: " @ %missionName); + $Server::LevelAsset = AssetDatabase.acquireAsset(%levelAsset); + + echo("*** LOADING MISSION: " @ $Server::LevelAsset.LevelName); echo("*** Stage 1 load"); // increment the mission sequence (used for ghost sequencing) $missionSequence++; $missionRunning = false; - $Server::MissionFile = %missionName; + $Server::MissionFile = $Server::LevelAsset.getLevelFile(); $Server::LoadFailMsg = ""; + + $Server::LevelAsset.loadDependencies(); // Extract mission info from the mission file, // including the display name and stuff to send // to the client. - buildLoadInfo( %missionName ); + buildLoadInfo( $Server::MissionFile ); // Download mission info to the clients %count = ClientGroup.getCount(); @@ -163,6 +167,9 @@ function endMission() getScene(0).delete(); MissionCleanup.delete(); + if(isObject($Server::LevelAsset)) + AssetDatabase.releaseAsset($Server::LevelAsset.getAssetId()); //cleanup + if ($Pref::Server::EnableDatablockCache) resetDatablockCache(); DatablockFilesList.empty(); diff --git a/Templates/BaseGame/game/core/clientServer/scripts/server/server.cs b/Templates/BaseGame/game/core/clientServer/scripts/server/server.cs index 427af25b1..d5ab978c3 100644 --- a/Templates/BaseGame/game/core/clientServer/scripts/server/server.cs +++ b/Templates/BaseGame/game/core/clientServer/scripts/server/server.cs @@ -93,9 +93,9 @@ function portInit(%port) /// create a local client connection to the server. // /// @return true if successful. -function createAndConnectToLocalServer( %serverType, %level ) +function createAndConnectToLocalServer( %serverType, %levelAsset ) { - if( !createServer( %serverType, %level ) ) + if( !createServer( %serverType, %levelAsset ) ) return false; %conn = new GameConnection( ServerConnection ); @@ -124,7 +124,7 @@ function createAndConnectToLocalServer( %serverType, %level ) /// Create a server with either a "SinglePlayer" or "MultiPlayer" type /// Specify the level to load on the server -function createServer(%serverType, %level) +function createServer(%serverType, %levelAsset) { if($Game::firstTimeServerRun == true) { @@ -135,7 +135,7 @@ function createServer(%serverType, %level) // working with the server session we think we are. $Server::Session++; - if (%level $= "") + if (%levelAsset $= "") { error("createServer(): level name unspecified"); return false; @@ -143,7 +143,7 @@ function createServer(%serverType, %level) // Make sure our level name is relative so that it can send // across the network correctly - %level = makeRelativePath(%level, getWorkingDirectory()); + //%level = makeRelativePath(%level, getWorkingDirectory()); destroyServer(); @@ -176,7 +176,7 @@ function createServer(%serverType, %level) // the server has been created onServerCreated(); - loadMission(%level, true); + loadMission(%levelAsset, true); $Game::running = true; diff --git a/Templates/BaseGame/game/data/ui/guis/chooseLevelDlg.cs b/Templates/BaseGame/game/data/ui/guis/chooseLevelDlg.cs index f325d8b7f..93b9a269c 100644 --- a/Templates/BaseGame/game/data/ui/guis/chooseLevelDlg.cs +++ b/Templates/BaseGame/game/data/ui/guis/chooseLevelDlg.cs @@ -51,6 +51,9 @@ function ChooseLevelDlg::onWake( %this ) for(%i=0; %i < %count; %i++) { %assetId = %assetQuery.getAsset(%i); + + if(AssetDatabase.getAssetModule(%assetId).ModuleId $= "ToolsModule") + continue; %levelAsset = AssetDatabase.acquireAsset(%assetId); @@ -93,53 +96,6 @@ function ChooseLevelDlg::onWake( %this ) else LevelSelectTitle.setText("CREATE SERVER"); - /*for (%i = 0; %i < LevelList.rowCount(); %i++) - { - %preview = new GuiButtonCtrl() { - profile = "GuiMenuButtonProfile"; - internalName = "SmallPreview" @ %i; - Extent = "368 35"; - text = getField(CL_levelList.getRowText(%i), 0); - command = "ChooseLevelWindow.previewSelected(ChooseLevelWindow->SmallPreviews->SmallPreview" @ %i @ ");"; - buttonType = "RadioButton"; - }; - - ChooseLevelWindow->SmallPreviews.add(%preview); - - %rowText = CL_levelList.getRowText(%i); - - // Set the level index - %preview.levelIndex = %i; - - // Get the name - %name = getField(CL_levelList.getRowText(%i), 0); - - %preview.levelName = %name; - - %file = getField(CL_levelList.getRowText(%i), 1); - - // Find the preview image - %levelPreview = getField(CL_levelList.getRowText(%i), 3); - - // Test against all of the different image formats - // This should probably be moved into an engine function - if (isFile(%levelPreview @ ".png") || - isFile(%levelPreview @ ".jpg") || - isFile(%levelPreview @ ".bmp") || - isFile(%levelPreview @ ".gif") || - isFile(%levelPreview @ ".jng") || - isFile(%levelPreview @ ".mng") || - isFile(%levelPreview @ ".tga")) - { - %preview.bitmap = %levelPreview; - } - - // Get the description - %desc = getField(CL_levelList.getRowText(%i), 2); - - %preview.levelDesc = %desc; - }*/ - ChooseLevelButtonHolder.setActive(); } @@ -184,28 +140,7 @@ function ChooseLevelDlg::addMissionFile( %this, %file ) function ChooseLevelDlg::addLevelAsset( %this, %levelAsset ) { - %file = %levelAsset.getLevelFile(); - - /*%levelName = fileBase(%file); - %levelDesc = "A Torque level"; - - %LevelInfoObject = getLevelInfo(%file); - - if (%LevelInfoObject != 0) - { - if(%LevelInfoObject.levelName !$= "") - %levelName = %LevelInfoObject.levelName; - else if(%LevelInfoObject.name !$= "") - %levelName = %LevelInfoObject.name; - - if (%LevelInfoObject.desc0 !$= "") - %levelDesc = %LevelInfoObject.desc0; - - if (%LevelInfoObject.preview !$= "") - %levelPreview = %LevelInfoObject.preview; - - %LevelInfoObject.delete(); - }*/ + %file = %levelAsset.getAssetId(); %levelName = %levelAsset.LevelName; %levelDesc = %levelAsset.description; @@ -224,7 +159,7 @@ function LevelList::onChange(%this) ChooseLevelWindow->LevelName.text = getField(%levelEntry, 0); // Get the level file - $selectedLevelFile = getField(%levelEntry, 1); + $selectedLevelAsset = getField(%levelEntry, 1); // Find the preview image %levelPreview = getField(%levelEntry, 3); diff --git a/Templates/BaseGame/game/tools/Tools.cs b/Templates/BaseGame/game/tools/Tools.cs index fcbcf66ed..c9e0e01f5 100644 --- a/Templates/BaseGame/game/tools/Tools.cs +++ b/Templates/BaseGame/game/tools/Tools.cs @@ -16,7 +16,7 @@ function ToolsModule::onCreate(%this) // to find exactly which subsystems should be readied before kicking things off. // ---------------------------------------------------------------------------- - ModuleDatabase.LoadExplicit( "MainEditor" ); + //ModuleDatabase.LoadExplicit( "MainEditor" ); //ModuleDatabase.LoadExplicit( "Tools_ObjectViewer" ); } diff --git a/Templates/BaseGame/game/tools/Tools.module b/Templates/BaseGame/game/tools/Tools.module index b710db944..ac27644a9 100644 --- a/Templates/BaseGame/game/tools/Tools.module +++ b/Templates/BaseGame/game/tools/Tools.module @@ -5,4 +5,10 @@ ScriptFile="Tools.cs" CreateFunction="onCreate" DestroyFunction="onDestroy" - Group="Tools"/> \ No newline at end of file + Group="Tools"> + + \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/levels/DefaultEditorFile.mis b/Templates/BaseGame/game/tools/levels/DefaultEditorFile.mis deleted file mode 100644 index e6fe2b4fb..000000000 --- a/Templates/BaseGame/game/tools/levels/DefaultEditorFile.mis +++ /dev/null @@ -1,141 +0,0 @@ -//--- OBJECT WRITE BEGIN --- -new Scene(EditorTemplateLevel) { - canSave = "1"; - canSaveDynamicFields = "1"; - isSubScene = "0"; - isEditing = "0"; - isDirty = "0"; - cdTrack = "2"; - CTF_scoreLimit = "5"; - Enabled = "1"; - musicTrack = "lush"; - - new LevelInfo(theLevelInfo) { - nearClip = "0.1"; - visibleDistance = "1000"; - visibleGhostDistance = "0"; - decalBias = "0.0015"; - fogColor = "0.6 0.6 0.7 1"; - fogDensity = "0"; - fogDensityOffset = "700"; - fogAtmosphereHeight = "0"; - canvasClearColor = "0 0 0 255"; - ambientLightBlendPhase = "1"; - ambientLightBlendCurve = "0 0 -1 -1"; - soundAmbience = "AudioAmbienceDefault"; - soundDistanceModel = "Linear"; - canSave = "1"; - canSaveDynamicFields = "1"; - advancedLightmapSupport = "0"; - desc0 = "A blank room template that acts as a starting point."; - Enabled = "1"; - LevelName = "Blank Room Template"; - }; - new SkyBox(theSky) { - Material = "BlankSkyMat"; - drawBottom = "0"; - fogBandHeight = "0"; - dirtyGameObject = "0"; - position = "0 0 0"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - canSave = "1"; - canSaveDynamicFields = "1"; - }; - new Sun(theSun) { - azimuth = "230.396"; - elevation = "45"; - color = "0.968628 0.901961 0.901961 1"; - ambient = "0.337255 0.533333 0.619608 1"; - brightness = "1"; - castShadows = "1"; - staticRefreshFreq = "250"; - dynamicRefreshFreq = "8"; - coronaEnabled = "1"; - coronaScale = "0.5"; - coronaTint = "1 1 1 1"; - coronaUseLightColor = "1"; - flareScale = "1"; - attenuationRatio = "0 1 1"; - shadowType = "PSSM"; - texSize = "2048"; - overDarkFactor = "3000 1500 750 250"; - shadowDistance = "200"; - shadowSoftness = "0.25"; - numSplits = "4"; - logWeight = "0.9"; - fadeStartDistance = "0"; - lastSplitTerrainOnly = "0"; - representedInLightmap = "0"; - shadowDarkenColor = "0 0 0 -1"; - includeLightmappedGeometryInShadow = "0"; - dirtyGameObject = "0"; - position = "0 0 0"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - canSave = "1"; - canSaveDynamicFields = "1"; - bias = "0.1"; - Blur = "1"; - Enabled = "1"; - height = "1024"; - lightBleedFactor = "0.8"; - minVariance = "0"; - pointShadowType = "PointShadowType_Paraboloid"; - shadowBox = "-100 -100 -100 100 100 100"; - splitFadeDistances = "1 1 1 1"; - width = "3072"; - }; - new GroundPlane() { - squareSize = "128"; - scaleU = "25"; - scaleV = "25"; - Material = "Grid_512_Grey"; - dirtyGameObject = "0"; - canSave = "1"; - canSaveDynamicFields = "1"; - Enabled = "1"; - position = "0 0 0"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - }; - new Skylight() { - Enabled = "1"; - ReflectionMode = "Baked Cubemap"; - dirtyGameObject = "0"; - position = "1.37009 -5.23561 46.5817"; - rotation = "1 0 0 0"; - canSave = "1"; - canSaveDynamicFields = "1"; - persistentId = "d5eb3afb-dced-11e9-a423-bb0e346e3870"; - reflectionPath = "tools/levels/BlankRoom/probes/"; - }; - new TSStatic() { - ShapeAsset = "pbr:material_ball"; - playAmbient = "1"; - meshCulling = "0"; - originSort = "0"; - overrideColor = "0 0 0 0"; - collisionType = "Collision Mesh"; - decalType = "Collision Mesh"; - allowPlayerStep = "0"; - alphaFadeEnable = "0"; - alphaFadeStart = "100"; - alphaFadeEnd = "150"; - alphaFadeInverse = "0"; - renderNormals = "0"; - forceDetail = "-1"; - ignoreZodiacs = "0"; - useGradientRange = "0"; - gradientRange = "0 180"; - invertGradientRange = "0"; - dirtyGameObject = "0"; - position = "-0.000554562 -0.0734091 1.05277"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - canSave = "1"; - canSaveDynamicFields = "1"; - materialSlot0 = "base_material_ball"; - }; -}; -//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/levels/DefaultEditorLevel.asset.taml b/Templates/BaseGame/game/tools/levels/DefaultEditorLevel.asset.taml new file mode 100644 index 000000000..fc6aa0b1f --- /dev/null +++ b/Templates/BaseGame/game/tools/levels/DefaultEditorLevel.asset.taml @@ -0,0 +1,10 @@ + diff --git a/Templates/BaseGame/game/tools/main.cs b/Templates/BaseGame/game/tools/main.cs index 8ec861108..9f4068d7d 100644 --- a/Templates/BaseGame/game/tools/main.cs +++ b/Templates/BaseGame/game/tools/main.cs @@ -272,7 +272,7 @@ function fastLoadWorldEdit(%val) if( !$missionRunning ) { - EditorNewLevel("tools/levels/DefaultEditorLevel.mis"); + EditorNewLevel("ToolsModule:DefaultEditorLevel"); } else { diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.cs index 17768e762..6abfee59e 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.cs +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.cs @@ -199,7 +199,7 @@ function EditorOpenDeclarationInTorsion( %object ) EditorOpenFileInTorsion( makeFullPath( %fileName ), %object.getDeclarationLine() ); } -function EditorNewLevel( %file ) +function EditorNewLevel( %level ) { %saveFirst = false; if ( EditorIsDirty() ) @@ -219,18 +219,18 @@ function EditorNewLevel( %file ) Editor.getUndoManager().clearAll(); } - if( %file $= "" ) + if( %level $= "" ) { - %file = "tools/levels/DefaultEditorLevel.mis"; + %level = "ToolsModule:DefaultEditorLevel"; } if( !$missionRunning ) { activatePackage( "BootEditor" ); - StartGame( %file ); + StartGame( %level ); } else - EditorOpenMission(%file); + EditorOpenMission(%level); //EWorldEditor.isDirty = true; //ETerrainEditor.isDirty = true; @@ -360,6 +360,15 @@ function EditorSaveMissionAs( %levelAsset ) if( fileExt( %missionName ) !$= ".mis" ) %missionName = %missionName @ ".mis"; + //Update to be our active + $Server::MissionFile = %missionName; + %Server::LevelAsset = %levelAssetDef; + + //Do the save + EditorSaveMission(); + + //TODO: doublecheck that we rename the scene properly + //Make sure we have a selected module so we can create our module //if(AssetBrowser.selectedModule $= "") // Canvas.pushDialog(