From f68da6ada715067ce7edd8181fcb67d156e9c1a0 Mon Sep 17 00:00:00 2001 From: Pavel Penev Date: Sun, 18 Oct 2015 15:05:47 +0300 Subject: [PATCH 1/4] Small refactoring to AutoTarget - Move a check for AutoTargetIgnore up the chain - Simplify some LINQs to a single .FirstOrDefault() - Rename local variable --- OpenRA.Mods.Common/Traits/AutoTarget.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/OpenRA.Mods.Common/Traits/AutoTarget.cs b/OpenRA.Mods.Common/Traits/AutoTarget.cs index 8a45e5fcb5..d5c47acfd7 100644 --- a/OpenRA.Mods.Common/Traits/AutoTarget.cs +++ b/OpenRA.Mods.Common/Traits/AutoTarget.cs @@ -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()); // 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( 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() == null) + .Where(kv => kv.Key != null) .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; } From 8c7bdae617cc808a96da74724e5401fc17e73558 Mon Sep 17 00:00:00 2001 From: Pavel Penev Date: Sun, 18 Oct 2015 16:43:54 +0300 Subject: [PATCH 2/4] Fix AutoTarget acquiring targets under fog/shroud --- OpenRA.Mods.Common/Traits/AutoTarget.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenRA.Mods.Common/Traits/AutoTarget.cs b/OpenRA.Mods.Common/Traits/AutoTarget.cs index d5c47acfd7..559eff04dc 100644 --- a/OpenRA.Mods.Common/Traits/AutoTarget.cs +++ b/OpenRA.Mods.Common/Traits/AutoTarget.cs @@ -180,7 +180,7 @@ namespace OpenRA.Mods.Common.Traits && !target.IsInRange(self.CenterPosition, arm.Weapon.MinRange))), a); }) - .Where(kv => kv.Key != 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)); From 000c701414bc7eb89c98345919135cc0a3f8b9fa Mon Sep 17 00:00:00 2001 From: Pavel Penev Date: Sun, 18 Oct 2015 18:29:55 +0300 Subject: [PATCH 3/4] Fix actors ignoring Disguise --- .../Traits/Attack/AttackBase.cs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs b/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs index 187e323bb9..09c7653da5 100644 --- a/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs +++ b/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs @@ -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()) + 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]))); } From a69f26b70588b657357f380423b8655238f735f8 Mon Sep 17 00:00:00 2001 From: Pavel Penev Date: Sun, 18 Oct 2015 16:23:47 +0300 Subject: [PATCH 4/4] Fix players being able to manually attack invisible structures --- OpenRA.Game/Orders/UnitOrderGenerator.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenRA.Game/Orders/UnitOrderGenerator.cs b/OpenRA.Game/Orders/UnitOrderGenerator.cs index bf4fcb8f98..6636c8db58 100644 --- a/OpenRA.Game/Orders/UnitOrderGenerator.cs +++ b/OpenRA.Game/Orders/UnitOrderGenerator.cs @@ -29,7 +29,7 @@ namespace OpenRA.Orders else { var frozen = world.ScreenMap.FrozenActorsAt(world.RenderPlayer, mi) - .Where(a => a.Info.HasTraitInfo() && !a.Footprint.All(world.ShroudObscures)) + .Where(a => a.Info.HasTraitInfo() && 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() && !a.Footprint.All(world.ShroudObscures)) + .Where(a => a.Info.HasTraitInfo() && a.Visible && a.HasRenderables) .WithHighestSelectionPriority(); target = frozen != null ? Target.FromFrozenActor(frozen) : Target.FromCell(world, xy); }