Merge pull request #9672 from penev92/fixAutoTarget

Fix a series of visibility/targeting bugs
This commit is contained in:
Oliver Brakmann
2015-10-23 20:53:03 +02:00
3 changed files with 24 additions and 13 deletions

View File

@@ -29,7 +29,7 @@ namespace OpenRA.Orders
else
{
var frozen = world.ScreenMap.FrozenActorsAt(world.RenderPlayer, mi)
.Where(a => a.Info.HasTraitInfo<ITargetableInfo>() && !a.Footprint.All(world.ShroudObscures))
.Where(a => a.Info.HasTraitInfo<ITargetableInfo>() && a.Visible && a.HasRenderables)
.WithHighestSelectionPriority();
target = frozen != null ? Target.FromFrozenActor(frozen) : Target.FromCell(world, xy);
}
@@ -73,7 +73,7 @@ namespace OpenRA.Orders
else
{
var frozen = world.ScreenMap.FrozenActorsAt(world.RenderPlayer, mi)
.Where(a => a.Info.HasTraitInfo<ITargetableInfo>() && !a.Footprint.All(world.ShroudObscures))
.Where(a => a.Info.HasTraitInfo<ITargetableInfo>() && a.Visible && a.HasRenderables)
.WithHighestSelectionPriority();
target = frozen != null ? Target.FromFrozenActor(frozen) : Target.FromCell(world, xy);
}

View File

@@ -223,13 +223,24 @@ namespace OpenRA.Mods.Common.Traits
// (short-circuiting in the logical expression below)
var owner = null as Player;
if (t.Type == TargetType.FrozenActor)
{
owner = t.FrozenActor.Owner;
}
else if (t.Type == TargetType.Actor)
owner = t.Actor.Owner;
{
owner = t.Actor.EffectiveOwner != null && t.Actor.EffectiveOwner.Owner != null
? t.Actor.EffectiveOwner.Owner
: t.Actor.Owner;
return Armaments.Where(a => (!a.IsTraitDisabled || !onlyEnabled) &&
a.Weapon.IsValidAgainst(t, self.World, self) &&
(owner == null || (forceAttack ? a.Info.ForceTargetStances : a.Info.TargetStances)
// Special cases for spies so we don't kill friendly disguised spies
// and enable dogs to kill enemy disguised spies.
if (self.Owner.Stances[t.Actor.Owner] == Stance.Ally || self.Info.HasTraitInfo<IgnoresDisguiseInfo>())
owner = t.Actor.Owner;
}
return Armaments.Where(a => (!a.IsTraitDisabled || !onlyEnabled)
&& a.Weapon.IsValidAgainst(t, self.World, self)
&& (owner == null || (forceAttack ? a.Info.ForceTargetStances : a.Info.TargetStances)
.HasStance(self.Owner.Stances[owner])));
}

View File

@@ -157,14 +157,15 @@ namespace OpenRA.Mods.Common.Traits
Actor ChooseTarget(Actor self, WDist range, bool allowMove)
{
var inRange = self.World.FindActorsInCircle(self.CenterPosition, range);
var inRange = self.World.FindActorsInCircle(self.CenterPosition, range)
.Where(a => !a.Info.HasTraitInfo<AutoTargetIgnoreInfo>());
// Armaments are enumerated in attack.Armaments in construct order
// When autotargeting, first choose targets according to the used armament construct order
// And then according to distance from actor
// This enables preferential treatment of certain armaments
// (e.g. tesla trooper's tesla zap should have precedence over tesla charge)
var actrarms = inRange
var actorByArmament = inRange
// Select only the first compatible armament for each actor: if this actor is selected
// it will be thanks to the first armament anyways, since that is the first selection
@@ -174,20 +175,19 @@ namespace OpenRA.Mods.Common.Traits
var target = Target.FromActor(a);
return new KeyValuePair<Armament, Actor>(
attack.ChooseArmamentsForTarget(target, false)
.Where(arm => allowMove
.FirstOrDefault(arm => allowMove
|| (target.IsInRange(self.CenterPosition, arm.MaxRange())
&& !target.IsInRange(self.CenterPosition, arm.Weapon.MinRange)))
.FirstOrDefault(), a);
&& !target.IsInRange(self.CenterPosition, arm.Weapon.MinRange))), a);
})
.Where(kv => kv.Key != null && kv.Value.TraitOrDefault<AutoTargetIgnore>() == null)
.Where(kv => kv.Key != null && self.Owner.CanViewActor(kv.Value))
.GroupBy(kv => kv.Key, kv => kv.Value)
.ToDictionary(kv => kv.Key, kv => kv.ClosestTo(self));
foreach (var arm in attack.Armaments)
{
Actor actor;
if (actrarms.TryGetValue(arm, out actor))
if (actorByArmament.TryGetValue(arm, out actor))
return actor;
}