Change GetCustomMovementLayers to expose an array, not a dictionary.
As there are few custom movement layers, using an array is good for improving lookup speed. Additionally, we can simplify some code by reserving index 0 of the array for the ground layer. Code that needs to maintain a state for the ground layer and every custom movement layer can now maintain a flat array of state using index 0 for the ground layer, and the the ICustomMovementLayer.Index for the custom movement layer. This removes a lot of ternary statements checking for the ground layer special case.
This commit is contained in:
committed by
Paul Chote
parent
3310f14dea
commit
dd9d600ef9
@@ -88,22 +88,23 @@ namespace OpenRA.Mods.Common.Pathfinder
|
||||
readonly Locomotor locomotor;
|
||||
readonly CellInfoLayerPool.PooledCellInfoLayer pooledLayer;
|
||||
readonly bool checkTerrainHeight;
|
||||
CellLayer<CellInfo> groundInfo;
|
||||
|
||||
readonly Dictionary<byte, (ICustomMovementLayer Layer, CellLayer<CellInfo> Info)> customLayerInfo =
|
||||
new Dictionary<byte, (ICustomMovementLayer, CellLayer<CellInfo>)>();
|
||||
readonly CellLayer<CellInfo>[] cellInfoForLayer;
|
||||
|
||||
public PathGraph(CellInfoLayerPool layerPool, Locomotor locomotor, Actor actor, World world, BlockedByActor check)
|
||||
{
|
||||
pooledLayer = layerPool.Get();
|
||||
groundInfo = pooledLayer.GetLayer();
|
||||
var locomotorInfo = locomotor.Info;
|
||||
this.locomotor = locomotor;
|
||||
|
||||
// As we support a search over the whole map area,
|
||||
// use the pool to grab the CellInfos we need to track the graph state.
|
||||
// This allows us to avoid the cost of allocating large arrays constantly.
|
||||
// PERF: Avoid LINQ
|
||||
foreach (var cml in world.GetCustomMovementLayers().Values)
|
||||
if (cml.EnabledForLocomotor(locomotorInfo))
|
||||
customLayerInfo[cml.Index] = (cml, pooledLayer.GetLayer());
|
||||
var cmls = world.GetCustomMovementLayers();
|
||||
pooledLayer = layerPool.Get();
|
||||
cellInfoForLayer = new CellLayer<CellInfo>[cmls.Length];
|
||||
cellInfoForLayer[0] = pooledLayer.GetLayer();
|
||||
foreach (var cml in cmls)
|
||||
if (cml != null && cml.EnabledForLocomotor(locomotor.Info))
|
||||
cellInfoForLayer[cml.Index] = pooledLayer.GetLayer();
|
||||
|
||||
World = world;
|
||||
Actor = actor;
|
||||
@@ -132,8 +133,8 @@ namespace OpenRA.Mods.Common.Pathfinder
|
||||
|
||||
public List<GraphConnection> GetConnections(CPos position)
|
||||
{
|
||||
var posLayer = position.Layer;
|
||||
var info = posLayer == 0 ? groundInfo : customLayerInfo[posLayer].Info;
|
||||
var layer = position.Layer;
|
||||
var info = cellInfoForLayer[layer];
|
||||
var previousPos = info[position].PreviousPos;
|
||||
|
||||
var dx = position.X - previousPos.X;
|
||||
@@ -141,7 +142,7 @@ namespace OpenRA.Mods.Common.Pathfinder
|
||||
var index = dy * 3 + dx + 4;
|
||||
|
||||
var directions = DirectedNeighbors[index];
|
||||
var validNeighbors = new List<GraphConnection>(directions.Length + (posLayer == 0 ? customLayerInfo.Count : 1));
|
||||
var validNeighbors = new List<GraphConnection>(directions.Length + (layer == 0 ? cellInfoForLayer.Length : 1));
|
||||
for (var i = 0; i < directions.Length; i++)
|
||||
{
|
||||
var dir = directions[i];
|
||||
@@ -153,12 +154,16 @@ namespace OpenRA.Mods.Common.Pathfinder
|
||||
validNeighbors.Add(new GraphConnection(neighbor, pathCost));
|
||||
}
|
||||
|
||||
if (posLayer == 0)
|
||||
var cmls = World.GetCustomMovementLayers();
|
||||
if (layer == 0)
|
||||
{
|
||||
foreach (var cli in customLayerInfo.Values)
|
||||
foreach (var cml in cmls)
|
||||
{
|
||||
var layerPosition = new CPos(position.X, position.Y, cli.Layer.Index);
|
||||
var entryCost = cli.Layer.EntryMovementCost(locomotor.Info, layerPosition);
|
||||
if (cml == null || !cml.EnabledForLocomotor(locomotor.Info))
|
||||
continue;
|
||||
|
||||
var layerPosition = new CPos(position.X, position.Y, cml.Index);
|
||||
var entryCost = cml.EntryMovementCost(locomotor.Info, layerPosition);
|
||||
if (entryCost != MovementCostForUnreachableCell)
|
||||
validNeighbors.Add(new GraphConnection(layerPosition, entryCost));
|
||||
}
|
||||
@@ -166,7 +171,7 @@ namespace OpenRA.Mods.Common.Pathfinder
|
||||
else
|
||||
{
|
||||
var layerPosition = new CPos(position.X, position.Y, 0);
|
||||
var exitCost = customLayerInfo[posLayer].Layer.ExitMovementCost(locomotor.Info, layerPosition);
|
||||
var exitCost = cmls[layer].ExitMovementCost(locomotor.Info, layerPosition);
|
||||
if (exitCost != MovementCostForUnreachableCell)
|
||||
validNeighbors.Add(new GraphConnection(layerPosition, exitCost));
|
||||
}
|
||||
@@ -226,14 +231,12 @@ namespace OpenRA.Mods.Common.Pathfinder
|
||||
|
||||
public CellInfo this[CPos pos]
|
||||
{
|
||||
get => (pos.Layer == 0 ? groundInfo : customLayerInfo[pos.Layer].Info)[pos];
|
||||
set => (pos.Layer == 0 ? groundInfo : customLayerInfo[pos.Layer].Info)[pos] = value;
|
||||
get => cellInfoForLayer[pos.Layer][pos];
|
||||
set => cellInfoForLayer[pos.Layer][pos] = value;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
groundInfo = null;
|
||||
customLayerInfo.Clear();
|
||||
pooledLayer.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -428,10 +428,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (ToCell.Layer == 0)
|
||||
return true;
|
||||
|
||||
if (self.World.GetCustomMovementLayers().TryGetValue(ToCell.Layer, out var layer))
|
||||
return layer.InteractsWithDefaultLayer;
|
||||
|
||||
return true;
|
||||
var layer = self.World.GetCustomMovementLayers()[ToCell.Layer];
|
||||
return layer == null || layer.InteractsWithDefaultLayer;
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -862,9 +860,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return;
|
||||
}
|
||||
|
||||
var cml = self.World.WorldActor.TraitsImplementing<ICustomMovementLayer>()
|
||||
.First(l => l.Index == self.Location.Layer);
|
||||
|
||||
var cml = self.World.GetCustomMovementLayers()[self.Location.Layer];
|
||||
if (!cml.ReturnToGroundLayerOnIdle)
|
||||
return;
|
||||
|
||||
|
||||
@@ -171,9 +171,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
readonly Dictionary<int, ProximityTrigger> proximityTriggers = new Dictionary<int, ProximityTrigger>();
|
||||
int nextTriggerId;
|
||||
|
||||
readonly CellLayer<InfluenceNode> influence;
|
||||
readonly Dictionary<int, CellLayer<InfluenceNode>> customInfluence = new Dictionary<int, CellLayer<InfluenceNode>>();
|
||||
public readonly Dictionary<int, ICustomMovementLayer> CustomMovementLayers = new Dictionary<int, ICustomMovementLayer>();
|
||||
CellLayer<InfluenceNode>[] influence;
|
||||
|
||||
// Index 0 is kept null as layer 0 is used for the ground layer.
|
||||
public ICustomMovementLayer[] CustomMovementLayers = new ICustomMovementLayer[] { null };
|
||||
public event Action<CPos> CellUpdated;
|
||||
readonly Bin[] bins;
|
||||
readonly int rows, cols;
|
||||
@@ -191,7 +192,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
this.info = info;
|
||||
map = world.Map;
|
||||
influence = new CellLayer<InfluenceNode>(world.Map);
|
||||
influence = new[] { new CellLayer<InfluenceNode>(world.Map) };
|
||||
|
||||
cols = CellCoordToBinIndex(world.Map.MapSize.X) + 1;
|
||||
rows = CellCoordToBinIndex(world.Map.MapSize.Y) + 1;
|
||||
@@ -210,10 +211,18 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
void INotifyCreated.Created(Actor self)
|
||||
{
|
||||
foreach (var cml in self.TraitsImplementing<ICustomMovementLayer>())
|
||||
var cmls = self.TraitsImplementing<ICustomMovementLayer>().ToList();
|
||||
if (cmls.Count == 0)
|
||||
return;
|
||||
|
||||
var length = cmls.Max(cml => cml.Index) + 1;
|
||||
Array.Resize(ref CustomMovementLayers, length);
|
||||
Array.Resize(ref influence, length);
|
||||
|
||||
foreach (var cml in cmls)
|
||||
{
|
||||
CustomMovementLayers[cml.Index] = cml;
|
||||
customInfluence.Add(cml.Index, new CellLayer<InfluenceNode>(self.World.Map));
|
||||
influence[cml.Index] = new CellLayer<InfluenceNode>(self.World.Map);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,21 +268,21 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
// PERF: Custom enumerator for efficiency - using `yield` is slower.
|
||||
var uv = a.ToMPos(map);
|
||||
if (!influence.Contains(uv))
|
||||
var layer = influence[a.Layer];
|
||||
if (!layer.Contains(uv))
|
||||
return Enumerable.Empty<Actor>();
|
||||
|
||||
var layer = a.Layer == 0 ? influence : customInfluence[a.Layer];
|
||||
return new ActorsAtEnumerable(layer[uv]);
|
||||
}
|
||||
|
||||
public IEnumerable<Actor> GetActorsAt(CPos a, SubCell sub)
|
||||
{
|
||||
var uv = a.ToMPos(map);
|
||||
if (!influence.Contains(uv))
|
||||
var layer = influence[a.Layer];
|
||||
if (!layer.Contains(uv))
|
||||
yield break;
|
||||
|
||||
var always = sub == SubCell.FullCell || sub == SubCell.Any;
|
||||
var layer = a.Layer == 0 ? influence : customInfluence[a.Layer];
|
||||
for (var i = layer[uv]; i != null; i = i.Next)
|
||||
if (!i.Actor.Disposed && (i.SubCell == sub || i.SubCell == SubCell.FullCell || always))
|
||||
yield return i.Actor;
|
||||
@@ -287,17 +296,18 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public SubCell FreeSubCell(CPos cell, SubCell preferredSubCell = SubCell.Any, bool checkTransient = true)
|
||||
{
|
||||
var uv = cell.ToMPos(map);
|
||||
if (!influence.Contains(uv))
|
||||
var layer = influence[cell.Layer];
|
||||
if (!layer.Contains(uv))
|
||||
return preferredSubCell != SubCell.Any ? preferredSubCell : SubCell.First;
|
||||
|
||||
if (preferredSubCell != SubCell.Any && !AnyActorsAt(uv, cell, preferredSubCell, checkTransient))
|
||||
if (preferredSubCell != SubCell.Any && !AnyActorsAt(uv, cell, layer, preferredSubCell, checkTransient))
|
||||
return preferredSubCell;
|
||||
|
||||
if (!AnyActorsAt(uv, cell.Layer))
|
||||
if (!AnyActorsAt(uv, layer))
|
||||
return map.Grid.DefaultSubCell;
|
||||
|
||||
for (var i = (int)SubCell.First; i < map.Grid.SubCellOffsets.Length; i++)
|
||||
if (i != (int)preferredSubCell && !AnyActorsAt(uv, cell, (SubCell)i, checkTransient))
|
||||
if (i != (int)preferredSubCell && !AnyActorsAt(uv, cell, layer, (SubCell)i, checkTransient))
|
||||
return (SubCell)i;
|
||||
|
||||
return SubCell.Invalid;
|
||||
@@ -306,26 +316,26 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public SubCell FreeSubCell(CPos cell, SubCell preferredSubCell, Func<Actor, bool> checkIfBlocker)
|
||||
{
|
||||
var uv = cell.ToMPos(map);
|
||||
if (!influence.Contains(uv))
|
||||
var layer = influence[cell.Layer];
|
||||
if (!layer.Contains(uv))
|
||||
return preferredSubCell != SubCell.Any ? preferredSubCell : SubCell.First;
|
||||
|
||||
if (preferredSubCell != SubCell.Any && !AnyActorsAt(uv, cell, preferredSubCell, checkIfBlocker))
|
||||
if (preferredSubCell != SubCell.Any && !AnyActorsAt(uv, layer, preferredSubCell, checkIfBlocker))
|
||||
return preferredSubCell;
|
||||
|
||||
if (!AnyActorsAt(uv, cell.Layer))
|
||||
if (!AnyActorsAt(uv, layer))
|
||||
return map.Grid.DefaultSubCell;
|
||||
|
||||
for (var i = (byte)SubCell.First; i < map.Grid.SubCellOffsets.Length; i++)
|
||||
if (i != (byte)preferredSubCell && !AnyActorsAt(uv, cell, (SubCell)i, checkIfBlocker))
|
||||
if (i != (byte)preferredSubCell && !AnyActorsAt(uv, layer, (SubCell)i, checkIfBlocker))
|
||||
return (SubCell)i;
|
||||
|
||||
return SubCell.Invalid;
|
||||
}
|
||||
|
||||
// NOTE: pos required to be in map bounds
|
||||
bool AnyActorsAt(MPos uv, int layerIndex)
|
||||
bool AnyActorsAt(MPos uv, CellLayer<InfluenceNode> layer)
|
||||
{
|
||||
var layer = layerIndex == 0 ? influence : customInfluence[layerIndex];
|
||||
return layer[uv] != null;
|
||||
}
|
||||
|
||||
@@ -333,17 +343,17 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public bool AnyActorsAt(CPos a)
|
||||
{
|
||||
var uv = a.ToMPos(map);
|
||||
if (!influence.Contains(uv))
|
||||
var layer = influence[a.Layer];
|
||||
if (!layer.Contains(uv))
|
||||
return false;
|
||||
|
||||
return AnyActorsAt(uv, a.Layer);
|
||||
return AnyActorsAt(uv, layer);
|
||||
}
|
||||
|
||||
// NOTE: pos required to be in map bounds
|
||||
bool AnyActorsAt(MPos uv, CPos a, SubCell sub, bool checkTransient)
|
||||
bool AnyActorsAt(MPos uv, CPos a, CellLayer<InfluenceNode> layer, SubCell sub, bool checkTransient)
|
||||
{
|
||||
var always = sub == SubCell.FullCell || sub == SubCell.Any;
|
||||
var layer = a.Layer == 0 ? influence : customInfluence[a.Layer];
|
||||
for (var i = layer[uv]; i != null; i = i.Next)
|
||||
{
|
||||
if (always || i.SubCell == sub || i.SubCell == SubCell.FullCell)
|
||||
@@ -364,17 +374,17 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public bool AnyActorsAt(CPos a, SubCell sub, bool checkTransient = true)
|
||||
{
|
||||
var uv = a.ToMPos(map);
|
||||
if (!influence.Contains(uv))
|
||||
var layer = influence[a.Layer];
|
||||
if (!layer.Contains(uv))
|
||||
return false;
|
||||
|
||||
return AnyActorsAt(uv, a, sub, checkTransient);
|
||||
return AnyActorsAt(uv, a, layer, sub, checkTransient);
|
||||
}
|
||||
|
||||
// NOTE: can not check aircraft
|
||||
bool AnyActorsAt(MPos uv, CPos a, SubCell sub, Func<Actor, bool> withCondition)
|
||||
bool AnyActorsAt(MPos uv, CellLayer<InfluenceNode> layer, SubCell sub, Func<Actor, bool> withCondition)
|
||||
{
|
||||
var always = sub == SubCell.FullCell || sub == SubCell.Any;
|
||||
var layer = a.Layer == 0 ? influence : customInfluence[a.Layer];
|
||||
for (var i = layer[uv]; i != null; i = i.Next)
|
||||
if ((always || i.SubCell == sub || i.SubCell == SubCell.FullCell) && !i.Actor.Disposed && withCondition(i.Actor))
|
||||
return true;
|
||||
@@ -386,10 +396,11 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public bool AnyActorsAt(CPos a, SubCell sub, Func<Actor, bool> withCondition)
|
||||
{
|
||||
var uv = a.ToMPos(map);
|
||||
if (!influence.Contains(uv))
|
||||
var layer = influence[a.Layer];
|
||||
if (!layer.Contains(uv))
|
||||
return false;
|
||||
|
||||
return AnyActorsAt(uv, a, sub, withCondition);
|
||||
return AnyActorsAt(uv, layer, sub, withCondition);
|
||||
}
|
||||
|
||||
public void AddInfluence(Actor self, IOccupySpace ios)
|
||||
@@ -397,10 +408,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
foreach (var c in ios.OccupiedCells())
|
||||
{
|
||||
var uv = c.Cell.ToMPos(map);
|
||||
if (!influence.Contains(uv))
|
||||
var layer = influence[c.Cell.Layer];
|
||||
if (!layer.Contains(uv))
|
||||
continue;
|
||||
|
||||
var layer = c.Cell.Layer == 0 ? influence : customInfluence[c.Cell.Layer];
|
||||
layer[uv] = new InfluenceNode { Next = layer[uv], SubCell = c.SubCell, Actor = self };
|
||||
|
||||
if (cellTriggerInfluence.TryGetValue(c.Cell, out var triggers))
|
||||
@@ -416,10 +427,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
foreach (var c in ios.OccupiedCells())
|
||||
{
|
||||
var uv = c.Cell.ToMPos(map);
|
||||
if (!influence.Contains(uv))
|
||||
var layer = influence[c.Cell.Layer];
|
||||
if (!layer.Contains(uv))
|
||||
continue;
|
||||
|
||||
var layer = c.Cell.Layer == 0 ? influence : customInfluence[c.Cell.Layer];
|
||||
var temp = layer[uv];
|
||||
RemoveInfluenceInner(ref temp, self);
|
||||
layer[uv] = temp;
|
||||
@@ -496,9 +507,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
var t = new CellTrigger(cells, onEntry, onExit);
|
||||
cellTriggers.Add(id, t);
|
||||
|
||||
var layer = influence[0];
|
||||
foreach (var c in cells)
|
||||
{
|
||||
if (!influence.Contains(c))
|
||||
if (!layer.Contains(c))
|
||||
continue;
|
||||
|
||||
if (!cellTriggerInfluence.ContainsKey(c))
|
||||
@@ -649,7 +661,15 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public static class ActorMapWorldExts
|
||||
{
|
||||
public static Dictionary<int, ICustomMovementLayer> GetCustomMovementLayers(this World world)
|
||||
/// <summary>
|
||||
/// Returns an array of custom movement layers.
|
||||
/// The <see cref="ICustomMovementLayer.Index"/> of a layer is used to index into this array.
|
||||
/// This array may contain null entries for layers which are not present in the world.
|
||||
/// This array is guaranteed to have a length of at least one. Index 0 is always null.
|
||||
/// Index 0 is kept null as layer 0 is used for the ground layer, consumers can combine
|
||||
/// the ground layer and custom layers into a single array for easy indexing.
|
||||
/// </summary>
|
||||
public static ICustomMovementLayer[] GetCustomMovementLayers(this World world)
|
||||
{
|
||||
return ((ActorMap)world.ActorMap).CustomMovementLayers;
|
||||
}
|
||||
|
||||
@@ -144,18 +144,16 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public readonly LocomotorInfo Info;
|
||||
public readonly uint MovementClass;
|
||||
CellLayer<short> cellsCost;
|
||||
CellLayer<CellCache> blockingCache;
|
||||
|
||||
readonly Dictionary<byte, CellLayer<short>> customLayerCellsCost = new Dictionary<byte, CellLayer<short>>();
|
||||
readonly Dictionary<byte, CellLayer<CellCache>> customLayerBlockingCache = new Dictionary<byte, CellLayer<CellCache>>();
|
||||
|
||||
readonly LocomotorInfo.TerrainInfo[] terrainInfos;
|
||||
readonly World world;
|
||||
readonly HashSet<CPos> dirtyCells = new HashSet<CPos>();
|
||||
readonly bool sharesCell;
|
||||
|
||||
CellLayer<short>[] cellsCost;
|
||||
CellLayer<CellCache>[] blockingCache;
|
||||
|
||||
IActorMap actorMap;
|
||||
bool sharesCell;
|
||||
|
||||
public Locomotor(Actor self, LocomotorInfo info)
|
||||
{
|
||||
@@ -177,7 +175,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (!world.Map.Contains(cell))
|
||||
return PathGraph.MovementCostForUnreachableCell;
|
||||
|
||||
return cell.Layer == 0 ? cellsCost[cell] : customLayerCellsCost[cell.Layer][cell];
|
||||
return cellsCost[cell.Layer][cell];
|
||||
}
|
||||
|
||||
public int MovementSpeedForCell(CPos cell)
|
||||
@@ -193,7 +191,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (!world.Map.Contains(destNode))
|
||||
return PathGraph.MovementCostForUnreachableCell;
|
||||
|
||||
var cellCost = destNode.Layer == 0 ? cellsCost[destNode] : customLayerCellsCost[destNode.Layer][destNode];
|
||||
var cellCost = cellsCost[destNode.Layer][destNode];
|
||||
|
||||
if (cellCost == PathGraph.MovementCostForUnreachableCell ||
|
||||
!CanMoveFreelyInto(actor, destNode, check, ignoreActor))
|
||||
@@ -359,8 +357,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
actorMap = w.ActorMap;
|
||||
actorMap.CellUpdated += CellUpdated;
|
||||
|
||||
blockingCache = new CellLayer<CellCache>(map);
|
||||
cellsCost = new CellLayer<short>(map);
|
||||
cellsCost = new[] { new CellLayer<short>(map) };
|
||||
blockingCache = new[] { new CellLayer<CellCache>(map) };
|
||||
|
||||
foreach (var cell in map.AllCells)
|
||||
UpdateCellCost(cell);
|
||||
@@ -371,12 +369,17 @@ namespace OpenRA.Mods.Common.Traits
|
||||
// This section needs to run after WorldLoaded() because we need to be sure that all types of ICustomMovementLayer have been initialized.
|
||||
w.AddFrameEndTask(_ =>
|
||||
{
|
||||
var customMovementLayers = w.WorldActor.TraitsImplementing<ICustomMovementLayer>();
|
||||
foreach (var cml in customMovementLayers)
|
||||
var cmls = world.GetCustomMovementLayers();
|
||||
Array.Resize(ref cellsCost, cmls.Length);
|
||||
Array.Resize(ref blockingCache, cmls.Length);
|
||||
foreach (var cml in cmls)
|
||||
{
|
||||
if (cml == null)
|
||||
continue;
|
||||
|
||||
var cellLayer = new CellLayer<short>(map);
|
||||
customLayerCellsCost[cml.Index] = cellLayer;
|
||||
customLayerBlockingCache[cml.Index] = new CellLayer<CellCache>(map);
|
||||
cellsCost[cml.Index] = cellLayer;
|
||||
blockingCache[cml.Index] = new CellLayer<CellCache>(map);
|
||||
|
||||
foreach (var cell in map.AllCells)
|
||||
{
|
||||
@@ -395,13 +398,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
CellCache GetCache(CPos cell)
|
||||
{
|
||||
if (dirtyCells.Contains(cell))
|
||||
{
|
||||
if (dirtyCells.Remove(cell))
|
||||
UpdateCellBlocking(cell);
|
||||
dirtyCells.Remove(cell);
|
||||
}
|
||||
|
||||
var cache = cell.Layer == 0 ? blockingCache : customLayerBlockingCache[cell.Layer];
|
||||
var cache = blockingCache[cell.Layer];
|
||||
|
||||
return cache[cell];
|
||||
}
|
||||
@@ -422,7 +422,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (index != byte.MaxValue)
|
||||
cost = terrainInfos[index].Cost;
|
||||
|
||||
var cache = cell.Layer == 0 ? cellsCost : customLayerCellsCost[cell.Layer];
|
||||
var cache = cellsCost[cell.Layer];
|
||||
|
||||
cache[cell] = cost;
|
||||
}
|
||||
@@ -431,7 +431,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
using (new PerfSample("locomotor_cache"))
|
||||
{
|
||||
var cache = cell.Layer == 0 ? blockingCache : customLayerBlockingCache[cell.Layer];
|
||||
var cache = blockingCache[cell.Layer];
|
||||
|
||||
var actors = actorMap.GetActorsAt(cell);
|
||||
var cellFlag = CellFlag.HasFreeSpace;
|
||||
|
||||
Reference in New Issue
Block a user