diff --git a/OpenRA.Game/Traits/World/ActorMap.cs b/OpenRA.Game/Traits/World/ActorMap.cs index 8b9ab1ee98..8242e991fc 100644 --- a/OpenRA.Game/Traits/World/ActorMap.cs +++ b/OpenRA.Game/Traits/World/ActorMap.cs @@ -51,6 +51,7 @@ namespace OpenRA.Traits // to ensure consistency during a tick readonly List addActorPosition = new List(); readonly HashSet removeActorPosition = new HashSet(); + readonly Predicate actorShouldBeRemoved; public ActorMap(World world, ActorMapInfo info) { @@ -64,6 +65,9 @@ namespace OpenRA.Traits for (var j = 0; j < rows; j++) for (var i = 0; i < cols; i++) actors[j * cols + i] = new List(); + + // Cache this delegate so it does not have to be allocated repeatedly. + actorShouldBeRemoved = removeActorPosition.Contains; } public IEnumerable GetUnitsAt(CPos a) @@ -144,7 +148,7 @@ namespace OpenRA.Traits // Position updates are done in one pass // to ensure consistency during a tick foreach (var bin in actors) - bin.RemoveAll(removeActorPosition.Contains); + bin.RemoveAll(actorShouldBeRemoved); removeActorPosition.Clear(); diff --git a/OpenRA.Mods.RA/Attack/AttackBase.cs b/OpenRA.Mods.RA/Attack/AttackBase.cs index 4276a4e91b..fd80502e63 100644 --- a/OpenRA.Mods.RA/Attack/AttackBase.cs +++ b/OpenRA.Mods.RA/Attack/AttackBase.cs @@ -157,7 +157,7 @@ namespace OpenRA.Mods.RA public bool IsReachableTarget(Target target, bool allowMove) { return HasAnyValidWeapons(target) - && (target.IsInRange(self.CenterPosition, GetMaximumRange()) || (self.HasTrait() && allowMove)); + && (target.IsInRange(self.CenterPosition, GetMaximumRange()) || (allowMove && self.HasTrait())); } class AttackOrderTargeter : IOrderTargeter diff --git a/OpenRA.Mods.RA/AutoTarget.cs b/OpenRA.Mods.RA/AutoTarget.cs index 15d9bfed4b..7e31612268 100644 --- a/OpenRA.Mods.RA/AutoTarget.cs +++ b/OpenRA.Mods.RA/AutoTarget.cs @@ -119,10 +119,12 @@ namespace OpenRA.Mods.RA public Actor ScanForTarget(Actor self, Actor currentTarget) { - var range = info.ScanRadius > 0 ? WRange.FromCells(info.ScanRadius) : attack.GetMaximumRange(); - if (self.IsIdle || currentTarget == null || !Target.FromActor(currentTarget).IsInRange(self.CenterPosition, range)) - if (nextScanTime <= 0) + if (nextScanTime <= 0) + { + var range = info.ScanRadius > 0 ? WRange.FromCells(info.ScanRadius) : attack.GetMaximumRange(); + if (self.IsIdle || currentTarget == null || !Target.FromActor(currentTarget).IsInRange(self.CenterPosition, range)) return ChooseTarget(self, range); + } return currentTarget; } @@ -148,10 +150,11 @@ namespace OpenRA.Mods.RA var inRange = self.World.FindActorsInCircle(self.CenterPosition, range); return inRange - .Where(a => a.AppearsHostileTo(self)) - .Where(a => !a.HasTrait()) - .Where(a => attack.HasAnyValidWeapons(Target.FromActor(a))) - .Where(a => self.Owner.Shroud.IsTargetable(a)) + .Where(a => + a.AppearsHostileTo(self) && + !a.HasTrait() && + attack.HasAnyValidWeapons(Target.FromActor(a)) && + self.Owner.Shroud.IsTargetable(a)) .ClosestTo(self); } }