diff --git a/OpenRA.Mods.Common/Scripting/Global/TriggerGlobal.cs b/OpenRA.Mods.Common/Scripting/Global/TriggerGlobal.cs index 195639f7e8..aa034cd795 100644 --- a/OpenRA.Mods.Common/Scripting/Global/TriggerGlobal.cs +++ b/OpenRA.Mods.Common/Scripting/Global/TriggerGlobal.cs @@ -51,6 +51,20 @@ namespace OpenRA.Mods.Common.Scripting Context.World.AddFrameEndTask(w => w.Add(new DelayedAction(delay, doCall))); } + [Desc("Call a function for each passenger when it enters a transport. " + + "The callback function will be called as func(Actor transport, Actor passenger).")] + public void OnPassengerEntered(Actor a, LuaFunction func) + { + GetScriptTriggers(a).RegisterCallback(Trigger.OnPassengerEntered, func, Context); + } + + [Desc("Call a function for each passenger when it exits a transport. " + + "The callback function will be called as func(Actor transport, Actor passenger).")] + public void OnPassengerExited(Actor a, LuaFunction func) + { + GetScriptTriggers(a).RegisterCallback(Trigger.OnPassengerExited, func, Context); + } + [Desc("Call a function each tick that the actor is idle. " + "The callback function will be called as func(Actor self).")] public void OnIdle(Actor a, LuaFunction func) diff --git a/OpenRA.Mods.Common/Scripting/ScriptTriggers.cs b/OpenRA.Mods.Common/Scripting/ScriptTriggers.cs index 271435e7a1..ac820884b5 100644 --- a/OpenRA.Mods.Common/Scripting/ScriptTriggers.cs +++ b/OpenRA.Mods.Common/Scripting/ScriptTriggers.cs @@ -12,6 +12,7 @@ using System; using System.Collections.Generic; using Eluant; +using OpenRA.Mods.Common.Traits; using OpenRA.Scripting; using OpenRA.Traits; @@ -21,7 +22,8 @@ namespace OpenRA.Mods.Common.Scripting { OnIdle, OnDamaged, OnKilled, OnProduction, OnOtherProduction, OnPlayerWon, OnPlayerLost, OnObjectiveAdded, OnObjectiveCompleted, OnObjectiveFailed, OnCapture, OnInfiltrated, - OnAddedToWorld, OnRemovedFromWorld, OnDiscovered, OnPlayerDiscovered + OnAddedToWorld, OnRemovedFromWorld, OnDiscovered, OnPlayerDiscovered, + OnPassengerEntered, OnPassengerExited } [Desc("Allows map scripts to attach triggers to this actor via the Triggers global.")] @@ -31,7 +33,8 @@ namespace OpenRA.Mods.Common.Scripting } public sealed class ScriptTriggers : INotifyIdle, INotifyDamage, INotifyKilled, INotifyProduction, INotifyOtherProduction, - INotifyObjectivesUpdated, INotifyCapture, INotifyInfiltrated, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyDiscovered, INotifyActorDisposing + INotifyObjectivesUpdated, INotifyCapture, INotifyInfiltrated, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyDiscovered, INotifyActorDisposing, + INotifyPassengerEntered, INotifyPassengerExited { readonly World world; readonly Actor self; @@ -421,6 +424,48 @@ namespace OpenRA.Mods.Common.Scripting } } + void INotifyPassengerEntered.OnPassengerEntered(Actor self, Actor passenger) + { + if (world.Disposing) + return; + + foreach (var f in Triggerables(Trigger.OnPassengerEntered)) + { + try + { + using (var trans = self.ToLuaValue(f.Context)) + using (var pass = passenger.ToLuaValue(f.Context)) + f.Function.Call(trans, pass).Dispose(); + } + catch (Exception ex) + { + f.Context.FatalError(ex.Message); + return; + } + } + } + + void INotifyPassengerExited.OnPassengerExited(Actor self, Actor passenger) + { + if (world.Disposing) + return; + + foreach (var f in Triggerables(Trigger.OnPassengerExited)) + { + try + { + using (var trans = self.ToLuaValue(f.Context)) + using (var pass = passenger.ToLuaValue(f.Context)) + f.Function.Call(trans, pass).Dispose(); + } + catch (Exception ex) + { + f.Context.FatalError(ex.Message); + return; + } + } + } + public void Clear(Trigger trigger) { world.AddFrameEndTask(w => diff --git a/OpenRA.Mods.Common/Traits/Attack/AttackGarrisoned.cs b/OpenRA.Mods.Common/Traits/Attack/AttackGarrisoned.cs index e4bef9512a..3243247c96 100644 --- a/OpenRA.Mods.Common/Traits/Attack/AttackGarrisoned.cs +++ b/OpenRA.Mods.Common/Traits/Attack/AttackGarrisoned.cs @@ -93,7 +93,7 @@ namespace OpenRA.Mods.Common.Traits getArmaments = () => armaments; } - public void PassengerEntered(Actor self, Actor passenger) + void INotifyPassengerEntered.OnPassengerEntered(Actor self, Actor passenger) { paxFacing.Add(passenger, passenger.Trait()); paxPos.Add(passenger, passenger.Trait()); @@ -103,7 +103,7 @@ namespace OpenRA.Mods.Common.Traits .Where(a => Info.Armaments.Contains(a.Info.Name))); } - public void PassengerExited(Actor self, Actor passenger) + void INotifyPassengerExited.OnPassengerExited(Actor self, Actor passenger) { paxFacing.Remove(passenger); paxPos.Remove(passenger); diff --git a/OpenRA.Mods.Common/Traits/Cargo.cs b/OpenRA.Mods.Common/Traits/Cargo.cs index e0895b0792..e319885829 100644 --- a/OpenRA.Mods.Common/Traits/Cargo.cs +++ b/OpenRA.Mods.Common/Traits/Cargo.cs @@ -246,7 +246,7 @@ namespace OpenRA.Mods.Common.Traits SetPassengerFacing(a); foreach (var npe in self.TraitsImplementing()) - npe.PassengerExited(self, a); + npe.OnPassengerExited(self, a); var p = a.Trait(); p.Transport = null; @@ -311,7 +311,7 @@ namespace OpenRA.Mods.Common.Traits } foreach (var npe in self.TraitsImplementing()) - npe.PassengerEntered(self, a); + npe.OnPassengerEntered(self, a); var p = a.Trait(); p.Transport = self; @@ -406,7 +406,7 @@ namespace OpenRA.Mods.Common.Traits c.Trait().Transport = self; foreach (var npe in self.TraitsImplementing()) - npe.PassengerEntered(self, c); + npe.OnPassengerEntered(self, c); } initialized = true; @@ -421,8 +421,11 @@ namespace OpenRA.Mods.Common.Traits } } - public interface INotifyPassengerEntered { void PassengerEntered(Actor self, Actor passenger); } - public interface INotifyPassengerExited { void PassengerExited(Actor self, Actor passenger); } + [RequireExplicitImplementation] + public interface INotifyPassengerEntered { void OnPassengerEntered(Actor self, Actor passenger); } + + [RequireExplicitImplementation] + public interface INotifyPassengerExited { void OnPassengerExited(Actor self, Actor passenger); } public class RuntimeCargoInit : IActorInit, ISuppressInitExport {