From 33eeee4680f2d6dc3a4e5ead5edabac5482bf873 Mon Sep 17 00:00:00 2001 From: abcdefg30 Date: Fri, 21 Nov 2014 17:01:42 +0100 Subject: [PATCH] Added OnKilledOrCaptured and OnAllKilledOrCaptured --- .../Scripting/Global/TriggerGlobal.cs | 62 +++++++++++++++++++ OpenRA.Mods.RA/Scripting/ScriptTriggers.cs | 4 ++ mods/ra/maps/survival01/survival01.lua | 9 +-- 3 files changed, 69 insertions(+), 6 deletions(-) diff --git a/OpenRA.Mods.RA/Scripting/Global/TriggerGlobal.cs b/OpenRA.Mods.RA/Scripting/Global/TriggerGlobal.cs index 62dc04a764..1c48768fa4 100644 --- a/OpenRA.Mods.RA/Scripting/Global/TriggerGlobal.cs +++ b/OpenRA.Mods.RA/Scripting/Global/TriggerGlobal.cs @@ -220,6 +220,68 @@ namespace OpenRA.Mods.RA.Scripting GetScriptTriggers(a).RegisterCallback(Trigger.OnCapture, func, context); } + [Desc("Call a function when this actor is killed or captured. " + + "The callback function will be called as func().")] + public void OnKilledOrCaptured(Actor a, LuaFunction func) + { + var called = false; + + var copy = (LuaFunction)func.CopyReference(); + Action OnKilledOrCaptured = m => + { + try + { + if (called) + return; + + copy.Call().Dispose(); + copy.Dispose(); + called = true; + } + catch (Exception e) + { + context.FatalError(e.Message); + } + }; + + GetScriptTriggers(a).OnCapturedInternal += OnKilledOrCaptured; + GetScriptTriggers(a).OnKilledInternal += OnKilledOrCaptured; + } + + [Desc("Call a function when all of the actors in a group have been killed or captured. " + + "The callback function will be called as func().")] + public void OnAllKilledOrCaptured(Actor[] actors, LuaFunction func) + { + var group = actors.ToList(); + + var copy = (LuaFunction)func.CopyReference(); + Action OnMemberKilledOrCaptured = m => + { + try + { + if (!group.Contains(m)) + return; + + group.Remove(m); + if (!group.Any()) + { + copy.Call().Dispose(); + copy.Dispose(); + } + } + catch (Exception e) + { + context.FatalError(e.Message); + } + }; + + foreach (var a in group) + { + GetScriptTriggers(a).OnCapturedInternal += OnMemberKilledOrCaptured; + GetScriptTriggers(a).OnKilledInternal += OnMemberKilledOrCaptured; + } + } + [Desc("Call a function when a ground-based actor enters this cell footprint." + "Returns the trigger id for later removal using RemoveFootprintTrigger(int id)." + "The callback function will be called as func(Actor a, int id).")] diff --git a/OpenRA.Mods.RA/Scripting/ScriptTriggers.cs b/OpenRA.Mods.RA/Scripting/ScriptTriggers.cs index ffbe4902b1..f2bcb6b922 100644 --- a/OpenRA.Mods.RA/Scripting/ScriptTriggers.cs +++ b/OpenRA.Mods.RA/Scripting/ScriptTriggers.cs @@ -32,6 +32,7 @@ namespace OpenRA.Mods.RA.Scripting readonly World world; public event Action OnKilledInternal = _ => { }; + public event Action OnCapturedInternal = _ => { }; public event Action OnRemovedInternal = _ => { }; public event Action OnProducedInternal = (a, b) => { }; public event Action OnOtherProducedInternal = (a, b) => { }; @@ -236,6 +237,9 @@ namespace OpenRA.Mods.RA.Scripting return; } } + + // Run any internally bound callbacks + OnCapturedInternal(self); } public void Infiltrated(Actor self, Actor infiltrator) diff --git a/mods/ra/maps/survival01/survival01.lua b/mods/ra/maps/survival01/survival01.lua index 56d65c01e2..4eb867d4c2 100644 --- a/mods/ra/maps/survival01/survival01.lua +++ b/mods/ra/maps/survival01/survival01.lua @@ -63,7 +63,7 @@ SovietRallyPoints = { SovietRallyPoint1, SovietRallyPoint2, SovietRallyPoint3, S SovietGateRallyPoints = { AlliesBaseGate2, AlliesBaseGate2, AlliesBaseGate1, AlliesBaseGate1, AlliesBaseGate1 } Airfields = { SovietAirfield1, SovietAirfield2, SovietAirfield3 } -SovietBuildings = { Barrack1, SubPen, RadarDome, AdvancedPowerPlant1, AdvancedPowerPlant2, AdvancedPowerPlant3, WarFactory, Refinery, Silo1, Silo2, FlameTower1, FlameTower2, FlameTower3, Sam3, Sam4 } +SovietBuildings = { Barrack1, SubPen, RadarDome, AdvancedPowerPlant1, AdvancedPowerPlant2, AdvancedPowerPlant3, WarFactory, Refinery, Silo1, Silo2, FlameTower1, FlameTower2, FlameTower3, Sam1, Sam2, Sam3, Sam4, SovietAirfield1, SovietAirfield2, SovietAirfield3 } IdleTrigger = function(units, dest) Utils.Do(units, function(unit) @@ -321,7 +321,7 @@ InitMission = function() end) end) - Trigger.OnAllKilled(SovietBuildings, function() + Trigger.OnAllKilledOrCaptured(SovietBuildings, function() if DestroyObj then if not soviets.HasNoRequiredUnits() then KillObj = allies.AddPrimaryObjective("Kill all remaining soviet forces.") @@ -339,10 +339,7 @@ end SetupSoviets = function() Barrack1.IsPrimaryBuilding = true Barrack1.RallyPoint = SovietInfantryRally1.Location - Trigger.OnKilled(Barrack1, function() - SpawningInfantry = false - end) - Trigger.OnCapture(Barrack1, function() + Trigger.OnKilledOrCaptured(Barrack1, function() SpawningInfantry = false end)