Add a SubCell field to UIM. Allow UIM to query for units by subcell.

This commit is contained in:
Paul Chote
2011-02-02 21:27:32 +13:00
parent 451e06190f
commit 4b3c6cc62a
16 changed files with 60 additions and 29 deletions

View File

@@ -81,11 +81,21 @@ namespace OpenRA.Traits
{
int2 PxPosition { get; }
}
public enum SubCell
{
FullCell,
TopLeft,
TopRight,
Center,
BottomLeft,
BottomRight
}
public interface IOccupySpace : IHasLocation
{
int2 TopLeft { get; }
IEnumerable<int2> OccupiedCells();
IEnumerable<Pair<int2, SubCell>> OccupiedCells();
}
public static class IOccupySpaceExts
@@ -96,10 +106,10 @@ namespace OpenRA.Traits
var nearestDistance = int.MaxValue;
foreach( var cell in ios.OccupiedCells() )
{
var dist = ( other - cell ).LengthSquared;
var dist = ( other - cell.First ).LengthSquared;
if( dist < nearestDistance )
{
nearest = cell;
nearest = cell.First;
nearestDistance = dist;
}
}

View File

@@ -136,7 +136,7 @@ namespace OpenRA.Traits
if (ios != null)
{
var cells = ios.OccupiedCells();
if (cells.Any()) return cells;
if (cells.Any()) return cells.Select(c => c.First);
}
return new[] { a.CenterLocation / Game.CellSize };

View File

@@ -26,9 +26,10 @@ namespace OpenRA.Traits
class InfluenceNode
{
public InfluenceNode next;
public SubCell subCell;
public Actor actor;
}
InfluenceNode[,] influence;
Map map;
@@ -51,21 +52,32 @@ namespace OpenRA.Traits
public bool AnyUnitsAt(int2 a)
{
return /*map.IsInMap(a) && */influence[ a.X, a.Y ] != null;
return influence[ a.X, a.Y ] != null;
}
public bool AnyUnitsAt(int2 a, SubCell sub)
{
var node = influence[ a.X, a.Y ];
while (node != null)
{
if (node.subCell == sub) return true;
node = node.next;
}
return false;
}
public void Add( Actor self, IOccupySpace unit )
{
if (unit != null)
foreach( var c in unit.OccupiedCells() )
influence[ c.X, c.Y ] = new InfluenceNode { next = influence[ c.X, c.Y ], actor = self };
influence[ c.First.X, c.First.Y ] = new InfluenceNode { next = influence[ c.First.X, c.First.Y ], subCell = c.Second, actor = self };
}
public void Remove( Actor self, IOccupySpace unit )
{
if (unit != null)
foreach (var c in unit.OccupiedCells())
RemoveInner( ref influence[ c.X, c.Y ], self );
RemoveInner( ref influence[ c.First.X, c.First.Y ], self );
}
void RemoveInner( ref InfluenceNode influenceNode, Actor toRemove )