Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FindAndDeliverResources, trivial optimizations. #19525

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 14 additions & 10 deletions OpenRA.Mods.Common/Activities/FindAndDeliverResources.cs
Expand Up @@ -180,7 +180,8 @@ public override bool Tick(Actor self)

var searchRadiusSquared = searchRadius * searchRadius;

var procPos = procLoc.HasValue ? (WPos?)self.World.Map.CenterOfCell(procLoc.Value) : null;
var map = self.World.Map;
var procPos = procLoc.HasValue ? (WPos?)map.CenterOfCell(procLoc.Value) : null;
var harvPos = self.CenterPosition;

// Find any harvestable resources:
Expand All @@ -190,25 +191,28 @@ public override bool Tick(Actor self)
.WithCustomCost(loc =>
{
if ((loc - searchFromLoc).LengthSquared > searchRadiusSquared)
return int.MaxValue;
return PathGraph.CostForInvalidCell;

// Add a cost modifier to harvestable cells to prefer resources that are closer to the refinery.
// This reduces the tendancy for harvesters to move in straight lines
if (procPos.HasValue && harvInfo.ResourceRefineryDirectionPenalty > 0 && harv.CanHarvestCell(self, loc))
{
var pos = self.World.Map.CenterOfCell(loc);
var pos = map.CenterOfCell(loc);

// Calculate harv-cell-refinery angle (cosine rule)
var a = harvPos - procPos.Value;
var b = pos - procPos.Value;
var c = pos - harvPos;

if (b != WVec.Zero && c != WVec.Zero)
if (b != WVec.Zero)
{
var cosA = (int)(512 * (b.LengthSquared + c.LengthSquared - a.LengthSquared) / b.Length / c.Length);

// Cost modifier varies between 0 and ResourceRefineryDirectionPenalty
return Math.Abs(harvInfo.ResourceRefineryDirectionPenalty / 2) + harvInfo.ResourceRefineryDirectionPenalty * cosA / 2048;
var c = pos - harvPos;
if (c != WVec.Zero)
{
var a = harvPos - procPos.Value;
var cosA = (int)(512 * (b.LengthSquared + c.LengthSquared - a.LengthSquared) / b.Length / c.Length);

// Cost modifier varies between 0 and ResourceRefineryDirectionPenalty
return Math.Abs(harvInfo.ResourceRefineryDirectionPenalty / 2) + harvInfo.ResourceRefineryDirectionPenalty * cosA / 2048;
}
}
}

Expand Down
9 changes: 6 additions & 3 deletions OpenRA.Mods.Common/Traits/World/PathFinder.cs
Expand Up @@ -110,11 +110,14 @@ public List<CPos> FindUnitPathToRange(CPos source, SubCell srcSub, WPos target,
// Correct for SubCell offset
target -= world.Map.Grid.OffsetOfSubCell(srcSub);

var rangeLengthSquared = range.LengthSquared;
abcdefg30 marked this conversation as resolved.
Show resolved Hide resolved
var map = world.Map;

// Select only the tiles that are within range from the requested SubCell
// 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
&& mobile.Info.CanEnterCell(self.World, self, t));
var tilesInRange = map.FindTilesInCircle(targetCell, range.Length / 1024 + 1)
.Where(t => (map.CenterOfCell(t) - target).LengthSquared <= rangeLengthSquared
&& mobile.Info.CanEnterCell(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
Expand Down