diff --git a/OpenRA.Game/Traits/World/ActorMap.cs b/OpenRA.Game/Traits/World/ActorMap.cs index fa6014a108..c259eb4b5f 100644 --- a/OpenRA.Game/Traits/World/ActorMap.cs +++ b/OpenRA.Game/Traits/World/ActorMap.cs @@ -137,11 +137,13 @@ namespace OpenRA.Traits var entered = currentActors.Except(oldActors); var exited = oldActors.Except(currentActors); - foreach (var a in entered) - onActorEntered(a); + if (onActorEntered != null) + foreach (var a in entered) + onActorEntered(a); - foreach (var a in exited) - onActorExited(a); + if (onActorExited != null) + foreach (var a in exited) + onActorExited(a); Dirty = false; } diff --git a/OpenRA.Mods.RA/Scripting/Global/TriggerGlobal.cs b/OpenRA.Mods.RA/Scripting/Global/TriggerGlobal.cs index e2c6c9838c..62dc04a764 100644 --- a/OpenRA.Mods.RA/Scripting/Global/TriggerGlobal.cs +++ b/OpenRA.Mods.RA/Scripting/Global/TriggerGlobal.cs @@ -278,6 +278,64 @@ namespace OpenRA.Mods.RA.Scripting context.World.ActorMap.RemoveCellTrigger(id); } + [Desc("Call a function when an actor enters this range." + + "Returns the trigger id for later removal using RemoveProximityTrigger(int id)." + + "The callback function will be called as func(Actor a, int id).")] + public int OnEnteredProximityTrigger(WPos pos, WRange range, LuaFunction func) + { + var triggerId = 0; + var onEntry = (LuaFunction)func.CopyReference(); + Action invokeEntry = a => + { + try + { + using (var luaActor = a.ToLuaValue(context)) + using (var id = triggerId.ToLuaValue(context)) + onEntry.Call(luaActor, id).Dispose(); + } + catch (Exception e) + { + context.FatalError(e.Message); + } + }; + + triggerId = context.World.ActorMap.AddProximityTrigger(pos, range, invokeEntry, null); + + return triggerId; + } + + [Desc("Call a function when an actor leaves this range." + + "Returns the trigger id for later removal using RemoveProximityTrigger(int id)." + + "The callback function will be called as func(Actor a, int id).")] + public int OnExitedProximityTrigger(WPos pos, WRange range, LuaFunction func) + { + var triggerId = 0; + var onExit = (LuaFunction)func.CopyReference(); + Action invokeExit = a => + { + try + { + using (var luaActor = a.ToLuaValue(context)) + using (var id = triggerId.ToLuaValue(context)) + onExit.Call(luaActor, id).Dispose(); + } + catch (Exception e) + { + context.FatalError(e.Message); + } + }; + + triggerId = context.World.ActorMap.AddProximityTrigger(pos, range, null, invokeExit); + + return triggerId; + } + + [Desc("Removes a previously created proximitry trigger.")] + public void RemoveProximityTrigger(int id) + { + context.World.ActorMap.RemoveProximityTrigger(id); + } + [Desc("Call a function when this actor is infiltrated. The callback function " + "will be called as func(Actor self, Actor infiltrator).")] public void OnInfiltrated(Actor a, LuaFunction func)