Add support for arbitrary objective type names

This commit is contained in:
abcdefg30
2019-03-07 19:46:06 +01:00
committed by reaperrr
parent 38b3a4a668
commit b2278e85f0
5 changed files with 33 additions and 35 deletions

View File

@@ -29,12 +29,20 @@ namespace OpenRA.Mods.Common.Scripting
shortGame = player.World.WorldActor.Trait<MapOptions>().ShortGame; shortGame = player.World.WorldActor.Trait<MapOptions>().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] [ScriptActorPropertyActivity]
[Desc("Add a primary mission objective for this player. The function returns the " + [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.")] "ID of the newly created objective, so that it can be referred to later.")]
public int AddPrimaryObjective(string description) public int AddPrimaryObjective(string description)
{ {
return mo.Add(Player, description, ObjectiveType.Primary); return AddObjective(description);
} }
[ScriptActorPropertyActivity] [ScriptActorPropertyActivity]
@@ -42,7 +50,7 @@ namespace OpenRA.Mods.Common.Scripting
"ID of the newly created objective, so that it can be referred to later.")] "ID of the newly created objective, so that it can be referred to later.")]
public int AddSecondaryObjective(string description) public int AddSecondaryObjective(string description)
{ {
return mo.Add(Player, description, ObjectiveType.Secondary); return AddObjective(description, "Secondary", false);
} }
[ScriptActorPropertyActivity] [ScriptActorPropertyActivity]
@@ -106,7 +114,7 @@ namespace OpenRA.Mods.Common.Scripting
if (id < 0 || id >= mo.Objectives.Count) if (id < 0 || id >= mo.Objectives.Count)
throw new LuaException("Objective ID is out of range."); throw new LuaException("Objective ID is out of range.");
return mo.Objectives[id].Type == ObjectiveType.Primary ? "Primary" : "Secondary"; return mo.Objectives[id].Type;
} }
[ScriptActorPropertyActivity] [ScriptActorPropertyActivity]

View File

@@ -46,10 +46,11 @@ namespace OpenRA.Mods.Common.Traits
void ITick.Tick(Actor self) 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) 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)) if (!self.Owner.NonCombatant && self.Owner.HasNoRequiredUnits(shortGame))
mo.MarkFailed(self.Owner, objectiveID); mo.MarkFailed(self.Owner, objectiveID);

View File

@@ -16,19 +16,20 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
{ {
public enum ObjectiveType { Primary, Secondary }
public enum ObjectiveState { Incomplete, Completed, Failed } public enum ObjectiveState { Incomplete, Completed, Failed }
public class MissionObjective public class MissionObjective
{ {
public readonly ObjectiveType Type; public readonly bool Required;
public readonly string Description; public readonly string Description;
public readonly string Type;
public ObjectiveState State; public ObjectiveState State;
public MissionObjective(ObjectiveType type, string description) public MissionObjective(string description, string type, bool required = true)
{ {
Type = type;
Description = description; Description = description;
Type = type;
Required = required;
State = ObjectiveState.Incomplete; State = ObjectiveState.Incomplete;
} }
} }
@@ -88,11 +89,10 @@ namespace OpenRA.Mods.Common.Traits
Objectives = new ReadOnlyList<MissionObjective>(objectives); Objectives = new ReadOnlyList<MissionObjective>(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; var newID = objectives.Count;
objectives.Insert(newID, new MissionObjective(description, type, required));
objectives.Insert(newID, new MissionObjective(type, description));
ObjectiveAdded(player, inhibitAnnouncement); ObjectiveAdded(player, inhibitAnnouncement);
foreach (var inou in player.PlayerActor.TraitsImplementing<INotifyObjectivesUpdated>()) foreach (var inou in player.PlayerActor.TraitsImplementing<INotifyObjectivesUpdated>())
@@ -110,17 +110,13 @@ namespace OpenRA.Mods.Common.Traits
foreach (var inou in player.PlayerActor.TraitsImplementing<INotifyObjectivesUpdated>()) foreach (var inou in player.PlayerActor.TraitsImplementing<INotifyObjectivesUpdated>())
inou.OnObjectiveCompleted(player, objectiveID); 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<INotifyWinStateChanged>())
inwc.OnPlayerWon(player);
if (playerWon) CheckIfGameIsOver(player);
{
foreach (var inwc in player.PlayerActor.TraitsImplementing<INotifyWinStateChanged>())
inwc.OnPlayerWon(player);
CheckIfGameIsOver(player);
}
} }
} }
@@ -133,17 +129,12 @@ namespace OpenRA.Mods.Common.Traits
foreach (var inou in player.PlayerActor.TraitsImplementing<INotifyObjectivesUpdated>()) foreach (var inou in player.PlayerActor.TraitsImplementing<INotifyObjectivesUpdated>())
inou.OnObjectiveFailed(player, objectiveID); 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<INotifyWinStateChanged>())
inwc.OnPlayerLost(player);
if (playerLost) CheckIfGameIsOver(player);
{
foreach (var inwc in player.PlayerActor.TraitsImplementing<INotifyWinStateChanged>())
inwc.OnPlayerLost(player);
CheckIfGameIsOver(player);
}
} }
} }

View File

@@ -79,7 +79,7 @@ namespace OpenRA.Mods.Common.Traits
return; return;
if (objectiveID < 0) 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)) if (!self.Owner.NonCombatant && self.Owner.HasNoRequiredUnits(shortGame))
mo.MarkFailed(self.Owner, objectiveID); mo.MarkFailed(self.Owner, objectiveID);

View File

@@ -62,13 +62,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{ {
parent.RemoveChildren(); 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 widget = template.Clone();
var label = widget.Get<LabelWidget>("OBJECTIVE_TYPE"); var label = widget.Get<LabelWidget>("OBJECTIVE_TYPE");
label.GetText = () => objective.Type == ObjectiveType.Primary ? "Primary" : "Secondary"; label.GetText = () => objective.Type;
var checkbox = widget.Get<CheckboxWidget>("OBJECTIVE_STATUS"); var checkbox = widget.Get<CheckboxWidget>("OBJECTIVE_STATUS");
checkbox.IsChecked = () => objective.State != ObjectiveState.Incomplete; checkbox.IsChecked = () => objective.State != ObjectiveState.Incomplete;