diff --git a/OpenRA.Game/GameRules/WeaponInfo.cs b/OpenRA.Game/GameRules/WeaponInfo.cs
index 6af645ce6b..00838d70a8 100644
--- a/OpenRA.Game/GameRules/WeaponInfo.cs
+++ b/OpenRA.Game/GameRules/WeaponInfo.cs
@@ -138,8 +138,7 @@ namespace OpenRA.GameRules
/// Checks if the weapon is valid against (can target) the frozen actor.
public bool IsValidAgainst(FrozenActor victim, Actor firedBy)
{
- var targetable = victim.Info.Traits.WithInterface();
- if (!IsValidTarget(targetable.SelectMany(t => t.GetTargetTypes())))
+ if (!IsValidTarget(victim.TargetTypes))
return false;
if (!Warheads.Any(w => w.IsValidAgainst(victim, firedBy)))
diff --git a/OpenRA.Game/Traits/Player/FrozenActorLayer.cs b/OpenRA.Game/Traits/Player/FrozenActorLayer.cs
index 384de66273..a1c652889d 100644
--- a/OpenRA.Game/Traits/Player/FrozenActorLayer.cs
+++ b/OpenRA.Game/Traits/Player/FrozenActorLayer.cs
@@ -27,6 +27,7 @@ namespace OpenRA.Traits
public readonly PPos[] Footprint;
public readonly WPos CenterPosition;
public readonly Rectangle Bounds;
+ public readonly string[] TargetTypes;
readonly IRemoveFrozenActor[] removeFrozenActors;
readonly Actor actor;
readonly Shroud shroud;
@@ -56,6 +57,7 @@ namespace OpenRA.Traits
CenterPosition = self.CenterPosition;
Bounds = self.Bounds;
+ TargetTypes = self.TraitsImplementing().Where(Exts.IsTraitEnabled).SelectMany(t => t.TargetTypes).Distinct().ToArray();
UpdateVisibility();
}
diff --git a/OpenRA.Mods.Common/Orders/UnitOrderTargeter.cs b/OpenRA.Mods.Common/Orders/UnitOrderTargeter.cs
index 175da6c5b4..6e873260c1 100644
--- a/OpenRA.Mods.Common/Orders/UnitOrderTargeter.cs
+++ b/OpenRA.Mods.Common/Orders/UnitOrderTargeter.cs
@@ -82,7 +82,7 @@ namespace OpenRA.Mods.Common.Orders
public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor)
{
- return target.Info.Traits.WithInterface().Any(t => t.GetTargetTypes().Intersect(targetTypes).Any());
+ return target.TargetTypes.Intersect(targetTypes).Any();
}
}
}
diff --git a/OpenRA.Mods.Common/Warheads/Warhead.cs b/OpenRA.Mods.Common/Warheads/Warhead.cs
index b9b3e1c1a6..a471a97925 100644
--- a/OpenRA.Mods.Common/Warheads/Warhead.cs
+++ b/OpenRA.Mods.Common/Warheads/Warhead.cs
@@ -75,8 +75,7 @@ namespace OpenRA.Mods.Common.Warheads
return false;
// A target type is valid if it is in the valid targets list, and not in the invalid targets list.
- var targetable = victim.Info.Traits.WithInterface();
- if (!IsValidTarget(targetable.SelectMany(t => t.GetTargetTypes())))
+ if (!IsValidTarget(victim.TargetTypes))
return false;
return true;
diff --git a/OpenRA.Mods.RA/Traits/Infiltration/Infiltrates.cs b/OpenRA.Mods.RA/Traits/Infiltration/Infiltrates.cs
index f8c4e6ace8..656ad379ac 100644
--- a/OpenRA.Mods.RA/Traits/Infiltration/Infiltrates.cs
+++ b/OpenRA.Mods.RA/Traits/Infiltration/Infiltrates.cs
@@ -61,7 +61,7 @@ namespace OpenRA.Mods.RA.Traits
if (order.ExtraData == 0 && order.TargetActor == null)
return false;
- ActorInfo ai;
+ IEnumerable targetTypes;
if (order.ExtraData != 0)
{
@@ -74,13 +74,13 @@ namespace OpenRA.Mods.RA.Traits
if (frozen == null)
return false;
- ai = frozen.Info;
+ targetTypes = frozen.TargetTypes;
}
else
- ai = order.TargetActor.Info;
+ targetTypes = order.TargetActor.TraitsImplementing().Where(Exts.IsTraitEnabled)
+ .SelectMany(t => t.TargetTypes);
- return ai.Traits.WithInterface()
- .SelectMany(t => t.GetTargetTypes()).Intersect(Info.Types).Any();
+ return targetTypes.Intersect(Info.Types).Any();
}
public string VoicePhraseForOrder(Actor self, Order order)