Store Targetables in Actor.
This can be used to avoid several lookups for these traits, as well as allow Actor to provide specialised methods to deal with target types efficiently. This also reduces some code duplication.
This commit is contained in:
@@ -63,7 +63,7 @@ namespace OpenRA.Mods.Common.AI
|
||||
if (!a.Info.HasTraitInfo<AttackBaseInfo>())
|
||||
return false;
|
||||
|
||||
var targetTypes = target.TraitsImplementing<ITargetable>().Where(Exts.IsTraitEnabled).SelectMany(t => t.TargetTypes);
|
||||
var targetTypes = target.GetEnabledTargetTypes();
|
||||
if (!targetTypes.Any())
|
||||
return false;
|
||||
|
||||
|
||||
@@ -125,11 +125,10 @@ namespace OpenRA.Mods.Common.AI
|
||||
if (a == null)
|
||||
return 0;
|
||||
|
||||
var targetable = a.TraitsImplementing<ITargetable>().Where(Exts.IsTraitEnabled);
|
||||
if (!targetable.Any(t => t.TargetableBy(a, firedBy.PlayerActor)))
|
||||
if (!a.IsTargetableBy(firedBy.PlayerActor))
|
||||
return 0;
|
||||
|
||||
if (Types.Overlaps(targetable.SelectMany(t => t.TargetTypes)))
|
||||
if (Types.Overlaps(a.GetEnabledTargetTypes()))
|
||||
{
|
||||
switch (TargetMetric)
|
||||
{
|
||||
|
||||
@@ -25,12 +25,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
var attack = self.Trait<AttackBase>();
|
||||
targets = self.World.ActorsHavingTrait<Huntable>().Where(
|
||||
a => self != a && !a.IsDead && a.IsInWorld && a.AppearsHostileTo(self)
|
||||
&& IsTargetable(a, self) && attack.HasAnyValidWeapons(Target.FromActor(a)));
|
||||
}
|
||||
|
||||
bool IsTargetable(Actor self, Actor viewer)
|
||||
{
|
||||
return self.TraitsImplementing<ITargetable>().Any(t => t.IsTraitEnabled() && t.TargetableBy(self, viewer));
|
||||
&& a.IsTargetableBy(self) && attack.HasAnyValidWeapons(Target.FromActor(a)));
|
||||
}
|
||||
|
||||
public override Activity Tick(Actor self)
|
||||
|
||||
@@ -67,9 +67,9 @@ namespace OpenRA.Mods.Common.Orders
|
||||
|
||||
public class TargetTypeOrderTargeter : UnitOrderTargeter
|
||||
{
|
||||
readonly string[] targetTypes;
|
||||
readonly HashSet<string> targetTypes;
|
||||
|
||||
public TargetTypeOrderTargeter(string[] targetTypes, string order, int priority, string cursor, bool targetEnemyUnits, bool targetAllyUnits)
|
||||
public TargetTypeOrderTargeter(HashSet<string> targetTypes, string order, int priority, string cursor, bool targetEnemyUnits, bool targetAllyUnits)
|
||||
: base(order, priority, cursor, targetEnemyUnits, targetAllyUnits)
|
||||
{
|
||||
this.targetTypes = targetTypes;
|
||||
@@ -77,7 +77,7 @@ namespace OpenRA.Mods.Common.Orders
|
||||
|
||||
public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
|
||||
{
|
||||
return target.TraitsImplementing<ITargetable>().Any(t => t.IsTraitEnabled() && t.TargetTypes.Overlaps(targetTypes));
|
||||
return targetTypes.Overlaps(target.GetEnabledTargetTypes());
|
||||
}
|
||||
|
||||
public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor)
|
||||
|
||||
@@ -58,8 +58,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (info.ValidFactions.Any() && !info.ValidFactions.Contains(collector.Owner.Faction.InternalName))
|
||||
return false;
|
||||
|
||||
var targetable = collector.TraitsImplementing<ITargetable>().Where(Exts.IsTraitEnabled);
|
||||
if (!info.ValidTargets.Overlaps(targetable.SelectMany(t => t.TargetTypes)))
|
||||
if (!info.ValidTargets.Overlaps(collector.GetEnabledTargetTypes()))
|
||||
return false;
|
||||
|
||||
var positionable = collector.TraitOrDefault<IPositionable>();
|
||||
|
||||
@@ -56,8 +56,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.TraitsImplementing<ITargetable>().Where(Exts.IsTraitEnabled);
|
||||
if (!IsValidTarget(targetable.SelectMany(t => t.TargetTypes)))
|
||||
if (!IsValidTarget(victim.GetEnabledTargetTypes()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user