From 5566f8a3962556915de44ef82f9d382f0f6966f6 Mon Sep 17 00:00:00 2001 From: JeffR Date: Sun, 30 Mar 2025 16:36:15 -0500 Subject: [PATCH] Updated handling of subscenes in assets to be it's own distinct definition to avoid parsing and detection issues, as well as fields to be handled distinctly between the types --- Engine/source/T3D/SubScene.cpp | 32 ++-- Engine/source/T3D/SubScene.h | 12 +- Engine/source/T3D/assets/LevelAsset.cpp | 15 +- Engine/source/T3D/assets/LevelAsset.h | 3 - Engine/source/T3D/assets/SubSceneAsset.cpp | 166 ++++++++++++++++++ Engine/source/T3D/assets/SubSceneAsset.h | 113 ++++++++++++ .../game/tools/assetBrowser/main.tscript | 1 + .../scripts/assetTypes/level.tscript | 18 +- .../scripts/assetTypes/subScene.tscript | 156 ++++++++++++++++ 9 files changed, 469 insertions(+), 47 deletions(-) create mode 100644 Engine/source/T3D/assets/SubSceneAsset.cpp create mode 100644 Engine/source/T3D/assets/SubSceneAsset.h create mode 100644 Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/subScene.tscript diff --git a/Engine/source/T3D/SubScene.cpp b/Engine/source/T3D/SubScene.cpp index ecab32ff0..2b773bfd6 100644 --- a/Engine/source/T3D/SubScene.cpp +++ b/Engine/source/T3D/SubScene.cpp @@ -24,7 +24,7 @@ IMPLEMENT_CALLBACK(SubScene, onUnloaded, void, (), (), "@brief Called when a subScene has been unloaded and has game mode implications.\n\n"); SubScene::SubScene() : - mLevelAssetId(StringTable->EmptyString()), + mSubSceneAssetId(StringTable->EmptyString()), mGameModesNames(StringTable->EmptyString()), mScopeDistance(-1), mLoaded(false), @@ -67,7 +67,7 @@ void SubScene::initPersistFields() { addGroup("SubScene"); addField("isGlobalLayer", TypeBool, Offset(mGlobalLayer, SubScene), ""); - INITPERSISTFIELD_LEVELASSET(Level, SubScene, "The level asset to load."); + INITPERSISTFIELD_SUBSCENEASSET(SubScene, SubScene, "The subscene asset to load."); addField("tickPeriodMS", TypeS32, Offset(mTickPeriodMS, SubScene), "evaluation rate (ms)"); addField("gameModes", TypeGameModeList, Offset(mGameModesNames, SubScene), "The game modes that this subscene is associated with."); endGroup("SubScene"); @@ -265,13 +265,13 @@ void SubScene::processTick(const Move* move) void SubScene::_onFileChanged(const Torque::Path& path) { - if(mLevelAsset.isNull() || Torque::Path(mLevelAsset->getLevelPath()) != path) + if(mSubSceneAsset.isNull() || Torque::Path(mSubSceneAsset->getLevelPath()) != path) return; if (mSaving) return; - AssertFatal(path == mLevelAsset->getLevelPath(), "Prefab::_onFileChanged - path does not match filename."); + AssertFatal(path == mSubSceneAsset->getLevelPath(), "SubScene::_onFileChanged - path does not match filename."); _closeFile(false); _loadFile(false); @@ -307,9 +307,9 @@ void SubScene::_closeFile(bool removeFileNotify) _removeContents(SimGroupIterator(this)); - if (removeFileNotify && mLevelAsset.notNull() && mLevelAsset->getLevelPath() != StringTable->EmptyString()) + if (removeFileNotify && mSubSceneAsset.notNull() && mSubSceneAsset->getLevelPath() != StringTable->EmptyString()) { - Torque::FS::RemoveChangeNotification(mLevelAsset->getLevelPath(), this, &SubScene::_onFileChanged); + Torque::FS::RemoveChangeNotification(mSubSceneAsset->getLevelPath(), this, &SubScene::_onFileChanged); } mGameModesList.clear(); @@ -319,18 +319,18 @@ void SubScene::_loadFile(bool addFileNotify) { AssertFatal(isServerObject(), "Trying to load a SubScene file on the client is bad!"); - if(mLevelAsset.isNull() || mLevelAsset->getLevelPath() == StringTable->EmptyString()) + if(mSubSceneAsset.isNull() || mSubSceneAsset->getLevelPath() == StringTable->EmptyString()) return; - String evalCmd = String::ToString("exec(\"%s\");", mLevelAsset->getLevelPath()); + String evalCmd = String::ToString("exec(\"%s\");", mSubSceneAsset->getLevelPath()); String instantGroup = Con::getVariable("InstantGroup"); Con::setIntVariable("InstantGroup", this->getId()); - Con::evaluate((const char*)evalCmd.c_str(), false, mLevelAsset->getLevelPath()); + Con::evaluate((const char*)evalCmd.c_str(), false, mSubSceneAsset->getLevelPath()); Con::setVariable("InstantGroup", instantGroup.c_str()); if (addFileNotify) - Torque::FS::AddChangeNotification(mLevelAsset->getLevelPath(), this, &SubScene::_onFileChanged); + Torque::FS::AddChangeNotification(mSubSceneAsset->getLevelPath(), this, &SubScene::_onFileChanged); } void SubScene::load() @@ -432,7 +432,7 @@ bool SubScene::save() if (size() == 0 || !isLoaded()) return false; - if (mLevelAsset.isNull()) + if (mSubSceneAsset.isNull()) return false; if (mSaving) @@ -446,7 +446,7 @@ bool SubScene::save() PersistenceManager prMger; - StringTableEntry levelPath = mLevelAsset->getLevelPath(); + StringTableEntry levelPath = mSubSceneAsset->getLevelPath(); FileStream fs; fs.open(levelPath, Torque::FS::File::Write); @@ -460,7 +460,7 @@ bool SubScene::save() { if ((*itr)->isMethod("onSaving")) { - Con::executef((*itr), "onSaving", mLevelAssetId); + Con::executef((*itr), "onSaving", mSubSceneAssetId); } if (childObj->getGroup() == this) @@ -481,14 +481,14 @@ bool SubScene::save() bool saveSuccess = false; //Get the level asset - if (mLevelAsset.isNull()) + if (mSubSceneAsset.isNull()) return saveSuccess; //update the gamemode list as well - mLevelAsset->setDataField(StringTable->insert("gameModesNames"), NULL, StringTable->insert(mGameModesNames)); + mSubSceneAsset->setDataField(StringTable->insert("gameModesNames"), NULL, StringTable->insert(mGameModesNames)); //Finally, save - saveSuccess = mLevelAsset->saveAsset(); + saveSuccess = mSubSceneAsset->saveAsset(); mSaving = false; diff --git a/Engine/source/T3D/SubScene.h b/Engine/source/T3D/SubScene.h index e73133057..cfc3606ad 100644 --- a/Engine/source/T3D/SubScene.h +++ b/Engine/source/T3D/SubScene.h @@ -5,8 +5,8 @@ #ifndef SCENE_GROUP_H #include "SceneGroup.h" #endif -#ifndef LEVEL_ASSET_H -#include "assets/LevelAsset.h" +#ifndef SUBSCENE_ASSET_H +#include "assets/SubSceneAsset.h" #endif class GameMode; @@ -21,13 +21,13 @@ public: NextFreeMask = Parent::NextFreeMask << 0 }; - void onLevelChanged() {} + void onSubSceneChanged() {} protected: static bool smTransformChildren; private: - DECLARE_LEVELASSET(SubScene, Level, onLevelChanged); + DECLARE_SUBSCENEASSET(SubScene, SubScene, onSubSceneChanged); StringTableEntry mGameModesNames; Vector mGameModesList; @@ -61,7 +61,7 @@ public: static void initPersistFields(); static void consoleInit(); - StringTableEntry getTypeHint() const override { return (getLevelAsset()) ? getLevelAsset()->getAssetName() : StringTable->EmptyString(); } + StringTableEntry getTypeHint() const override { return (getSubSceneAsset()) ? getSubSceneAsset()->getAssetName() : StringTable->EmptyString(); } // SimObject bool onAdd() override; @@ -122,6 +122,6 @@ public: DECLARE_CALLBACK(void, onLoaded, ()); DECLARE_CALLBACK(void, onUnloaded, ()); - DECLARE_ASSET_SETGET(SubScene, Level); + DECLARE_ASSET_SETGET(SubScene, SubScene); }; #endif diff --git a/Engine/source/T3D/assets/LevelAsset.cpp b/Engine/source/T3D/assets/LevelAsset.cpp index e47a6f563..f04bfe058 100644 --- a/Engine/source/T3D/assets/LevelAsset.cpp +++ b/Engine/source/T3D/assets/LevelAsset.cpp @@ -101,7 +101,7 @@ ConsoleSetType(TypeLevelAssetId) } //----------------------------------------------------------------------------- -LevelAsset::LevelAsset() : AssetBase(), mIsSubLevel(false) +LevelAsset::LevelAsset() : AssetBase() { mLevelName = StringTable->EmptyString(); mLevelFile = StringTable->EmptyString(); @@ -117,7 +117,6 @@ LevelAsset::LevelAsset() : AssetBase(), mIsSubLevel(false) mNavmeshPath = StringTable->EmptyString(); mGameModesNames = StringTable->EmptyString(); - mMainLevelAsset = StringTable->EmptyString(); mEditorFile = StringTable->EmptyString(); mBakedSceneFile = StringTable->EmptyString(); @@ -158,7 +157,6 @@ void LevelAsset::initPersistFields() addProtectedField("BakedSceneFile", TypeAssetLooseFilePath, Offset(mBakedSceneFile, LevelAsset), &setBakedSceneFile, &getBakedSceneFile, "Path to the level file with the objects generated as part of the baking process"); - addField("isSubScene", TypeBool, Offset(mIsSubLevel, LevelAsset), "Is this a sublevel to another Scene"); addField("gameModesNames", TypeString, Offset(mGameModesNames, LevelAsset), "Name of the Game Mode to be used with this level"); } @@ -480,15 +478,8 @@ GuiControl* GuiInspectorTypeLevelAssetPtr::constructEditControl() // Create "Open in Editor" button mEditButton = new GuiBitmapButtonCtrl(); - String setSubSceneValue = "$createLevelAssetIsSubScene = \"\";"; - if(dynamic_cast(mInspector->getInspectObject()) != NULL) - { - setSubSceneValue = "$createLevelAssetIsSubScene = true;"; - } - - dSprintf(szBuffer, sizeof(szBuffer), "$createAndAssignField = %s; %s AssetBrowser.setupCreateNewAsset(\"LevelAsset\", AssetBrowser.selectedModule, \"createAndAssignLevelAsset\");", - getIdString(), - setSubSceneValue.c_str()); + dSprintf(szBuffer, sizeof(szBuffer), "$createAndAssignField = %s; AssetBrowser.setupCreateNewAsset(\"LevelAsset\", AssetBrowser.selectedModule, \"createAndAssignLevelAsset\");", + getIdString()); mEditButton->setField("Command", szBuffer); char bitmapName[512] = "ToolsModule:iconAdd_image"; diff --git a/Engine/source/T3D/assets/LevelAsset.h b/Engine/source/T3D/assets/LevelAsset.h index 8b02495ed..39339a41e 100644 --- a/Engine/source/T3D/assets/LevelAsset.h +++ b/Engine/source/T3D/assets/LevelAsset.h @@ -66,9 +66,6 @@ class LevelAsset : public AssetBase StringTableEntry mEditorFile; StringTableEntry mBakedSceneFile; - bool mIsSubLevel; - StringTableEntry mMainLevelAsset; - StringTableEntry mGameModesNames; Vector mAssetDependencies; diff --git a/Engine/source/T3D/assets/SubSceneAsset.cpp b/Engine/source/T3D/assets/SubSceneAsset.cpp new file mode 100644 index 000000000..a55af9cad --- /dev/null +++ b/Engine/source/T3D/assets/SubSceneAsset.cpp @@ -0,0 +1,166 @@ +#include "SubSceneAsset.h" + +#include "T3D/SubScene.h" +IMPLEMENT_CONOBJECT(SubSceneAsset); + + +ConsoleType(SubSceneAssetPtr, TypeSubSceneAssetPtr, const char*, "") + +//----------------------------------------------------------------------------- + +ConsoleGetType(TypeSubSceneAssetPtr) +{ + // Fetch asset Id. + return *((const char**)(dptr)); +} + +//----------------------------------------------------------------------------- + +ConsoleSetType(TypeSubSceneAssetPtr) +{ + // Was a single argument specified? + if (argc == 1) + { + // Yes, so fetch field value. + *((const char**)dptr) = StringTable->insert(argv[0]); + + return; + } + + // Warn. + Con::warnf("(TypeSubSceneAssetPtr) - Cannot set multiple args to a single asset."); +} + +//----------------------------------------------------------------------------- +ConsoleType(assetIdString, TypeSubSceneAssetId, const char*, "") + +ConsoleGetType(TypeSubSceneAssetId) +{ + // Fetch asset Id. + return *((const char**)(dptr)); +} + +ConsoleSetType(TypeSubSceneAssetId) +{ + // Was a single argument specified? + if (argc == 1) + { + *((const char**)dptr) = StringTable->insert(argv[0]); + + return; + } + + // Warn. + Con::warnf("(TypeSubSceneAssetId) - Cannot set multiple args to a single asset."); +} + +SubSceneAsset::SubSceneAsset() : LevelAsset() +{ +} + +SubSceneAsset::~SubSceneAsset() +{ +} + +void SubSceneAsset::initPersistFields() +{ + docsURL; + Parent::initPersistFields(); +} + + +//----------------------------------------------------------------------------- +// GuiInspectorTypeAssetId +//----------------------------------------------------------------------------- + +IMPLEMENT_CONOBJECT(GuiInspectorTypeSubSceneAssetPtr); + +ConsoleDocClass(GuiInspectorTypeSubSceneAssetPtr, + "@brief Inspector field type for Shapes\n\n" + "Editor use only.\n\n" + "@internal" +); + +void GuiInspectorTypeSubSceneAssetPtr::consoleInit() +{ + Parent::consoleInit(); + + ConsoleBaseType::getType(TypeSubSceneAssetPtr)->setInspectorFieldType("GuiInspectorTypeSubSceneAssetPtr"); +} + +GuiControl* GuiInspectorTypeSubSceneAssetPtr::constructEditControl() +{ + // Create base filename edit controls + GuiControl* retCtrl = Parent::constructEditControl(); + if (retCtrl == NULL) + return retCtrl; + + // Change filespec + char szBuffer[512]; + dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.showDialog(\"SubSceneAsset\", \"AssetBrowser.changeAsset\", %s, \"\");", + getIdString()); + mBrowseButton->setField("Command", szBuffer); + + setDataField(StringTable->insert("targetObject"), NULL, mInspector->getInspectObject()->getIdString()); + + // Create "Open in Editor" button + mEditButton = new GuiBitmapButtonCtrl(); + + dSprintf(szBuffer, sizeof(szBuffer), "$createAndAssignField = %s; AssetBrowser.setupCreateNewAsset(\"SubSceneAsset\", AssetBrowser.selectedModule);", + getIdString()); + mEditButton->setField("Command", szBuffer); + + char bitmapName[512] = "ToolsModule:iconAdd_image"; + mEditButton->setBitmap(StringTable->insert(bitmapName)); + + mEditButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile"); + mEditButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile"); + mEditButton->setDataField(StringTable->insert("hovertime"), NULL, "1000"); + mEditButton->setDataField(StringTable->insert("tooltip"), NULL, "Test play this sound"); + + mEditButton->registerObject(); + addObject(mEditButton); + + return retCtrl; +} + +bool GuiInspectorTypeSubSceneAssetPtr::updateRects() +{ + S32 dividerPos, dividerMargin; + mInspector->getDivider(dividerPos, dividerMargin); + Point2I fieldExtent = getExtent(); + Point2I fieldPos = getPosition(); + + mCaptionRect.set(0, 0, fieldExtent.x - dividerPos - dividerMargin, fieldExtent.y); + mEditCtrlRect.set(fieldExtent.x - dividerPos + dividerMargin, 1, dividerPos - dividerMargin - 34, fieldExtent.y); + + bool resized = mEdit->resize(mEditCtrlRect.point, mEditCtrlRect.extent); + if (mBrowseButton != NULL) + { + mBrowseRect.set(fieldExtent.x - 32, 2, 14, fieldExtent.y - 4); + resized |= mBrowseButton->resize(mBrowseRect.point, mBrowseRect.extent); + } + + if (mEditButton != NULL) + { + RectI shapeEdRect(fieldExtent.x - 16, 2, 14, fieldExtent.y - 4); + resized |= mEditButton->resize(shapeEdRect.point, shapeEdRect.extent); + } + + return resized; +} + +IMPLEMENT_CONOBJECT(GuiInspectorTypeSubSceneAssetId); + +ConsoleDocClass(GuiInspectorTypeSubSceneAssetId, + "@brief Inspector field type for SubScene\n\n" + "Editor use only.\n\n" + "@internal" +); + +void GuiInspectorTypeSubSceneAssetId::consoleInit() +{ + Parent::consoleInit(); + + ConsoleBaseType::getType(TypeSubSceneAssetId)->setInspectorFieldType("GuiInspectorTypeSubSceneAssetId"); +} diff --git a/Engine/source/T3D/assets/SubSceneAsset.h b/Engine/source/T3D/assets/SubSceneAsset.h new file mode 100644 index 000000000..444c4c23a --- /dev/null +++ b/Engine/source/T3D/assets/SubSceneAsset.h @@ -0,0 +1,113 @@ +#pragma once +#ifndef SUBSCENE_ASSET_H +#define SUBSCENE_ASSET_H + +#ifndef LEVEL_ASSET_H +#include "LevelAsset.h" +#endif + +#ifndef _ASSET_DEFINITION_H_ +#include "assets/assetDefinition.h" +#endif + +#ifndef _GUI_INSPECTOR_TYPES_H_ +#include "gui/editor/guiInspectorTypes.h" +#endif + +class SubSceneAsset : public LevelAsset +{ + typedef LevelAsset Parent; + +public: + SubSceneAsset(); + virtual ~SubSceneAsset(); + + /// Engine. + static void initPersistFields(); + + /// Declare Console Object. + DECLARE_CONOBJECT(SubSceneAsset); +}; + +#ifdef TORQUE_TOOLS +class GuiInspectorTypeSubSceneAssetPtr : public GuiInspectorTypeFileName +{ + typedef GuiInspectorTypeFileName Parent; +public: + + GuiBitmapButtonCtrl* mEditButton; + + DECLARE_CONOBJECT(GuiInspectorTypeSubSceneAssetPtr); + static void consoleInit(); + + GuiControl* constructEditControl() override; + bool updateRects() override; +}; + +class GuiInspectorTypeSubSceneAssetId : public GuiInspectorTypeSubSceneAssetPtr +{ + typedef GuiInspectorTypeSubSceneAssetPtr Parent; +public: + + DECLARE_CONOBJECT(GuiInspectorTypeSubSceneAssetId); + static void consoleInit(); +}; +#endif + +DefineConsoleType(TypeSubSceneAssetPtr, SubSceneAsset) +DefineConsoleType(TypeSubSceneAssetId, String) + +#pragma region Singular Asset Macros + +//Singular assets +/// +/// Declares an SubScene asset +/// This establishes the assetId, asset and legacy filepath fields, along with supplemental getter and setter functions +/// +#define DECLARE_SUBSCENEASSET(className, name, changeFunc) public: \ + StringTableEntry m##name##AssetId;\ + AssetPtr m##name##Asset;\ +public: \ + const AssetPtr & get##name##Asset() const { return m##name##Asset; }\ + void set##name##Asset(const AssetPtr &_in) { m##name##Asset = _in;}\ + \ + bool _set##name(StringTableEntry _in)\ + {\ + if(m##name##AssetId != _in)\ + {\ + if (m##name##Asset.notNull())\ + {\ + m##name##Asset->getChangedSignal().remove(this, &className::changeFunc);\ + }\ + if (_in == NULL || _in == StringTable->EmptyString())\ + {\ + m##name##AssetId = StringTable->EmptyString();\ + m##name##Asset = NULL;\ + return true;\ + }\ + if (AssetDatabase.isDeclaredAsset(_in))\ + {\ + m##name##AssetId = _in;\ + m##name##Asset = _in;\ + return true;\ + }\ + }\ + \ + if(get##name() == StringTable->EmptyString())\ + return true;\ + \ + return false;\ + }\ + \ + const StringTableEntry get##name() const\ + {\ + return m##name##AssetId;\ + }\ + bool name##Valid() {return (get##name() != StringTable->EmptyString() && m##name##Asset->getStatus() == AssetBase::Ok); } + +#define INITPERSISTFIELD_SUBSCENEASSET(name, consoleClass, docs) \ + addProtectedField(assetText(name, Asset), TypeSubSceneAssetId, Offset(m##name##AssetId, consoleClass), _set##name##Data, &defaultProtectedGetFn, assetDoc(name, asset docs.)); + +#pragma endregion + +#endif // SUBSCENE_ASSET_H diff --git a/Templates/BaseGame/game/tools/assetBrowser/main.tscript b/Templates/BaseGame/game/tools/assetBrowser/main.tscript index 73d2a314a..2b3e0938c 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/main.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/main.tscript @@ -75,6 +75,7 @@ function initializeAssetBrowser() exec("./scripts/assetTypes/gui." @ $TorqueScriptFileExtension); exec("./scripts/assetTypes/image." @ $TorqueScriptFileExtension); exec("./scripts/assetTypes/level." @ $TorqueScriptFileExtension); + exec("./scripts/assetTypes/subScene." @ $TorqueScriptFileExtension); exec("./scripts/assetTypes/material." @ $TorqueScriptFileExtension); exec("./scripts/assetTypes/postFX." @ $TorqueScriptFileExtension); exec("./scripts/assetTypes/script." @ $TorqueScriptFileExtension); diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/level.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/level.tscript index d0e673628..015a798ae 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/level.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/level.tscript @@ -3,17 +3,9 @@ AssetBrowser::registerAssetType("LevelAsset", "Levels"); function LevelAsset::setupCreateNew() { NewAssetPropertiesInspector.startGroup("Level"); - NewAssetPropertiesInspector.addField("LevelName", "Level Name", "String", "Human-readable name of new level", "", "", $CurrentAssetBrowser.callAssetTypeFunc(%assetType, "setupCreateNew");.newAssetSettings); + NewAssetPropertiesInspector.addField("LevelName", "Level Name", "String", "Human-readable name of new level", "", "", $CurrentAssetBrowser.newAssetSettings); NewAssetPropertiesInspector.addField("levelPreviewImage", "Level Preview Image", "Image", "Preview Image for the level", "", "", $CurrentAssetBrowser.newAssetSettings); - //If we forcefully set it elsewhere, adhere - if($createLevelAssetIsSubScene == true) - %this.newAssetSettings.isSubScene = true; - else - %this.newAssetSettings.isSubScene = false; - - NewAssetPropertiesInspector.addField("isSubScene", "Is SubScene", "bool", "Is this levelAsset intended as a subScene", %this.newAssetSettings.isSubScene, "", %this.newAssetSettings); - NewAssetPropertiesInspector.endGroup(); } @@ -88,11 +80,17 @@ function LevelAsset::onCreateNew(%this) if(!%addSuccess) { - error("AssetBrowser::createLevelAsset() - failed to add declared asset: " @ %tamlpath @ " for module: " @ %moduleDef); + error("LevelAsset::onCreateNew() - failed to add declared asset: " @ %tamlpath @ " for module: " @ %moduleDef); } $CurrentAssetBrowser.refresh(); + if(%addSuccess && isObject($createAndAssignField)) + { + $createAndAssignField.apply(%moduleName @ ":" @ %assetName); + $createAndAssignField = ""; + } + return %tamlpath; } diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/subScene.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/subScene.tscript new file mode 100644 index 000000000..bd72e7080 --- /dev/null +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/subScene.tscript @@ -0,0 +1,156 @@ +AssetBrowser::registerAssetType("SubSceneAsset", "SubScenes"); + +function SubSceneAsset::setupCreateNew() +{ + NewAssetPropertiesInspector.startGroup("SubScene"); + NewAssetPropertiesInspector.addField("LevelName", "SubScene Name", "String", "Human-readable name of new subScene", "", "", $CurrentAssetBrowser.newAssetSettings); + + NewAssetPropertiesInspector.endGroup(); +} + +function SubSceneAsset::onCreateNew(%this) +{ + %moduleName = $CurrentAssetBrowser.newAssetSettings.moduleName; + %modulePath = "data/" @ %moduleName; + + %assetName = $CurrentAssetBrowser.newAssetSettings.assetName; + + %assetPath = NewAssetTargetAddress.getText() @ "/"; + + %misExtension = ".subMis"; + + %tamlpath = %assetPath @ %assetName @ ".asset.taml"; + %levelPath = %assetPath @ %assetName @ %misExtension; + + %asset = new SubSceneAsset() + { + AssetName = %assetName; + versionId = 1; + LevelFile = %assetName @ %misExtension; + LevelName = $CurrentAssetBrowser.newAssetSettings.levelName; + AssetDescription = $CurrentAssetBrowser.newAssetSettings.description; + }; + + TamlWrite(%asset, %tamlpath); + + %fileObj = new FileObject(); + if (!%fileObj.openForWrite(%levelPath)) + { + echo("Unable to write subScene file!"); + } + else + { + %fileObj.writeLine(""); + %fileObj.close(); + %fileObj.delete(); + } + + %moduleDef = ModuleDatabase.findModule(%moduleName, 1); + %addSuccess = AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); + + if(!%addSuccess) + { + error("SubSceneAsset::onCreateNew() - failed to add declared asset: " @ %tamlpath @ " for module: " @ %moduleDef); + } + + $CurrentAssetBrowser.refresh(); + + if(%addSuccess && isObject($createAndAssignField)) + { + $createAndAssignField.apply(%moduleName @ ":" @ %assetName); + $createAndAssignField = ""; + } + + return %tamlpath; +} + +function SubSceneAsset::buildBrowserElement(%this, %previewData) +{ + %previewData.assetName = %this.assetName; + %previewData.assetPath = %this.getLevelPath(); + %previewData.doubleClickCommand = "AssetBrowser.selectAsset(" @ %this @ ");"; + + %levelPreviewImage = %this.PreviewImage; + + if(isFile(%levelPreviewImage)) + %previewData.previewImage = %levelPreviewImage; + else + %previewData.previewImage = "ToolsModule:levelIcon_image"; + + %previewData.assetFriendlyName = %this.assetName; + %previewData.assetDesc = %this.description; + %previewData.tooltip = "Asset Name: " @ %this.assetName @ "\n" @ + "Asset Type: SubScene Asset\n" @ + "Asset Definition ID: " @ %this @ "\n" @ + "SubScene File path: " @ %this.getLevelPath(); +} + +function EWorldEditor::createSelectedAsSubScene( %this, %object ) +{ + //create new level asset here + AssetBrowser.setupCreateNewAsset("SubSceneAsset", AssetBrowser.selectedModule, "finishCreateSelectedAsSubScene"); + %this.contextActionObject = %object; +} + +function finishCreateSelectedAsSubScene(%assetId) +{ + //echo("finishCreateSelectedAsSubScene"); + + %subScene = new SubScene() { + levelAsset = %assetId; + }; + + %levelAssetDef = AssetDatabase.acquireAsset(%assetId); + %levelFilePath = %levelAssetDef.getLevelPath(); + + //write out to file + EWorldEditor.contextActionObject.save(%levelFilePath); + + AssetDatabase.releaseAsset(%assetId); + + getRootScene().add(%subScene); + + EWorldEditor.contextActionObject.delete(); + + %subScene.load(); + + %subScene.recalculateBounds(); + + %scalar = $SubScene::createScalar; + if(%scalar $= "") + %scalar = 1.5; + + //pad for loading boundary + %subScene.scale = VectorScale(%subScene.scale, %scalar); +} + +function SubSceneAsset::onWorldEditorDropped(%assetDef, %position) +{ + %assetId = %assetDef.getAssetId(); + + if(!%assetDef.isSubScene) + { + errorf("Cannot drag-and-drop LevelAsset into WorldEditor"); + return; + } + + %newSubScene = new SubScene() + { + position = %position; + levelAsset = %assetId; + }; + + getScene(0).add(%newSubScene); + + %newSubScene.load(); + %newSubScene.recalculateBounds(); + + EWorldEditor.clearSelection(); + EWorldEditor.selectObject(%newSubScene); + + EWorldEditor.dropSelection(); + + EWorldEditor.isDirty = true; + + MECreateUndoAction::submit(%newSubScene ); +} \ No newline at end of file