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;
}
[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]

View File

@@ -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);

View File

@@ -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<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;
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<INotifyObjectivesUpdated>())
@@ -110,11 +110,8 @@ namespace OpenRA.Mods.Common.Traits
foreach (var inou in player.PlayerActor.TraitsImplementing<INotifyObjectivesUpdated>())
inou.OnObjectiveCompleted(player, objectiveID);
if (objectives[objectiveID].Type == ObjectiveType.Primary)
{
var playerWon = objectives.Where(o => o.Type == ObjectiveType.Primary).All(o => o.State == ObjectiveState.Completed);
if (playerWon)
if (objectives[objectiveID].Required
&& objectives.Where(o => o.Required).All(o => o.State == ObjectiveState.Completed))
{
foreach (var inwc in player.PlayerActor.TraitsImplementing<INotifyWinStateChanged>())
inwc.OnPlayerWon(player);
@@ -122,7 +119,6 @@ namespace OpenRA.Mods.Common.Traits
CheckIfGameIsOver(player);
}
}
}
public void MarkFailed(Player player, int objectiveID)
{
@@ -133,11 +129,7 @@ namespace OpenRA.Mods.Common.Traits
foreach (var inou in player.PlayerActor.TraitsImplementing<INotifyObjectivesUpdated>())
inou.OnObjectiveFailed(player, objectiveID);
if (objectives[objectiveID].Type == ObjectiveType.Primary)
{
var playerLost = objectives.Where(o => o.Type == ObjectiveType.Primary).Any(o => o.State == ObjectiveState.Failed);
if (playerLost)
if (objectives[objectiveID].Required)
{
foreach (var inwc in player.PlayerActor.TraitsImplementing<INotifyWinStateChanged>())
inwc.OnPlayerLost(player);
@@ -145,7 +137,6 @@ namespace OpenRA.Mods.Common.Traits
CheckIfGameIsOver(player);
}
}
}
void CheckIfGameIsOver(Player player)
{

View File

@@ -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);

View File

@@ -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<LabelWidget>("OBJECTIVE_TYPE");
label.GetText = () => objective.Type == ObjectiveType.Primary ? "Primary" : "Secondary";
label.GetText = () => objective.Type;
var checkbox = widget.Get<CheckboxWidget>("OBJECTIVE_STATUS");
checkbox.IsChecked = () => objective.State != ObjectiveState.Incomplete;