diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 132c5cebc8..8d182014a0 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -485,6 +485,7 @@ + diff --git a/OpenRA.Mods.RA/Scripting/Global/TriggerGlobal.cs b/OpenRA.Mods.RA/Scripting/Global/TriggerGlobal.cs index a6faa0f59c..a2dca58344 100644 --- a/OpenRA.Mods.RA/Scripting/Global/TriggerGlobal.cs +++ b/OpenRA.Mods.RA/Scripting/Global/TriggerGlobal.cs @@ -109,6 +109,41 @@ namespace OpenRA.Mods.RA.Scripting GetScriptTriggers(a).RegisterCallback(Trigger.OnProduction, func, context); } + [Desc("Call a function when this player completes all primary objectives. " + + "The callback function will be called as func(Player player).")] + public void OnPlayerWon(Player player, LuaFunction func) + { + GetScriptTriggers(player.PlayerActor).RegisterCallback(Trigger.OnPlayerWon, func, context); + } + + [Desc("Call a function when this player fails any primary objective. " + + "The callback function will be called as func(Player player).")] + public void OnPlayerLost(Player player, LuaFunction func) + { + GetScriptTriggers(player.PlayerActor).RegisterCallback(Trigger.OnPlayerLost, func, context); + } + + [Desc("Call a function when this player is assigned a new objective. " + + "The callback function will be called as func(Player player, int objectiveID).")] + public void OnObjectiveAdded(Player player, LuaFunction func) + { + GetScriptTriggers(player.PlayerActor).RegisterCallback(Trigger.OnObjectiveAdded, func, context); + } + + [Desc("Call a function when this player completes an objective " + + "The callback function will be called as func(Player player, int objectiveID).")] + public void OnObjectiveCompleted(Player player, LuaFunction func) + { + GetScriptTriggers(player.PlayerActor).RegisterCallback(Trigger.OnObjectiveCompleted, func, context); + } + + [Desc("Call a function when this player fails an objective " + + "The callback function will be called as func(Player player, int objectiveID).")] + public void OnObjectiveFailed(Player player, LuaFunction func) + { + GetScriptTriggers(player.PlayerActor).RegisterCallback(Trigger.OnObjectiveFailed, func, context); + } + [Desc("Removes all triggers from this actor")] public void ClearAll(Actor a) { diff --git a/OpenRA.Mods.RA/Scripting/Properties/MissionObjectiveProperties.cs b/OpenRA.Mods.RA/Scripting/Properties/MissionObjectiveProperties.cs new file mode 100644 index 0000000000..b11a6b6af4 --- /dev/null +++ b/OpenRA.Mods.RA/Scripting/Properties/MissionObjectiveProperties.cs @@ -0,0 +1,70 @@ +#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; +using OpenRA.Traits; +using OpenRA.Scripting; +using OpenRA.Mods.RA; + +namespace OpenRA.Mods.RA.Scripting +{ + [ScriptPropertyGroup("MissionObjectives")] + public class MissionObjectiveProperties : ScriptPlayerProperties + { + readonly MissionObjectives mo; + + public MissionObjectiveProperties(Player player) + : base(player) + { + mo = player.PlayerActor.Trait(); + } + + [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); + } + + [ScriptActorPropertyActivity] + [Desc("Add a secondary 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 AddSecondaryObjective(string description) + { + return mo.Add(player, description, ObjectiveType.Secondary); + } + + [ScriptActorPropertyActivity] + [Desc("Mark an objective as completed. This needs the objective ID returned " + + "by AddObjective as argument. When the player has completed all primary " + + "objectives, (s)he has won the game.")] + public void MarkCompletedObjective(int id) + { + mo.MarkCompleted(player, id); + } + + [ScriptActorPropertyActivity] + [Desc("Mark an objective as failed. This needs the objective ID returned " + + "by AddObjective as argument. Secondary objectives do not have any " + + "influence whatsoever on the outcome of the game.")] + public void MarkFailedObjective(int id) + { + mo.MarkFailed(player, id); + } + + [ScriptActorPropertyActivity] + [Desc("Returns true if 'player' has lost all units/actors that have the 'MustBeDestroyed' trait.")] + public bool HasNoRequiredUnits() + { + return player.HasNoRequiredUnits(); + } + } +} diff --git a/OpenRA.Mods.RA/Scripting/ScriptTriggers.cs b/OpenRA.Mods.RA/Scripting/ScriptTriggers.cs index 0961e31bf6..9c2a8e597b 100644 --- a/OpenRA.Mods.RA/Scripting/ScriptTriggers.cs +++ b/OpenRA.Mods.RA/Scripting/ScriptTriggers.cs @@ -18,12 +18,12 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Scripting { - public enum Trigger { OnIdle, OnDamaged, OnKilled, OnProduction }; + public enum Trigger { OnIdle, OnDamaged, OnKilled, OnProduction, OnPlayerWon, OnPlayerLost, OnObjectiveAdded, OnObjectiveCompleted, OnObjectiveFailed }; [Desc("Allows map scripts to attach triggers to this actor via the Triggers global.")] public class ScriptTriggersInfo : TraitInfo { } - public sealed class ScriptTriggers : INotifyIdle, INotifyDamage, INotifyKilled, INotifyProduction, IDisposable + public sealed class ScriptTriggers : INotifyIdle, INotifyDamage, INotifyKilled, INotifyProduction, INotifyObjectivesUpdated, IDisposable { public event Action OnKilledInternal = _ => {}; @@ -90,6 +90,62 @@ namespace OpenRA.Mods.RA.Scripting } } + public void OnPlayerWon(Player player) + { + foreach (var f in Triggers[Trigger.OnPlayerWon]) + { + var a = player.ToLuaValue(f.Second); + f.First.Call(a).Dispose(); + a.Dispose(); + } + } + + public void OnPlayerLost(Player player) + { + foreach (var f in Triggers[Trigger.OnPlayerLost]) + { + var a = player.ToLuaValue(f.Second); + f.First.Call(a).Dispose(); + a.Dispose(); + } + } + + public void OnObjectiveAdded(Player player, int id) + { + foreach (var f in Triggers[Trigger.OnObjectiveAdded]) + { + var a = player.ToLuaValue(f.Second); + var b = id.ToLuaValue(f.Second); + f.First.Call(a, b).Dispose(); + a.Dispose(); + b.Dispose(); + } + } + + public void OnObjectiveCompleted(Player player, int id) + { + foreach (var f in Triggers[Trigger.OnObjectiveCompleted]) + { + var a = player.ToLuaValue(f.Second); + var b = id.ToLuaValue(f.Second); + f.First.Call(a, b).Dispose(); + a.Dispose(); + b.Dispose(); + } + } + + public void OnObjectiveFailed(Player player, int id) + { + foreach (var f in Triggers[Trigger.OnObjectiveFailed]) + { + var a = player.ToLuaValue(f.Second); + var b = id.ToLuaValue(f.Second); + f.First.Call(a, b).Dispose(); + a.Dispose(); + b.Dispose(); + } + } + public void Clear(Trigger trigger) { Triggers[trigger].Clear(); diff --git a/mods/cnc/rules/player.yaml b/mods/cnc/rules/player.yaml index 6fabed5517..f177d84ce9 100644 --- a/mods/cnc/rules/player.yaml +++ b/mods/cnc/rules/player.yaml @@ -2,6 +2,7 @@ Player: PlaceBuilding: TechTree: SupportPowerManager: + ScriptTriggers: MissionObjectives: ConquestVictoryConditions: PowerManager: diff --git a/mods/d2k/rules/player.yaml b/mods/d2k/rules/player.yaml index 4cbf92ba82..e55955cda7 100644 --- a/mods/d2k/rules/player.yaml +++ b/mods/d2k/rules/player.yaml @@ -34,6 +34,7 @@ Player: BlockedAudio: NoRoom PlaceBuilding: SupportPowerManager: + ScriptTriggers: MissionObjectives: ConquestVictoryConditions: PowerManager: diff --git a/mods/ra/rules/player.yaml b/mods/ra/rules/player.yaml index dfc510caf6..fdf86884bc 100644 --- a/mods/ra/rules/player.yaml +++ b/mods/ra/rules/player.yaml @@ -42,6 +42,7 @@ Player: RequireOwner: false PlaceBuilding: SupportPowerManager: + ScriptTriggers: MissionObjectives: ConquestVictoryConditions: PowerManager: diff --git a/mods/ts/rules/player.yaml b/mods/ts/rules/player.yaml index 48e5ad9742..80a376ccd8 100644 --- a/mods/ts/rules/player.yaml +++ b/mods/ts/rules/player.yaml @@ -26,6 +26,7 @@ Player: LowPowerSlowdown: 3 PlaceBuilding: SupportPowerManager: + ScriptTriggers: MissionObjectives: ConquestVictoryConditions: PowerManager: