diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index 37cb6858f8..fde21b6c23 100644 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -179,8 +179,11 @@ namespace OpenRA { var replay = OrderManager.Connection as ReplayConnection; var replayName = replay != null ? replay.Filename : null; - var uid = OrderManager.World.Map.Uid; - var globalSettings = OrderManager.LobbyInfo.GlobalSettings; + var lobbyInfo = OrderManager.LobbyInfo; + var orders = new[] { + Order.Command("sync_lobby {0}".F(lobbyInfo.Serialize())), + Order.Command("startgame") + }; // Disconnect from the current game Disconnect(); @@ -190,10 +193,10 @@ namespace OpenRA if (replay != null) JoinReplay(replayName); else - StartMission(uid, globalSettings.GameSpeedType, globalSettings.Difficulty); + CreateAndStartLocalServer(lobbyInfo.GlobalSettings.Map, orders); } - public static void StartMission(string mapUID, string gameSpeed, string difficulty, Action onStart = null) + public static void CreateAndStartLocalServer(string mapUID, IEnumerable setupOrders, Action onStart = null) { OrderManager om = null; @@ -201,9 +204,9 @@ namespace OpenRA lobbyReady = () => { LobbyInfoChanged -= lobbyReady; - om.IssueOrder(Order.Command("gamespeed {0}".F(gameSpeed))); - om.IssueOrder(Order.Command("difficulty {0}".F(difficulty))); - om.IssueOrder(Order.Command("state {0}".F(Session.ClientState.Ready))); + foreach (var o in setupOrders) + om.IssueOrder(o); + if (onStart != null) onStart(); }; diff --git a/OpenRA.Mods.Common/ServerTraits/LobbyCommands.cs b/OpenRA.Mods.Common/ServerTraits/LobbyCommands.cs index 21581d2c40..86f9ed434b 100644 --- a/OpenRA.Mods.Common/ServerTraits/LobbyCommands.cs +++ b/OpenRA.Mods.Common/ServerTraits/LobbyCommands.cs @@ -889,6 +889,28 @@ namespace OpenRA.Mods.Common.Server return true; } + }, + { "sync_lobby", + s => + { + if (!client.IsAdmin) + { + server.SendOrderTo(conn, "Message", "Only the host can set lobby info"); + return true; + } + + var lobbyInfo = Session.Deserialize(s); + if (lobbyInfo == null) + { + server.SendOrderTo(conn, "Message", "Invalid Lobby Info Sent"); + return true; + } + + server.LobbyInfo = lobbyInfo; + + server.SyncLobbyInfo(); + return true; + } } }; diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/IngameMenuLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/IngameMenuLogic.cs index 69366d7708..41a7937125 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/IngameMenuLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/IngameMenuLogic.cs @@ -90,14 +90,14 @@ namespace OpenRA.Mods.Common.Widgets.Logic { hideMenu = true; - if (world.LocalPlayer == null || (world.LocalPlayer.WinState != WinState.Won && - (!world.IsGameOver || world.Map.Visibility == MapVisibility.MissionSelector))) + if (world.LocalPlayer == null || world.LocalPlayer.WinState != WinState.Won) { Action restartAction = null; - if (world.IsReplay || world.Map.Visibility == MapVisibility.MissionSelector) + var iop = world.WorldActor.TraitsImplementing().FirstOrDefault(); + var exitDelay = iop != null ? iop.ExitDelay : 0; + + if (world.LobbyInfo.IsSinglePlayer) { - var iop = world.WorldActor.TraitsImplementing().FirstOrDefault(); - var exitDelay = iop != null ? iop.ExitDelay : 0; restartAction = () => { Ui.CloseWindow(); @@ -145,7 +145,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic }; var surrenderButton = menu.Get("SURRENDER"); surrenderButton.IsVisible = () => world.Type == WorldType.Regular; - surrenderButton.IsDisabled = () => (world.LocalPlayer == null || world.LocalPlayer.WinState != WinState.Undefined) || hasError; + surrenderButton.IsDisabled = () => + world.LocalPlayer == null || world.LocalPlayer.WinState != WinState.Undefined || + world.Map.Visibility.HasFlag(MapVisibility.MissionSelector) || hasError; surrenderButton.OnClick = () => { hideMenu = true; @@ -153,7 +155,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic title: "Surrender", text: "Are you sure you want to surrender?", onConfirm: onSurrender, - onCancel: showMenu); + onCancel: showMenu, + confirmText: "Surrender", + cancelText: "Stay"); }; var saveMapButton = menu.Get("SAVE_MAP"); diff --git a/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs index a7c3f78db4..726f5f1914 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs @@ -14,6 +14,7 @@ using System.IO; using System.Linq; using System.Threading; using OpenRA.Graphics; +using OpenRA.Network; using OpenRA.Primitives; using OpenRA.Widgets; @@ -301,6 +302,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic return; var gameStartVideo = selectedMap.Videos.GameStart; + var orders = new[] { + Order.Command("gamespeed {0}".F(gameSpeed)), + Order.Command("difficulty {0}".F(difficulty)), + Order.Command("state {0}".F(Session.ClientState.Ready)) + }; + if (gameStartVideo != null && Game.ModData.ModFiles.Exists(gameStartVideo)) { var fsPlayer = fullscreenVideoPlayer.Get("PLAYER"); @@ -308,11 +315,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic PlayVideo(fsPlayer, gameStartVideo, PlayingVideo.GameStart, () => { StopVideo(fsPlayer); - Game.StartMission(selectedMapPreview.Uid, gameSpeed, difficulty, onStart); + Game.CreateAndStartLocalServer(selectedMapPreview.Uid, orders, onStart); }); } else - Game.StartMission(selectedMapPreview.Uid, gameSpeed, difficulty, onStart); + Game.CreateAndStartLocalServer(selectedMapPreview.Uid, orders, onStart); } class DropDownOption