diff --git a/OpenRA.Mods.Common/Traits/World/PathFinder.cs b/OpenRA.Mods.Common/Traits/World/PathFinder.cs index a4e988d24c..95c524c703 100644 --- a/OpenRA.Mods.Common/Traits/World/PathFinder.cs +++ b/OpenRA.Mods.Common/Traits/World/PathFinder.cs @@ -64,8 +64,8 @@ namespace OpenRA.Mods.Common.Traits public List FindUnitPath(CPos source, CPos target, Actor self, Actor ignoreActor, BlockedByActor check) { - var mobile = self.Trait(); - var locomotor = mobile.Locomotor; + // PERF: Because we can be sure that OccupiesSpace is Mobile here, we can save some performance by avoiding querying for the trait. + var locomotor = ((Mobile)self.OccupiesSpace).Locomotor; if (!cached) { @@ -102,9 +102,10 @@ namespace OpenRA.Mods.Common.Traits cached = true; } - var mobile = self.Trait(); - var mi = mobile.Info; - var li = mi.LocomotorInfo; + // PERF: Because we can be sure that OccupiesSpace is Mobile here, we can save some performance by avoiding querying for the trait. + var mobile = (Mobile)self.OccupiesSpace; + var locomotor = mobile.Locomotor; + var targetCell = world.Map.CellContaining(target); // Correct for SubCell offset @@ -114,19 +115,17 @@ namespace OpenRA.Mods.Common.Traits // This assumes that the SubCell does not change during the path traversal var tilesInRange = world.Map.FindTilesInCircle(targetCell, range.Length / 1024 + 1) .Where(t => (world.Map.CenterOfCell(t) - target).LengthSquared <= range.LengthSquared - && mi.CanEnterCell(self.World, self, t)); + && mobile.Info.CanEnterCell(self.World, self, t)); // See if there is any cell within range that does not involve a cross-domain request // Really, we only need to check the circle perimeter, but it's not clear that would be a performance win if (domainIndex != null) { - tilesInRange = new List(tilesInRange.Where(t => domainIndex.IsPassable(source, t, li))); + tilesInRange = new List(tilesInRange.Where(t => domainIndex.IsPassable(source, t, locomotor.Info))); if (!tilesInRange.Any()) return EmptyPath; } - var locomotor = mobile.Locomotor; - using (var fromSrc = PathSearch.FromPoints(world, locomotor, self, tilesInRange, source, check)) using (var fromDest = PathSearch.FromPoint(world, locomotor, self, source, targetCell, check).Reverse()) return FindBidiPath(fromSrc, fromDest);