Bläddra i källkod

Adds utility function and method to be able to enact a load of subscenes at a specific world position
Adds loadIf conditional logic to evaluate if a subscene is 'allowed' to load when tested
Adds isAlwaysActive to GameMode to be able to flag a gamemode as being defaulted to on and used automatically
Updated GetGameModesList function to return an arrayObject of the gamemodes found
Overhauled CallGameModeFunction to utilize the gamemodes list with active/alwaysActive modes being called against, rather than level-scanning
Updated ChooseLevelMenu to be able to toggle on/off multiple gamemodes with an image indicator if it's active or not

JeffR 11 månader sedan
förälder
incheckning
e4d07c7e8d

+ 21 - 0
Engine/source/T3D/Scene.cpp

@@ -391,6 +391,21 @@ Vector<SceneObject*> Scene::getObjectsByClass(String className)
    return Vector<SceneObject*>();
 }
 
+void Scene::loadAtPosition(const Point3F& position)
+{
+   for (U32 i = 0; i < mSubScenes.size(); i++)
+   {
+      Box3F testBox = Box3F(0.5);
+      testBox.setCenter(position);
+
+      if (mSubScenes[i]->testBox(testBox))
+      {
+         mSubScenes[i]->setUnloadTimeMS(-1);
+         mSubScenes[i]->load();
+      }
+   }
+}
+
 DefineEngineFunction(getScene, Scene*, (U32 sceneId), (0),
    "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")
@@ -489,3 +504,9 @@ DefineEngineMethod(Scene, save, bool, (const char* fileName), (""),
 {
    return object->saveScene(StringTable->insert(fileName));
 }
+
+DefineEngineMethod(Scene, loadAtPosition, void, (Point3F position), (Point3F::Zero),
+   "Loads any subscenes at a given point by force.\n")
+{
+   object->loadAtPosition(position);
+}

+ 2 - 0
Engine/source/T3D/Scene.h

@@ -93,6 +93,8 @@ public:
    template <class T>
    Vector<T*> getObjectsByClass();
 
+   void loadAtPosition(const Point3F& position);
+
    static Scene *getRootScene() 
    { 
       if (Scene::smSceneList.empty())

+ 13 - 3
Engine/source/T3D/SubScene.cpp

@@ -49,6 +49,7 @@ void SubScene::initPersistFields()
    addGroup("SubScene");
    addField("isGlobalLayer", TypeBool, Offset(mGlobalLayer, SubScene), "");
    INITPERSISTFIELD_LEVELASSET(Level, SubScene, "The level asset to load.");
+   addField("loadIf", TypeCommand, Offset(mLoadIf, SubScene), "evaluation condition (true/false)");
    addField("gameModes", TypeGameModeList, Offset(mGameModesNames, SubScene), "The game modes that this subscene is associated with.");
    endGroup("SubScene");
 
@@ -143,9 +144,18 @@ bool SubScene::testBox(const Box3F& testBox)
    if (mGlobalLayer)
       return true;
 
-   bool isOverlapped = getWorldBox().isOverlapped(testBox);
-      
-   return getWorldBox().isOverlapped(testBox);
+   bool passes = getWorldBox().isOverlapped(testBox);
+   if (passes && !mLoadIf.isEmpty())
+   {
+      //test the mapper plugged in condition line
+      String resVar = getIdString() + String(".result");
+      Con::setBoolVariable(resVar.c_str(), false);
+      String command = resVar + "=" + mLoadIf + ";";
+      Con::evaluatef(command.c_str());
+      passes = Con::getBoolVariable(resVar.c_str());
+   }
+
+   return passes;
 }
 
 void SubScene::write(Stream& stream, U32 tabStop, U32 flags)

+ 1 - 0
Engine/source/T3D/SubScene.h

@@ -38,6 +38,7 @@ private:
    S32 mStartUnloadTimerMS;
 
    bool mLoaded;
+   String mLoadIf;
 
    bool mGlobalLayer;
 public:

+ 32 - 8
Engine/source/T3D/gameMode.cpp

@@ -4,6 +4,8 @@
 #include "gui/containers/guiDynamicCtrlArrayCtrl.h"
 #endif
 
+#include "console/arrayObject.h"
+
 IMPLEMENT_CONOBJECT(GameMode);
 
 IMPLEMENT_CALLBACK(GameMode, onActivated, void, (), (),
@@ -47,7 +49,9 @@ ConsoleSetType(TypeGameModeList)
 
 GameMode::GameMode() :
    mGameModeName(StringTable->EmptyString()),
-   mGameModeDesc(StringTable->EmptyString())
+   mGameModeDesc(StringTable->EmptyString()),
+   mIsActive(false),
+   mIsAlwaysActive(false)
 {
    INIT_ASSET(PreviewImage);
 }
@@ -62,6 +66,7 @@ void GameMode::initPersistFields()
      INITPERSISTFIELD_IMAGEASSET(PreviewImage, GameMode, "Preview Image");
 
      addField("active", TypeBool, Offset(mIsActive, GameMode), "Is the gamemode active");
+     addField("alwaysActive", TypeBool, Offset(mIsAlwaysActive, GameMode), "Is the gamemode always active");
 }
 
 bool GameMode::onAdd()
@@ -110,6 +115,11 @@ void GameMode::setActive(const bool& active)
       onDeactivated_callback();
 }
 
+void GameMode::setAlwaysActive(const bool& alwaysActive)
+{
+   mIsAlwaysActive = alwaysActive;
+}
+
 DefineEngineMethod(GameMode, isActive, bool, (), ,
    "Returns if the GameMode is currently active.\n"
    "@return The active status of the GameMode")
@@ -124,24 +134,38 @@ DefineEngineMethod(GameMode, setActive, void, (bool active), (true),
    object->setActive(active);
 }
 
-DefineEngineFunction(getGameModesList, const char*, (), , "")
+DefineEngineMethod(GameMode, isALwaysActive, bool, (), ,
+   "Returns if the GameMode is currently active.\n"
+   "@return The active status of the GameMode")
+{
+   return object->isActive();
+}
+
+DefineEngineMethod(GameMode, setAlwaysActive, void, (bool alwaysActive), (true),
+   "Sets the active state of the GameMode.\n"
+   "@param active A bool of the state the GameMode should be set to")
+{
+   object->setAlwaysActive(alwaysActive);
+}
+
+DefineEngineFunction(getGameModesList, ArrayObject*, (), , "")
 {
-   char* returnBuffer = Con::getReturnBuffer(1024);
+   ArrayObject* dictionary = new ArrayObject();
+   dictionary->registerObject();
 
-   String formattedList;
+   char activeValBuffer[16];
 
    for (SimGroup::iterator itr = Sim::getRootGroup()->begin(); itr != Sim::getRootGroup()->end(); itr++)
    {
       GameMode* gm = dynamic_cast<GameMode*>(*itr);
       if (gm)
       {
-         formattedList += String(gm->getName()) + ";";
+         dSprintf(activeValBuffer, 16, "%d", (gm->mIsActive || gm->mIsAlwaysActive));
+         dictionary->push_back(gm->getName(), activeValBuffer);
       }
    }
 
-   dSprintf(returnBuffer, 1024, "%s", formattedList.c_str());
-
-   return returnBuffer;
+   return dictionary;
 }
 
 //-----------------------------------------------------------------------------

+ 4 - 0
Engine/source/T3D/gameMode.h

@@ -22,6 +22,7 @@ private:
    DECLARE_ASSET_SETGET(GameMode, PreviewImage);
 
    bool mIsActive;
+   bool mIsAlwaysActive;
 
 public:
 
@@ -34,6 +35,9 @@ public:
    bool isActive() { return mIsActive; }
    void setActive(const bool& active);
 
+   bool isAlwaysActive() { return mIsAlwaysActive; }
+   void setAlwaysActive(const bool& alwaysActive);
+
    DECLARE_CONOBJECT(GameMode);
 
    static void findGameModes(const char* gameModeList, Vector<GameMode*>* outGameModes);

+ 14 - 44
Templates/BaseGame/game/core/utility/scripts/scene.tscript

@@ -1,52 +1,22 @@
 function callGamemodeFunction(%gameModeFuncName, %arg0, %arg1, %arg2, %arg3, %arg4, %arg5, %arg6)
 {
-   %activeSceneCount = getSceneCount();
-      
-   %hasGameMode = 0;
-   for(%i=0; %i < %activeSceneCount; %i++)
+   %validGameModeCall = false;
+   %gamemodeList = getGameModesList();
+   %gameModeCount = %gamemodeList.count();
+   for(%i=0; %i < %gameModeCount; %i++)
    {
-      %gamemodeName = getScene(%i).gameModeName;
-      if(%gamemodeName !$= "")
+      %gameModeObj = %gamemodeList.getKey(%i);
+      %active = %gamemodeList.getValue(%i);
+      
+      if(!isObject(%gameModeObj) || !%active)
+         continue;
+      
+      if(%gameModeObj.isMethod(%gameModeFuncName))
       {
-         //if the scene defines a game mode, go ahead and envoke it here
-         if(isObject(%gamemodeName) && %gamemodeName.isMethod(%gameModeFuncName))
-         {
-            eval(%gamemodeName @ "."@%gameModeFuncName@"(\""@%arg0@"\", \""@%arg1@"\", \""@%arg2@"\", \""@%arg3@"\", \""@%arg4@"\", \""@%arg5@"\", \""@%arg6@"\");" );
-            %hasGameMode = 1;
-         }
-         else
-         {
-            //if we don't have an object, attempt the static call  
-            if(isMethod(%gamemodeName, %gameModeFuncName))
-            {
-               eval(%gamemodeName @ "::"@%gameModeFuncName@"(\""@%arg0@"\", \""@%arg1@"\", \""@%arg2@"\", \""@%arg3@"\", \""@%arg4@"\", \""@%arg5@"\", \""@%arg6@"\");" );
-               %hasGameMode = 1;
-            }
-         }
+         eval(%gameModeObj @ "."@%gameModeFuncName@"(\""@%arg0@"\", \""@%arg1@"\", \""@%arg2@"\", \""@%arg3@"\", \""@%arg4@"\", \""@%arg5@"\", \""@%arg6@"\");" );
+         %validGameModeCall = true;
       }
    }
    
-   //if none of our scenes have gamemodes, we need to kick off a default
-   if(%hasGameMode == 0)
-   {
-      %defaultModeName = ProjectSettings.value("Gameplay/GameModes/defaultModeName");
-      if(%defaultModeName !$= "")
-      {
-         if(isObject(%defaultModeName) && %defaultModeName.isMethod(%gameModeFuncName))
-         {
-            eval(%defaultModeName @ "."@%gameModeFuncName@"(\""@%arg0@"\", \""@%arg1@"\", \""@%arg2@"\", \""@%arg3@"\", \""@%arg4@"\", \""@%arg5@"\", \""@%arg6@"\");" );
-            %hasGameMode = 1;
-         }
-         else
-         {
-            if(isMethod(%defaultModeName, %gameModeFuncName))
-            {
-               eval(%defaultModeName @ "::"@%gameModeFuncName@"(\""@%arg0@"\", \""@%arg1@"\", \""@%arg2@"\", \""@%arg3@"\", \""@%arg4@"\", \""@%arg5@"\", \""@%arg6@"\");" );
-               %hasGameMode = 1;
-            }  
-         }
-      }
-   }  
-   
-   return %hasGameMode;
+   return %validGameModeCall;
 }

+ 15 - 12
Templates/BaseGame/game/data/UI/guis/ChooseLevelMenu.gui

@@ -11,7 +11,6 @@ $guiContent = new GuiControl(ChooseLevelMenu) {
    canSaveDynamicFields = "1";
       currentMenuIdx = "0";
       launchInEditor = "0";
-      previewButtonSize = "445 120";
 
    new GuiInputCtrl(ChooseLevelInputHandler) {
       ignoreMouseEvents = "1";
@@ -40,8 +39,8 @@ $guiContent = new GuiControl(ChooseLevelMenu) {
    new GuiStackControl(ChooseLevelMenuTabList) {
       stackingType = "Horizontal";
       padding = "10";
-      position = "405 61";
-      extent = "470 41";
+      position = "485 61";
+      extent = "310 41";
       horizSizing = "center";
       profile = "GuiDefaultProfile";
       tooltipProfile = "GuiToolTipProfile";
@@ -73,10 +72,12 @@ $guiContent = new GuiControl(ChooseLevelMenu) {
          position = "320 0";
          extent = "150 41";
          profile = "GuiMenuButtonProfile";
+         visible = "0";
          command = "ChooseLevelMenu.openMenu(2);";
          tooltipProfile = "GuiToolTipProfile";
          internalName = "ConfigBtn";
          class = "ChooseLevelMenuButton";
+         hidden = "1";
       };
    };
    new GuiControl(ChooseLevelMenuNavButtonOverlay) {
@@ -89,7 +90,7 @@ $guiContent = new GuiControl(ChooseLevelMenu) {
 
       new GuiBitmapCtrl(ChooseLevelMenuPrevNavIcon) {
          BitmapAsset = "UI:Keyboard_Black_Q_image";
-         position = "405 24";
+         position = "485 24";
          extent = "40 40";
          vertSizing = "top";
          profile = "GuiNonModalDefaultProfile";
@@ -97,7 +98,7 @@ $guiContent = new GuiControl(ChooseLevelMenu) {
       };
       new GuiBitmapCtrl(ChooseLevelMenuNextNavIcon) {
          BitmapAsset = "UI:Keyboard_Black_E_image";
-         position = "515 24";
+         position = "595 24";
          extent = "40 40";
          vertSizing = "top";
          profile = "GuiNonModalDefaultProfile";
@@ -121,8 +122,8 @@ $guiContent = new GuiControl(ChooseLevelMenu) {
 
          new GuiStackControl(GameModePreviewArray) {
             padding = "5";
-            position = "0 1";
-            extent = "445 120";
+            position = "1 1";
+            extent = "443 60";
             horizSizing = "width";
             vertSizing = "height";
             profile = "GuiMenuDefaultProfile";
@@ -130,15 +131,16 @@ $guiContent = new GuiControl(ChooseLevelMenu) {
          };
       };
       new GuiBitmapCtrl(GameModePreviewBitmap) {
-         BitmapAsset = "UI:no_preview_image";
          position = "448 0";
          extent = "440 440";
          horizSizing = "left";
          profile = "GuiNonModalDefaultProfile";
+         visible = "0";
          tooltipProfile = "GuiToolTipProfile";
+         hidden = "1";
       };
       new GuiTextCtrl(GameModeNameText) {
-         text = "Example Level";
+         text = "DeathMatchGame";
          position = "448 445";
          extent = "440 20";
          horizSizing = "left";
@@ -175,7 +177,7 @@ $guiContent = new GuiControl(ChooseLevelMenu) {
          new GuiStackControl(LevelPreviewArray) {
             padding = "5";
             position = "0 1";
-            extent = "445 120";
+            extent = "445 60";
             horizSizing = "width";
             vertSizing = "height";
             profile = "GuiMenuDefaultProfile";
@@ -277,6 +279,7 @@ $guiContent = new GuiControl(ChooseLevelMenu) {
                   tooltipProfile = "GuiToolTipProfile";
                };
                new GuiTextEditCtrl(serverNameCTRL) {
+                  text = "Torque 3D Server";
                   position = "606 4";
                   extent = "295 22";
                   horizSizing = "left";
@@ -374,8 +377,8 @@ $guiContent = new GuiControl(ChooseLevelMenu) {
       profile = "GuiMenuPanelProfile";
       tooltipProfile = "GuiToolTipProfile";
 
-      new GuiIconButtonCtrl(ChooseLevelStartBtn) {
-         BitmapAsset = "UI:Keyboard_Black_Space_image";
+      new GuiIconButtonCtrl(ChooseLevelNextBtn) {
+         BitmapAsset = "UI:Keyboard_Black_Blank_image";
          sizeIconToButton = "1";
          makeIconSquare = "1";
          textLocation = "Center";

+ 127 - 46
Templates/BaseGame/game/data/UI/guis/ChooseLevelMenu.tscript

@@ -25,7 +25,7 @@ function ChooseLevelMenu::onAdd( %this )
    if(!isObject(ChooseLevelAssetQuery))
       new AssetQuery(ChooseLevelAssetQuery);
       
-   %this.previewButtonSize = "445 120";
+   $LevelPreviewButtonSize = "445 60";
 }
 
 function ChooseLevelMenu::fillPrefEntries( %this )
@@ -40,9 +40,9 @@ function ChooseLevelMenu::fillPrefEntries( %this )
 function ChooseLevelMenu::onWake(%this)
 {
    %this.fillPrefEntries();
-   LevelPreviewArray.clear();
    
    refreshGameModesList();
+   refreshLevelsList();
 
    if(!$pref::HostMultiPlayer)
       ChooseLevelTitleText.setText("SINGLE PLAYER");
@@ -66,35 +66,48 @@ function refreshGameModesList()
    
    //popilate the gamemodes list first
    %gamemodeList = getGameModesList();
-   for(%i=0; %i < getTokenCount(%gamemodeList, ";"); %i++)
+   %gameModeCount = %gamemodeList.count();
+   
+   for (%i=0; %i<%gameModeCount; %i++)
    {
-      %gameModeObj = getToken(%gamemodeList, ";", %i);
-      
+      %gameModeObj = %gamemodeList.getKey(%i);
       if(isObject(%gameModeObj))
       {
          %gameModeName = %gameModeObj.gameModeName;
          if(%gameModeName $= "")
             %gameModeName = %gameModeObj.getName();
             
-         %preview = new GuiButtonCtrl() {
-            position = "0 0";
-            extent = ChooseLevelMenu.previewButtonSize;
-            buttonType = "PushButton";
-            profile = GuiMenuButtonLeftJustProfile;
-            horizSizing = "right";
-            vertSizing = "bottom";
-            internalName = "button";
-            class = "GameModePreviewButton";
-            //command = "ChooseGameModeBegin(" @ %i @ ");";
-            altCommand = "ChooseGameModeBegin(" @ %i @ ");"; //allow doubleclick to quick action it
-            text = %gameModeName;
-            gameModeObj = %gameModeObj;
-            gameModeDesc = %gameModeObj.description;
-            previewImage = %gameModeObj.previewImage;
-            textMargin = 120;
-            groupNum = 2;
-            cansave = false;
-         };
+            %preview = new GuiContainer() {
+               position = "0 0";
+               extent = $LevelPreviewButtonSize;
+               horizSizing = "right";
+               vertSizing = "bottom";
+               gameModeObj = %gameModeObj;
+               gameModeDesc = %gameModeObj.description;
+               previewImage = %gameModeObj.previewImage;
+               cansave = false;
+               
+               new GuiToggleButtonCtrl() {
+                  position = $LevelPreviewButtonSize.y SPC 0;
+                  extent = $LevelPreviewButtonSize.x - $LevelPreviewButtonSize.y - 5 SPC $LevelPreviewButtonSize.y;
+                  profile = GuiMenuButtonProfile;
+                  horizSizing = "right";
+                  vertSizing = "bottom";
+                  internalName = "button";
+                  class = "GameModePreviewButton";
+                  text = %gameModeName;
+                  command = "ToggleGameMode(" @ %i @ ");"; //allow doubleclick to quick action it
+                  textMargin = 120;
+               };
+               
+               new GuiBitmapCtrl() {
+                  position = "0 0";
+                  extent = $LevelPreviewButtonSize.y SPC $LevelPreviewButtonSize.y;
+                  internalName = "checkbox";
+                  bitmapAsset = "UI:toggleMarker_image";
+               };
+            };
+        
          
          GameModePreviewArray.add(%preview);
       }
@@ -122,6 +135,7 @@ function refreshLevelsList()
    }
    
    //filter the levelAssets by the gamemode selected
+   %filteredIndex = 0;
    for(%i=0; %i < %count; %i++)
 	{
 	   %assetId = ChooseLevelAssetQuery.getAsset(%i);
@@ -142,21 +156,26 @@ function refreshLevelsList()
       //filter for selected gamemode
       %levelGameModes = %levelAsset.gameModesNames;
       
-      echo("LevelAsset gamemodes: " @ %levelGameModes);
-      
       %foundGameModeMatch = false;
       for(%gm = 0; %gm < getTokenCount(%levelGameModes, ";"); %gm++)
       {
          %gameModeName = getToken(%levelGameModes, ";", %gm);
          
-         echo("testing gamemode: " @ %gameModeName);
-         echo("selected gamemode: " @ $pref::Server::GameMode.getName());
-         
-         if(%gameModeName $= $pref::Server::GameMode.getName())
+         for(%g=0; %g < GameModePreviewArray.getCount(); %g++)
          {
-            %foundGameModeMatch = true;
-            break;
+            %gmb = GameModePreviewArray.getObject(%g);
+            if(!isObject(%gmb.gameModeObj) || (!%gmb.gameModeObj.active && !%gmb.gameModeObj.alwaysActive))
+               continue;
+               
+            if(%gameModeName $= %gmb.gameModeObj.getName())
+            {
+               %foundGameModeMatch = true;
+               break;  
+            }
          }
+         
+         if(%foundGameModeMatch)
+            break;
       }
       
       if(!%foundGameModeMatch)
@@ -169,7 +188,7 @@ function refreshLevelsList()
          
       %preview = new GuiIconButtonCtrl() {
          position = "0 0";
-         extent = ChooseLevelMenu.previewButtonSize;
+         extent = $LevelPreviewButtonSize;
          buttonType = "PushButton";
          profile = GuiMenuButtonLeftJustProfile;
          horizSizing = "right";
@@ -177,7 +196,7 @@ function refreshLevelsList()
          internalName = "button";
          class = "LevelPreviewButton";
          //command = "$selectedLevelAsset = " @ %assetId @ ";";
-         altCommand = "ChooseLevelBegin(" @ %i @ ");"; //allow doubleclick to quick action it
+         altCommand = "ChooseLevelBegin(" @ %filteredIndex @ ");"; //allow doubleclick to quick action it
          text = %levelAsset.levelName;
          bitmapAsset = %levelPreviewImg;
          levelAsset = %levelAsset;
@@ -192,8 +211,11 @@ function refreshLevelsList()
       };
       
       LevelPreviewArray.add(%preview);
+      
+      %filteredIndex++;
    }
-   
+
+   GameModePreviewArray.listPosition = 0;   
    LevelPreviewArray.listPosition = 0;
    
    // Also add the new level mission as defined in the world editor settings
@@ -236,10 +258,31 @@ function ChooseLevelMenu::syncGUI(%this)
      
    ChooseLevelBackBtn.setBitmap(BaseUIActionMap.getCommandButtonBitmap(%device, "BaseUIBackOut"));
    
-   ChooseLevelStartBtn.setBitmap(ChooseLevelActionMap.getCommandButtonBitmap(%device, "ChooseLevelBegin"));
+   if(ChooseLevelMenu.currentMenuIdx == 0)
+      ChooseLevelNextBtn.text = "Toggle Mode";
+   else
+      ChooseLevelNextBtn.text = "Start Game";
+   
+   ChooseLevelNextBtn.setBitmap(ChooseLevelActionMap.getCommandButtonBitmap(%device, "ChooseLevelMenuOption"));
    
    ChooseLevelMenuPrevNavIcon.setBitmap(ChooseLevelActionMap.getCommandButtonBitmap(%device, "ChooseLevelMenuPrevMenu"));
    ChooseLevelMenuNextNavIcon.setBitmap(ChooseLevelActionMap.getCommandButtonBitmap(%device, "ChooseLevelMenuNextMenu"));
+   
+   %hasActiveGameMode = false;
+   for(%i=0; %i < GameModePreviewArray.getCount(); %i++)
+   {
+      %btn = GameModePreviewArray.getObject(%i);
+      if(!isObject(%btn.gameModeObj))
+         continue;
+         
+      if((%btn.gameModeObj.isActive() || %btn.gameModeObj.isAlwaysActive()) == true)
+      {
+         %hasActiveGameMode = true;
+         break;
+      }
+   }
+   
+   ChooseLevelMenuTabList-->LevelBtn.active = %hasActiveGameMode;
 }
 
 function LevelPreviewArray::syncGUI(%this)
@@ -252,10 +295,19 @@ function LevelPreviewArray::syncGUI(%this)
 
 function GameModePreviewArray::syncGUI(%this)
 {
+   for(%i=0; %i < %this.getCount(); %i++)
+   {
+      %btn = %this.getObject(%i);
+      %btn-->button.setHighlighted(false);
+      
+      %bitmapAst = (%btn.gameModeObj.active || %btn.gameModeObj.alwaysActive) ? "UI:toggleMarker_h_image" : "UI:toggleMarker_image";
+      %btn-->checkbox.setBitmap(%bitmapAst);
+   }
+   
    %btn = %this.getObject(%this.listPosition);
-   %btn.setHighlighted(true);
+   %btn-->button.setHighlighted(true);
    
-   $pref::Server::GameMode = %btn.gameModeObject;
+   //$pref::Server::GameMode = %btn.gameModeObject;
 }
 
 function ChooseLevelMenuPrevMenu(%val)
@@ -270,6 +322,13 @@ function ChooseLevelMenuPrevMenu(%val)
          %endIndex = 2;
       
       ChooseLevelMenu.currentMenuIdx = mClamp(ChooseLevelMenu.currentMenuIdx, 0, %endIndex);
+      
+      //bail if we're trying to step into a hidden or disabled menu
+      if(!ChooseLevelMenu.isMenuAvailable(ChooseLevelMenu.currentMenuIdx))
+      {
+         ChooseLevelMenu.currentMenuIdx = %currentIdx;
+         return;
+      }
     
       if(%currentIdx == ChooseLevelMenu.currentMenuIdx)
          return;
@@ -290,6 +349,13 @@ function ChooseLevelMenuNextMenu(%val)
          %endIndex = 2;
       
       ChooseLevelMenu.currentMenuIdx = mClamp(ChooseLevelMenu.currentMenuIdx, 0, %endIndex);
+      
+      //bail if we're trying to step into a hidden or disabled menu
+      if(!ChooseLevelMenu.isMenuAvailable(ChooseLevelMenu.currentMenuIdx))
+      {
+         ChooseLevelMenu.currentMenuIdx = %currentIdx;
+         return;
+      }
     
       if(%currentIdx == ChooseLevelMenu.currentMenuIdx)
          return;
@@ -319,33 +385,48 @@ function ChooseLevelMenu::openMenu(%this, %menuIdx)
    %this.syncGui();
 }
 
+function ChooseLevelMenu::isMenuAvailable(%this, %menuIdx)
+{
+   if(%menuIdx == 0)
+      %btn = %this-->GameModeBtn;
+   else if(%menuIdx == 1)
+      %btn = %this-->LevelBtn;
+   else if(%menuIdx == 2)
+      %btn = %this-->ConfigBtn;
+      
+   return %btn.isActive() && %btn.isVisible();
+}
+
 function ChooseLevelMenuOption(%val)
 {
    if(%val)
    {
       if(ChooseLevelMenu.currentMenuIdx == 0)
-         ChooseGameModeBegin(ChooseLevelMenu.listPosition);
+         ToggleGameMode(ChooseLevelMenu.listPosition);
       else if(ChooseLevelMenu.currentMenuIdx == 1)
          ChooseLevelBegin(ChooseLevelMenu.listPosition);
    }
 }
 
-function ChooseGameModeBegin(%index)
+function ToggleGameMode(%index)
 {
+   if(%index $= "")
+      %index = $MenuList.listPosition;
+   
    %entry = GameModePreviewArray.getObject(%index);
    if(!isObject(%entry) || !isObject(%entry.gameModeObj))
    {
       MessageBoxOK("Error", "Selected game mode does not have a valid mode");
       return; 
    }
-
-   $pref::Server::GameMode = %entry.gameModeObj;
-
-   ChooseLevelMenuTabList-->LevelBtn.active = true;
+   
+   %entry.gameModeObj.active = !%entry.gameModeObj.active;
    
    refreshLevelsList();
    
-   ChooseLevelMenu.openMenu(1);
+   $MenuList.syncGui();
+   ChooseLevelMenu.syncGui();
+   
 }
 
 function ChooseLevelBegin(%index)
@@ -399,7 +480,7 @@ function GameModePreviewButton::onHighlighted(%this, %highlighted)
 {
    if(%highlighted)
    {
-      $MenuList.listPosition = $MenuList.getObjectIndex(%this);
+      $MenuList.listPosition = $MenuList.getObjectIndex(%this.getParent());
       
       GameModePreviewBitmap.bitmapAsset = %this.previewImage;
       

BIN
Templates/BaseGame/game/data/UI/images/toggleMarker.png


BIN
Templates/BaseGame/game/data/UI/images/toggleMarker_h.png


+ 3 - 0
Templates/BaseGame/game/data/UI/images/toggleMarker_h_image.asset.taml

@@ -0,0 +1,3 @@
+<ImageAsset
+    AssetName="toggleMarker_h_image"
+    imageFile="@assetFile=toggleMarker_h.png"/>

+ 3 - 0
Templates/BaseGame/game/data/UI/images/toggleMarker_image.asset.taml

@@ -0,0 +1,3 @@
+<ImageAsset
+    AssetName="toggleMarker_image"
+    imageFile="@assetFile=toggleMarker.png"/>

+ 23 - 84
Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/gameMode.tscript

@@ -1,96 +1,35 @@
-function AssetBrowser::createGameMode(%this)
+AssetBrowser::registerObjectType("GameModeType", "Gamemode Objects", "Gamemode");
+
+function GameModeType::setupCreateNew()
 {
-   %moduleName = AssetBrowser.newAssetSettings.moduleName;
-   %moduleDef = ModuleDatabase.findModule(%moduleName, 1);
-      
-   %assetName = AssetBrowser.newAssetSettings.assetName;   
-   %assetPath = NewAssetTargetAddress.getText() @ "/";
    
-   %scriptPath = %assetPath @ %assetName @ "." @ $TorqueScriptFileExtension;
-   %fullScriptPath = makeFullPath(%scriptPath);
+}
 
-   %file = new FileObject();
-	%templateFile = new FileObject();
-	
-   %postFXTemplateCodeFilePath = %this.templateFilesPath @ "gameMode." @ $TorqueScriptFileExtension @ ".template";
+function GameModeType::onCreateNew()
+{
    
-   if(%file.openForWrite(%fullScriptPath) && %templateFile.openForRead(%postFXTemplateCodeFilePath))
-   {
-      while( !%templateFile.isEOF() )
-      {
-         %line = %templateFile.readline();
-         %line = strreplace( %line, "@@", %assetName );
-         
-         %file.writeline(%line);
-      }
-      
-      %file.close();
-      %templateFile.close();
-   }
-   else
-   {
-      %file.close();
-      %templateFile.close();
-      
-      warnf("createGameMode - Something went wrong and we couldn't write the gameMode script file!");
-   }
+}
 
-   %localScriptPath = strReplace(%scriptPath, "data/" @ %moduleName @ "/", "./");
-   %execLine = "   %this.queueExec(\"" @ %localScriptPath @ "\");";
-   
-   %moduleScriptPath = makeFullPath(%moduleDef.ModuleScriptFilePath @ "." @ $TorqueScriptFileExtension);
-   
-   echo("Attempting exec insert for file: " @ %moduleScriptPath);
-   
-   %lineIdx = Tools::findInFile(%moduleScriptPath, "*function*" @ %moduleName @ "::initClient*");
-   if(%lineIdx != -1)
-   {
-      echo("INIT CLIENT FUNCTION LINE FOUND ON: " @ %lineIdx);
-      
-      %insertLineIdx = Tools::findInFunction(%moduleScriptPath, %moduleName, "initClient", "*//--FILE EXEC END--*");
-      echo("FILE EXEC END LINE FOUND ON: " @ %insertLineIdx);
-      
-      if(%insertLineIdx == -1)
-      {
-         //If there are not 'blocking' comments, then just slap the exec on the end of the function def
-         //as it doesn't really matter now
-         Tools::appendLineToFunction(%moduleScriptPath, %moduleName, "initClient", %execLine);
-      }
-      else
-      {
-         Tools::insertInFile(%moduleScriptPath, %insertLineIdx, %execLine, true);
-      }
-   }
+function GameModeType::buildBrowserElement(%this, %className, %previewData)
+{
+   //echo("DatablockObjectType::buildBrowserElement() - " @ %datablock @ ", " @ %name @ ", " @ %previewData);
+   %previewData.assetName = %this.getName();
+   %previewData.assetPath = %this.getFileName();
    
-   %lineIdx = Tools::findInFile(%moduleScriptPath, "*function*" @ %moduleName @ "::initServer*");
-   if(%lineIdx != -1)
-   {
-      echo("INIT SERVER FUNCTION LINE FOUND ON: " @ %lineIdx);
-      
-      %insertLineIdx = Tools::findInFunction(%moduleScriptPath, %moduleName, "initServer", "*//--FILE EXEC END--*");
-      echo("FILE EXEC END LINE FOUND ON: " @ %insertLineIdx);
-      
-      if(%insertLineIdx == -1)
-      {
-         //If there are not 'blocking' comments, then just slap the exec on the end of the function def
-         //as it doesn't really matter now
-         Tools::appendLineToFunction(%moduleScriptPath, %moduleName, "initServer", %execLine);
-      }
-      else
-      {
-         Tools::insertInFile(%moduleScriptPath, %insertLineIdx, %execLine, true);
-      }
-   }
+   %previewData.previewImage = "ToolsModule:genericAssetIcon_image";
    
-   //and we'll go ahead and force execute the script file so the gamemode is 'available' for use immediately
-   exec(%scriptPath);
+   //Lets see if we have a icon for specifically for this datablock type
+   %dataClass = %this.getClassName();
+   %dataClass = strreplace(%dataClass, "Data", "");
    
-   if(isObject(%assetName))
+   %previewImage = "tools/classIcons/" @ %dataClass @ ".png";
+   if(isFile(%previewImage))
    {
-      //it's possible it got moved to an instant group upon execution, so we'll just 
-      //shove it back to the RootGroup by force to be 100% sure
-      RootGroup.add(%assetName); 
+      %previewData.previewImage = %previewImage;
    }
    
-	return %scriptPath;
+   //%previewData.assetFriendlyName = %assetDef.assetName;
+   %previewData.assetDesc = %this;
+   %previewData.tooltip =  "\nGameMode Name: " @ %previewData.assetName @ 
+                           "\nPath: " @ %previewData.assetPath;
 }