Only use largest blocker instead of largest actor for projectile blocker overscan
Before this, we unconditionally used the largest OuterRadius of all actors inside a mod for overscanning of blockable projectiles. However, in many mods the only blockable actors are 1-cell walls, and even if there are gates like in TS, they usually aren't the largest actors in terms of hit-shape. So this measure should save a bit of performance by reducing the overscan radius of blockable projectiles, especially in mods where walls are the only blocking actors.
This commit is contained in:
@@ -259,6 +259,7 @@ namespace OpenRA.Traits
|
|||||||
IEnumerable<Actor> ActorsInBox(WPos a, WPos b);
|
IEnumerable<Actor> ActorsInBox(WPos a, WPos b);
|
||||||
|
|
||||||
WDist LargestActorRadius { get; }
|
WDist LargestActorRadius { get; }
|
||||||
|
WDist LargestBlockingActorRadius { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IRenderModifier
|
public interface IRenderModifier
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
public static bool AnyBlockingActorsBetween(World world, WPos start, WPos end, WDist width, out WPos hit)
|
public static bool AnyBlockingActorsBetween(World world, WPos start, WPos end, WDist width, out WPos hit)
|
||||||
{
|
{
|
||||||
var actors = world.FindActorsOnLine(start, end, width);
|
var actors = world.FindBlockingActorsOnLine(start, end, width);
|
||||||
var length = (end - start).Length;
|
var length = (end - start).Length;
|
||||||
|
|
||||||
foreach (var a in actors)
|
foreach (var a in actors)
|
||||||
|
|||||||
@@ -184,6 +184,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
readonly Predicate<Actor> actorShouldBeRemoved;
|
readonly Predicate<Actor> actorShouldBeRemoved;
|
||||||
|
|
||||||
public WDist LargestActorRadius { get; private set; }
|
public WDist LargestActorRadius { get; private set; }
|
||||||
|
public WDist LargestBlockingActorRadius { get; private set; }
|
||||||
|
|
||||||
public ActorMap(World world, ActorMapInfo info)
|
public ActorMap(World world, ActorMapInfo info)
|
||||||
{
|
{
|
||||||
@@ -202,6 +203,8 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
actorShouldBeRemoved = removeActorPosition.Contains;
|
actorShouldBeRemoved = removeActorPosition.Contains;
|
||||||
|
|
||||||
LargestActorRadius = map.Rules.Actors.SelectMany(a => a.Value.TraitInfos<HitShapeInfo>()).Max(h => h.Type.OuterRadius);
|
LargestActorRadius = map.Rules.Actors.SelectMany(a => a.Value.TraitInfos<HitShapeInfo>()).Max(h => h.Type.OuterRadius);
|
||||||
|
var blockers = map.Rules.Actors.Where(a => a.Value.HasTraitInfo<IBlocksProjectilesInfo>());
|
||||||
|
LargestBlockingActorRadius = blockers.Any() ? blockers.SelectMany(a => a.Value.TraitInfos<HitShapeInfo>()).Max(h => h.Type.OuterRadius) : WDist.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
void INotifyCreated.Created(Actor self)
|
void INotifyCreated.Created(Actor self)
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ namespace OpenRA.Mods.Common
|
|||||||
/// <param name="lineEnd">The position the line should end at</param>
|
/// <param name="lineEnd">The position the line should end at</param>
|
||||||
/// <param name="lineWidth">How close an actor's health radius needs to be to the line to be considered 'intersected' by the line</param>
|
/// <param name="lineWidth">How close an actor's health radius needs to be to the line to be considered 'intersected' by the line</param>
|
||||||
/// <returns>A list of all the actors intersected by the line</returns>
|
/// <returns>A list of all the actors intersected by the line</returns>
|
||||||
public static IEnumerable<Actor> FindActorsOnLine(this World world, WPos lineStart, WPos lineEnd, WDist lineWidth)
|
public static IEnumerable<Actor> FindActorsOnLine(this World world, WPos lineStart, WPos lineEnd, WDist lineWidth, bool onlyBlockers = false)
|
||||||
{
|
{
|
||||||
// This line intersection check is done by first just finding all actors within a square that starts at the source, and ends at the target.
|
// This line intersection check is done by first just finding all actors within a square that starts at the source, and ends at the target.
|
||||||
// Then we iterate over this list, and find all actors for which their health radius is at least within lineWidth of the line.
|
// Then we iterate over this list, and find all actors for which their health radius is at least within lineWidth of the line.
|
||||||
@@ -39,7 +39,8 @@ namespace OpenRA.Mods.Common
|
|||||||
var yDir = yDiff < 0 ? -1 : 1;
|
var yDir = yDiff < 0 ? -1 : 1;
|
||||||
|
|
||||||
var dir = new WVec(xDir, yDir, 0);
|
var dir = new WVec(xDir, yDir, 0);
|
||||||
var overselect = dir * (1024 + lineWidth.Length + world.ActorMap.LargestActorRadius.Length);
|
var largestValidActorRadius = onlyBlockers ? world.ActorMap.LargestBlockingActorRadius.Length : world.ActorMap.LargestActorRadius.Length;
|
||||||
|
var overselect = dir * (1024 + lineWidth.Length + largestValidActorRadius);
|
||||||
var finalTarget = lineEnd + overselect;
|
var finalTarget = lineEnd + overselect;
|
||||||
var finalSource = lineStart - overselect;
|
var finalSource = lineStart - overselect;
|
||||||
|
|
||||||
@@ -64,6 +65,11 @@ namespace OpenRA.Mods.Common
|
|||||||
return intersectedActors;
|
return intersectedActors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<Actor> FindBlockingActorsOnLine(this World world, WPos lineStart, WPos lineEnd, WDist lineWidth)
|
||||||
|
{
|
||||||
|
return world.FindActorsOnLine(lineStart, lineEnd, lineWidth, true);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finds all the actors of which their health radius is intersected by a specified circle.
|
/// Finds all the actors of which their health radius is intersected by a specified circle.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user