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:
RoosterDragon
2015-10-17 00:45:40 +01:00
parent 8230be6a14
commit dcf375a412
14 changed files with 66 additions and 35 deletions

View File

@@ -59,7 +59,7 @@ namespace OpenRA.Traits
CenterPosition = self.CenterPosition;
Bounds = self.Bounds;
TargetTypes = self.TraitsImplementing<ITargetable>().Where(Exts.IsTraitEnabled).SelectMany(t => t.TargetTypes).ToHashSet();
TargetTypes = self.GetEnabledTargetTypes().ToHashSet();
UpdateVisibility();
}

View File

@@ -22,7 +22,6 @@ namespace OpenRA.Traits
TargetType type;
Actor actor;
IEnumerable<ITargetable> targetable;
FrozenActor frozen;
WPos pos;
int generation;
@@ -48,7 +47,6 @@ namespace OpenRA.Traits
return new Target
{
actor = a,
targetable = a.TraitsImplementing<ITargetable>(),
type = TargetType.Actor,
generation = a.Generation,
};
@@ -83,8 +81,7 @@ namespace OpenRA.Traits
if (targeter == null || Type == TargetType.Invalid)
return false;
var targeted = this.actor;
if (targeted != null && !targetable.Any(t => t.IsTraitEnabled() && t.TargetableBy(targeted, targeter)))
if (actor != null && !actor.IsTargetableBy(targeter))
return false;
return true;
@@ -94,7 +91,24 @@ namespace OpenRA.Traits
// TODO: either replace based on target type or put in singleton trait
public bool RequiresForceFire
{
get { return targetable != null && targetable.Any(Exts.IsTraitEnabled) && targetable.Where(Exts.IsTraitEnabled).All(t => t.RequiresForceFire); }
get
{
if (actor == null)
return false;
var isTargetable = false;
foreach (var targetable in actor.Targetables)
{
if (!targetable.IsTraitEnabled())
continue;
isTargetable = true;
if (!targetable.RequiresForceFire)
return false;
}
return isTargetable;
}
}
// Representative position - see Positions for the full set of targetable positions.
@@ -126,8 +140,7 @@ namespace OpenRA.Traits
switch (Type)
{
case TargetType.Actor:
var targetable = actor.TraitsImplementing<ITargetable>().Where(Exts.IsTraitEnabled);
if (!targetable.Any())
if (!actor.Targetables.Any(Exts.IsTraitEnabled))
return new[] { actor.CenterPosition };
var targetablePositions = actor.TraitOrDefault<ITargetablePositions>();