diff --git a/OpenRA.Game/Server/Server.cs b/OpenRA.Game/Server/Server.cs index b582377d8f..e8b98dcb31 100644 --- a/OpenRA.Game/Server/Server.cs +++ b/OpenRA.Game/Server/Server.cs @@ -336,10 +336,6 @@ namespace OpenRA.Server // Send initial ping SendOrderTo(newConn, "Ping", Game.RunTime.ToString()); - // Send Lobby info to newly connected client - if (!client.IsAdmin) - NotifyNewClientOfLobbyInfo(newConn); - if (Settings.Dedicated) { var motdFile = Path.Combine(Platform.SupportDir, "motd.txt"); @@ -359,39 +355,6 @@ namespace OpenRA.Server catch (Exception) { DropClient(newConn); } } - void NotifyNewClientOfLobbyInfo(Connection newConn) - { - var defaults = new Session.Global(); - FieldLoader.Load(defaults, Game.modData.Manifest.LobbyDefaults); - - if (LobbyInfo.GlobalSettings.FragileAlliances != defaults.FragileAlliances) - SendOrderTo(newConn, "Message", "Diplomacy Changes: {0}".F(LobbyInfo.GlobalSettings.FragileAlliances)); - - if (LobbyInfo.GlobalSettings.AllowCheats != defaults.AllowCheats) - SendOrderTo(newConn, "Message", "Allow Cheats: {0}".F(LobbyInfo.GlobalSettings.AllowCheats)); - - if (LobbyInfo.GlobalSettings.Shroud != defaults.Shroud) - SendOrderTo(newConn, "Message", "Shroud: {0}".F(LobbyInfo.GlobalSettings.Shroud)); - - if (LobbyInfo.GlobalSettings.Fog != defaults.Fog) - SendOrderTo(newConn, "Message", "Fog of war: {0}".F(LobbyInfo.GlobalSettings.Fog)); - - if (LobbyInfo.GlobalSettings.Crates != defaults.Crates) - SendOrderTo(newConn, "Message", "Crates Appear: {0}".F(LobbyInfo.GlobalSettings.Crates)); - - if (LobbyInfo.GlobalSettings.AllyBuildRadius != defaults.AllyBuildRadius) - SendOrderTo(newConn, "Message", "Build off Ally ConYards: {0}".F(LobbyInfo.GlobalSettings.AllyBuildRadius)); - - if (LobbyInfo.GlobalSettings.StartingUnitsClass != defaults.StartingUnitsClass) - SendOrderTo(newConn, "Message", "Starting Units: {0}".F(LobbyInfo.GlobalSettings.StartingUnitsClass)); - - if (LobbyInfo.GlobalSettings.StartingCash != defaults.StartingCash) - SendOrderTo(newConn, "Message", "Starting Cash: ${0}".F(LobbyInfo.GlobalSettings.StartingCash)); - - if (LobbyInfo.GlobalSettings.TechLevel != defaults.TechLevel) - SendOrderTo(newConn, "Message", "Tech Level: {0}".F(LobbyInfo.GlobalSettings.TechLevel)); - } - void SetOrderLag() { if (LobbyInfo.IsSinglePlayer) diff --git a/OpenRA.Mods.RA/MPStartUnits.cs b/OpenRA.Mods.RA/MPStartUnits.cs index d2d1f331cd..1bca9eb766 100644 --- a/OpenRA.Mods.RA/MPStartUnits.cs +++ b/OpenRA.Mods.RA/MPStartUnits.cs @@ -15,10 +15,19 @@ namespace OpenRA.Mods.RA [Desc("Used by SpawnMPUnits. Attach these to the world actor. You can have multiple variants by adding @suffixes.")] public class MPStartUnitsInfo : TraitInfo { + [Desc("Internal class ID.")] public readonly string Class = "none"; + + [Desc("Exposed via the UI to the player.")] + public readonly string ClassName = "Unlabeled"; + + [Desc("Only available when selecting this faction.", "Leave empty for no restrictions.")] public readonly string[] Races = { }; + [Desc("The mobile construction vehicle.")] public readonly string BaseActor = null; + + [Desc("A group of units ready to defend or scout.")] public readonly string[] SupportActors = { }; [Desc("Inner radius for spawning support actors")] diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 9dc726733a..691417e495 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -561,6 +561,7 @@ + diff --git a/OpenRA.Mods.RA/ServerTraits/LobbyCommands.cs b/OpenRA.Mods.RA/ServerTraits/LobbyCommands.cs index 885a499c6c..35a011bb56 100644 --- a/OpenRA.Mods.RA/ServerTraits/LobbyCommands.cs +++ b/OpenRA.Mods.RA/ServerTraits/LobbyCommands.cs @@ -552,9 +552,13 @@ namespace OpenRA.Mods.RA.Server return true; } + var startUnitsInfo = server.Map.Rules.Actors["world"].Traits.WithInterface(); + var selectedClass = startUnitsInfo.Where(u => u.Class == s).Select(u => u.ClassName).FirstOrDefault(); + var className = selectedClass != null ? selectedClass : s; + server.LobbyInfo.GlobalSettings.StartingUnitsClass = s; server.SyncLobbyGlobalSettings(); - server.SendMessage("{0} changed Starting Units to {1}.".F(client.Name, s)); + server.SendMessage("{0} changed Starting Units to {1}.".F(client.Name, className)); return true; }}, diff --git a/OpenRA.Mods.RA/ServerTraits/LobbySettingsNotification.cs b/OpenRA.Mods.RA/ServerTraits/LobbySettingsNotification.cs new file mode 100644 index 0000000000..0cf68370c0 --- /dev/null +++ b/OpenRA.Mods.RA/ServerTraits/LobbySettingsNotification.cs @@ -0,0 +1,60 @@ +#region Copyright & License Information +/* + * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System.Linq; +using OpenRA.Network; +using OpenRA.Server; + +namespace OpenRA.Mods.RA.Server +{ + public class LobbySettingsNotification : ServerTrait, IClientJoined + { + public void ClientJoined(OpenRA.Server.Server server, Connection conn) + { + if (server.LobbyInfo.ClientWithIndex(conn.PlayerIndex).IsAdmin) + return; + + var defaults = new Session.Global(); + FieldLoader.Load(defaults, Game.modData.Manifest.LobbyDefaults); + + if (server.LobbyInfo.GlobalSettings.FragileAlliances != defaults.FragileAlliances) + server.SendOrderTo(conn, "Message", "Diplomacy Changes: {0}".F(server.LobbyInfo.GlobalSettings.FragileAlliances)); + + if (server.LobbyInfo.GlobalSettings.AllowCheats != defaults.AllowCheats) + server.SendOrderTo(conn, "Message", "Allow Cheats: {0}".F(server.LobbyInfo.GlobalSettings.AllowCheats)); + + if (server.LobbyInfo.GlobalSettings.Shroud != defaults.Shroud) + server.SendOrderTo(conn, "Message", "Shroud: {0}".F(server.LobbyInfo.GlobalSettings.Shroud)); + + if (server.LobbyInfo.GlobalSettings.Fog != defaults.Fog) + server.SendOrderTo(conn, "Message", "Fog of war: {0}".F(server.LobbyInfo.GlobalSettings.Fog)); + + if (server.LobbyInfo.GlobalSettings.Crates != defaults.Crates) + server.SendOrderTo(conn, "Message", "Crates Appear: {0}".F(server.LobbyInfo.GlobalSettings.Crates)); + + if (server.LobbyInfo.GlobalSettings.AllyBuildRadius != defaults.AllyBuildRadius) + server.SendOrderTo(conn, "Message", "Build off Ally ConYards: {0}".F(server.LobbyInfo.GlobalSettings.AllyBuildRadius)); + + if (server.LobbyInfo.GlobalSettings.StartingUnitsClass != defaults.StartingUnitsClass) + { + var startUnitsInfo = server.Map.Rules.Actors["world"].Traits.WithInterface(); + var selectedClass = startUnitsInfo.Where(u => u.Class == server.LobbyInfo.GlobalSettings.StartingUnitsClass).Select(u => u.ClassName).FirstOrDefault(); + var className = selectedClass != null ? selectedClass : server.LobbyInfo.GlobalSettings.StartingUnitsClass; + server.SendOrderTo(conn, "Message", "Starting Units: {0}".F(className)); + } + + if (server.LobbyInfo.GlobalSettings.StartingCash != defaults.StartingCash) + server.SendOrderTo(conn, "Message", "Starting Cash: ${0}".F(server.LobbyInfo.GlobalSettings.StartingCash)); + + if (server.LobbyInfo.GlobalSettings.TechLevel != defaults.TechLevel) + server.SendOrderTo(conn, "Message", "Tech Level: {0}".F(server.LobbyInfo.GlobalSettings.TechLevel)); + } + } +} \ No newline at end of file diff --git a/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs index 956e29d928..900c0a7049 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs @@ -371,17 +371,14 @@ namespace OpenRA.Mods.RA.Widgets.Logic var startingUnits = optionsBin.GetOrNull("STARTINGUNITS_DROPDOWNBUTTON"); if (startingUnits != null) { - var classNames = new Dictionary() + var startUnitsInfo = modRules.Actors["world"].Traits.WithInterface(); + var classes = startUnitsInfo.Select(a => a.Class).Distinct(); + Func className = c => { - { "none", "MCV Only" }, - { "light", "Light Support" }, - { "heavy", "Heavy Support" }, + var selectedClass = startUnitsInfo.Where(s => s.Class == c).Select(u => u.ClassName).FirstOrDefault(); + return selectedClass != null ? selectedClass : c; }; - Func className = c => classNames.ContainsKey(c) ? classNames[c] : c; - var classes = modRules.Actors["world"].Traits.WithInterface() - .Select(a => a.Class).Distinct(); - startingUnits.IsDisabled = () => Map.Status != MapStatus.Available || !Map.Map.Options.ConfigurableStartingUnits || configurationDisabled(); startingUnits.GetText = () => Map.Status != MapStatus.Available || !Map.Map.Options.ConfigurableStartingUnits ? "Not Available" : className(orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass); startingUnits.OnMouseDown = _ => diff --git a/mods/cnc/mod.yaml b/mods/cnc/mod.yaml index 38afa45035..348c62f414 100644 --- a/mods/cnc/mod.yaml +++ b/mods/cnc/mod.yaml @@ -152,6 +152,7 @@ ServerTraits: LobbyCommands PlayerPinger MasterServerPinger + LobbySettingsNotification LobbyDefaults: AllowCheats: false diff --git a/mods/cnc/rules/world.yaml b/mods/cnc/rules/world.yaml index fe0e1d98e3..7f130c290c 100644 --- a/mods/cnc/rules/world.yaml +++ b/mods/cnc/rules/world.yaml @@ -130,50 +130,60 @@ World: CreateMPPlayers: MPStartUnits@mcvonly: Class: none + ClassName: MCV Only Races: gdi, nod BaseActor: mcv MPStartUnits@defaultgdia: Class: light + ClassName: Light Support Races: gdi BaseActor: mcv SupportActors: e1,e1,e1,e1,e1,e3,e3,jeep MPStartUnits@defaultgdib: Class: light + ClassName: Light Support Races: gdi BaseActor: mcv SupportActors: e1,e1,e1,e1,e1,e1,e3,apc MPStartUnits@defaultnoda: Class: light + ClassName: Light Support Races: nod BaseActor: mcv SupportActors: e1,e1,e1,e1,e3,bggy,bike MPStartUnits@defaultnodb: Class: light + ClassName: Light Support Races: nod BaseActor: mcv SupportActors: e1,e1,e1,e3,e3,e3,bggy MPStartUnits@defaultnodc: Class: light + ClassName: Light Support Races: nod BaseActor: mcv SupportActors: e1,e1,e1,e1,e1,e1,e1,e3,bike MPStartUnits@heavynoda: Class: heavy + ClassName: Heavy Support Races: nod BaseActor: mcv SupportActors: e1,e1,e1,e1,e3,e3,ltnk,ltnk,ftnk MPStartUnits@heavynodb: Class: heavy + ClassName: Heavy Support Races: nod BaseActor: mcv SupportActors: e1,e1,e1,e1,e1,e3,e3,e3,ftnk,ftnk MPStartUnits@heavygdia: Class: heavy + ClassName: Heavy Support Races: gdi BaseActor: mcv SupportActors: e1,e1,e1,e1,e3,e3,jeep,mtnk,mtnk MPStartUnits@heavygdib: Class: heavy + ClassName: Heavy Support Races: gdi BaseActor: mcv SupportActors: e1,e1,e1,e1,e1,e2,e2,e2,e3,e3,apc,mtnk diff --git a/mods/d2k/mod.yaml b/mods/d2k/mod.yaml index e4703fe110..ad47ee8a29 100644 --- a/mods/d2k/mod.yaml +++ b/mods/d2k/mod.yaml @@ -134,6 +134,7 @@ ServerTraits: LobbyCommands PlayerPinger MasterServerPinger + LobbySettingsNotification LobbyDefaults: AllowCheats: false diff --git a/mods/d2k/rules/world.yaml b/mods/d2k/rules/world.yaml index d1dfee1296..e3d091e8b1 100644 --- a/mods/d2k/rules/world.yaml +++ b/mods/d2k/rules/world.yaml @@ -132,18 +132,22 @@ World: MPStartLocations: MPStartUnits@mcvatreides: Class: none + ClassName: MCV Only Races: atreides BaseActor: mcva MPStartUnits@mcvharkonnen: Class: none Races: harkonnen + ClassName: MCV Only BaseActor: mcvh MPStartUnits@mcvordos: Class: none + ClassName: MCV Only Races: ordos BaseActor: mcvo MPStartUnits@lightatreides: Class: light + ClassName: Light Support Races: atreides BaseActor: mcva SupportActors: rifle, rifle, bazooka, trike, quad @@ -151,6 +155,7 @@ World: OuterSupportRadius: 5 MPStartUnits@lightharkonnen: Class: light + ClassName: Light Support Races: harkonnen BaseActor: mcvh SupportActors: rifle, bazooka, grenadier, trike, quad @@ -158,6 +163,7 @@ World: OuterSupportRadius: 5 MPStartUnits@lightordos: Class: light + ClassName: Light Support Races: ordos BaseActor: mcvo SupportActors: rifle, rifle, engineer, raider, quad @@ -165,6 +171,7 @@ World: OuterSupportRadius: 5 MPStartUnits@heavyatreides: Class: heavy + ClassName: Heavy Support Races: atreides BaseActor: mcva SupportActors: rifle, bazooka, grenadier, trike, combata, missiletank @@ -172,6 +179,7 @@ World: OuterSupportRadius: 5 MPStartUnits@heavyharkonnen: Class: heavy + ClassName: Heavy Support Races: harkonnen BaseActor: mcvh SupportActors: rifle, bazooka, engineer, quad, combath, siegetank @@ -179,6 +187,7 @@ World: OuterSupportRadius: 5 MPStartUnits@heavyordos: Class: heavy + ClassName: Heavy Support Races: ordos BaseActor: mcvo SupportActors: rifle, bazooka, engineer, raider, combato, missiletank diff --git a/mods/ra/mod.yaml b/mods/ra/mod.yaml index 1bb66eab72..555af16850 100644 --- a/mods/ra/mod.yaml +++ b/mods/ra/mod.yaml @@ -150,6 +150,7 @@ ServerTraits: LobbyCommands PlayerPinger MasterServerPinger + LobbySettingsNotification LobbyDefaults: AllowCheats: false diff --git a/mods/ra/rules/world.yaml b/mods/ra/rules/world.yaml index 49cd27c7fd..078edd0d4c 100644 --- a/mods/ra/rules/world.yaml +++ b/mods/ra/rules/world.yaml @@ -137,10 +137,12 @@ World: CreateMPPlayers: MPStartUnits@mcvonly: Class: none + ClassName: MCV Only Races: soviet, allies BaseActor: mcv MPStartUnits@lightallies: Class: light + ClassName: Light Support Races: allies BaseActor: mcv SupportActors: e1,e1,e1,e3,e3,jeep,1tnk @@ -148,6 +150,7 @@ World: OuterSupportRadius: 5 MPStartUnits@lightsoviet: Class: light + ClassName: Light Support Races: soviet BaseActor: mcv SupportActors: e1,e1,e1,e3,e3,apc,ftrk @@ -155,6 +158,7 @@ World: OuterSupportRadius: 5 MPStartUnits@heavyallies: Class: heavy + ClassName: Heavy Support Races: allies BaseActor: mcv SupportActors: e1,e1,e1,e3,e3,jeep,1tnk,2tnk,2tnk,2tnk @@ -162,6 +166,7 @@ World: OuterSupportRadius: 5 MPStartUnits@heavysoviet: Class: heavy + ClassName: Heavy Support Races: soviet BaseActor: mcv SupportActors: e1,e1,e1,e3,e3,apc,ftrk,3tnk,3tnk diff --git a/mods/ts/mod.yaml b/mods/ts/mod.yaml index e889a0e0ae..0609f5075f 100644 --- a/mods/ts/mod.yaml +++ b/mods/ts/mod.yaml @@ -179,6 +179,7 @@ ServerTraits: LobbyCommands PlayerPinger MasterServerPinger + LobbySettingsNotification LobbyDefaults: AllowCheats: true diff --git a/mods/ts/rules/world.yaml b/mods/ts/rules/world.yaml index d57bab86bf..443eab8628 100644 --- a/mods/ts/rules/world.yaml +++ b/mods/ts/rules/world.yaml @@ -132,10 +132,13 @@ World: SpawnMapActors: CreateMPPlayers: MPStartUnits@MCV: + Class: none + ClassName: MCV Only Races: gdi, nod BaseActor: mcv MPStartUnits@TEST: Class: heavy + ClassName: Heavy Support Races: gdi,nod BaseActor: mcv SupportActors: e1,e2,e3,cyborg,cyc2,jumpjet,umagon,ghost,mmch,smech,hmec,bggy,bike,art2,ttnk,hvr,sonic,subtank,repair,4tnk