diff --git a/OpenRA.Mods.Common/Scripting/Global/MapGlobal.cs b/OpenRA.Mods.Common/Scripting/Global/MapGlobal.cs index 98f9583407..71384d39c3 100644 --- a/OpenRA.Mods.Common/Scripting/Global/MapGlobal.cs +++ b/OpenRA.Mods.Common/Scripting/Global/MapGlobal.cs @@ -21,10 +21,13 @@ namespace OpenRA.Mods.Common.Scripting public class MapGlobal : ScriptGlobal { readonly SpawnMapActors sma; + readonly World world; + public MapGlobal(ScriptContext context) : base(context) { sma = context.World.WorldActor.Trait(); + world = context.World; // Register map actors as globals (yuck!) foreach (var kv in sma.Actors) @@ -133,5 +136,8 @@ namespace OpenRA.Mods.Common.Scripting { return Context.World.ActorsHavingTrait(t => t.HasTag(tag)).ToArray(); } + + [Desc("Returns a table of all the actors that are currently on the map/in the world.")] + public Actor[] ActorsInWorld { get { return world.Actors.ToArray(); } } } } diff --git a/OpenRA.Mods.Common/Scripting/Global/UtilsGlobal.cs b/OpenRA.Mods.Common/Scripting/Global/UtilsGlobal.cs index 66fa9f4fdd..50ca3e5add 100644 --- a/OpenRA.Mods.Common/Scripting/Global/UtilsGlobal.cs +++ b/OpenRA.Mods.Common/Scripting/Global/UtilsGlobal.cs @@ -9,6 +9,7 @@ */ #endregion +using System.Collections; using System.Linq; using Eluant; using OpenRA.Scripting; @@ -54,6 +55,20 @@ namespace OpenRA.Mods.Common.Scripting return true; } + [Desc("Returns the original collection filtered with the func.")] + public LuaTable Where(LuaValue[] collection, LuaFunction func) + { + var t = Context.CreateTable(); + + foreach (var c in collection) + using (var ret = func.Call(c)) + using (var result = ret.FirstOrDefault()) + if (result != null && result.ToBoolean()) + t.Add(t.Count + 1, c); + + return t; + } + [Desc("Returns the first n values from a collection.")] public LuaValue[] Take(int n, LuaValue[] source) { diff --git a/mods/cnc/maps/nod02a/nod02a.lua b/mods/cnc/maps/nod02a/nod02a.lua index ad78934615..b23e9146c1 100644 --- a/mods/cnc/maps/nod02a/nod02a.lua +++ b/mods/cnc/maps/nod02a/nod02a.lua @@ -26,7 +26,7 @@ getActors = function(owner, units) local maxUnits = 0 local actors = { } for type, count in pairs(units) do - local globalActors = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(actor) + local globalActors = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Owner == owner and actor.Type == type and not actor.IsDead end) if #globalActors < count then @@ -234,7 +234,7 @@ Tick = function() end checkProduction = function(player) - local Units = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(actor) + local Units = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Owner == player and actor.Type == UnitToRebuild end) @@ -251,7 +251,7 @@ checkProduction = function(player) end getStartUnits = function() - local Units = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(actor) + local Units = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Owner == enemy end) Utils.Do(Units, function(unit) diff --git a/mods/cnc/maps/nod02b/nod02b.lua b/mods/cnc/maps/nod02b/nod02b.lua index 1f63f6f702..1c9231a4f5 100644 --- a/mods/cnc/maps/nod02b/nod02b.lua +++ b/mods/cnc/maps/nod02b/nod02b.lua @@ -180,7 +180,7 @@ getActors = function(owner, units) local maxUnits = 0 local actors = { } for type, count in pairs(units) do - local globalActors = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(actor) + local globalActors = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Owner == owner and actor.Type == type and not actor.IsDead end) if #globalActors < count then @@ -196,7 +196,7 @@ getActors = function(owner, units) end checkProduction = function(player) - local Units = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(actor) + local Units = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Owner == player and actor.Type == UnitToRebuild end) @@ -213,7 +213,7 @@ checkProduction = function(player) end getStartUnits = function() - local Units = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(actor) + local Units = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Owner == enemy end) Utils.Do(Units, function(unit) diff --git a/mods/cnc/maps/nod05/nod05.lua b/mods/cnc/maps/nod05/nod05.lua index d31edb7bb3..1da5994a36 100644 --- a/mods/cnc/maps/nod05/nod05.lua +++ b/mods/cnc/maps/nod05/nod05.lua @@ -275,7 +275,7 @@ CheckForSams = function(player) end checkProduction = function(player) - local Units = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(actor) + local Units = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Owner == enemy end) @@ -304,7 +304,7 @@ checkProduction = function(player) end getStartUnits = function() - local Units = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(actor) + local Units = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Owner == enemy and ( actor.Type == 'e2' or actor.Type == 'e1' or actor.Type == 'jeep' or actor.Type == 'mtnk') end) Utils.Do(Units, function(unit) diff --git a/mods/d2k/maps/atreides-01a/atreides01a.lua b/mods/d2k/maps/atreides-01a/atreides01a.lua index 4bf0a70a41..e5dd723ba8 100644 --- a/mods/d2k/maps/atreides-01a/atreides01a.lua +++ b/mods/d2k/maps/atreides-01a/atreides01a.lua @@ -88,9 +88,7 @@ WorldLoaded = function() InitObjectives() Trigger.OnRemovedFromWorld(AtreidesConyard, function() - local refs = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(actor) - return actor.Type == "refinery" - end) + local refs = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Type == "refinery" end) if #refs == 0 then harkonnen.MarkCompletedObjective(KillAtreides) diff --git a/mods/d2k/maps/atreides-01b/atreides01b.lua b/mods/d2k/maps/atreides-01b/atreides01b.lua index f963efc2c4..13b7497f1d 100644 --- a/mods/d2k/maps/atreides-01b/atreides01b.lua +++ b/mods/d2k/maps/atreides-01b/atreides01b.lua @@ -88,9 +88,7 @@ WorldLoaded = function() InitObjectives() Trigger.OnRemovedFromWorld(AtreidesConyard, function() - local refs = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(actor) - return actor.Type == "refinery" - end) + local refs = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Type == "refinery" end) if #refs == 0 then harkonnen.MarkCompletedObjective(KillAtreides) diff --git a/mods/ra/maps/allies-03a/allies03a.lua b/mods/ra/maps/allies-03a/allies03a.lua index b4603ad71a..6bbfe58b0c 100644 --- a/mods/ra/maps/allies-03a/allies03a.lua +++ b/mods/ra/maps/allies-03a/allies03a.lua @@ -145,11 +145,12 @@ InitTriggers = function() end) Trigger.OnKilled(ExplosiveBarrel, function() - local bridge = Map.ActorsInBox(USSRReinforcementsCameraWaypoint.CenterPosition, USSRReinforcementsEntryWaypoint.CenterPosition, - function(self) return self.Type == "bridge1" end) - if not bridge[1].IsDead then - bridge[1].Kill() + -- We need the first bridge which is returned + local bridge = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Type == "bridge1" end)[1] + + if not bridge.IsDead then + bridge.Kill() end end) @@ -237,7 +238,7 @@ InitTriggers = function() end) Trigger.AfterDelay(0, function() - local bridges = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(self) return self.Type == "bridge1" end) + local bridges = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Type == "bridge1" end) Trigger.OnAllKilled(bridges, function() player.MarkCompletedObjective(KillBridges) diff --git a/mods/ra/maps/allies-03b/allies03b.lua b/mods/ra/maps/allies-03b/allies03b.lua index 65650f60c2..53d1396dee 100644 --- a/mods/ra/maps/allies-03b/allies03b.lua +++ b/mods/ra/maps/allies-03b/allies03b.lua @@ -348,7 +348,7 @@ InitTriggers = function() end) Trigger.AfterDelay(0, function() - local bridges = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(self) return self.Type == "bridge1" or self.Type == "bridge2" end) + local bridges = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Type == "bridge1" or actor.Type == "bridge2" end) ExplodingBridge = bridges[1] Trigger.OnAllKilled(bridges, function() diff --git a/mods/ra/maps/allies-05a/allies05a-AI.lua b/mods/ra/maps/allies-05a/allies05a-AI.lua index 8f71aa4e02..2244404ed0 100644 --- a/mods/ra/maps/allies-05a/allies05a-AI.lua +++ b/mods/ra/maps/allies-05a/allies05a-AI.lua @@ -105,9 +105,9 @@ ProtectHarvester = function(unit) end InitAIUnits = function() - IdlingUnits = Map.ActorsInBox(MainBaseTopLeft.CenterPosition, Map.BottomRight, function(self) return self.Owner == ussr and self.HasProperty("Hunt") end) + IdlingUnits = Utils.Where(Map.ActorsInWorld, function(self) return self.Owner == ussr and self.HasProperty("Hunt") and self.Location.Y > MainBaseTopLeft.Location.Y end) - local buildings = Map.ActorsInBox(MainBaseTopLeft.CenterPosition, Map.BottomRight, function(self) return self.Owner == ussr and self.HasProperty("StartBuildingRepairs") end) + local buildings = Utils.Where(Map.ActorsInWorld, function(self) return self.Owner == ussr and self.HasProperty("StartBuildingRepairs") end) Utils.Do(buildings, function(actor) Trigger.OnDamaged(actor, function(building) if building.Owner == ussr and building.Health < building.MaxHealth * 3/4 then @@ -255,7 +255,7 @@ ProduceAircraft = function() Trigger.OnIdle(units[1], function() if not target or target.IsDead or (not target.IsInWorld) then - local enemies = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(self) return self.Owner == greece and self.HasProperty("Health") end) + local enemies = Utils.Where(Map.ActorsInWorld, function(self) return self.Owner == greece and self.HasProperty("Health") end) if #enemies > 0 then target = Utils.Random(enemies) units[1].Attack(target) diff --git a/mods/ra/maps/allies-05a/allies05a.lua b/mods/ra/maps/allies-05a/allies05a.lua index 5ff7b8886d..db78fba1a9 100644 --- a/mods/ra/maps/allies-05a/allies05a.lua +++ b/mods/ra/maps/allies-05a/allies05a.lua @@ -226,11 +226,6 @@ ActivatePatrols = function() GroupPatrol(PatrolA, PatrolAPath, DateTime.Seconds(7)) GroupPatrol(PatrolB, PatrolBPath, DateTime.Seconds(6)) end) - - local units = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(self) return self.Owner == soviets and self.HasProperty("AutoTarget") end) - Utils.Do(units, function(unit) - unit.Stance = "Defend" - end) end InitTriggers = function() diff --git a/mods/ra/maps/monster-tank-madness/monster-tank-madness.lua b/mods/ra/maps/monster-tank-madness/monster-tank-madness.lua index 74fd14a786..298b9cf814 100644 --- a/mods/ra/maps/monster-tank-madness/monster-tank-madness.lua +++ b/mods/ra/maps/monster-tank-madness/monster-tank-madness.lua @@ -168,9 +168,7 @@ SuperTankDomeInfiltrated = function() end SuperTanksDestruction = function() - local badGuys = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, - function(self) return self.Owner == badguy and self.HasProperty("Health") end) - + local badGuys = Utils.Where(Map.ActorsInWorld, function(self) return self.Owner == badguy and self.HasProperty("Health") end) Utils.Do(badGuys, function(unit) unit.Kill() end) diff --git a/mods/ra/maps/soviet-02a/soviet02a.lua b/mods/ra/maps/soviet-02a/soviet02a.lua index 01e5b9d2a7..a4a01694a9 100644 --- a/mods/ra/maps/soviet-02a/soviet02a.lua +++ b/mods/ra/maps/soviet-02a/soviet02a.lua @@ -36,7 +36,7 @@ WorldLoaded = function() end) Trigger.AfterDelay(0, function() - local buildings = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(self) return self.Owner == germany and self.HasProperty("StartBuildingRepairs") end) + local buildings = Utils.Where(Map.ActorsInWorld, function(self) return self.Owner == germany and self.HasProperty("StartBuildingRepairs") end) Utils.Do(buildings, function(actor) Trigger.OnDamaged(actor, function(building, attacker) if building.Owner == germany and building.Health < building.MaxHealth * 0.8 then diff --git a/mods/ra/maps/soviet-02b/soviet02b.lua b/mods/ra/maps/soviet-02b/soviet02b.lua index ef93fa84ba..2e4a101c98 100644 --- a/mods/ra/maps/soviet-02b/soviet02b.lua +++ b/mods/ra/maps/soviet-02b/soviet02b.lua @@ -128,7 +128,7 @@ WorldLoaded = function() end end) Trigger.AfterDelay(0, function() - local buildings = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(self) return self.Owner == enemy and self.HasProperty("StartBuildingRepairs") end) + local buildings = Utils.Where(Map.ActorsInWorld, function(self) return self.Owner == enemy and self.HasProperty("StartBuildingRepairs") end) Utils.Do(buildings, function(actor) Trigger.OnDamaged(actor, function(building, attacker) if building.Owner == enemy and building.Health < building.MaxHealth * 0.8 then diff --git a/mods/ra/maps/soviet-05/map.yaml b/mods/ra/maps/soviet-05/map.yaml index ac376f94e0..7356e317a1 100644 --- a/mods/ra/maps/soviet-05/map.yaml +++ b/mods/ra/maps/soviet-05/map.yaml @@ -581,9 +581,6 @@ Actors: ReinfRoadPoint: waypoint Location: 52,42 Owner: Neutral - NWIdlePoint: waypoint - Location: 38,42 - Owner: Neutral EIslandPoint: waypoint Location: 51,58 Owner: Neutral diff --git a/mods/ra/maps/soviet-05/soviet05-AI.lua b/mods/ra/maps/soviet-05/soviet05-AI.lua index f41f3cc86e..dcc617b496 100644 --- a/mods/ra/maps/soviet-05/soviet05-AI.lua +++ b/mods/ra/maps/soviet-05/soviet05-AI.lua @@ -1,7 +1,7 @@ IdleHunt = function(unit) if not unit.IsDead then Trigger.OnIdle(unit, unit.Hunt) end end IdlingUnits = function() - local lazyUnits = Map.ActorsInBox(NWIdlePoint.CenterPosition, Map.BottomRight, function(actor) + local lazyUnits = Utils.Where(Map.ActorsInWorld, function(actor) return actor.HasProperty("Hunt") and (actor.Owner == GoodGuy or actor.Owner == Greece) end) Utils.Do(lazyUnits, function(unit) @@ -12,7 +12,8 @@ IdlingUnits = function() end) end -BaseBuildings = { +BaseBuildings = +{ { type = "powr", pos = CVec.New(3, -2), cost = 300 }, { type = "tent", pos = CVec.New(0, 4), cost = 400 }, { type = "hbox", pos = CVec.New(3, 6), cost = 600 }, diff --git a/mods/ra/maps/soviet-05/soviet05.lua b/mods/ra/maps/soviet-05/soviet05.lua index a0a6533d86..5f5acb14ee 100644 --- a/mods/ra/maps/soviet-05/soviet05.lua +++ b/mods/ra/maps/soviet-05/soviet05.lua @@ -15,11 +15,7 @@ CheckForCYard = function() end CheckForSPen = function() - SPens = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(actor) - return actor.Type == "spen" - end) - - return #SPens >=1 + return Utils.Any(Map.ActorsInWorld, function(actor) return actor.Type == "spen" end) end RunInitialActivities = function() @@ -36,7 +32,7 @@ RunInitialActivities = function() IdlingUnits() Media.PlaySpeechNotification(player, "ReinforcementsArrived") - local buildings = Map.ActorsInBox(NWIdlePoint.CenterPosition, Map.BottomRight, function(self) return self.Owner == Greece and self.HasProperty("StartBuildingRepairs") end) + local buildings = Utils.Where(Map.ActorsInWorld, function(self) return self.Owner == Greece and self.HasProperty("StartBuildingRepairs") end) Utils.Do(buildings, function(actor) Trigger.OnDamaged(actor, function(building) if building.Owner == Greece and building.Health < building.MaxHealth * 3/4 then diff --git a/mods/ra/maps/survival01/survival01.lua b/mods/ra/maps/survival01/survival01.lua index 9c4cf41b0f..104dce037d 100644 --- a/mods/ra/maps/survival01/survival01.lua +++ b/mods/ra/maps/survival01/survival01.lua @@ -382,7 +382,7 @@ SetupSoviets = function() end) Trigger.AfterDelay(0, function() - local buildings = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(self) return self.Owner == soviets and self.HasProperty("StartBuildingRepairs") end) + local buildings = Utils.Where(Map.ActorsInWorld, function(self) return self.Owner == soviets and self.HasProperty("StartBuildingRepairs") end) Utils.Do(buildings, function(actor) Trigger.OnDamaged(actor, function(building) if building.Owner == soviets and building.Health < building.MaxHealth * DamageModifier then diff --git a/mods/ra/maps/survival02/survival02.lua b/mods/ra/maps/survival02/survival02.lua index 87bcfb7431..b23054626f 100644 --- a/mods/ra/maps/survival02/survival02.lua +++ b/mods/ra/maps/survival02/survival02.lua @@ -378,7 +378,7 @@ SetupSoviets = function() end) Trigger.AfterDelay(0, function() - local buildings = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(self) return self.Owner == soviets and self.HasProperty("StartBuildingRepairs") end) + local buildings = Utils.Where(Map.ActorsInWorld, function(self) return self.Owner == soviets and self.HasProperty("StartBuildingRepairs") end) Utils.Do(buildings, function(actor) Trigger.OnDamaged(actor, function(building) if building.Owner == soviets and building.Health < building.MaxHealth * 3/4 then @@ -386,11 +386,6 @@ SetupSoviets = function() end end) end) - - local units = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(self) return self.Owner == soviets and self.HasProperty("AutoTarget") end) - Utils.Do(units, function(unit) - unit.Stance = "Defend" - end) end) end