diff --git a/OpenRA.Mods.Common/Scripting/Properties/MissionObjectiveProperties.cs b/OpenRA.Mods.Common/Scripting/Properties/MissionObjectiveProperties.cs index c2e67c76bc..94618276b2 100644 --- a/OpenRA.Mods.Common/Scripting/Properties/MissionObjectiveProperties.cs +++ b/OpenRA.Mods.Common/Scripting/Properties/MissionObjectiveProperties.cs @@ -29,12 +29,20 @@ namespace OpenRA.Mods.Common.Scripting shortGame = player.World.WorldActor.Trait().ShortGame; } + [ScriptActorPropertyActivity] + [Desc("Add a mission objective for this player. The function returns the " + + "ID of the newly created objective, so that it can be referred to later.")] + public int AddObjective(string description, string type = "Primary", bool required = true) + { + return mo.Add(Player, description, type, required); + } + [ScriptActorPropertyActivity] [Desc("Add a primary mission objective for this player. The function returns the " + "ID of the newly created objective, so that it can be referred to later.")] public int AddPrimaryObjective(string description) { - return mo.Add(Player, description, ObjectiveType.Primary); + return AddObjective(description); } [ScriptActorPropertyActivity] @@ -42,7 +50,7 @@ namespace OpenRA.Mods.Common.Scripting "ID of the newly created objective, so that it can be referred to later.")] public int AddSecondaryObjective(string description) { - return mo.Add(Player, description, ObjectiveType.Secondary); + return AddObjective(description, "Secondary", false); } [ScriptActorPropertyActivity] @@ -106,7 +114,7 @@ namespace OpenRA.Mods.Common.Scripting if (id < 0 || id >= mo.Objectives.Count) throw new LuaException("Objective ID is out of range."); - return mo.Objectives[id].Type == ObjectiveType.Primary ? "Primary" : "Secondary"; + return mo.Objectives[id].Type; } [ScriptActorPropertyActivity] diff --git a/OpenRA.Mods.Common/Traits/Player/ConquestVictoryConditions.cs b/OpenRA.Mods.Common/Traits/Player/ConquestVictoryConditions.cs index fd9126f4d7..3c83f2076a 100644 --- a/OpenRA.Mods.Common/Traits/Player/ConquestVictoryConditions.cs +++ b/OpenRA.Mods.Common/Traits/Player/ConquestVictoryConditions.cs @@ -46,10 +46,11 @@ namespace OpenRA.Mods.Common.Traits void ITick.Tick(Actor self) { - if (self.Owner.WinState != WinState.Undefined || self.Owner.NonCombatant) return; + if (self.Owner.WinState != WinState.Undefined || self.Owner.NonCombatant) + return; if (objectiveID < 0) - objectiveID = mo.Add(self.Owner, info.Objective, ObjectiveType.Primary, true); + objectiveID = mo.Add(self.Owner, info.Objective, "Primary", inhibitAnnouncement: true); if (!self.Owner.NonCombatant && self.Owner.HasNoRequiredUnits(shortGame)) mo.MarkFailed(self.Owner, objectiveID); diff --git a/OpenRA.Mods.Common/Traits/Player/MissionObjectives.cs b/OpenRA.Mods.Common/Traits/Player/MissionObjectives.cs index c76fc2bfb7..af58deec6a 100644 --- a/OpenRA.Mods.Common/Traits/Player/MissionObjectives.cs +++ b/OpenRA.Mods.Common/Traits/Player/MissionObjectives.cs @@ -16,19 +16,20 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { - public enum ObjectiveType { Primary, Secondary } public enum ObjectiveState { Incomplete, Completed, Failed } public class MissionObjective { - public readonly ObjectiveType Type; + public readonly bool Required; public readonly string Description; + public readonly string Type; public ObjectiveState State; - public MissionObjective(ObjectiveType type, string description) + public MissionObjective(string description, string type, bool required = true) { - Type = type; Description = description; + Type = type; + Required = required; State = ObjectiveState.Incomplete; } } @@ -88,11 +89,10 @@ namespace OpenRA.Mods.Common.Traits Objectives = new ReadOnlyList(objectives); } - public int Add(Player player, string description, ObjectiveType type = ObjectiveType.Primary, bool inhibitAnnouncement = false) + public int Add(Player player, string description, string type, bool required = true, bool inhibitAnnouncement = false) { var newID = objectives.Count; - - objectives.Insert(newID, new MissionObjective(type, description)); + objectives.Insert(newID, new MissionObjective(description, type, required)); ObjectiveAdded(player, inhibitAnnouncement); foreach (var inou in player.PlayerActor.TraitsImplementing()) @@ -110,17 +110,13 @@ namespace OpenRA.Mods.Common.Traits foreach (var inou in player.PlayerActor.TraitsImplementing()) inou.OnObjectiveCompleted(player, objectiveID); - if (objectives[objectiveID].Type == ObjectiveType.Primary) + if (objectives[objectiveID].Required + && objectives.Where(o => o.Required).All(o => o.State == ObjectiveState.Completed)) { - var playerWon = objectives.Where(o => o.Type == ObjectiveType.Primary).All(o => o.State == ObjectiveState.Completed); + foreach (var inwc in player.PlayerActor.TraitsImplementing()) + inwc.OnPlayerWon(player); - if (playerWon) - { - foreach (var inwc in player.PlayerActor.TraitsImplementing()) - inwc.OnPlayerWon(player); - - CheckIfGameIsOver(player); - } + CheckIfGameIsOver(player); } } @@ -133,17 +129,12 @@ namespace OpenRA.Mods.Common.Traits foreach (var inou in player.PlayerActor.TraitsImplementing()) inou.OnObjectiveFailed(player, objectiveID); - if (objectives[objectiveID].Type == ObjectiveType.Primary) + if (objectives[objectiveID].Required) { - var playerLost = objectives.Where(o => o.Type == ObjectiveType.Primary).Any(o => o.State == ObjectiveState.Failed); + foreach (var inwc in player.PlayerActor.TraitsImplementing()) + inwc.OnPlayerLost(player); - if (playerLost) - { - foreach (var inwc in player.PlayerActor.TraitsImplementing()) - inwc.OnPlayerLost(player); - - CheckIfGameIsOver(player); - } + CheckIfGameIsOver(player); } } diff --git a/OpenRA.Mods.Common/Traits/Player/StrategicVictoryConditions.cs b/OpenRA.Mods.Common/Traits/Player/StrategicVictoryConditions.cs index d4c2d8d29f..66dae62808 100644 --- a/OpenRA.Mods.Common/Traits/Player/StrategicVictoryConditions.cs +++ b/OpenRA.Mods.Common/Traits/Player/StrategicVictoryConditions.cs @@ -79,7 +79,7 @@ namespace OpenRA.Mods.Common.Traits return; if (objectiveID < 0) - objectiveID = mo.Add(player, info.Objective, ObjectiveType.Primary, true); + objectiveID = mo.Add(player, info.Objective, "Primary", inhibitAnnouncement: true); if (!self.Owner.NonCombatant && self.Owner.HasNoRequiredUnits(shortGame)) mo.MarkFailed(self.Owner, objectiveID); diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/GameInfoObjectivesLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/GameInfoObjectivesLogic.cs index 0fe40696c5..da4e8f0647 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/GameInfoObjectivesLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/GameInfoObjectivesLogic.cs @@ -62,13 +62,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic { parent.RemoveChildren(); - foreach (var o in mo.Objectives.OrderBy(o => o.Type)) + foreach (var objective in mo.Objectives.OrderBy(o => o.Type)) { - var objective = o; // Work around the loop closure issue in older versions of C# var widget = template.Clone(); - var label = widget.Get("OBJECTIVE_TYPE"); - label.GetText = () => objective.Type == ObjectiveType.Primary ? "Primary" : "Secondary"; + label.GetText = () => objective.Type; var checkbox = widget.Get("OBJECTIVE_STATUS"); checkbox.IsChecked = () => objective.State != ObjectiveState.Incomplete;