diff --git a/OpenRA.Mods.Common/Scripting/Properties/CombatProperties.cs b/OpenRA.Mods.Common/Scripting/Properties/CombatProperties.cs index b50d1bdbe7..4140b949b4 100644 --- a/OpenRA.Mods.Common/Scripting/Properties/CombatProperties.cs +++ b/OpenRA.Mods.Common/Scripting/Properties/CombatProperties.cs @@ -90,7 +90,7 @@ namespace OpenRA.Mods.Common.Scripting public void Attack(Actor targetActor, bool allowMove = true, bool forceAttack = false) { var target = Target.FromActor(targetActor); - if (!target.IsValidFor(Self) || target.Type == TargetType.FrozenActor) + if (!target.IsValidFor(Self)) Log.Write("lua", "{1} is an invalid target for {0}!", Self, targetActor); if (!targetActor.Info.HasTraitInfo() && !Self.Owner.CanTargetActor(targetActor)) @@ -98,5 +98,11 @@ namespace OpenRA.Mods.Common.Scripting attackBase.AttackTarget(target, true, allowMove, forceAttack); } + + [Desc("Checks if the targeted actor is a valid target for this actor.")] + public bool CanTarget(Actor targetActor) + { + return Target.FromActor(targetActor).IsValidFor(Self); + } } } diff --git a/mods/ra/maps/allies-04/allies04-AI.lua b/mods/ra/maps/allies-04/allies04-AI.lua index 50d1807fd6..3a3ceaa924 100644 --- a/mods/ra/maps/allies-04/allies04-AI.lua +++ b/mods/ra/maps/allies-04/allies04-AI.lua @@ -236,15 +236,14 @@ end TargetAndAttack = function(yak, target) if not target or target.IsDead or (not target.IsInWorld) then - local enemies = Utils.Where(Map.ActorsInWorld, function(self) return self.Owner == player and self.HasProperty("Health") end) + local enemies = Utils.Where(Map.ActorsInWorld, function(self) return self.Owner == player and self.HasProperty("Health") and yak.CanTarget(self) end) + if #enemies > 0 then target = Utils.Random(enemies) - else - yak.Wait(DateTime.Seconds(5)) end end - if target and yak.AmmoCount() > 0 then + if target and yak.AmmoCount() > 0 and yak.CanTarget(target) then yak.Attack(target) else yak.ReturnToBase() diff --git a/mods/ra/maps/allies-05a/allies05a-AI.lua b/mods/ra/maps/allies-05a/allies05a-AI.lua index 2803e1d6bd..d766fc2425 100644 --- a/mods/ra/maps/allies-05a/allies05a-AI.lua +++ b/mods/ra/maps/allies-05a/allies05a-AI.lua @@ -257,15 +257,13 @@ end TargetAndAttack = function(yak, target) if not target or target.IsDead or (not target.IsInWorld) then - local enemies = Utils.Where(Map.ActorsInWorld, 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") and yak.CanTarget(self) end) if #enemies > 0 then target = Utils.Random(enemies) - else - yak.Wait(DateTime.Seconds(5)) end end - if target and yak.AmmoCount() > 0 then + if target and yak.AmmoCount() > 0 and yak.CanTarget(target) then yak.Attack(target) else yak.ReturnToBase() diff --git a/mods/ra/maps/evacuation/evacuation.lua b/mods/ra/maps/evacuation/evacuation.lua index 0c0772ebba..44db3d3ec6 100644 --- a/mods/ra/maps/evacuation/evacuation.lua +++ b/mods/ra/maps/evacuation/evacuation.lua @@ -75,7 +75,7 @@ end Yak = nil YakAttack = function(yak) local targets = Map.ActorsInCircle(YakAttackPoint.CenterPosition, WDist.FromCells(10), function(a) - return a.Owner == allies1 and not a.IsDead and a ~= Einstein and a ~= Tanya and a ~= Engineer + return a.Owner == allies1 and not a.IsDead and a ~= Einstein and a ~= Tanya and a ~= Engineer and yak.CanTarget(a) end) if (#targets > 0) then diff --git a/mods/ra/maps/exodus/exodus.lua b/mods/ra/maps/exodus/exodus.lua index 61fe13522d..1f4ef39913 100644 --- a/mods/ra/maps/exodus/exodus.lua +++ b/mods/ra/maps/exodus/exodus.lua @@ -190,31 +190,30 @@ IdleHunt = function(unit) end) end -AircraftTargets = function() +AircraftTargets = function(yak) local targets = Utils.Where(Map.ActorsInWorld, function(a) - return (a.Owner == allies1 or a.Owner == allies2) and a.HasProperty("Health") + return (a.Owner == allies1 or a.Owner == allies2) and a.HasProperty("Health") and yak.CanTarget(a) end) - -- prefer mobile units + -- Prefer mobile units table.sort(targets, function(a, b) return a.HasProperty("Move") and not b.HasProperty("Move") end) return targets end YakAttack = function(yak, target) - if not target or target.IsDead or (not target.IsInWorld) then - local targets = AircraftTargets() + if not target or target.IsDead or (not target.IsInWorld) or (not yak.CanTarget(target)) then + local targets = AircraftTargets(yak) if #targets > 0 then target = Utils.Random(targets) - else - yak.Wait(DateTime.Seconds(5)) end end - if target and yak.AmmoCount() > 0 then + if target and yak.AmmoCount() > 0 and yak.CanTarget(target) then yak.Attack(target) else - yak.ReturnToBase() -- includes yak.Resupply() + -- Includes yak.Resupply() + yak.ReturnToBase() end yak.CallFunc(function()