Add plumbing for custom movement layers.
This commit is contained in:
@@ -26,7 +26,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public object Create(ActorInitializer init) { return new ActorMap(init.World, this); }
|
||||
}
|
||||
|
||||
public class ActorMap : IActorMap, ITick
|
||||
public class ActorMap : IActorMap, ITick, INotifyCreated
|
||||
{
|
||||
class InfluenceNode
|
||||
{
|
||||
@@ -165,6 +165,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
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>();
|
||||
|
||||
readonly Bin[] bins;
|
||||
readonly int rows, cols;
|
||||
@@ -192,6 +194,15 @@ namespace OpenRA.Mods.Common.Traits
|
||||
actorShouldBeRemoved = removeActorPosition.Contains;
|
||||
}
|
||||
|
||||
void INotifyCreated.Created(Actor self)
|
||||
{
|
||||
foreach (var cml in self.TraitsImplementing<ICustomMovementLayer>())
|
||||
{
|
||||
CustomMovementLayers[cml.Index] = cml;
|
||||
customInfluence.Add(cml.Index, new CellLayer<InfluenceNode>(self.World.Map));
|
||||
}
|
||||
}
|
||||
|
||||
sealed class ActorsAtEnumerator : IEnumerator<Actor>
|
||||
{
|
||||
InfluenceNode node;
|
||||
@@ -228,7 +239,9 @@ namespace OpenRA.Mods.Common.Traits
|
||||
var uv = a.ToMPos(map);
|
||||
if (!influence.Contains(uv))
|
||||
return Enumerable.Empty<Actor>();
|
||||
return new ActorsAtEnumerable(influence[uv]);
|
||||
|
||||
var layer = a.Layer == 0 ? influence : customInfluence[a.Layer];
|
||||
return new ActorsAtEnumerable(layer[uv]);
|
||||
}
|
||||
|
||||
public IEnumerable<Actor> GetActorsAt(CPos a, SubCell sub)
|
||||
@@ -237,7 +250,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (!influence.Contains(uv))
|
||||
yield break;
|
||||
|
||||
for (var i = influence[uv]; i != null; i = i.Next)
|
||||
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))
|
||||
yield return i.Actor;
|
||||
}
|
||||
@@ -283,7 +297,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (!influence.Contains(uv))
|
||||
return false;
|
||||
|
||||
return influence[uv] != null;
|
||||
var layer = a.Layer == 0 ? influence : customInfluence[a.Layer];
|
||||
return layer[uv] != null;
|
||||
}
|
||||
|
||||
// NOTE: can not check aircraft
|
||||
@@ -294,7 +309,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return false;
|
||||
|
||||
var always = sub == SubCell.FullCell || sub == SubCell.Any;
|
||||
for (var i = influence[uv]; i != null; i = i.Next)
|
||||
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)
|
||||
{
|
||||
@@ -318,7 +334,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return false;
|
||||
|
||||
var always = sub == SubCell.FullCell || sub == SubCell.Any;
|
||||
for (var i = influence[uv]; i != null; i = i.Next)
|
||||
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;
|
||||
|
||||
@@ -333,7 +350,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (!influence.Contains(uv))
|
||||
continue;
|
||||
|
||||
influence[uv] = new InfluenceNode { Next = influence[uv], SubCell = c.Second, Actor = self };
|
||||
var layer = c.First.Layer == 0 ? influence : customInfluence[c.First.Layer];
|
||||
layer[uv] = new InfluenceNode { Next = layer[uv], SubCell = c.Second, Actor = self };
|
||||
|
||||
List<CellTrigger> triggers;
|
||||
if (cellTriggerInfluence.TryGetValue(c.First, out triggers))
|
||||
@@ -350,9 +368,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (!influence.Contains(uv))
|
||||
continue;
|
||||
|
||||
var temp = influence[uv];
|
||||
var layer = c.First.Layer == 0 ? influence : customInfluence[c.First.Layer];
|
||||
var temp = layer[uv];
|
||||
RemoveInfluenceInner(ref temp, self);
|
||||
influence[uv] = temp;
|
||||
layer[uv] = temp;
|
||||
|
||||
List<CellTrigger> triggers;
|
||||
if (cellTriggerInfluence.TryGetValue(c.First, out triggers))
|
||||
@@ -567,4 +586,12 @@ namespace OpenRA.Mods.Common.Traits
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class ActorMapWorldExts
|
||||
{
|
||||
public static Dictionary<int, ICustomMovementLayer> GetCustomMovementLayers(this World world)
|
||||
{
|
||||
return ((ActorMap)world.ActorMap).CustomMovementLayers;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user