mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-19 20:24:49 +00:00
Fixes behavior with gamemode selection in ChooseLevelMenu so if there is only one gamemode, it is auto-selected and advances to the level selection Update ExampleLevel in ExampleModule to have updated gamemodes field name
539 lines
16 KiB
Plaintext
539 lines
16 KiB
Plaintext
//-----------------------------------------------------------------------------
|
|
// Copyright (c) 2012 GarageGames, LLC
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to
|
|
// deal in the Software without restriction, including without limitation the
|
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
// sell copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
// IN THE SOFTWARE.
|
|
//-----------------------------------------------------------------------------
|
|
//----------------------------------------
|
|
function ChooseLevelMenu::onAdd( %this )
|
|
{
|
|
if(!isObject(ChooseLevelAssetQuery))
|
|
new AssetQuery(ChooseLevelAssetQuery);
|
|
|
|
$LevelPreviewButtonSize = "445 60";
|
|
}
|
|
|
|
function ChooseLevelMenu::fillPrefEntries( %this )
|
|
{
|
|
playerNameCTRL.setText($Pref::Player::Name);
|
|
serverNameCTRL.setText($Pref::Server::Name);
|
|
serverPassCTRL.setText($Pref::Server::Password);
|
|
serverInfoCTRL.setText($Pref::Server::Info);
|
|
serverMaxPlayersCTRL.setText($Pref::Server::MaxPlayers);
|
|
}
|
|
|
|
function ChooseLevelMenu::onWake(%this)
|
|
{
|
|
%this.fillPrefEntries();
|
|
|
|
refreshGameModesList();
|
|
refreshLevelsList();
|
|
|
|
if(!$pref::HostMultiPlayer)
|
|
ChooseLevelTitleText.setText("SINGLE PLAYER");
|
|
else
|
|
ChooseLevelTitleText.setText("CREATE SERVER");
|
|
|
|
ChooseLevelMenuTabList-->ConfigBtn.visible = $pref::HostMultiPlayer;
|
|
|
|
ChooseLevelMenuTabList.visible = true;//$pref::HostMultiPlayer;
|
|
ChooseLevelMenuNavButtonOverlay.visible = true;//$pref::HostMultiPlayer;
|
|
|
|
//If we've only got one gamemode, just force it to use that one, as we can
|
|
//assume that is THE game's gamemode
|
|
%gamemodeList = getGameModesList();
|
|
if(%gamemodeList.count() == 1)
|
|
{
|
|
%gameModeObj = %gamemodeList.getKey(0);
|
|
if(isObject(%gameModeObj))
|
|
{
|
|
%gameModeObj.active = true;
|
|
|
|
ChooseLevelMenuTabList-->LevelBtn.active = true;
|
|
ChooseLevelMenuTabList-->GameModeBtn.active = false;
|
|
|
|
ChooseLevelMenu.openMenu(1);
|
|
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//Otherwise open the gamemode list as normal
|
|
%this.schedule(32, openMenu, 0);
|
|
}
|
|
}
|
|
|
|
function refreshGameModesList()
|
|
{
|
|
GameModePreviewArray.clear();
|
|
|
|
$pref::Server::GameMode = "";
|
|
ChooseLevelMenuTabList-->LevelBtn.active = false;
|
|
|
|
//popilate the gamemodes list first
|
|
%gamemodeList = getGameModesList();
|
|
%gameModeCount = %gamemodeList.count();
|
|
|
|
for (%i=0; %i<%gameModeCount; %i++)
|
|
{
|
|
%gameModeObj = %gamemodeList.getKey(%i);
|
|
if(isObject(%gameModeObj))
|
|
{
|
|
%gameModeName = %gameModeObj.gameModeName;
|
|
if(%gameModeName $= "")
|
|
%gameModeName = %gameModeObj.getName();
|
|
|
|
%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);
|
|
}
|
|
}
|
|
}
|
|
|
|
function refreshLevelsList()
|
|
{
|
|
LevelPreviewArray.clear();
|
|
|
|
//fetch the levelAssets
|
|
ChooseLevelAssetQuery.clear();
|
|
AssetDatabase.findAssetType(ChooseLevelAssetQuery, "LevelAsset");
|
|
|
|
%count = ChooseLevelAssetQuery.getCount();
|
|
|
|
if(%count == 0 && !IsDirectory("tools"))
|
|
{
|
|
//We have no levels found. Prompt the user to open the editor to the default level if the tools are present
|
|
MessageBoxOK("Error", "No levels were found in any modules. Please ensure you have modules loaded that contain gameplay code and level files.",
|
|
"Canvas.popDialog(ChooseLevelMenu); if(isObject(ChooseLevelMenu.returnGui) && ChooseLevelMenu.returnGui.isMethod(\"onReturnTo\")) ChooseLevelMenu.returnGui.onReturnTo();");
|
|
|
|
ChooseLevelAssetQuery.clear();
|
|
return;
|
|
}
|
|
|
|
%gameModesList = getGameModesList();
|
|
|
|
//filter the levelAssets by the gamemode selected
|
|
%filteredIndex = 0;
|
|
for(%i=0; %i < %count; %i++)
|
|
{
|
|
%assetId = ChooseLevelAssetQuery.getAsset(%i);
|
|
|
|
if(AssetDatabase.getAssetModule(%assetId).ModuleId $= "ToolsModule")
|
|
continue;
|
|
|
|
%levelAsset = AssetDatabase.acquireAsset(%assetId);
|
|
|
|
%file = %levelAsset.getLevelPath();
|
|
|
|
if ( !isFile(%file) )
|
|
continue;
|
|
|
|
if( %levelAsset.isSubScene )
|
|
continue;
|
|
|
|
//filter for selected gamemode
|
|
%levelGameModes = %levelAsset.gameModesNames;
|
|
|
|
//If the level has no gamemodes defined, we just assume the default case of it being a wildcard to whatever gamemode
|
|
//is available
|
|
if(%levelGameModes $= "")
|
|
{
|
|
%foundGameModeMatch = true;
|
|
}
|
|
else
|
|
{
|
|
%foundGameModeMatch = false;
|
|
for(%gm = 0; %gm < getTokenCount(%levelGameModes, ";"); %gm++)
|
|
{
|
|
%gameModeName = getToken(%levelGameModes, ";", %gm);
|
|
for(%g=0; %g < %gameModesList.count(); %g++)
|
|
{
|
|
%gameModeObj = %gameModesList.getKey(%g);
|
|
|
|
if(!isObject(%gameModeObj) || (!%gameModeObj.active && !%gameModeObj.alwaysActive && %gameModesList.count() > 1))
|
|
continue;
|
|
|
|
if(%gameModeName $= %gameModeObj.getName())
|
|
{
|
|
%foundGameModeMatch = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(%foundGameModeMatch)
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(!%foundGameModeMatch)
|
|
continue;
|
|
|
|
%levelPreviewImg = %levelAsset.getPreviewImagePath();
|
|
|
|
if (!isFile(%levelPreviewImg))
|
|
%levelPreviewImg = "UI:no_preview_image";
|
|
|
|
%preview = new GuiIconButtonCtrl() {
|
|
position = "0 0";
|
|
extent = $LevelPreviewButtonSize;
|
|
buttonType = "PushButton";
|
|
profile = GuiMenuButtonLeftJustProfile;
|
|
horizSizing = "right";
|
|
vertSizing = "bottom";
|
|
internalName = "button";
|
|
class = "LevelPreviewButton";
|
|
//command = "$selectedLevelAsset = " @ %assetId @ ";";
|
|
altCommand = "ChooseLevelBegin(" @ %filteredIndex @ ");"; //allow doubleclick to quick action it
|
|
text = %levelAsset.levelName;
|
|
bitmapAsset = %levelPreviewImg;
|
|
levelAsset = %levelAsset;
|
|
levelAssetId = %assetId;
|
|
iconLocation = "left";
|
|
sizeIconToButton = true;
|
|
makeIconSquare = true;
|
|
textLocation = "left";
|
|
textMargin = 120;
|
|
groupNum = 2;
|
|
cansave = false;
|
|
};
|
|
|
|
LevelPreviewArray.add(%preview);
|
|
|
|
%filteredIndex++;
|
|
}
|
|
|
|
GameModePreviewArray.listPosition = 0;
|
|
LevelPreviewArray.listPosition = 0;
|
|
|
|
// Also add the new level mission as defined in the world editor settings
|
|
// if we are choosing a level to launch in the editor.
|
|
if ( ChooseLevelMenu.launchInEditor )
|
|
{
|
|
ChooseLevelMenu.addMissionFile( "tools/levels/DefaultEditorLevel.mis" );
|
|
}
|
|
}
|
|
|
|
if(!isObject( ChooseLevelActionMap ) )
|
|
{
|
|
new ActionMap(ChooseLevelActionMap){};
|
|
|
|
ChooseLevelActionMap.bind( keyboard, q, ChooseLevelMenuPrevMenu);
|
|
ChooseLevelActionMap.bind( gamepad, btn_l, ChooseLevelMenuPrevMenu);
|
|
|
|
ChooseLevelActionMap.bind( keyboard, e, ChooseLevelMenuNextMenu);
|
|
ChooseLevelActionMap.bind( gamepad, btn_r, ChooseLevelMenuNextMenu);
|
|
|
|
ChooseLevelActionMap.bind( keyboard, Space, ChooseLevelMenuOption );
|
|
ChooseLevelActionMap.bind( gamepad, btn_a, ChooseLevelMenuOption );
|
|
}
|
|
|
|
function ChooseLevelMenu::syncGUI(%this)
|
|
{
|
|
//Update the button imagery to comply to the last input device we'd used
|
|
%device = Canvas.getLastInputDevice();
|
|
if(%device $= "mouse")
|
|
%device = "keyboard";
|
|
|
|
//Category handling
|
|
%btn = ChooseLevelMenuTabList.getObject(%this.currentMenuIdx);
|
|
%btn.setHighlighted(true);
|
|
|
|
%buttonPosX = %btn.position.x + ChooseLevelMenuTabList.position.x;
|
|
|
|
ChooseLevelMenuPrevNavIcon.position.x = %buttonPosX;
|
|
ChooseLevelMenuNextNavIcon.position.x = %buttonPosX + %btn.extent.x - 40;
|
|
|
|
ChooseLevelBackBtn.setBitmap(BaseUIActionMap.getCommandButtonBitmap(%device, "BaseUIBackOut"));
|
|
|
|
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)
|
|
{
|
|
%btn = %this.getObject(%this.listPosition);
|
|
%btn.setHighlighted(true);
|
|
|
|
$selectedLevelAsset = %btn.levelAssetId;
|
|
}
|
|
|
|
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-->button.setHighlighted(true);
|
|
}
|
|
|
|
function ChooseLevelMenuPrevMenu(%val)
|
|
{
|
|
if(%val)
|
|
{
|
|
%currentIdx = ChooseLevelMenu.currentMenuIdx;
|
|
ChooseLevelMenu.currentMenuIdx -= 1;
|
|
|
|
%endIndex = 1;
|
|
if($pref::HostMultiPlayer)
|
|
%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;
|
|
|
|
ChooseLevelMenu.openMenu(ChooseLevelMenu.currentMenuIdx);
|
|
}
|
|
}
|
|
|
|
function ChooseLevelMenuNextMenu(%val)
|
|
{
|
|
if(%val)
|
|
{
|
|
%currentIdx = ChooseLevelMenu.currentMenuIdx;
|
|
ChooseLevelMenu.currentMenuIdx += 1;
|
|
|
|
%endIndex = 1;
|
|
if($pref::HostMultiPlayer)
|
|
%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;
|
|
|
|
ChooseLevelMenu.openMenu(ChooseLevelMenu.currentMenuIdx);
|
|
}
|
|
}
|
|
|
|
function ChooseLevelMenu::openMenu(%this, %menuIdx)
|
|
{
|
|
GameModeSelectContainer.setVisible(%menuIdx == 0);
|
|
LevelSelectContainer.setVisible(%menuIdx == 1);
|
|
ServerConfigContainer.setVisible(%menuIdx == 2);
|
|
|
|
if(%menuIdx == 0)
|
|
$MenuList = GameModePreviewArray;
|
|
else if(%menuIdx == 1)
|
|
$MenuList = LevelPreviewArray;
|
|
else if(%menuIdx == 2)
|
|
$MenuList = ServerConfigList;
|
|
|
|
%this.currentMenuIdx = %menuIdx;
|
|
|
|
if($MenuList.isMethod("syncGui"))
|
|
$MenuList.syncGui();
|
|
|
|
%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)
|
|
ToggleGameMode(ChooseLevelMenu.listPosition);
|
|
else if(ChooseLevelMenu.currentMenuIdx == 1)
|
|
ChooseLevelBegin(ChooseLevelMenu.listPosition);
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
%entry.gameModeObj.active = !%entry.gameModeObj.active;
|
|
|
|
refreshLevelsList();
|
|
|
|
$MenuList.syncGui();
|
|
ChooseLevelMenu.syncGui();
|
|
|
|
}
|
|
|
|
function ChooseLevelBegin(%index)
|
|
{
|
|
// So we can't fire the button when loading is in progress.
|
|
if ( isObject( ServerGroup ) )
|
|
return;
|
|
|
|
Canvas.popDialog();
|
|
|
|
%entry = LevelPreviewArray.getObject(%index);
|
|
|
|
if(!AssetDatabase.isDeclaredAsset(%entry.levelAssetId))
|
|
{
|
|
MessageBoxOK("Error", "Selected level preview does not have a valid level asset!");
|
|
return;
|
|
}
|
|
|
|
$selectedLevelAsset = %entry.levelAssetId;
|
|
|
|
// Launch the chosen level with the editor open?
|
|
if ( ChooseLevelMenu.launchInEditor )
|
|
{
|
|
activatePackage( "BootEditor" );
|
|
ChooseLevelMenu.launchInEditor = false;
|
|
StartGame(%entry.levelAssetId, "SinglePlayer");
|
|
}
|
|
else
|
|
{
|
|
StartGame(%entry.levelAssetId);
|
|
}
|
|
}
|
|
|
|
function ChooseLevelMenu::onSleep( %this )
|
|
{
|
|
// This is set from the outside, only stays true for a single wake/sleep
|
|
// cycle.
|
|
%this.launchInEditor = false;
|
|
|
|
//Ensure any changes we made to our server configs is saved out
|
|
if($pref::HostMultiPlayer)
|
|
{
|
|
echo("Exporting server prefs");
|
|
%prefPath = getPrefpath();
|
|
export("$Pref::Server::*", %prefPath @ "/serverPrefs." @ $TorqueScriptFileExtension, false);
|
|
BanList::Export(%prefPath @ "/banlist." @ $TorqueScriptFileExtension);
|
|
}
|
|
}
|
|
|
|
function GameModePreviewButton::onHighlighted(%this, %highlighted)
|
|
{
|
|
if(%highlighted)
|
|
{
|
|
$MenuList.listPosition = $MenuList.getObjectIndex(%this.getParent());
|
|
|
|
GameModePreviewBitmap.bitmapAsset = %this.previewImage;
|
|
|
|
GameModePreviewBitmap.visible = (%this.previewImage !$= "");
|
|
|
|
GameModeNameText.text = %this.text;
|
|
GameModeDescriptionText.setText(%this.gameModeDesc);
|
|
|
|
GameModePreviewScroll.scrollToObject(%this);
|
|
}
|
|
}
|
|
|
|
function LevelPreviewButton::onHighlighted(%this, %highlighted)
|
|
{
|
|
if(%highlighted)
|
|
{
|
|
$MenuList.listPosition = $MenuList.getObjectIndex(%this);
|
|
|
|
LevelPreviewBitmap.bitmapAsset = %this.bitmapAsset;
|
|
LevelNameText.text = %this.levelAsset.levelName;
|
|
LevelDescriptionText.setText(%this.levelAsset.levelDescription);
|
|
|
|
LevelPreviewScroll.scrollToObject(%this);
|
|
}
|
|
} |