diff --git a/Engine/source/T3D/Scene.cpp b/Engine/source/T3D/Scene.cpp index d8061f32b..0d7908fe3 100644 --- a/Engine/source/T3D/Scene.cpp +++ b/Engine/source/T3D/Scene.cpp @@ -391,6 +391,21 @@ Vector Scene::getObjectsByClass(String className) return Vector(); } +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); +} diff --git a/Engine/source/T3D/Scene.h b/Engine/source/T3D/Scene.h index d99b1f4b9..8f48b80b1 100644 --- a/Engine/source/T3D/Scene.h +++ b/Engine/source/T3D/Scene.h @@ -93,6 +93,8 @@ public: template Vector getObjectsByClass(); + void loadAtPosition(const Point3F& position); + static Scene *getRootScene() { if (Scene::smSceneList.empty()) diff --git a/Engine/source/T3D/SubScene.cpp b/Engine/source/T3D/SubScene.cpp index 5b93c473d..59f68d3dd 100644 --- a/Engine/source/T3D/SubScene.cpp +++ b/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) diff --git a/Engine/source/T3D/SubScene.h b/Engine/source/T3D/SubScene.h index 5347a08b7..53c8b1296 100644 --- a/Engine/source/T3D/SubScene.h +++ b/Engine/source/T3D/SubScene.h @@ -38,6 +38,7 @@ private: S32 mStartUnloadTimerMS; bool mLoaded; + String mLoadIf; bool mGlobalLayer; public: diff --git a/Engine/source/T3D/gameMode.cpp b/Engine/source/T3D/gameMode.cpp index 404f13624..0032b12ad 100644 --- a/Engine/source/T3D/gameMode.cpp +++ b/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") { - char* returnBuffer = Con::getReturnBuffer(1024); + return object->isActive(); +} - String formattedList; +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*, (), , "") +{ + ArrayObject* dictionary = new ArrayObject(); + dictionary->registerObject(); + + char activeValBuffer[16]; for (SimGroup::iterator itr = Sim::getRootGroup()->begin(); itr != Sim::getRootGroup()->end(); itr++) { GameMode* gm = dynamic_cast(*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; } //----------------------------------------------------------------------------- diff --git a/Engine/source/T3D/gameMode.h b/Engine/source/T3D/gameMode.h index 85958620e..9ebde69ed 100644 --- a/Engine/source/T3D/gameMode.h +++ b/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* outGameModes); diff --git a/Templates/BaseGame/game/core/utility/scripts/scene.tscript b/Templates/BaseGame/game/core/utility/scripts/scene.tscript index 4062c4749..2d8897dee 100644 --- a/Templates/BaseGame/game/core/utility/scripts/scene.tscript +++ b/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; } \ No newline at end of file diff --git a/Templates/BaseGame/game/data/UI/guis/ChooseLevelMenu.gui b/Templates/BaseGame/game/data/UI/guis/ChooseLevelMenu.gui index 7bc485001..8fb0928e2 100644 --- a/Templates/BaseGame/game/data/UI/guis/ChooseLevelMenu.gui +++ b/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"; diff --git a/Templates/BaseGame/game/data/UI/guis/ChooseLevelMenu.tscript b/Templates/BaseGame/game/data/UI/guis/ChooseLevelMenu.tscript index 3d949d870..ac1b9d782 100644 --- a/Templates/BaseGame/game/data/UI/guis/ChooseLevelMenu.tscript +++ b/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) { - %btn = %this.getObject(%this.listPosition); - %btn.setHighlighted(true); + 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); + } - $pref::Server::GameMode = %btn.gameModeObject; + %btn = %this.getObject(%this.listPosition); + %btn-->button.setHighlighted(true); + + //$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; diff --git a/Templates/BaseGame/game/data/UI/images/toggleMarker.png b/Templates/BaseGame/game/data/UI/images/toggleMarker.png new file mode 100644 index 000000000..6d3a0dfd4 Binary files /dev/null and b/Templates/BaseGame/game/data/UI/images/toggleMarker.png differ diff --git a/Templates/BaseGame/game/data/UI/images/toggleMarker_h.png b/Templates/BaseGame/game/data/UI/images/toggleMarker_h.png new file mode 100644 index 000000000..d97740823 Binary files /dev/null and b/Templates/BaseGame/game/data/UI/images/toggleMarker_h.png differ diff --git a/Templates/BaseGame/game/data/UI/images/toggleMarker_h_image.asset.taml b/Templates/BaseGame/game/data/UI/images/toggleMarker_h_image.asset.taml new file mode 100644 index 000000000..57c53f354 --- /dev/null +++ b/Templates/BaseGame/game/data/UI/images/toggleMarker_h_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/data/UI/images/toggleMarker_image.asset.taml b/Templates/BaseGame/game/data/UI/images/toggleMarker_image.asset.taml new file mode 100644 index 000000000..d8b681616 --- /dev/null +++ b/Templates/BaseGame/game/data/UI/images/toggleMarker_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/gameMode.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/gameMode.tscript index e58be2c7f..ae5e59b3e 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/gameMode.tscript +++ b/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 @ "\");"; +function GameModeType::buildBrowserElement(%this, %className, %previewData) +{ + //echo("DatablockObjectType::buildBrowserElement() - " @ %datablock @ ", " @ %name @ ", " @ %previewData); + %previewData.assetName = %this.getName(); + %previewData.assetPath = %this.getFileName(); - %moduleScriptPath = makeFullPath(%moduleDef.ModuleScriptFilePath @ "." @ $TorqueScriptFileExtension); + %previewData.previewImage = "ToolsModule:genericAssetIcon_image"; - echo("Attempting exec insert for file: " @ %moduleScriptPath); + //Lets see if we have a icon for specifically for this datablock type + %dataClass = %this.getClassName(); + %dataClass = strreplace(%dataClass, "Data", ""); - %lineIdx = Tools::findInFile(%moduleScriptPath, "*function*" @ %moduleName @ "::initClient*"); - if(%lineIdx != -1) + %previewImage = "tools/classIcons/" @ %dataClass @ ".png"; + if(isFile(%previewImage)) { - 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); - } + %previewData.previewImage = %previewImage; } - %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); - } - } - - //and we'll go ahead and force execute the script file so the gamemode is 'available' for use immediately - exec(%scriptPath); - - if(isObject(%assetName)) - { - //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); - } - - return %scriptPath; + //%previewData.assetFriendlyName = %assetDef.assetName; + %previewData.assetDesc = %this; + %previewData.tooltip = "\nGameMode Name: " @ %previewData.assetName @ + "\nPath: " @ %previewData.assetPath; } \ No newline at end of file