Index: ps/trunk/binaries/data/mods/public/gui/common/sprites.xml =================================================================== --- ps/trunk/binaries/data/mods/public/gui/common/sprites.xml +++ ps/trunk/binaries/data/mods/public/gui/common/sprites.xml @@ -8,14 +8,14 @@ ========================================== --> - + - + Index: ps/trunk/binaries/data/mods/public/gui/pregame/BackgroundHandler.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/pregame/BackgroundHandler.js +++ ps/trunk/binaries/data/mods/public/gui/pregame/BackgroundHandler.js @@ -0,0 +1,48 @@ +class BackgroundHandler +{ + constructor(layers) + { + this.initTime = Date.now(); + this.layerSet = layers; + + this.initBackgrounds(); + } + + initBackgrounds() + { + this.layerSet.forEach((layer, i) => { + + let background = Engine.GetGUIObjectByName("background[" + i + "]"); + background.sprite = layer.sprite; + background.z = i; + background.hidden = false; + }); + } + + onTick() + { + let now = Date.now(); + + this.layerSet.forEach((layer, i) => { + + let background = Engine.GetGUIObjectByName("background[" + i + "]"); + + let screen = background.parent.getComputedSize(); + let h = screen.bottom - screen.top; + let w = h * 16/9; + let iw = h * 2; + + let offset = layer.offset((now - this.initTime) / 1000, w); + + if (layer.tiling) + { + let left = offset % iw; + if (left >= 0) + left -= iw; + background.size = new GUISize(left, screen.top, screen.right, screen.bottom); + } + else + background.size = new GUISize(screen.right/2 - h + offset, screen.top, screen.right/2 + h + offset, screen.bottom); + }); + } +} Index: ps/trunk/binaries/data/mods/public/gui/pregame/MainMenuItemHandler.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/pregame/MainMenuItemHandler.js +++ ps/trunk/binaries/data/mods/public/gui/pregame/MainMenuItemHandler.js @@ -0,0 +1,108 @@ +class MainMenuItemHandler +{ + constructor(menuItems, menuSpeed = 1.2, margin = 4, buttonHeight = 28) + { + this.menuItems = menuItems; + this.menuSpeed = menuSpeed; + this.margin = margin; + this.buttonHeight = buttonHeight; + this.lastTickTime = Date.now(); + + this.mainMenu = Engine.GetGUIObjectByName("mainMenu"); + this.mainMenuButtons = Engine.GetGUIObjectByName("mainMenuButtons"); + this.submenu = Engine.GetGUIObjectByName("submenu"); + this.submenuButtons = Engine.GetGUIObjectByName("submenuButtons"); + this.MainMenuPanelRightBorderTop = Engine.GetGUIObjectByName("MainMenuPanelRightBorderTop"); + this.MainMenuPanelRightBorderBottom = Engine.GetGUIObjectByName("MainMenuPanelRightBorderBottom"); + + this.setupMenuButtons(this.mainMenuButtons.children, this.menuItems); + this.setupHotkeys(this.menuItems); + Engine.GetGUIObjectByName("closeMenuButton").onPress = () => { this.closeSubmenu(); }; + } + + setupMenuButtons(buttons, menuItems) + { + buttons.forEach((button, i) => { + let item = menuItems[i]; + button.hidden = !item; + if (button.hidden) + return; + + button.size = new GUISize( + 0, (this.buttonHeight + this.margin) * i, + 0, (this.buttonHeight + this.margin) * i + this.buttonHeight, + 0, 0, 100, 0); + button.caption = item.caption; + button.tooltip = item.tooltip; + button.enabled = item.enabled === undefined || item.enabled; + button.onPress = () => { + this.closeSubmenu(); + + if (item.onPress) + item.onPress(); + else + this.openSubmenu(i); + }; + button.hidden = false; + }); + + if (buttons.length < menuItems.length) + error("GUI page has space for " + buttons.length + " menu buttons, but " + menuItems.length + " items are provided!"); + } + + setupHotkeys(menuItems) + { + for (let name in menuItems) + { + let item = menuItems[name]; + + if (item.onPress && item.hotkey) + { + Engine.SetGlobalHotkey(item.hotkey, () => { + this.closeSubmenu(); + item.onPress(); + }); + } + + if (item.submenu) + this.setupHotkeys(item.submenu); + } + } + + openSubmenu(i) + { + this.setupMenuButtons(this.submenuButtons.children, this.menuItems[i].submenu); + let top = this.mainMenuButtons.size.top + this.mainMenuButtons.children[i].size.top; + this.submenu.size = new GUISize( + this.submenu.size.left, top - this.margin, + this.submenu.size.right, top + ((this.buttonHeight + this.margin) * this.menuItems[i].submenu.length)); + this.submenu.hidden = false; + this.MainMenuPanelRightBorderTop.size = "100%-2 0 100% " + (this.submenu.size.top + this.margin); + this.MainMenuPanelRightBorderBottom.size = "100%-2 " + this.submenu.size.bottom + " 100% 100%"; + } + + closeSubmenu() + { + this.submenu.hidden = true; + this.submenu.size = this.mainMenu.size; + this.MainMenuPanelRightBorderTop.size = "100%-2 0 100% 100%"; + } + + onTick() + { + let now = Date.now(); + + let maxOffset = this.mainMenu.size.right - this.submenu.size.left; + let offset = Math.min(this.menuSpeed * (now - this.lastTickTime), maxOffset); + + this.lastTickTime = now; + + if (this.submenu.hidden || offset <= 0) + return; + + let size = this.submenu.size; + size.left += offset; + size.right += offset; + this.submenu.size = size; + } +} Index: ps/trunk/binaries/data/mods/public/gui/pregame/MainMenuItems.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/pregame/MainMenuItems.js +++ ps/trunk/binaries/data/mods/public/gui/pregame/MainMenuItems.js @@ -0,0 +1,194 @@ +var g_MainMenuItems = [ + { + "caption": translate("Learn To Play"), + "tooltip": translate("Learn how to play, start the tutorial, discover the technology trees, and the history behind the civilizations"), + "submenu": [ + { + "caption": translate("Manual"), + "tooltip": translate("Open the 0 A.D. Game Manual."), + "onPress": () => { + Engine.PushGuiPage("page_manual.xml"); + } + }, + { + "caption": translate("Tutorial"), + "tooltip": translate("Start the economic tutorial."), + "onPress": () => { + Engine.SwitchGuiPage("page_gamesetup.xml", { + "tutorial": true + }); + } + }, + { + "caption": translate("Structure Tree"), + "tooltip": colorizeHotkey(translate("%(hotkey)s: View the structure tree of civilizations featured in 0 A.D."), "structree"), + "hotkey": "structree", + "onPress": () => { + Engine.PushGuiPage("page_structree.xml"); + } + }, + { + "caption": translate("History"), + "tooltip": colorizeHotkey(translate("%(hotkey)s: Learn about the many civilizations featured in 0 A.D."), "civinfo"), + "hotkey": "civinfo", + "onPress": () => { + Engine.PushGuiPage("page_civinfo.xml"); + } + } + ] + }, + { + "caption": translate("Single Player"), + "tooltip": translate("Click here to start a new single player game."), + "submenu": [ + { + "caption": translate("Matches"), + "tooltip": translate("Start the economic tutorial."), + "onPress": () => { + Engine.SwitchGuiPage("page_gamesetup.xml", {}); + } + }, + { + "caption": translate("Campaigns"), + "tooltip": translate("Relive history through historical military campaigns. \\[NOT YET IMPLEMENTED]"), + "enabled": false + }, + { + "caption": translate("Load Game"), + "tooltip": translate("Click here to load a saved game."), + "onPress": () => { + Engine.PushGuiPage("page_loadgame.xml", { + "type": "offline" + }); + } + }, + { + "caption": translate("Replays"), + "tooltip": translate("Playback previous games."), + "onPress": () => { + Engine.SwitchGuiPage("page_replaymenu.xml", { + "replaySelectionData": { + "filters": { + "singleplayer": "Singleplayer" + } + } + }); + } + } + ] + }, + { + "caption": translate("Multiplayer"), + "tooltip": translate("Fight against one or more human players in a multiplayer game."), + "submenu": [ + { + // Translation: Join a game by specifying the host's IP address. + "caption": translate("Join Game"), + "tooltip": translate("Joining an existing multiplayer game."), + "onPress": () => { + Engine.PushGuiPage("page_gamesetup_mp.xml", { + "multiplayerGameType": "join" + }); + } + }, + { + "caption": translate("Host Game"), + "tooltip": translate("Host a multiplayer game."), + "onPress": () => { + Engine.PushGuiPage("page_gamesetup_mp.xml", { + "multiplayerGameType": "host" + }); + } + }, + { + "caption": translate("Game Lobby"), + "tooltip": + colorizeHotkey(translate("%(hotkey)s: Launch the multiplayer lobby to join and host publicly visible games and chat with other players."), "lobby") + + (Engine.StartXmppClient ? "" : translate("Launch the multiplayer lobby. \\[DISABLED BY BUILD]")), + "enabled": !!Engine.StartXmppClient, + "hotkey": "lobby", + "onPress": () => { + if (Engine.StartXmppClient) + Engine.PushGuiPage("page_prelobby_entrance.xml"); + } + }, + { + "caption": translate("Replays"), + "tooltip": translate("Playback previous games."), + "onPress": () => { + Engine.SwitchGuiPage("page_replaymenu.xml", { + "replaySelectionData": { + "filters": { + "singleplayer": "Multiplayer" + } + } + }); + } + } + ] + }, + { + "caption": translate("Settings"), + "tooltip": translate("Game options and scenario design tools."), + "submenu": [ + { + "caption": translate("Options"), + "tooltip": translate("Adjust game settings."), + "onPress": () => { + Engine.PushGuiPage("page_options.xml"); + } + }, + { + "caption": translate("Language"), + "tooltip": translate("Choose the language of the game."), + "onPress": () => { + Engine.PushGuiPage("page_locale.xml"); + } + }, + { + "caption": translate("Mod Selection"), + "tooltip": translate("Select and download mods for the game."), + "onPress": () => { + Engine.SwitchGuiPage("page_modmod.xml"); + } + }, + { + "caption": translate("Welcome Screen"), + "tooltip": translate("Show the Welcome Screen. Useful if you hid it by mistake."), + "onPress": () => { + Engine.PushGuiPage("page_splashscreen.xml"); + } + } + ] + }, + { + "caption": translate("Scenario Editor"), + "tooltip": translate('Open the Atlas Scenario Editor in a new window. You can run this more reliably by starting the game with the command-line argument "-editor".'), + "onPress": () => { + if (Engine.AtlasIsAvailable()) + messageBox( + 400, 200, + translate("Are you sure you want to quit 0 A.D. and open the Scenario Editor?"), + translate("Confirmation"), + [translate("No"), translate("Yes")], + [null, Engine.RestartInAtlas]); + else + messageBox( + 400, 200, + translate("The scenario editor is not available or failed to load. See the game logs for additional information."), + translate("Error")); + } + }, + { + "caption": translate("Exit"), + "tooltip": translate("Exits the game."), + "onPress": () => { + messageBox( + 400, 200, + translate("Are you sure you want to quit 0 A.D.?"), + translate("Confirmation"), + [translate("No"), translate("Yes")], + [null, Engine.Exit]); + } + } +]; Index: ps/trunk/binaries/data/mods/public/gui/pregame/ProjectInformation.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/pregame/ProjectInformation.js +++ ps/trunk/binaries/data/mods/public/gui/pregame/ProjectInformation.js @@ -0,0 +1,72 @@ +/** + * IMPORTANT: Remember to update session/top_panel/label.xml in sync with this. + */ +var g_ProjectInformation = { + "organizationName": { + "caption": translate("WILDFIRE GAMES") + }, + "organizationLogo": { + "sprite": "WildfireGamesLogo" + }, + "productLogo": { + "sprite": "0ADLogo" + }, + "productBuild": { + "caption": getBuildString() + }, + "productDescription": { + "caption": setStringTags(translate("Alpha XXIV"), { "font": "sans-bold-16" }) + "\n\n" + + translate("Notice: This game is under development and many features have not been added yet.") + } +}; + +var g_CommunityButtons = [ + { + "caption": translate("Website"), + "tooltip": translate("Click to open play0ad.com in your web browser."), + "size": "8 100%-180 50%-4 100%-152", + "onPress": () => { + openURL("https://play0ad.com/"); + } + }, + { + "caption": translate("Chat"), + "tooltip": translate("Click to open the 0 A.D. IRC chat in your browser. (#0ad on webchat.quakenet.org)"), + "size": "50%+4 100%-180 100%-8 100%-152", + "onPress": () => { + openURL("https://webchat.quakenet.org/?channels=0ad"); + } + }, + { + "caption": translate("Report a Bug"), + "tooltip": translate("Click to visit 0 A.D. Trac to report a bug, crash, or error."), + "size": "8 100%-144 100%-8 100%-116", + "onPress": () => { + openURL("https://trac.wildfiregames.com/wiki/ReportingErrors/"); + } + }, + { + "caption": translate("Translate the Game"), + "tooltip": translate("Click to open the 0 A.D. translate page in your browser."), + "size": "8 100%-108 100%-8 100%-80", + "onPress": () => { + openURL("https://trac.wildfiregames.com/wiki/Localization"); + } + }, + { + "caption": translate("Donate"), + "tooltip": translate("Help with the project expenses by donating."), + "size": "8 100%-72 100%-8 100%-44", + "onPress": () => { + openURL("https://play0ad.com/community/donate/"); + } + }, + { + "caption": translate("Credits"), + "tooltip": translate("Click to see the 0 A.D. credits."), + "size": "8 100%-36 100%-8 100%-8", + "onPress": () => { + Engine.PushGuiPage("page_credits.xml"); + } + } +]; Index: ps/trunk/binaries/data/mods/public/gui/pregame/ProjectInformation.xml =================================================================== --- ps/trunk/binaries/data/mods/public/gui/pregame/ProjectInformation.xml +++ ps/trunk/binaries/data/mods/public/gui/pregame/ProjectInformation.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + Index: ps/trunk/binaries/data/mods/public/gui/pregame/SplashscreenHandler.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/pregame/SplashscreenHandler.js +++ ps/trunk/binaries/data/mods/public/gui/pregame/SplashscreenHandler.js @@ -0,0 +1,62 @@ +class SplashScreenHandler +{ + constructor(initData, hotloadData) + { + this.showSplashScreen = hotloadData ? hotloadData.showSplashScreen : initData && initData.isStartup; + } + + getHotloadData() + { + // Only show splash screen(s) once at startup, but not again after hotloading + return { + "showSplashScreen": this.showSplashScreen + }; + } + + // Don't call this from the init function in order to not crash when opening the new page on init on hotloading + // and not possibly crash when opening the new page on init and throwing a JS error. + onTick() + { + if (this.showSplashScreen) + this.openPage(); + } + + openPage() + { + this.showSplashScreen = false; + + if (Engine.ConfigDB_GetValue("user", "gui.splashscreen.enable") === "true" || + Engine.ConfigDB_GetValue("user", "gui.splashscreen.version") < Engine.GetFileMTime("gui/splashscreen/splashscreen.txt")) + Engine.PushGuiPage("page_splashscreen.xml", {}, this.showRenderPathMessage); + else + this.showRenderPathMessage(); + } + + showRenderPathMessage() + { + // Warn about removing fixed render path + if (Engine.Renderer_GetRenderPath() != "fixed") + return; + + messageBox( + 600, 300, + "[font=\"sans-bold-16\"]" + + sprintf(translate("%(warning)s You appear to be using non-shader (fixed function) graphics. This option will be removed in a future 0 A.D. release, to allow for more advanced graphics features. We advise upgrading your graphics card to a more recent, shader-compatible model."), { + "warning": coloredText("Warning:", "200 20 20") + }) + + "\n\n" + + // Translation: This is the second paragraph of a warning. The + // warning explains that the user is using “non-shader“ graphics, + // and that in the future this will not be supported by the game, so + // the user will need a better graphics card. + translate("Please press \"Read More\" for more information or \"OK\" to continue."), + translate("WARNING!"), + [translate("OK"), translate("Read More")], + [ + null, + () => { + Engine.OpenURL("https://www.wildfiregames.com/forum/index.php?showtopic=16734"); + } + ]); + } +} Index: ps/trunk/binaries/data/mods/public/gui/pregame/backgrounds.xml =================================================================== --- ps/trunk/binaries/data/mods/public/gui/pregame/backgrounds.xml +++ ps/trunk/binaries/data/mods/public/gui/pregame/backgrounds.xml @@ -0,0 +1,6 @@ + + + + Index: ps/trunk/binaries/data/mods/public/gui/pregame/mainmenu.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/pregame/mainmenu.js +++ ps/trunk/binaries/data/mods/public/gui/pregame/mainmenu.js @@ -1,244 +1,70 @@ -var currentSubmenuType; // contains submenu type -var MARGIN = 4; // menu border size -var g_ShowSplashScreens; - /** - * Available backdrops + * Available backgrounds, added by the files in backgrounds/. */ var g_BackgroundLayerData = []; -/** - * Chosen backdrop - */ -var g_BackgroundLayerset; - -var g_T0 = Date.now(); -var g_LastTickTime = Date.now(); +var g_BackgroundHandler; +var g_MenuHandler; +var g_SplashScreenHandler; + +function init(data, hotloadData) +{ + g_MenuHandler = new MainMenuItemHandler(g_MainMenuItems); + g_BackgroundHandler = new BackgroundHandler(pickRandom(g_BackgroundLayerData)); + g_SplashScreenHandler = new SplashScreenHandler(data, hotloadData && hotloadData.splashScreenHandler); + + new MusicHandler(); + new ProjectInformationHandler(g_ProjectInformation); + new CommunityButtonHandler(); +} -function init(initData, hotloadData) +function onTick() { - initMusic(); - - global.music.setState(global.music.states.MENU); - - // Initialize currentSubmenuType with placeholder to avoid null when switching - currentSubmenuType = "submenuSinglePlayer"; - - // Only show splash screen(s) once at startup, but not again after hotloading - g_ShowSplashScreens = hotloadData ? hotloadData.showSplashScreens : initData && initData.isStartup; - - // Pick a random background and initialise it - g_BackgroundLayerset = pickRandom(g_BackgroundLayerData); - for (let i = 0; i < g_BackgroundLayerset.length; ++i) - { - let guiObj = Engine.GetGUIObjectByName("background[" + i + "]"); - guiObj.hidden = false; - guiObj.sprite = g_BackgroundLayerset[i].sprite; - guiObj.z = i; - } - - Engine.GetGUIObjectByName("structreeButton").tooltip = colorizeHotkey( - translate("%(hotkey)s: View the structure tree of civilizations featured in 0 A.D."), - "structree"); - - Engine.GetGUIObjectByName("civInfoButton").tooltip = colorizeHotkey( - translate("%(hotkey)s: Learn about the many civilizations featured in 0 A.D."), - "civinfo"); - - Engine.GetGUIObjectByName("lobbyButton").tooltip = colorizeHotkey( - translate("%(hotkey)s: Launch the multiplayer lobby to join and host publicly visible games and chat with other players."), - "lobby"); + g_MenuHandler.onTick(); + g_BackgroundHandler.onTick(); + g_SplashScreenHandler.onTick(); } function getHotloadData() { - return { "showSplashScreens": g_ShowSplashScreens }; + return { + "splashScreenHandler": g_SplashScreenHandler.getHotloadData() + }; } -function scrollBackgrounds() +class MusicHandler { - for (let i = 0; i < g_BackgroundLayerset.length; ++i) + constructor() { - let guiObj = Engine.GetGUIObjectByName("background[" + i + "]"); - - let screen = guiObj.parent.getComputedSize(); - let h = screen.bottom - screen.top; - let w = h * 16/9; - let iw = h * 2; - - let offset = g_BackgroundLayerset[i].offset((Date.now() - g_T0) / 1000, w); - - if (g_BackgroundLayerset[i].tiling) - { - let left = offset % iw; - if (left >= 0) - left -= iw; - guiObj.size = new GUISize(left, screen.top, screen.right, screen.bottom); - } - else - guiObj.size = new GUISize(screen.right/2 - h + offset, screen.top, screen.right/2 + h + offset, screen.bottom); + initMusic(); + global.music.setState(global.music.states.MENU); } } -function onTick() +class ProjectInformationHandler { - let now = Date.now(); - let tickLength = Date.now() - g_LastTickTime; - g_LastTickTime = now; - - scrollBackgrounds(); - - updateMenuPosition(tickLength); - - // Show splash screens here, so we don't interfere with main menu hotloading - if (g_ShowSplashScreens) + constructor(projectInformation) { - g_ShowSplashScreens = false; - - if (Engine.ConfigDB_GetValue("user", "gui.splashscreen.enable") === "true" || - Engine.ConfigDB_GetValue("user", "gui.splashscreen.version") < Engine.GetFileMTime("gui/splashscreen/splashscreen.txt")) - ShowSplashScreen(); - else - ShowRenderPathMessage(); + for (let objectName in projectInformation) + for (let propertyName in projectInformation[objectName]) + Engine.GetGUIObjectByName(objectName)[propertyName] = projectInformation[objectName][propertyName]; } } -function ShowSplashScreen() -{ - Engine.PushGuiPage("page_splashscreen.xml", {}, ShowRenderPathMessage); -} - -function ShowRenderPathMessage() -{ - // Warn about removing fixed render path - if (Engine.Renderer_GetRenderPath() == "fixed") - messageBox( - 600, 300, - "[font=\"sans-bold-16\"]" + - sprintf(translate("%(warning)s You appear to be using non-shader (fixed function) graphics. This option will be removed in a future 0 A.D. release, to allow for more advanced graphics features. We advise upgrading your graphics card to a more recent, shader-compatible model."), { - "warning": coloredText("Warning:", "200 20 20") - }) + - "\n\n" + - // Translation: This is the second paragraph of a warning. The - // warning explains that the user is using “non-shader“ graphics, - // and that in the future this will not be supported by the game, so - // the user will need a better graphics card. - translate("Please press \"Read More\" for more information or \"OK\" to continue."), - translate("WARNING!"), - [translate("OK"), translate("Read More")], - [ null, function() { Engine.OpenURL("https://www.wildfiregames.com/forum/index.php?showtopic=16734"); } ] - ); -} - -/** - * Slide menu. - */ -function updateMenuPosition(dt) +class CommunityButtonHandler { - let submenu = Engine.GetGUIObjectByName("submenu"); - - if (submenu.hidden == false) + constructor() { - // Number of pixels per millisecond to move - let SPEED = 1.2; - - let maxOffset = Engine.GetGUIObjectByName("mainMenu").size.right - submenu.size.left; - if (maxOffset > 0) - { - let offset = Math.min(SPEED * dt, maxOffset); - let size = submenu.size; - size.left += offset; - size.right += offset; - submenu.size = size; - } - } -} - -/** - * Opens the menu by revealing the screen which contains the menu. - */ -function openMenu(newSubmenu, position, buttonHeight, numButtons) -{ - currentSubmenuType = newSubmenu; - Engine.GetGUIObjectByName(currentSubmenuType).hidden = false; - - let submenu = Engine.GetGUIObjectByName("submenu"); - let top = position - MARGIN; - let bottom = position + ((buttonHeight + MARGIN) * numButtons); - submenu.size = new GUISize(submenu.size.left, top, submenu.size.right, bottom); - - // Blend in right border of main menu into the left border of the submenu - blendSubmenuIntoMain(top, bottom); - - submenu.hidden = false; -} - -function closeMenu() -{ - Engine.GetGUIObjectByName(currentSubmenuType).hidden = true; - - let submenu = Engine.GetGUIObjectByName("submenu"); - submenu.hidden = true; - submenu.size = Engine.GetGUIObjectByName("mainMenu").size; - - Engine.GetGUIObjectByName("MainMenuPanelRightBorderTop").size = "100%-2 0 100% 100%"; -} - -/** - * Sizes right border on main menu panel to match the submenu. - */ -function blendSubmenuIntoMain(topPosition, bottomPosition) -{ - Engine.GetGUIObjectByName("MainMenuPanelRightBorderTop").size = "100%-2 0 100% " + (topPosition + MARGIN); - Engine.GetGUIObjectByName("MainMenuPanelRightBorderBottom").size = "100%-2 " + (bottomPosition) + " 100% 100%"; -} - -function exitGamePressed() -{ - closeMenu(); - - messageBox( - 400, 200, - translate("Are you sure you want to quit 0 A.D.?"), - translate("Confirmation"), - [translate("No"), translate("Yes")], - [null, Engine.Exit] - ); -} - -function pressedScenarioEditorButton() -{ - closeMenu(); - - if (Engine.AtlasIsAvailable()) - messageBox( - 400, 200, - translate("Are you sure you want to quit 0 A.D. and open the Scenario Editor?"), - translate("Confirmation"), - [translate("No"), translate("Yes")], - [null, Engine.RestartInAtlas] - ); - else - messageBox( - 400, 200, - translate("The scenario editor is not available or failed to load. See the game logs for additional information."), - translate("Error") - ); -} - -function getLobbyDisabledByBuild() -{ - return translate("Launch the multiplayer lobby to join and host publicly visible games and chat with other players. \\[DISABLED BY BUILD]"); -} + let buttons = Engine.GetGUIObjectByName("communityButtons").children; -function openStrucTree(page) -{ - closeMenu(); - Engine.PushGuiPage(page, {}, storeCivInfoPage); -} + g_CommunityButtons.forEach((buttonInfo, i) => { + let button = buttons[i]; + button.hidden = false; + for (let propertyName in buttonInfo) + button[propertyName] = buttonInfo[propertyName]; + }); -function storeCivInfoPage(data) -{ - if (data.nextPage) - Engine.PushGuiPage(data.nextPage, { "civ": data.civ }, storeCivInfoPage); + if (buttons.length < g_CommunityButtons.length) + error("GUI page has space for " + buttons.length + " community buttons, but " + menuItems.length + " items are provided!"); + } } Index: ps/trunk/binaries/data/mods/public/gui/pregame/mainmenu.xml =================================================================== --- ps/trunk/binaries/data/mods/public/gui/pregame/mainmenu.xml +++ ps/trunk/binaries/data/mods/public/gui/pregame/mainmenu.xml @@ -1,5 +1,4 @@ -