Add plumbing for custom movement layers.

This commit is contained in:
Paul Chote
2017-01-04 18:10:46 +00:00
parent 695a572dc3
commit 2bd5a392d1
12 changed files with 207 additions and 56 deletions

View File

@@ -57,21 +57,28 @@ namespace OpenRA.Mods.Common.Pathfinder
public class PooledCellInfoLayer : IDisposable
{
public CellLayer<CellInfo> Layer { get; private set; }
CellInfoLayerPool layerPool;
List<CellLayer<CellInfo>> layers = new List<CellLayer<CellInfo>>();
public PooledCellInfoLayer(CellInfoLayerPool layerPool)
{
this.layerPool = layerPool;
Layer = layerPool.GetLayer();
}
public CellLayer<CellInfo> GetLayer()
{
var layer = layerPool.GetLayer();
layers.Add(layer);
return layer;
}
public void Dispose()
{
if (Layer == null)
return;
layerPool.ReturnLayer(Layer);
Layer = null;
if (layerPool != null)
foreach (var layer in layers)
layerPool.ReturnLayer(layer);
layers = null;
layerPool = null;
}
}

View File

@@ -11,7 +11,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Mods.Common.Traits;
using OpenRA.Primitives;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Pathfinder
{
@@ -84,12 +87,21 @@ namespace OpenRA.Mods.Common.Pathfinder
readonly MobileInfo mobileInfo;
readonly MobileInfo.WorldMovementInfo worldMovementInfo;
readonly CellInfoLayerPool.PooledCellInfoLayer pooledLayer;
CellLayer<CellInfo> cellInfo;
CellLayer<CellInfo> groundInfo;
readonly Dictionary<byte, Pair<ICustomMovementLayer, CellLayer<CellInfo>>> customLayerInfo =
new Dictionary<byte, Pair<ICustomMovementLayer, CellLayer<CellInfo>>>();
public PathGraph(CellInfoLayerPool layerPool, MobileInfo mobileInfo, Actor actor, World world, bool checkForBlocked)
{
pooledLayer = layerPool.Get();
cellInfo = pooledLayer.Layer;
groundInfo = pooledLayer.GetLayer();
var layers = world.GetCustomMovementLayers().Values
.Where(cml => cml.EnabledForActor(actor.Info, mobileInfo));
foreach (var cml in layers)
customLayerInfo[cml.Index] = Pair.New(cml, pooledLayer.GetLayer());
World = world;
this.mobileInfo = mobileInfo;
worldMovementInfo = mobileInfo.GetWorldMovementInfo(world);
@@ -117,7 +129,8 @@ namespace OpenRA.Mods.Common.Pathfinder
public List<GraphConnection> GetConnections(CPos position)
{
var previousPos = cellInfo[position].PreviousPos;
var info = position.Layer == 0 ? groundInfo : customLayerInfo[position.Layer].Second;
var previousPos = info[position].PreviousPos;
var dx = position.X - previousPos.X;
var dy = position.Y - previousPos.Y;
@@ -133,6 +146,24 @@ namespace OpenRA.Mods.Common.Pathfinder
validNeighbors.Add(new GraphConnection(neighbor, movementCost));
}
if (position.Layer == 0)
{
foreach (var cli in customLayerInfo.Values)
{
var layerPosition = new CPos(position.X, position.Y, cli.First.Index);
var entryCost = cli.First.EntryMovementCost(Actor.Info, mobileInfo, layerPosition);
if (entryCost != Constants.InvalidNode)
validNeighbors.Add(new GraphConnection(layerPosition, entryCost));
}
}
else
{
var layerPosition = new CPos(position.X, position.Y, 0);
var exitCost = customLayerInfo[position.Layer].First.ExitMovementCost(Actor.Info, mobileInfo, layerPosition);
if (exitCost != Constants.InvalidNode)
validNeighbors.Add(new GraphConnection(layerPosition, exitCost));
}
return validNeighbors;
}
@@ -179,14 +210,15 @@ namespace OpenRA.Mods.Common.Pathfinder
public CellInfo this[CPos pos]
{
get { return cellInfo[pos]; }
set { cellInfo[pos] = value; }
get { return (pos.Layer == 0 ? groundInfo : customLayerInfo[pos.Layer].Second)[pos]; }
set { (pos.Layer == 0 ? groundInfo : customLayerInfo[pos.Layer].Second)[pos] = value; }
}
public void Dispose()
{
groundInfo = null;
customLayerInfo.Clear();
pooledLayer.Dispose();
cellInfo = null;
}
}
}