Using the building footprint, the placement overlay is offset from the cursor so the cursor is in the approximate middle of the overlay (not precisely due to overlay snapping to tiles). The tile size (24) was used as a magic number in a lot of places, they have been replaced with Game.CellSize.
81 lines
1.8 KiB
C#
81 lines
1.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.IO;
|
|
using OpenRa.Game.Graphics;
|
|
|
|
namespace OpenRa.Game.GameRules
|
|
{
|
|
class Footprint
|
|
{
|
|
Dictionary<string, string[]> buildingFootprints;
|
|
|
|
public string[] GetFootprint(string name)
|
|
{
|
|
string[] val;
|
|
if (!buildingFootprints.TryGetValue(name, out val))
|
|
buildingFootprints.TryGetValue("*", out val);
|
|
return val;
|
|
}
|
|
|
|
public Footprint(Stream s)
|
|
{
|
|
var lines = Util.ReadAllLines(s).Where(a => !a.StartsWith("#"));
|
|
|
|
Func<string,string[]> words =
|
|
b => b.Split( new[] { ' ', '\t' },
|
|
StringSplitOptions.RemoveEmptyEntries );
|
|
|
|
var buildings = lines
|
|
.Select(a => a.Split(':'))
|
|
.SelectMany(a => words(a[1])
|
|
.Select( b => new { Name=b, Pat=words(a[0]) } ));
|
|
|
|
buildingFootprints = buildings
|
|
.ToDictionary(a => a.Name, a => a.Pat);
|
|
}
|
|
|
|
public static IEnumerable<int2> Tiles(string name, int2 position)
|
|
{
|
|
var footprint = Rules.Footprint.GetFootprint(name);
|
|
var j = 0;
|
|
|
|
int maxWidth = 0;
|
|
foreach (var row in footprint)
|
|
if (row.Length > maxWidth)
|
|
maxWidth = row.Length;
|
|
|
|
foreach (var row in footprint)
|
|
{
|
|
var i = 0;
|
|
foreach (var c in row)
|
|
{
|
|
if (c != '_')
|
|
yield return position + new int2(i, j) - new int2(maxWidth / 2, footprint.Length / 2);
|
|
++i;
|
|
}
|
|
++j;
|
|
}
|
|
}
|
|
|
|
public static IEnumerable<int2> UnpathableTiles( string name, int2 position )
|
|
{
|
|
var footprint = Rules.Footprint.GetFootprint( name );
|
|
var j = 0;
|
|
|
|
foreach( var row in footprint )
|
|
{
|
|
var i = 0;
|
|
foreach( var c in row )
|
|
{
|
|
if( c == 'x' )
|
|
yield return position + new int2( i, j );
|
|
++i;
|
|
}
|
|
++j;
|
|
}
|
|
}
|
|
}
|
|
}
|