diff --git a/OpenRA.Game/Map.cs b/OpenRA.Game/Map.cs index e60a4dbbc9..a38f2897cc 100644 --- a/OpenRA.Game/Map.cs +++ b/OpenRA.Game/Map.cs @@ -37,6 +37,7 @@ namespace OpenRA public string Description; public string Author; public string Tileset; + public string[] Difficulties; [FieldLoader.Ignore] public Lazy> Actors; @@ -178,6 +179,7 @@ namespace OpenRA "Description", "Author", "Tileset", + "Difficulties", "MapSize", "Bounds", "UseAsShellmap", diff --git a/OpenRA.Game/Network/Session.cs b/OpenRA.Game/Network/Session.cs index 305b92a49f..30f7ae16d5 100644 --- a/OpenRA.Game/Network/Session.cs +++ b/OpenRA.Game/Network/Session.cs @@ -78,6 +78,7 @@ namespace OpenRA.Network public bool LockTeams = true; // don't allow team changes after game start. public bool AllowCheats = false; public bool Dedicated; + public string Difficulty; } public Session(string[] mods) diff --git a/OpenRA.Mods.RA/ServerTraits/LobbyCommands.cs b/OpenRA.Mods.RA/ServerTraits/LobbyCommands.cs index ad9cfbb15d..cd0c4ca720 100644 --- a/OpenRA.Mods.RA/ServerTraits/LobbyCommands.cs +++ b/OpenRA.Mods.RA/ServerTraits/LobbyCommands.cs @@ -317,6 +317,25 @@ namespace OpenRA.Mods.RA.Server server.SyncLobbyInfo(); return true; }}, + { "difficulty", + s => + { + if (!client.IsAdmin) + { + server.SendChatTo(conn, "Only the host can set that option"); + return true; + } + if ((server.Map.Difficulties == null && s != null) || (server.Map.Difficulties != null && !server.Map.Difficulties.Contains(s))) + { + server.SendChatTo(conn, "Unsupported difficulty selected: {0}".F(s)); + server.SendChatTo(conn, "Supported difficulties: {0}".F(server.Map.Difficulties.JoinWith(","))); + return true; + } + + server.lobbyInfo.GlobalSettings.Difficulty = s; + server.SyncLobbyInfo(); + return true; + }}, { "kick", s => { diff --git a/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs index 57a49a23cb..89a60acf7c 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs @@ -156,6 +156,27 @@ namespace OpenRA.Mods.RA.Widgets.Logic allowCheats.OnClick = () => orderManager.IssueOrder(Order.Command( "allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats))); + var difficulty = lobby.Get("DIFFICULTY_DROPDOWNBUTTON"); + difficulty.IsVisible = () => Map != null && Map.Difficulties != null && Map.Difficulties.Any(); + difficulty.IsDisabled = () => !Game.IsHost || gameStarting || orderManager.LocalClient == null || orderManager.LocalClient.IsReady; + difficulty.GetText = () => orderManager.LobbyInfo.GlobalSettings.Difficulty; + difficulty.OnMouseDown = _ => + { + var options = Map.Difficulties.Select(d => new DifficultyDropDownOption + { + Title = d, + IsSelected = () => orderManager.LobbyInfo.GlobalSettings.Difficulty == d, + OnClick = () => orderManager.IssueOrder(Order.Command("difficulty {0}".F(d))) + }); + Func setupItem = (option, template) => + { + var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick); + item.Get("LABEL").GetText = () => option.Title; + return item; + }; + difficulty.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem); + }; + var startGameButton = lobby.Get("START_GAME_BUTTON"); startGameButton.IsVisible = () => Game.IsHost; startGameButton.IsDisabled = () => gameStarting; @@ -249,6 +270,8 @@ namespace OpenRA.Mods.RA.Widgets.Logic var title = Ui.Root.Get("TITLE"); title.Text = orderManager.LobbyInfo.GlobalSettings.ServerName; + + orderManager.LobbyInfo.GlobalSettings.Difficulty = Map.Difficulties != null && Map.Difficulties.Any() ? Map.Difficulties.First() : null; } void UpdatePlayerList() @@ -444,5 +467,12 @@ namespace OpenRA.Mods.RA.Widgets.Logic { orderManager.IssueOrder(Order.Command("ready")); } + + class DifficultyDropDownOption + { + public string Title; + public Func IsSelected; + public Action OnClick; + } } } diff --git a/mods/d2k/bits/TURRET1.aud b/mods/d2k/bits/TURRET1.aud deleted file mode 100644 index 7b89d0ca4e..0000000000 Binary files a/mods/d2k/bits/TURRET1.aud and /dev/null differ diff --git a/mods/ra/chrome/lobby.yaml b/mods/ra/chrome/lobby.yaml index b908c3bf44..a57f11c6d8 100644 --- a/mods/ra/chrome/lobby.yaml +++ b/mods/ra/chrome/lobby.yaml @@ -426,6 +426,13 @@ Background@SERVER_LOBBY: Height:25 Text:Disconnect Font:Bold + DropDownButton@DIFFICULTY_DROPDOWNBUTTON: + X:PARENT_RIGHT-154 + Y:PARENT_BOTTOM-219+25 + Width:120 + Height:25 + Font:Bold + Visible:false Checkbox@ALLOWCHEATS_CHECKBOX: X: PARENT_RIGHT-154 Y: PARENT_BOTTOM-229 diff --git a/mods/ra/maps/allies-01/map.yaml b/mods/ra/maps/allies-01/map.yaml index c16e3b5433..46bcb19d27 100644 --- a/mods/ra/maps/allies-01/map.yaml +++ b/mods/ra/maps/allies-01/map.yaml @@ -20,6 +20,8 @@ UseAsShellmap: False Type: Campaign +Difficulties: Normal + Players: PlayerReference@Neutral: Name: Neutral diff --git a/mods/ra/maps/allies-02/map.yaml b/mods/ra/maps/allies-02/map.yaml index e7733e6e99..e9422b4fbd 100644 --- a/mods/ra/maps/allies-02/map.yaml +++ b/mods/ra/maps/allies-02/map.yaml @@ -20,6 +20,8 @@ UseAsShellmap: False Type: Campaign +Difficulties: Normal + Players: PlayerReference@Neutral: Name: Neutral diff --git a/mods/ra/maps/allies-03/map.yaml b/mods/ra/maps/allies-03/map.yaml index 6812f755e8..5f04bc5f60 100644 --- a/mods/ra/maps/allies-03/map.yaml +++ b/mods/ra/maps/allies-03/map.yaml @@ -20,6 +20,8 @@ UseAsShellmap: False Type: Campaign +Difficulties: Normal + Players: PlayerReference@Neutral: Name: Neutral