diff --git a/OpenRA.Game/Map.cs b/OpenRA.Game/Map.cs index 5ea42c752f..4fad2b5b5f 100644 --- a/OpenRA.Game/Map.cs +++ b/OpenRA.Game/Map.cs @@ -38,6 +38,7 @@ namespace OpenRA public string Author; public string Tileset; public string[] Difficulties; + public bool AllowStartUnitConfig = true; [FieldLoader.Ignore] public Lazy> Actors; diff --git a/OpenRA.Mods.RA/ServerTraits/LobbyCommands.cs b/OpenRA.Mods.RA/ServerTraits/LobbyCommands.cs index 67a10b0a20..6b28a1b7a7 100644 --- a/OpenRA.Mods.RA/ServerTraits/LobbyCommands.cs +++ b/OpenRA.Mods.RA/ServerTraits/LobbyCommands.cs @@ -399,6 +399,32 @@ namespace OpenRA.Mods.RA.Server server.SyncLobbyInfo(); return true; }}, + { "startingunits", + s => + { + if (!client.IsAdmin) + { + server.SendOrderTo(conn, "Message", "Only the host can set that option"); + return true; + } + + if (!server.Map.AllowStartUnitConfig) + { + server.SendOrderTo(conn, "Message", "Map has disabled start unit configuration"); + return true; + } + + var startUnits = Rules.Info["world"].Traits.WithInterface(); + if (!startUnits.Any(msu => msu.Class == s)) + { + server.SendOrderTo(conn, "Message", "Unknown unit class: {0}".F(s)); + return true; + } + + server.lobbyInfo.GlobalSettings.StartingUnitsClass = 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 46670340cc..d8869f06d0 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs @@ -318,8 +318,46 @@ namespace OpenRA.Mods.RA.Widgets.Logic difficulty.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem); }; - var difficultyDesc = optionsBin.GetOrNull("DIFFICULTY_DESC"); - difficultyDesc.IsVisible = difficulty.IsVisible; + optionsBin.Get("DIFFICULTY_DESC").IsVisible = difficulty.IsVisible; + } + + var startingUnits = optionsBin.GetOrNull("STARTINGUNITS_DROPDOWNBUTTON"); + if (startingUnits != null) + { + var classNames = new Dictionary() + { + {"none", "MCV Only"}, + {"default", "Light Support"}, + {"heavy", "Heavy Support"}, + }; + + Func className = c => classNames.ContainsKey(c) ? classNames[c] : c; + var classes = Rules.Info["world"].Traits.WithInterface() + .Select(a => a.Class).Distinct(); + + startingUnits.IsDisabled = configurationDisabled; + startingUnits.IsVisible = () => Map.AllowStartUnitConfig; + startingUnits.GetText = () => className(orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass); + startingUnits.OnMouseDown = _ => + { + var options = classes.Select(c => new DropDownOption + { + Title = className(c), + IsSelected = () => orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass == c, + OnClick = () => orderManager.IssueOrder(Order.Command("startingunits {0}".F(c))) + }); + + Func setupItem = (option, template) => + { + var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick); + item.Get("LABEL").GetText = () => option.Title; + return item; + }; + + startingUnits.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem); + }; + + optionsBin.Get("STARTINGUNITS_DESC").IsVisible = startingUnits.IsVisible; } var disconnectButton = lobby.Get("DISCONNECT_BUTTON");