Use OccupiesSpace to avoid Mobile look-ups

in PathFinder.FindUnitPath and FindUnitPathToRange.
This commit is contained in:
reaperrr
2020-05-29 13:52:52 +02:00
committed by atlimit8
parent c999b2d778
commit e1b7df8b6a

View File

@@ -64,8 +64,8 @@ namespace OpenRA.Mods.Common.Traits
public List<CPos> FindUnitPath(CPos source, CPos target, Actor self, Actor ignoreActor, BlockedByActor check) public List<CPos> FindUnitPath(CPos source, CPos target, Actor self, Actor ignoreActor, BlockedByActor check)
{ {
var mobile = self.Trait<Mobile>(); // 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.Locomotor; var locomotor = ((Mobile)self.OccupiesSpace).Locomotor;
if (!cached) if (!cached)
{ {
@@ -102,9 +102,10 @@ namespace OpenRA.Mods.Common.Traits
cached = true; cached = true;
} }
var mobile = self.Trait<Mobile>(); // PERF: Because we can be sure that OccupiesSpace is Mobile here, we can save some performance by avoiding querying for the trait.
var mi = mobile.Info; var mobile = (Mobile)self.OccupiesSpace;
var li = mi.LocomotorInfo; var locomotor = mobile.Locomotor;
var targetCell = world.Map.CellContaining(target); var targetCell = world.Map.CellContaining(target);
// Correct for SubCell offset // 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 // This assumes that the SubCell does not change during the path traversal
var tilesInRange = world.Map.FindTilesInCircle(targetCell, range.Length / 1024 + 1) var tilesInRange = world.Map.FindTilesInCircle(targetCell, range.Length / 1024 + 1)
.Where(t => (world.Map.CenterOfCell(t) - target).LengthSquared <= range.LengthSquared .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 // 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 // Really, we only need to check the circle perimeter, but it's not clear that would be a performance win
if (domainIndex != null) if (domainIndex != null)
{ {
tilesInRange = new List<CPos>(tilesInRange.Where(t => domainIndex.IsPassable(source, t, li))); tilesInRange = new List<CPos>(tilesInRange.Where(t => domainIndex.IsPassable(source, t, locomotor.Info)));
if (!tilesInRange.Any()) if (!tilesInRange.Any())
return EmptyPath; return EmptyPath;
} }
var locomotor = mobile.Locomotor;
using (var fromSrc = PathSearch.FromPoints(world, locomotor, self, tilesInRange, source, check)) using (var fromSrc = PathSearch.FromPoints(world, locomotor, self, tilesInRange, source, check))
using (var fromDest = PathSearch.FromPoint(world, locomotor, self, source, targetCell, check).Reverse()) using (var fromDest = PathSearch.FromPoint(world, locomotor, self, source, targetCell, check).Reverse())
return FindBidiPath(fromSrc, fromDest); return FindBidiPath(fromSrc, fromDest);