diff --git a/OpenRA.Game/Map/Map.cs b/OpenRA.Game/Map/Map.cs index d2ac405aaa..0400dbda6d 100644 --- a/OpenRA.Game/Map/Map.cs +++ b/OpenRA.Game/Map/Map.cs @@ -68,6 +68,7 @@ namespace OpenRA public string TechLevel; public bool ConfigurableStartingUnits = true; public string[] Difficulties = { }; + public bool? ShortGame; public void UpdateServerSettings(Session.Global settings) { @@ -85,6 +86,8 @@ namespace OpenRA settings.StartingCash = StartingCash.Value; if (FragileAlliances.HasValue) settings.FragileAlliances = FragileAlliances.Value; + if (ShortGame.HasValue) + settings.ShortGame = ShortGame.Value; } } diff --git a/OpenRA.Game/Network/Session.cs b/OpenRA.Game/Network/Session.cs index 7c8bd1b632..bcb0d2dcd6 100644 --- a/OpenRA.Game/Network/Session.cs +++ b/OpenRA.Game/Network/Session.cs @@ -186,6 +186,7 @@ namespace OpenRA.Network public int StartingCash = 5000; public string TechLevel = "none"; public string StartingUnitsClass = "none"; + public bool ShortGame = true; public bool AllowVersionMismatch; public string GameUid; diff --git a/OpenRA.Mods.Common/PlayerExtensions.cs b/OpenRA.Mods.Common/PlayerExtensions.cs index 8ce8152701..7fef7480dc 100644 --- a/OpenRA.Mods.Common/PlayerExtensions.cs +++ b/OpenRA.Mods.Common/PlayerExtensions.cs @@ -17,7 +17,11 @@ namespace OpenRA.Mods.Common { public static bool HasNoRequiredUnits(this Player player) { - return player.World.ActorsWithTrait().All(p => p.Actor.Owner != player); + return !player.World.ActorsWithTrait().Any(p => + { + return p.Actor.Owner == player && + (player.World.LobbyInfo.GlobalSettings.ShortGame ? p.Trait.Info.RequiredForShortGame : p.Actor.IsInWorld); + }); } } } \ No newline at end of file diff --git a/OpenRA.Mods.Common/ServerTraits/LobbyCommands.cs b/OpenRA.Mods.Common/ServerTraits/LobbyCommands.cs index 659df43976..4d8b9287e1 100644 --- a/OpenRA.Mods.Common/ServerTraits/LobbyCommands.cs +++ b/OpenRA.Mods.Common/ServerTraits/LobbyCommands.cs @@ -809,6 +809,29 @@ namespace OpenRA.Mods.Common.Server server.SyncLobbyClients(); return true; } + }, + { "shortgame", + s => + { + if (!client.IsAdmin) + { + server.SendOrderTo(conn, "Message", "Only the host can set that option"); + return true; + } + + if (server.Map.Options.ShortGame.HasValue) + { + server.SendOrderTo(conn, "Message", "Map has disabled short game configuration"); + return true; + } + + bool.TryParse(s, out server.LobbyInfo.GlobalSettings.ShortGame); + server.SyncLobbyGlobalSettings(); + server.SendMessage("{0} {1} Short Game." + .F(client.Name, server.LobbyInfo.GlobalSettings.ShortGame ? "enabled" : "disabled")); + + return true; + } } }; diff --git a/OpenRA.Mods.Common/Traits/MustBeDestroyed.cs b/OpenRA.Mods.Common/Traits/MustBeDestroyed.cs index fe4a101744..d604b75ebc 100644 --- a/OpenRA.Mods.Common/Traits/MustBeDestroyed.cs +++ b/OpenRA.Mods.Common/Traits/MustBeDestroyed.cs @@ -12,7 +12,22 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { - [Desc("Tag trait for things that must be destroyed for a short game to end.")] - public class MustBeDestroyedInfo : TraitInfo { } - public class MustBeDestroyed { } + [Desc("Actors with this trait must be destroyed for a game to end.")] + public class MustBeDestroyedInfo : ITraitInfo + { + [Desc("In a short game only actors that have this value set to true need to be destroyed.")] + public bool RequiredForShortGame = false; + + public object Create(ActorInitializer init) { return new MustBeDestroyed(this); } + } + + public class MustBeDestroyed + { + public readonly MustBeDestroyedInfo Info; + + public MustBeDestroyed(MustBeDestroyedInfo info) + { + Info = info; + } + } } diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs index 54fc20a214..7878201840 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs @@ -690,6 +690,11 @@ namespace OpenRA.Mods.Common.UtilityCommands } } + // Adjust MustBeDestroyed for short games + if (engineVersion < 20141218) + if (depth == 1 && node.Key == "MustBeDestroyed") + node.Value.Nodes.Add(new MiniYamlNode("RequiredForShortGame", "true")); + UpgradeActorRules(engineVersion, ref node.Value.Nodes, node, depth + 1); } } diff --git a/OpenRA.Mods.RA/Scripting/Properties/MissionObjectiveProperties.cs b/OpenRA.Mods.RA/Scripting/Properties/MissionObjectiveProperties.cs index 1f08fff824..7df1ee0880 100644 --- a/OpenRA.Mods.RA/Scripting/Properties/MissionObjectiveProperties.cs +++ b/OpenRA.Mods.RA/Scripting/Properties/MissionObjectiveProperties.cs @@ -109,7 +109,8 @@ namespace OpenRA.Mods.RA.Scripting } [ScriptActorPropertyActivity] - [Desc("Returns true if this player has lost all units/actors that have the MustBeDestroyed trait.")] + [Desc("Returns true if this player has lost all units/actors that have" + + "the MustBeDestroyed trait (according to the short game option).")] public bool HasNoRequiredUnits() { return player.HasNoRequiredUnits();