diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index 69e795569a..77fd66493a 100644 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -375,6 +375,11 @@ namespace OpenRA ModData.LoadScreen.StartGame(args); } + public static void LoadEditor(string mapUid) + { + StartGame(mapUid, WorldType.Editor); + } + public static void LoadShellMap() { var shellmap = ChooseShellmap(); diff --git a/OpenRA.Game/World.cs b/OpenRA.Game/World.cs index b93f73b73d..c1933e3cc2 100644 --- a/OpenRA.Game/World.cs +++ b/OpenRA.Game/World.cs @@ -22,7 +22,7 @@ using OpenRA.Traits; namespace OpenRA { - public enum WorldType { Regular, Shellmap } + public enum WorldType { Regular, Shellmap, Editor } public class World { diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/IngameMenuLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/IngameMenuLogic.cs index c1a819a0a3..88ea5197a0 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/IngameMenuLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/IngameMenuLogic.cs @@ -36,7 +36,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic // TODO: Create a mechanism to do things like this cleaner. Also needed for scripted missions Action onQuit = () => { - Sound.PlayNotification(world.Map.Rules, null, "Speech", "Leave", world.LocalPlayer == null ? null : world.LocalPlayer.Country.Race); + if (world.Type == WorldType.Regular) + Sound.PlayNotification(world.Map.Rules, null, "Speech", "Leave", world.LocalPlayer == null ? null : world.LocalPlayer.Country.Race); + resumeDisabled = true; var exitDelay = 1200; @@ -64,18 +66,29 @@ namespace OpenRA.Mods.Common.Widgets.Logic Action showMenu = () => hideMenu = false; - menu.Get("ABORT_MISSION").OnClick = () => + var abortMissionButton = menu.Get("ABORT_MISSION"); + abortMissionButton.IsVisible = () => world.Type == WorldType.Regular; + abortMissionButton.OnClick = () => { hideMenu = true; ConfirmationDialogs.PromptConfirmAction("Abort Mission", "Leave this game and return to the menu?", onQuit, showMenu); }; + var exitEditorButton = menu.Get("EXIT_EDITOR"); + exitEditorButton.IsVisible = () => world.Type == WorldType.Editor; + exitEditorButton.OnClick = () => + { + hideMenu = true; + ConfirmationDialogs.PromptConfirmAction("Exit Map Editor", "Exit and lose all unsaved changes?", onQuit, showMenu); + }; + Action onSurrender = () => { world.IssueOrder(new Order("Surrender", world.LocalPlayer.PlayerActor, false)); closeMenu(); }; var surrenderButton = menu.Get("SURRENDER"); + surrenderButton.IsVisible = () => world.Type == WorldType.Regular; surrenderButton.IsDisabled = () => (world.LocalPlayer == null || world.LocalPlayer.WinState != WinState.Undefined); surrenderButton.OnClick = () => { @@ -84,6 +97,17 @@ namespace OpenRA.Mods.Common.Widgets.Logic }; surrenderButton.IsDisabled = () => world.LocalPlayer == null || world.LocalPlayer.WinState != WinState.Undefined; + var saveMapButton = menu.Get("SAVE_MAP"); + saveMapButton.IsVisible = () => world.Type == WorldType.Editor; + saveMapButton.OnClick = () => + { + Ui.OpenWindow("SAVE_MAP_PANEL", new WidgetArgs() + { + { "onExit", () => widget.Visible = true }, + { "world", world }, + }); + }; + menu.Get("MUSIC").OnClick = () => { hideMenu = true; @@ -111,7 +135,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic resumeButton.OnClick = closeMenu; var panelRoot = widget.GetOrNull("PANEL_ROOT"); - if (panelRoot != null) + if (panelRoot != null && world.Type != WorldType.Editor) { var gameInfoPanel = Game.LoadWidget(world, "GAME_INFO_PANEL", panelRoot, new WidgetArgs() { diff --git a/OpenRA.Mods.Common/Widgets/Logic/MainMenuLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/MainMenuLogic.cs index 46aff00b19..b58a92f4ef 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/MainMenuLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/MainMenuLogic.cs @@ -21,7 +21,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic { public class MainMenuLogic { - protected enum MenuType { Main, Singleplayer, Extras, None } + protected enum MenuType { Main, Singleplayer, Extras, MapEditor, None } protected MenuType menuType = MenuType.Main; readonly Widget rootMenu; @@ -122,6 +122,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic }); }; + extrasMenu.Get("MAP_EDITOR_BUTTON").OnClick = () => menuType = MenuType.MapEditor; + var assetBrowserButton = extrasMenu.GetOrNull("ASSETBROWSER_BUTTON"); if (assetBrowserButton != null) assetBrowserButton.OnClick = () => @@ -144,6 +146,43 @@ namespace OpenRA.Mods.Common.Widgets.Logic extrasMenu.Get("BACK_BUTTON").OnClick = () => menuType = MenuType.Main; + // Map editor menu + var mapEditorMenu = widget.Get("MAP_EDITOR_MENU"); + mapEditorMenu.IsVisible = () => menuType == MenuType.MapEditor; + + var onSelect = new Action(uid => + { + RemoveShellmapUI(); + LoadMapIntoEditor(Game.ModData.MapCache[uid].Map); + }); + + var newMapButton = widget.Get("NEW_MAP_BUTTON"); + newMapButton.OnClick = () => + { + menuType = MenuType.None; + Game.OpenWindow("NEW_MAP_BG", new WidgetArgs() + { + { "onSelect", onSelect }, + { "onExit", () => menuType = MenuType.MapEditor } + }); + }; + + var loadMapButton = widget.Get("LOAD_MAP_BUTTON"); + loadMapButton.OnClick = () => + { + var initialMap = Game.ModData.MapCache.FirstOrDefault(); + menuType = MenuType.None; + Game.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs() + { + { "initialMap", initialMap != null ? initialMap.Uid : null }, + { "onExit", () => menuType = MenuType.MapEditor }, + { "onSelect", onSelect }, + { "filter", MapVisibility.Lobby | MapVisibility.Shellmap | MapVisibility.MissionSelector }, + }); + }; + + mapEditorMenu.Get("BACK_BUTTON").OnClick = () => menuType = MenuType.Extras; + var newsBG = widget.GetOrNull("NEWS_BG"); if (newsBG != null) { @@ -189,6 +228,15 @@ namespace OpenRA.Mods.Common.Widgets.Logic }; } + void LoadMapIntoEditor(Map map) + { + ConnectionLogic.Connect(System.Net.IPAddress.Loopback.ToString(), + Game.CreateLocalServer(map.Uid), + "", + () => { Game.LoadEditor(map.Uid); }, + () => { Game.CloseServer(); menuType = MenuType.MapEditor; }); + } + void SetNewsStatus(string message) { message = WidgetUtils.WrapText(message, newsStatus.Bounds.Width, Game.Renderer.Fonts[newsStatus.Font]); diff --git a/OpenRA.Mods.Common/Widgets/Logic/ServerCreationLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/ServerCreationLogic.cs index 0a13a5aba8..71f1f67e6d 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/ServerCreationLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/ServerCreationLogic.cs @@ -47,6 +47,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic { "onExit", () => { } }, { "onSelect", (Action)(uid => preview = Game.ModData.MapCache[uid]) }, { "filter", MapVisibility.Lobby }, + { "onStart", () => { } } }); }; diff --git a/mods/cnc/chrome/mainmenu.yaml b/mods/cnc/chrome/mainmenu.yaml index 02662fce9e..8fe1b2a355 100644 --- a/mods/cnc/chrome/mainmenu.yaml +++ b/mods/cnc/chrome/mainmenu.yaml @@ -165,14 +165,21 @@ Container@MENU_BACKGROUND: Width: 140 Height: 35 Text: Music - Button@ASSETBROWSER_BUTTON: + Button@MAP_EDITOR_BUTTON: X: 300 Y: 0 Width: 140 Height: 35 + Text: Map Editor + Font: Bold + Button@ASSETBROWSER_BUTTON: + X: 450 + Y: 0 + Width: 140 + Height: 35 Text: Asset Browser Button@CREDITS_BUTTON: - X: 450 + X: 600 Y: 0 Width: 140 Height: 35 @@ -184,6 +191,41 @@ Container@MENU_BACKGROUND: Width: 140 Height: 35 Text: Back + Background@MAP_EDITOR_MENU: + Width: PARENT_RIGHT + Visible: False + Children: + Label@MAP_EDITOR_MENU_TITLE: + X: 0 + Y: 0-30 + Width: PARENT_RIGHT + Height: 20 + Text: Map Editor + Align: Center + Font: Bold + Contrast: True + Button@NEW_MAP_BUTTON: + X: 0 + Y: 0 + Width: 140 + Height: 35 + Text: New Map + Font: Bold + Button@LOAD_MAP_BUTTON: + X: 150 + Y: 0 + Width: 140 + Height: 35 + Text: Load Map + Font: Bold + Button@BACK_BUTTON: + X: 300 + Y: 0 + Width: 140 + Height: 35 + Text: Back + Font: Bold + Key: escape Container@NEWS_BG: Children: DropDownButton@NEWS_BUTTON: diff --git a/mods/d2k/chrome/mainmenu.yaml b/mods/d2k/chrome/mainmenu.yaml index a64df6482c..f7aae64d42 100644 --- a/mods/d2k/chrome/mainmenu.yaml +++ b/mods/d2k/chrome/mainmenu.yaml @@ -127,16 +127,23 @@ Container@MAINMENU: Height: 30 Text: Music Font: Bold - Button@ASSETBROWSER_BUTTON: + Button@MAP_EDITOR_BUTTON: X: PARENT_RIGHT/2-WIDTH/2 Y: 140 Width: 140 Height: 30 + Text: Map Editor + Font: Bold + Button@ASSETBROWSER_BUTTON: + X: PARENT_RIGHT/2-WIDTH/2 + Y: 180 + Width: 140 + Height: 30 Text: Asset Browser Font: Bold Button@CREDITS_BUTTON: X: PARENT_RIGHT/2-WIDTH/2 - Y: 180 + Y: 220 Width: 140 Height: 30 Text: Credits @@ -149,6 +156,40 @@ Container@MAINMENU: Height: 30 Text: Back Font: Bold + Background@MAP_EDITOR_MENU: + Width: PARENT_RIGHT + Height: PARENT_BOTTOM + Children: + Label@MAP_EDITOR_MENU_TITLE: + X: 0 + Y: 20 + Width: 200 + Height: 30 + Text: Map Editor + Align: Center + Font: Bold + Button@NEW_MAP_BUTTON: + X: PARENT_RIGHT/2-WIDTH/2 + Y: 60 + Width: 140 + Height: 30 + Text: New Map + Font: Bold + Button@LOAD_MAP_BUTTON: + X: PARENT_RIGHT/2-WIDTH/2 + Y: 100 + Width: 140 + Height: 30 + Text: Load Map + Font: Bold + Button@BACK_BUTTON: + X: PARENT_RIGHT/2-WIDTH/2 + Key: escape + Y: 260 + Width: 140 + Height: 30 + Text: Back + Font: Bold Background@NEWS_BG: X: (WINDOW_RIGHT - WIDTH)/2 Y: 35 diff --git a/mods/ra/chrome/mainmenu.yaml b/mods/ra/chrome/mainmenu.yaml index 082a8275d0..c0308d9df1 100644 --- a/mods/ra/chrome/mainmenu.yaml +++ b/mods/ra/chrome/mainmenu.yaml @@ -140,16 +140,23 @@ Container@MAINMENU: Height: 30 Text: Music Font: Bold - Button@ASSETBROWSER_BUTTON: + Button@MAP_EDITOR_BUTTON: X: PARENT_RIGHT/2-WIDTH/2 Y: 140 Width: 140 Height: 30 + Text: Map Editor + Font: Bold + Button@ASSETBROWSER_BUTTON: + X: PARENT_RIGHT/2-WIDTH/2 + Y: 180 + Width: 140 + Height: 30 Text: Asset Browser Font: Bold Button@CREDITS_BUTTON: X: PARENT_RIGHT/2-WIDTH/2 - Y: 180 + Y: 220 Width: 140 Height: 30 Text: Credits @@ -162,6 +169,40 @@ Container@MAINMENU: Height: 30 Text: Back Font: Bold + Background@MAP_EDITOR_MENU: + Width: PARENT_RIGHT + Height: PARENT_BOTTOM + Children: + Label@MAP_EDITOR_MENU_TITLE: + X: 0 + Y: 20 + Width: 200 + Height: 30 + Text: Map Editor + Align: Center + Font: Bold + Button@NEW_MAP_BUTTON: + X: PARENT_RIGHT/2-WIDTH/2 + Y: 60 + Width: 140 + Height: 30 + Text: New Map + Font: Bold + Button@LOAD_MAP_BUTTON: + X: PARENT_RIGHT/2-WIDTH/2 + Y: 100 + Width: 140 + Height: 30 + Text: Load Map + Font: Bold + Button@BACK_BUTTON: + X: PARENT_RIGHT/2-WIDTH/2 + Key: escape + Y: 260 + Width: 140 + Height: 30 + Text: Back + Font: Bold Container@PERFORMANCE_INFO: Logic: PerfDebugLogic Children: