소스 검색

Merge pull request #584 from Areloch/QOL20210918

Misc QOL and Bugfixes 2021/09/19
Brian Roberts 4 년 전
부모
커밋
bda5266c88

+ 24 - 3
Engine/source/T3D/assets/MaterialAsset.cpp

@@ -169,7 +169,13 @@ void MaterialAsset::initializeAsset()
    mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
 
    if (Torque::FS::IsScriptFile(mScriptPath))
-      Con::executeFile(mScriptPath, false, false);
+   {
+      if (!Sim::findObject(mMatDefinitionName))
+         if (Con::executeFile(mScriptPath, false, false))
+            mLoadedState = ScriptLoaded;
+         else
+            mLoadedState = Failed;
+   }
 
    loadMaterial();
 }
@@ -179,7 +185,22 @@ void MaterialAsset::onAssetRefresh()
    mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
 
    if (Torque::FS::IsScriptFile(mScriptPath))
-      Con::executeFile(mScriptPath, false, false);
+   {
+      //Since we're refreshing, we can assume that the file we're executing WILL have an existing definition.
+      //But that definition, whatever it is, is the 'correct' one, so we enable the Replace Existing behavior
+      //when the engine encounters a named object conflict.
+      String redefineBehaviorPrev = Con::getVariable("$Con::redefineBehavior");
+      Con::setVariable("$Con::redefineBehavior", "replaceExisting");
+
+      if (Con::executeFile(mScriptPath, false, false))
+         mLoadedState = ScriptLoaded;
+      else
+         mLoadedState = Failed;
+
+      //And now that we've executed, switch back to the prior behavior
+      Con::setVariable("$Con::redefineBehavior", redefineBehaviorPrev.c_str());
+      
+   }
 
    loadMaterial();
 }
@@ -206,7 +227,7 @@ void MaterialAsset::loadMaterial()
    if (mMaterialDefinition)
       SAFE_DELETE(mMaterialDefinition);
 
-   if (mMatDefinitionName != StringTable->EmptyString())
+   if (mLoadedState == ScriptLoaded && mMatDefinitionName != StringTable->EmptyString())
    {
       Material* matDef;
       if (!Sim::findObject(mMatDefinitionName, matDef))

+ 6 - 0
Engine/source/T3D/assets/MaterialAsset.h

@@ -70,6 +70,12 @@ class MaterialAsset : public AssetBase
 public:
    static StringTableEntry smNoMaterialAssetFallback;
 
+   enum MaterialAssetErrCode
+   {
+      ScriptLoaded = AssetErrCode::Extended,
+      Extended
+   };
+
 public:
    MaterialAsset();
    virtual ~MaterialAsset();

+ 2 - 2
Engine/source/T3D/prefab.cpp

@@ -242,7 +242,7 @@ bool Prefab::protectedSetFile( void *object, const char *index, const char *data
    return false;
 }
 
-void Prefab::setFile( String file )
+void Prefab::setFile( StringTableEntry file )
 {  
    AssertFatal( isServerObject(), "Prefab-bad" );
 
@@ -257,7 +257,7 @@ void Prefab::setFile( String file )
    // be called for the client-side prefab but maybe the user did so accidentally.
    if ( isClientObject() )
    {
-      Con::errorf( "Prefab::setFile( %s ) - Should not be called on a client-side Prefab.", file.c_str() );
+      Con::errorf( "Prefab::setFile( %s ) - Should not be called on a client-side Prefab.", file );
       return;
    }
 

+ 1 - 1
Engine/source/T3D/prefab.h

@@ -90,7 +90,7 @@ public:
    void render( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat );
 
    ///
-   void setFile( String file );
+   void setFile(StringTableEntry file );
 
    /// Removes all children from this Prefab and puts them into a SimGroup
    /// which is added to the Scene and returned to the caller.

+ 0 - 4
Engine/source/T3D/tsStatic.cpp

@@ -1675,10 +1675,6 @@ void TSStatic::onInspect(GuiInspector* inspector)
          {
             dSprintf(matFieldName, 128, "MaterialSlot%d", i);
 
-            //addComponentField(matFieldName, "A material used in the shape file", "Material", matAsset->getAssetId(), "");
-            //Con::executef(this, "onConstructComponentField", mTargetComponent, field->mFieldName);
-            Con::printf("Added material field for MaterialSlot %d", i);
-
             GuiInspectorField* fieldGui = materialGroup->constructField(TypeMaterialAssetPtr);
             fieldGui->init(inspector, materialGroup);
 

+ 12 - 0
Engine/source/terrain/terrData.cpp

@@ -1613,3 +1613,15 @@ void TerrainBlock::deleteZodiacPrimitiveBuffer()
    }
 }
 
+DefineEngineMethod(TerrainBlock, getTerrain, String, (), , "Returns the terrain file used for this terrain block, either via the asset or the filename assigned, which ever is valid")
+{
+   return object->getTerrain(); 
+}
+DefineEngineMethod(TerrainBlock, getTerrainAsset, String, (), , "Returns the assetId used for this terrain block")
+{
+   return object->getTerrainAssetId();
+}
+DefineEngineMethod(TerrainBlock, setTerrain, bool, (const char* terrain), , "Terrain assignment.first tries asset then flat file.")
+{
+   return object->_setTerrain(StringTable->insert(terrain));
+}

+ 33 - 0
Engine/source/terrain/terrData.h

@@ -488,6 +488,39 @@ public:
    void inspectPostApply();
 
    virtual void getUtilizedAssets(Vector<StringTableEntry>* usedAssetsList);
+
+   const StringTableEntry getTerrain() const
+   {
+      if (mTerrainAsset && (mTerrainAsset->getTerrainFilePath() != StringTable->EmptyString()))
+         return mTerrainAsset->getTerrainFilePath(); 
+      else if (mTerrainAssetId != StringTable->EmptyString())
+         return mTerrainAssetId; 
+      else if (mTerrFileName != StringTable->EmptyString())
+         return mTerrFileName; 
+      else
+         return StringTable->EmptyString(); 
+   }
+
+   const StringTableEntry getTerrainAssetId() const
+   {
+      if (mTerrainAssetId != StringTable->EmptyString())
+         return mTerrainAssetId;
+      else
+         return StringTable->EmptyString();
+   }
+
+   bool _setTerrain(StringTableEntry terrain)
+   {
+      if (terrain == StringTable->EmptyString())
+         return false;
+
+      if (AssetDatabase.isDeclaredAsset(terrain))
+         setTerrainAsset(terrain);
+      else
+         mTerrFileName = terrain;
+
+      return true;
+   }
  
 protected:
    bool mUpdateBasetex;

+ 0 - 2
Templates/BaseGame/game/data/UI/guis/mainMenu.gui

@@ -1,5 +1,3 @@
-exec( "tools/gui/profiles.ed.tscript" );
-
 //--- OBJECT WRITE BEGIN ---
 $guiContent = new GuiChunkedBitmapCtrl(MainMenuGui) {
    bitmapAsset = "UI:background_dark_image";

+ 3 - 1
Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript

@@ -618,7 +618,9 @@ function AssetBrowser::loadDirectories( %this )
    
    %dataItem = AssetBrowser-->filterTree.insertItem(AssetBrowser-->filterTree.modulesIdx, "data");
    AssetBrowser-->filterTree.tagsIdx = AssetBrowser-->filterTree.insertItem(1, "Tags");
-   AssetBrowser-->filterTree.creatorIdx = AssetBrowser-->filterTree.insertItem(1, "Creator");
+   
+   if(!%this.selectMode)
+      AssetBrowser-->filterTree.creatorIdx = AssetBrowser-->filterTree.insertItem(1, "Creator");
    
    %this.dirHandler.loadFolders("data", %dataItem);
    

+ 1 - 1
Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrain.tscript

@@ -79,7 +79,7 @@ function AssetBrowser::createTerrainAsset(%this)
       }
       else
       {
-         toolsMessageBox( "Import Terrain", 
+         MessageBox( "Import Terrain", 
             "Terrain import failed! Check console for error messages.", 
             "Ok", "Error" );
       }

+ 1 - 1
Templates/BaseGame/game/tools/assetBrowser/scripts/creator.tscript

@@ -47,7 +47,7 @@ function AssetBrowser::loadCreatorClasses(%this)
       %this.addCreatorClass("LevelInfo",    "Level Info" );
       %this.addCreatorClass("Marker",       "Path Node" );
       %this.addCreatorClass("MissionArea",  "Mission Area" );
-      %this.addCreatorClass("Note",         "Note" );
+      %this.addCreatorClass("NotesObject",         "Note" );
       %this.addCreatorClass("Path" );
       %this.addCreatorClass("SpawnSphere",  "General Spawn Sphere" );
       %this.addCreatorClass("SpawnSphere",  "Player Spawn Sphere"/*, "PlayerDropPoint"*/ );

+ 0 - 1
Templates/BaseGame/game/tools/convexEditor/main.tscript

@@ -145,7 +145,6 @@ function ConvexEditorPlugin::onDeactivated( %this )
 
    ConvexEditorTreeWindow.setVisible( false );
    ConvexEditorOptionsWindow.setVisible( false );
-   ConvexEditorToolbar.setVisible( false );
    %this.map.pop();
    
    // Remove our menu.

+ 1 - 1
Templates/BaseGame/game/tools/guiEditor/scripts/guiEditor.ed.tscript

@@ -910,7 +910,7 @@ function GuiEditorTabBook::onWake( %this )
          item[ 1 ] = "Categorized View" TAB "" TAB "GuiEditorToolbox.setViewType( \"Categorized\" );";
       };
       
-   GlobalActionMap.bindCmd( keyboard, space, "", "AssetBrowser.toggleDialog();" );
+   GlobalActionMap.bindCmd( keyboard, "shift space", "", "AssetBrowser.toggleDialog();" );
 }
 
 //---------------------------------------------------------------------------------------------

+ 5 - 5
Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorCanvas.ed.tscript

@@ -283,7 +283,7 @@ function GuiEditCanvas::load( %this, %filename )
    // group. And, it should be the only thing in the group.
    if( !isObject( $guiContent ) )
    {
-      toolsMessageBox( getEngineName(),
+      MessageBox( getEngineName(),
          "You have loaded a Gui file that was created before this version.  It has been loaded but you must open it manually from the content list dropdown",
          "Ok", "Information" );   
       return 0;
@@ -333,7 +333,7 @@ function GuiEditCanvas::save( %this, %selectedOnly, %noPrompt )
          return;
       else if( %selected.getCount() > 1 )
       {
-         toolsMessageBox( "Invalid selection", "Only a single control hierarchy can be saved to a file.  Make sure you have selected only one control in the tree view." );
+         MessageBox( "Invalid selection", "Only a single control hierarchy can be saved to a file.  Make sure you have selected only one control in the tree view." );
          return;
       }
          
@@ -464,7 +464,7 @@ function GuiEditCanvas::save( %this, %selectedOnly, %noPrompt )
       GuiEditorStatusBar.print( "Saved file '" @ %currentObject.getFileName() @ "'" );
    }
    else
-      toolsMessageBox( "Error writing to file", "There was an error writing to file '" @ %currentFile @ "'. The file may be read-only.", "Ok", "Error" );   
+      MessageBox( "Error writing to file", "There was an error writing to file '" @ %currentFile @ "'. The file may be read-only.", "Ok", "Error" );   
 }
 
 //---------------------------------------------------------------------------------------------
@@ -490,7 +490,7 @@ function GuiEditCanvas::append( %this )
    
    if( !isObject( $guiContent ) )
    {
-      toolsMessageBox( "Error loading GUI file", "The GUI content controls could not be found.  This function can only be used with files saved by the GUI editor.", "Ok", "Error" );
+      MessageBox( "Error loading GUI file", "The GUI content controls could not be found.  This function can only be used with files saved by the GUI editor.", "Ok", "Error" );
       return;
    }
    
@@ -519,7 +519,7 @@ function GuiEditCanvas::revert( %this )
    if( %filename $= "" )
       return;
       
-   if( toolsMessageBox( "Revert Gui", "Really revert the current Gui?  This cannot be undone.", "OkCancel", "Question" ) == $MROk )
+   if( MessageBox( "Revert Gui", "Really revert the current Gui?  This cannot be undone.", "OkCancel", "Question" ) == $MROk )
       %this.load( %filename );
 }
 

+ 1 - 1
Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorNewGuiDialog.ed.tscript

@@ -81,7 +81,7 @@ function GuiEditorNewGuiDialog::onOK( %this )
 
    if( isObject( %name ) && %name.isMemberOfClass( "GuiControl" ) )
    {
-      if( toolsMessageBox( "Warning", "Replace the existing control '" @ %name @ "'?", "OkCancel", "Question" ) == $MROk )
+      if( MessageBox( "Warning", "Replace the existing control '" @ %name @ "'?", "OkCancel", "Question" ) == $MROk )
          %name.delete();
       else
          return;

+ 3 - 3
Templates/BaseGame/game/tools/riverEditor/riverEditorGui.tscript

@@ -76,9 +76,9 @@ function RiverEditorGui::createRiver( %this )
 
       baseColor = "45 108 171 255";
       
-      rippleTex = "core/rendering/images/ripple.dds";
-      foamTex = "core/rendering/images/foam";
-      depthGradientTex = "core/rendering/images/depthcolor_ramp";
+      rippleTex = "Core_Rendering:ripple_image";
+      foamTex = "Core_Rendering:foam_image";
+      depthGradientTex = "Core_Rendering:depthcolor_ramp_image";
    };
    
    return %river;

+ 287 - 24
Templates/BaseGame/game/tools/worldEditor/gui/objectBuilderGui.ed.gui

@@ -313,10 +313,8 @@ function ObjectBuilderGui::createImageAssetType(%this, %index)
    else
       %name = %this.field[%index, text];
 
-   // 
-   /*%this.textControls[%this.numControls] = new GuiTextCtrl() {
+   %this.textControls[%this.numControls] = new GuiTextCtrl() {
       profile = "ToolsGuiTextRightProfile";
-      internalName = "assetText";
       text = %name;
       extent = %this.fieldNameExtent;
       position = %this.curXPos @ " " @ %this.curYPos;
@@ -324,18 +322,87 @@ function ObjectBuilderGui::createImageAssetType(%this, %index)
    };
 
    // 
-   %this.controls[%this.numControls] = new GuiButtonCtrl() {
+   %this.controls[%this.numControls] = new GuiControl() {
       HorizSizing = "width";
-      profile = "ToolsGuiButtonProfile";
-      internalName = "assetButton";
-      extent = %this.fileButtonExtent;
+      profile = "ToolsGuiDefaultProfile";
+      extent = %this.textEditExtent;
       position = %this.curXPos + %this.columnOffset @ " " @ %this.curYPos;
       modal = "1";
+   };
+   
+   %text = new GuiTextEditCtrl() {
+      class = ObjectBuilderGuiTextEditCtrl;
+      internalName = "assetText";
+      HorizSizing = "width";
+      profile = "ToolsGuiTextEditProfile";
+      extent = getWord(%this.textEditExtent,0) - getWord(%this.matButtonExtent,0) - 2 @ " " @ getWord(%this.textEditExtent,1);
+      text = %this.field[%index, value];
+      position = "0 0";
+      modal = "1";
+   };
+   %this.controls[%this.numControls].addGuiControl(%text);
+   
+   %button = new GuiBitmapButtonCtrl() {
+      internalName = "assetButton";
+      HorizSizing = "left";
+      profile = "ToolsGuiButtonProfile";
+      extent = %this.matButtonExtent;
+      position = getWord(%this.textEditExtent,0) - getWord(%this.matButtonExtent,0) @ " 0";
+      modal = "1";
       command = %this @ ".getImageAsset(" @ %index @ ");";
    };
+   %button.setBitmap("ToolsModule:GameTSCtrl_image");
+   %this.controls[%this.numControls].addGuiControl(%button);
 
-   %val = %this.field[%index, value];
-   %this.controls[%this.numControls].setText(fileBase(%val) @ fileExt(%val));*/
+   %this.numControls++;
+   %this.curYPos += %this.defaultFieldStep;
+}
+
+function ObjectBuilderGui::getImageAsset(%this, %index)
+{
+   if(%index >= %this.numFields || %this.field[%index, name] $= "")
+   {
+      error("ObjectBuilderGui::getImageAsset: invalid field");
+      return;
+   }
+   
+   %val = %this.field[%index, ext];
+
+   //%path = filePath(%val);
+   //%ext = fileExt(%val);
+
+   %this.currentControl = %index;
+   AssetBrowser.showDialog("ImageAsset", %this @ ".gotImageAsset", "", "", "");
+   //getLoadFilename( %val @ "|" @ %val, %this @ ".gotFileName", %this.lastPath );
+}
+
+function ObjectBuilderGui::gotImageAsset(%this, %name)
+{
+   %index = %this.currentControl;
+   
+   %this.field[%index, value] = %name;
+   %this.controls[%this.currentControl]-->assetText.setText(%name);
+   
+   %this.lastPath = %name;
+   
+   // This doesn't work for button controls as getValue returns their state!
+   //%this.controls[%this.currentControl].setValue(%name);
+}
+
+//------------------------------------------------------------------------------
+function ObjectBuilderGui::createMaterialAssetType(%this, %index)
+{
+   if(%index >= %this.numFields || %this.field[%index, name] $= "")
+   {
+      error("ObjectBuilderGui::createMaterialAssetType: invalid field");
+      return;
+   }
+
+   //
+   if(%this.field[%index, text] $= "")
+      %name = %this.field[%index, name];
+   else
+      %name = %this.field[%index, text];
    
    %this.textControls[%this.numControls] = new GuiTextCtrl() {
       profile = "ToolsGuiTextRightProfile";
@@ -373,7 +440,7 @@ function ObjectBuilderGui::createImageAssetType(%this, %index)
       extent = %this.matButtonExtent;
       position = getWord(%this.textEditExtent,0) - getWord(%this.matButtonExtent,0) @ " 0";
       modal = "1";
-      command = %this @ ".getImageAsset(" @ %index @ ");";
+      command = %this @ ".getMaterialAsset(" @ %index @ ");";
    };
    %button.setBitmap("ToolsModule:change_material_btn_n_image");
    %this.controls[%this.numControls].addGuiControl(%button);
@@ -382,11 +449,11 @@ function ObjectBuilderGui::createImageAssetType(%this, %index)
    %this.curYPos += %this.defaultFieldStep;
 }
 
-function ObjectBuilderGui::getImageAsset(%this, %index)
+function ObjectBuilderGui::getMaterialAsset(%this, %index)
 {
    if(%index >= %this.numFields || %this.field[%index, name] $= "")
    {
-      error("ObjectBuilderGui::getImageAsset: invalid field");
+      error("ObjectBuilderGui::getMaterialAsset: invalid field");
       return;
    }
    
@@ -396,11 +463,193 @@ function ObjectBuilderGui::getImageAsset(%this, %index)
    //%ext = fileExt(%val);
 
    %this.currentControl = %index;
-   AssetBrowser.showDialog("ImageAsset", %this @ ".gotImageAsset", "", "", "");
+   AssetBrowser.showDialog("MaterialAsset", %this @ ".gotMaterialAsset", "", "", "");
    //getLoadFilename( %val @ "|" @ %val, %this @ ".gotFileName", %this.lastPath );
 }
 
-function ObjectBuilderGui::gotImageAsset(%this, %name)
+function ObjectBuilderGui::gotMaterialAsset(%this, %name)
+{
+   %index = %this.currentControl;
+   
+   %this.field[%index, value] = %name;
+   %this.controls[%this.currentControl]-->assetText.setText(%name);
+   
+   %this.lastPath = %name;
+   
+   // This doesn't work for button controls as getValue returns their state!
+   //%this.controls[%this.currentControl].setValue(%name);
+}
+
+//------------------------------------------------------------------------------
+function ObjectBuilderGui::createShapeAssetType(%this, %index)
+{
+   if(%index >= %this.numFields || %this.field[%index, name] $= "")
+   {
+      error("ObjectBuilderGui::createShapeAssetType: invalid field");
+      return;
+   }
+
+   //
+   if(%this.field[%index, text] $= "")
+      %name = %this.field[%index, name];
+   else
+      %name = %this.field[%index, text];
+   
+   %this.textControls[%this.numControls] = new GuiTextCtrl() {
+      profile = "ToolsGuiTextRightProfile";
+      text = %name;
+      extent = %this.fieldNameExtent;
+      position = %this.curXPos @ " " @ %this.curYPos;
+      modal = "1";
+   };
+
+   // 
+   %this.controls[%this.numControls] = new GuiControl() {
+      HorizSizing = "width";
+      profile = "ToolsGuiDefaultProfile";
+      extent = %this.textEditExtent;
+      position = %this.curXPos + %this.columnOffset @ " " @ %this.curYPos;
+      modal = "1";
+   };
+   
+   %text = new GuiTextEditCtrl() {
+      class = ObjectBuilderGuiTextEditCtrl;
+      internalName = "assetText";
+      HorizSizing = "width";
+      profile = "ToolsGuiTextEditProfile";
+      extent = getWord(%this.textEditExtent,0) - getWord(%this.matButtonExtent,0) - 2 @ " " @ getWord(%this.textEditExtent,1);
+      text = %this.field[%index, value];
+      position = "0 0";
+      modal = "1";
+   };
+   %this.controls[%this.numControls].addGuiControl(%text);
+   
+   %button = new GuiBitmapButtonCtrl() {
+      internalName = "assetButton";
+      HorizSizing = "left";
+      profile = "ToolsGuiButtonProfile";
+      extent = %this.matButtonExtent;
+      position = getWord(%this.textEditExtent,0) - getWord(%this.matButtonExtent,0) @ " 0";
+      modal = "1";
+      command = %this @ ".getShapeAsset(" @ %index @ ");";
+   };
+   %button.setBitmap("ToolsModule:shape_editor_n_image");
+   %this.controls[%this.numControls].addGuiControl(%button);
+
+   %this.numControls++;
+   %this.curYPos += %this.defaultFieldStep;
+}
+
+function ObjectBuilderGui::getShapeAsset(%this, %index)
+{
+   if(%index >= %this.numFields || %this.field[%index, name] $= "")
+   {
+      error("ObjectBuilderGui::getShapeAsset: invalid field");
+      return;
+   }
+   
+   %val = %this.field[%index, ext];
+
+   //%path = filePath(%val);
+   //%ext = fileExt(%val);
+
+   %this.currentControl = %index;
+   AssetBrowser.showDialog("ShapeAsset", %this @ ".gotShapeAsset", "", "", "");
+   //getLoadFilename( %val @ "|" @ %val, %this @ ".gotFileName", %this.lastPath );
+}
+
+function ObjectBuilderGui::gotShapeAsset(%this, %name)
+{
+   %index = %this.currentControl;
+   
+   %this.field[%index, value] = %name;
+   %this.controls[%this.currentControl]-->assetText.setText(%name);
+   
+   %this.lastPath = %name;
+   
+   // This doesn't work for button controls as getValue returns their state!
+   //%this.controls[%this.currentControl].setValue(%name);
+}
+
+//------------------------------------------------------------------------------
+function ObjectBuilderGui::createSoundAssetType(%this, %index)
+{
+   if(%index >= %this.numFields || %this.field[%index, name] $= "")
+   {
+      error("ObjectBuilderGui::createSoundAssetType: invalid field");
+      return;
+   }
+
+   //
+   if(%this.field[%index, text] $= "")
+      %name = %this.field[%index, name];
+   else
+      %name = %this.field[%index, text];
+   
+   %this.textControls[%this.numControls] = new GuiTextCtrl() {
+      profile = "ToolsGuiTextRightProfile";
+      text = %name;
+      extent = %this.fieldNameExtent;
+      position = %this.curXPos @ " " @ %this.curYPos;
+      modal = "1";
+   };
+
+   // 
+   %this.controls[%this.numControls] = new GuiControl() {
+      HorizSizing = "width";
+      profile = "ToolsGuiDefaultProfile";
+      extent = %this.textEditExtent;
+      position = %this.curXPos + %this.columnOffset @ " " @ %this.curYPos;
+      modal = "1";
+   };
+   
+   %text = new GuiTextEditCtrl() {
+      class = ObjectBuilderGuiTextEditCtrl;
+      internalName = "assetText";
+      HorizSizing = "width";
+      profile = "ToolsGuiTextEditProfile";
+      extent = getWord(%this.textEditExtent,0) - getWord(%this.matButtonExtent,0) - 2 @ " " @ getWord(%this.textEditExtent,1);
+      text = %this.field[%index, value];
+      position = "0 0";
+      modal = "1";
+   };
+   %this.controls[%this.numControls].addGuiControl(%text);
+   
+   %button = new GuiBitmapButtonCtrl() {
+      internalName = "assetButton";
+      HorizSizing = "left";
+      profile = "ToolsGuiButtonProfile";
+      extent = %this.matButtonExtent;
+      position = getWord(%this.textEditExtent,0) - getWord(%this.matButtonExtent,0) @ " 0";
+      modal = "1";
+      command = %this @ ".getSoundAsset(" @ %index @ ");";
+   };
+   %button.setBitmap("ToolsModule:SFXEmitter_image");
+   %this.controls[%this.numControls].addGuiControl(%button);
+
+   %this.numControls++;
+   %this.curYPos += %this.defaultFieldStep;
+}
+
+function ObjectBuilderGui::getSoundAsset(%this, %index)
+{
+   if(%index >= %this.numFields || %this.field[%index, name] $= "")
+   {
+      error("ObjectBuilderGui::getSoundAsset: invalid field");
+      return;
+   }
+   
+   %val = %this.field[%index, ext];
+
+   //%path = filePath(%val);
+   //%ext = fileExt(%val);
+
+   %this.currentControl = %index;
+   AssetBrowser.showDialog("SoundAsset", %this @ ".gotSoundAsset", "", "", "");
+   //getLoadFilename( %val @ "|" @ %val, %this @ ".gotFileName", %this.lastPath );
+}
+
+function ObjectBuilderGui::gotSoundAsset(%this, %name)
 {
    %index = %this.currentControl;
    
@@ -680,6 +929,15 @@ function ObjectBuilderGui::process(%this)
          case "TypeImageAsset":
             %this.createImageAssetType(%i);
 
+         case "TypeMaterialAsset":
+            %this.createMaterialAssetType(%i);
+            
+         case "TypeShapeAsset":
+            %this.createShapeAssetType(%i);
+            
+         case "TypeSoundAsset":
+            %this.createSoundAssetType(%i);
+
          case "TypeMaterialName":
             %this.createMaterialNameType(%i);
 
@@ -753,7 +1011,10 @@ function ObjectBuilderGui::onOK(%this)
          continue;
       }
       if (%this.field[%i, type] $= "TypeImageAsset" || 
-      %this.field[%i, type] $= "TypeTerrainAsset")
+      %this.field[%i, type] $= "TypeTerrainAsset" || 
+      %this.field[%i, type] $= "TypeMaterialAsset" ||
+      %this.field[%i, type] $= "TypeShapeAsset"
+      )
       {
          %this.field[%i, value] = %this.controls[%i]-->assetText.getText();
          continue;
@@ -861,7 +1122,6 @@ function ObjectBuilderGui::buildScatterSky( %this, %dontWarnAboutSun )
    %this.addField( "moonMatAsset", "TypeMaterialAsset", "Moon Material", "Core_Rendering:moon_wglow" );
    %this.addField( "nightCubemap", "TypeCubemapName", "Night Cubemap", "NightCubemap" );
    %this.addField( "useNightCubemap", "TypeBool", "Use Night Cubemap", "true" );
-   
 }
 
 function ObjectBuilderGui::buildCloudLayer(%this)
@@ -954,7 +1214,7 @@ function ObjectBuilderGui::buildSun( %this, %dontWarnAboutScatterSky )
    
    // This is a trick... any fields added after process won't show
    // up as controls, but will be applied to the created object.
-   %this.addField( "coronaMaterial", "TypeMaterialName", "Corona Material", "Corona_Mat" );
+   %this.addField( "coronaMaterial", "TypeMaterialAsset", "Corona Material", "Core_Rendering:Corona_Mat" );
    %this.addField( "flareType", "TypeLightFlareDataPtr", "Flare", "SunFlareExample" );
 }
 
@@ -994,9 +1254,9 @@ function ObjectBuilderGui::addWaterObjectFields(%this)
    %this.addField("waveSpeed[2]", "TypeFloat", "Wave Speed", "1");
    %this.addField("overallWaveMagnitude", "TypeFloat", "Overall Wave Magnitude", "1.0");
    
-   %this.addField("rippleTexAsset", "TypeImageAssetId", "Ripple Texture", "Core_Rendering:ripple_image" );
-   %this.addField("depthGradientTexAsset", "TypeImageAssetId", "Depth Gradient Texture", "Core_Rendering:depthcolor_ramp_imag" );
-   %this.addField("foamTexAsset", "TypeImageAssetId", "Foam Texture", "Core_Rendering:foam_image" );
+   %this.addField("rippleTex", "TypeImageAsset", "Ripple Texture", "Core_Rendering:ripple_image" );
+   %this.addField("depthGradientTex", "TypeImageAsset", "Depth Gradient Texture", "Core_Rendering:depthcolor_ramp_image" );
+   %this.addField("foamTex", "TypeImageAsset", "Foam Texture", "Core_Rendering:foam_image" );
 }
 
 function ObjectBuilderGui::buildWaterBlock(%this)
@@ -1038,8 +1298,8 @@ function ObjectBuilderGui::buildTerrainBlock(%this)
 function ObjectBuilderGui::buildGroundCover( %this )
 {
    %this.objectClassName = "GroundCover";
-   %this.addField( "material", "TypeMaterialName", "Material Name", "" );
-   %this.addField( "shapeFilename[0]", "TypeFile", "Shape File [Optional]", "", "*.*");
+   %this.addField( "materialAsset", "TypeMaterialAsset", "Material Asset", "" );
+   %this.addField( "shapeAsset[0]", "TypeShapeAsset", "Shape Asset [Optional]", "", "");
    %this.process();
    
    // This is a trick... any fields added after process won't show
@@ -1212,6 +1472,9 @@ function ObjectBuilderGui::buildGeneralDropPoint(%this)
 function ObjectBuilderGui::buildNotesObject(%this)
 {
    %this.objectClassName = "NotesObject";
+   %this.addField("note",           "TypeString",     "Note Text", "");
+   %this.addField("showArrow",      "TypeBool",       "Show Arrow", "");
+   %this.addField("arrowColor",     "TypeColorI",     "Arrow Color", "255 0 0 255");
    %this.process();
 }
 //------------------------------------------------------------------------------
@@ -1221,11 +1484,11 @@ function ObjectBuilderGui::buildVolumetricFog(%this)
 {
 	// Change this if you want to default to another Folder
 	// Otherwise every time you want to add a Fog you will go this.
-	%defShape = "core/rendering/shapes/Fog_Cube.DAE";
+	%defShape = "Core_Rendering:Fog_Cube";
 	%this.lastPath=getMainDotCsDir() @ %defShape;
 	OBObjectName.setValue( "" );
 	%this.objectClassName = "VolumetricFog";
-	%this.addField( "shapeName", "TypeFile", "Shape (Fog volume)", "", "*.dts;*.dae");
+	%this.addField( "shapeAsset", "TypeShapeAsset", "Shape (Fog volume)", "", "");
 	%this.addField("Scale", "TypePoint3", "Scale", "1 1 1");
 	%this.addField("FogColor", "TypeColorI", "FogColor", "200 200 200 255");
 	%this.process();

+ 8 - 2
Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript

@@ -1826,7 +1826,10 @@ function EditorTree::update( %this )
 // Tooltip for TSStatic
 function EditorTree::GetTooltipTSStatic( %this, %obj )
 {
-   return "Shape: " @ %obj.shapeName;
+   %shapeName = %obj.shapeAsset;
+   if(%shapeName $= "")
+      %shapeName = %obj.getShape();
+   return "Shape: " @ %shapeName;
 }
 
 // Tooltip for ShapeBase
@@ -1862,7 +1865,10 @@ function EditorTree::GetTooltipPrefab( %this, %obj )
 // Tooltip for GroundCover
 function EditorTree::GetTooltipGroundCover( %this, %obj )
 {
-   %text = "Material: " @ %obj.material;
+   %matName = %obj.materialAsset;
+   if(%matName $= "")
+      %matName = %obj.getMaterial();
+   %text = "Material: " @ %matName;
    for(%i=0; %i<8; %i++)
    {
       if(%obj.probability[%i] > 0 && %obj.shapeFilename[%i] !$= "")

+ 1 - 1
Templates/BaseGame/game/tools/worldEditor/scripts/editor.keybinds.tscript

@@ -79,4 +79,4 @@ GlobalActionMap.bind(keyboard, "tilde", toggleConsole);
 
 EditorMap.bind( mouse, "alt zaxis", editorWheelFadeScroll );
 
-EditorMap.bindCmd( keyboard, space, "", "AssetBrowser.toggleDialog();" );
+EditorMap.bindCmd( keyboard, "shift space", "", "AssetBrowser.toggleDialog();" );

+ 31 - 11
Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.tscript

@@ -204,8 +204,7 @@ function EditorNewLevel( %level )
    %saveFirst = false;
    if ( EditorIsDirty() )
    {
-      error(knob);
-      %saveFirst = toolsMessageBox("Mission Modified", "Would you like to save changes to the current mission \"" @
+      %saveFirst = MessageBox("Mission Modified", "Would you like to save changes to the current mission \"" @
          $Server::MissionFile @ "\" before creating a new mission?", "SaveDontSave", "Question") == $MROk;
    }
       
@@ -300,7 +299,7 @@ function EditorSaveMission()
    // first check for dirty and read-only files:
    if((EWorldEditor.isDirty || ETerrainEditor.isMissionDirty) && !isWriteableFileName($Server::MissionFile))
    {
-      toolsMessageBox("Error", "Mission file \""@ $Server::MissionFile @ "\" is read-only.  Continue?", "Ok", "Stop");
+      MessageBox("Error", "Mission file \""@ $Server::MissionFile @ "\" is read-only.  Continue?", "Ok", "Stop");
       return false;
    }
    if(ETerrainEditor.isDirty)
@@ -310,9 +309,18 @@ function EditorSaveMission()
 
       while ((%terrainObject = containerSearchNext()) != 0)
       {
-         if (!isWriteableFileName(%terrainObject.terrainFile))
+         %terrFile = %terrainObject.getTerrain();
+         if(AssetDatabase.isDeclaredAsset(%terrFile))
          {
-            if (toolsMessageBox("Error", "Terrain file \""@ %terrainObject.terrainFile @ "\" is read-only.  Continue?", "Ok", "Stop") == $MROk)
+            %assetDef = AssetDatabase.acquireAsset(%terrFile);  
+            %file = %assetDef.getTerrainFilePath();
+            AssetDatabase.releaseAsset(%terrFile);
+            %terrFile = %file;
+         }
+         
+         if (!isWriteableFileName(%terrFile))
+         {
+            if (MessageBox("Error", "Terrain file \""@ %terrainObject.terrainFile @ "\" is read-only.  Continue?", "Ok", "Stop") == $MROk)
                continue;
             else
                return false;
@@ -497,12 +505,12 @@ function EditorOpenMission(%levelAsset)
    if( EditorIsDirty())
    {
       // "EditorSaveBeforeLoad();", "getLoadFilename(\"*.mis\", \"EditorDoLoadMission\");"
-      if(toolsMessageBox("Mission Modified", "Would you like to save changes to the current mission \"" @
+      if(MessageBox("Mission Modified", "Would you like to save changes to the current mission \"" @
          $Server::MissionFile @ "\" before opening a new mission?", SaveDontSave, Question) == $MROk)
       {
-         if(! EditorSaveMission())
-            return;
-      }
+      if(!EditorSaveMission())
+        return;
+   }
    }
 
    if(%levelAsset $= "")
@@ -779,8 +787,20 @@ function makeSelectedAMesh(%assetId)
 function EditorTakeControlOfEntity()
 {
    %object = EWorldEditor.getSelectedObject(0);
-   switchCamera(localClientConnection, %object);
-   switchControlObject(localClientConnection, %object);  
+   if(isObject(%object) && %object.getClassName() !$= "Camera")
+   {
+      $Editor::previousControlObject = localClientConnection.getControlObject(); 
+      localClientConnection.setControlObject(%object);
+
+   }
+}
+
+function EditorReleaseControlOfEntity()
+{
+   if(isObject($Editor::previousControlObject))
+   {
+      localClientConnection.setControlObject($Editor::previousControlObject);
+   }
 }
 
 function EditorMount()

+ 5 - 3
Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.tscript

@@ -459,9 +459,11 @@ function EditorGui::buildMenus(%this)
          Item[18] = "Explode Selected Prefab" TAB "" TAB "EditorExplodePrefab();";
          Item[19] = "-";
          Item[20] = "Take control of entity" TAB "" TAB "EditorTakeControlOfEntity();";
-         Item[21] = "-";
-         Item[22] = "Mount Selection A to B" TAB "" TAB "EditorMount();";
-         Item[23] = "Unmount Selected Object" TAB "" TAB "EditorUnmount();";
+         Item[21] = "Release control of entity" TAB "" TAB "EditorReleaseControlOfEntity();";
+
+         Item[22] = "-";
+         Item[23] = "Mount Selection A to B" TAB "" TAB "EditorMount();";
+         Item[24] = "Unmount Selected Object" TAB "" TAB "EditorUnmount();";
       };
    }
 }