Change terrain type from string based dictionaries to arrays
This commit is contained in:
@@ -32,6 +32,8 @@ namespace OpenRA.Graphics
|
|||||||
var bitmapData = terrain.LockBits(terrain.Bounds(),
|
var bitmapData = terrain.LockBits(terrain.Bounds(),
|
||||||
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
|
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
|
||||||
|
|
||||||
|
var mapTiles = map.MapTiles.Value;
|
||||||
|
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
int* c = (int*)bitmapData.Scan0;
|
int* c = (int*)bitmapData.Scan0;
|
||||||
@@ -41,11 +43,9 @@ namespace OpenRA.Graphics
|
|||||||
{
|
{
|
||||||
var mapX = x + map.Bounds.Left;
|
var mapX = x + map.Bounds.Left;
|
||||||
var mapY = y + map.Bounds.Top;
|
var mapY = y + map.Bounds.Top;
|
||||||
var type = tileset.GetTerrainType(map.MapTiles.Value[mapX, mapY]);
|
var type = tileset.GetTerrainInfo(mapTiles[mapX, mapY]);
|
||||||
if (!tileset.Terrain.ContainsKey(type))
|
|
||||||
throw new InvalidDataException("Tileset {0} lacks terraintype {1}".F(tileset.Id, type));
|
|
||||||
|
|
||||||
*(c + (y * bitmapData.Stride >> 2) + x) = tileset.Terrain[type].Color.ToArgb();
|
*(c + (y * bitmapData.Stride >> 2) + x) = type.Color.ToArgb();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ namespace OpenRA.Graphics
|
|||||||
if (res == null)
|
if (res == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
*(c + (y * bitmapData.Stride >> 2) + x) = tileset.Terrain[res].Color.ToArgb();
|
*(c + (y * bitmapData.Stride >> 2) + x) = tileset[tileset.GetTerrainIndex(res)].Color.ToArgb();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,9 +107,9 @@ namespace OpenRA.Graphics
|
|||||||
var mapX = x + map.Bounds.Left;
|
var mapX = x + map.Bounds.Left;
|
||||||
var mapY = y + map.Bounds.Top;
|
var mapY = y + map.Bounds.Top;
|
||||||
var custom = map.CustomTerrain[mapX, mapY];
|
var custom = map.CustomTerrain[mapX, mapY];
|
||||||
if (custom == null)
|
if (custom == -1)
|
||||||
continue;
|
continue;
|
||||||
*(c + (y * bitmapData.Stride >> 2) + x) = world.TileSet.Terrain[custom].Color.ToArgb();
|
*(c + (y * bitmapData.Stride >> 2) + x) = world.TileSet[custom].Color.ToArgb();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ namespace OpenRA
|
|||||||
|
|
||||||
[FieldLoader.Ignore] public Lazy<TileReference<ushort, byte>[,]> MapTiles;
|
[FieldLoader.Ignore] public Lazy<TileReference<ushort, byte>[,]> MapTiles;
|
||||||
[FieldLoader.Ignore] public Lazy<TileReference<byte, byte>[,]> MapResources;
|
[FieldLoader.Ignore] public Lazy<TileReference<byte, byte>[,]> MapResources;
|
||||||
[FieldLoader.Ignore] public string[,] CustomTerrain;
|
[FieldLoader.Ignore] public int[,] CustomTerrain;
|
||||||
|
|
||||||
[FieldLoader.Ignore] Lazy<Ruleset> rules;
|
[FieldLoader.Ignore] Lazy<Ruleset> rules;
|
||||||
public Ruleset Rules { get { return rules != null ? rules.Value : null; } }
|
public Ruleset Rules { get { return rules != null ? rules.Value : null; } }
|
||||||
@@ -228,7 +228,10 @@ namespace OpenRA
|
|||||||
NotificationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Notifications");
|
NotificationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Notifications");
|
||||||
TranslationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Translations");
|
TranslationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Translations");
|
||||||
|
|
||||||
CustomTerrain = new string[MapSize.X, MapSize.Y];
|
CustomTerrain = new int[MapSize.X, MapSize.Y];
|
||||||
|
for (var x = 0; x < MapSize.X; x++)
|
||||||
|
for (var y = 0; y < MapSize.Y; y++)
|
||||||
|
CustomTerrain[x, y] = -1;
|
||||||
|
|
||||||
MapTiles = Exts.Lazy(() => LoadMapTiles());
|
MapTiles = Exts.Lazy(() => LoadMapTiles());
|
||||||
MapResources = Exts.Lazy(() => LoadResourceTiles());
|
MapResources = Exts.Lazy(() => LoadResourceTiles());
|
||||||
@@ -529,7 +532,7 @@ namespace OpenRA
|
|||||||
var template = tileset.Templates[tr.Type];
|
var template = tileset.Templates[tr.Type];
|
||||||
if (!template.PickAny)
|
if (!template.PickAny)
|
||||||
continue;
|
continue;
|
||||||
tr.Index = (byte)r.Next(0, template.Tiles.Count);
|
tr.Index = (byte)r.Next(0, template.TilesCount);
|
||||||
MapTiles.Value[i, j] = tr;
|
MapTiles.Value[i, j] = tr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using OpenRA.Graphics;
|
using OpenRA.Graphics;
|
||||||
@@ -41,29 +42,81 @@ namespace OpenRA
|
|||||||
public readonly bool PickAny;
|
public readonly bool PickAny;
|
||||||
public readonly string Category;
|
public readonly string Category;
|
||||||
|
|
||||||
[FieldLoader.LoadUsing("LoadTiles")]
|
int[] tiles;
|
||||||
public readonly Dictionary<byte, string> Tiles = new Dictionary<byte, string>();
|
|
||||||
|
|
||||||
public TileTemplate() { }
|
public TileTemplate(ushort id, string image, int2 size, int[] tiles)
|
||||||
public TileTemplate(MiniYaml my) { FieldLoader.Load(this, my); }
|
|
||||||
|
|
||||||
public TileTemplate(ushort id, string image, int2 size)
|
|
||||||
{
|
{
|
||||||
this.Id = id;
|
this.Id = id;
|
||||||
this.Image = image;
|
this.Image = image;
|
||||||
this.Size = size;
|
this.Size = size;
|
||||||
|
this.tiles = tiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
static object LoadTiles(MiniYaml y)
|
public TileTemplate(TileSet tileSet, MiniYaml my)
|
||||||
{
|
{
|
||||||
return y.ToDictionary()["Tiles"].ToDictionary(
|
FieldLoader.Load(this, my);
|
||||||
name => byte.Parse(name),
|
|
||||||
my => my.Value);
|
tiles = LoadTiles(tileSet, my);
|
||||||
|
}
|
||||||
|
|
||||||
|
int[] LoadTiles(TileSet tileSet, MiniYaml y)
|
||||||
|
{
|
||||||
|
var nodes = y.ToDictionary()["Tiles"].Nodes;
|
||||||
|
|
||||||
|
if (!PickAny)
|
||||||
|
{
|
||||||
|
var tiles = new int[Size.X * Size.Y];
|
||||||
|
|
||||||
|
for (var i = 0; i < tiles.Length; i++)
|
||||||
|
tiles[i] = -1;
|
||||||
|
|
||||||
|
foreach (var node in nodes)
|
||||||
|
{
|
||||||
|
int key;
|
||||||
|
if (!int.TryParse(node.Key, out key) || key < 0 || key >= tiles.Length)
|
||||||
|
throw new InvalidDataException("Invalid tile key '{0}' on template '{1}' of tileset '{2}'.".F(node.Key, Id, tileSet.Id));
|
||||||
|
|
||||||
|
tiles[key] = tileSet.GetTerrainIndex(node.Value.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tiles;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var tiles = new int[nodes.Count];
|
||||||
|
var i = 0;
|
||||||
|
|
||||||
|
foreach (var node in nodes)
|
||||||
|
{
|
||||||
|
int key;
|
||||||
|
if (!int.TryParse(node.Key, out key) || key != i++)
|
||||||
|
throw new InvalidDataException("Invalid tile key '{0}' on template '{1}' of tileset '{2}'.".F(node.Key, Id, tileSet.Id));
|
||||||
|
|
||||||
|
tiles[key] = tileSet.GetTerrainIndex(node.Value.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tiles;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static readonly string[] Fields = { "Id", "Image", "Frames", "Size", "PickAny" };
|
static readonly string[] Fields = { "Id", "Image", "Frames", "Size", "PickAny" };
|
||||||
|
|
||||||
public MiniYaml Save()
|
public int this[int index]
|
||||||
|
{
|
||||||
|
get { return tiles[index]; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Contains(int index)
|
||||||
|
{
|
||||||
|
return index >= 0 && index < tiles.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int TilesCount
|
||||||
|
{
|
||||||
|
get { return tiles.Length; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public MiniYaml Save(TileSet tileSet)
|
||||||
{
|
{
|
||||||
var root = new List<MiniYamlNode>();
|
var root = new List<MiniYamlNode>();
|
||||||
foreach (var field in Fields)
|
foreach (var field in Fields)
|
||||||
@@ -76,7 +129,7 @@ namespace OpenRA
|
|||||||
}
|
}
|
||||||
|
|
||||||
root.Add(new MiniYamlNode("Tiles", null,
|
root.Add(new MiniYamlNode("Tiles", null,
|
||||||
Tiles.Select(x => new MiniYamlNode(x.Key.ToString(), x.Value)).ToList()));
|
tiles.Select((terrainTypeIndex, templateIndex) => new MiniYamlNode(templateIndex.ToString(), tileSet[terrainTypeIndex].Type)).ToList()));
|
||||||
|
|
||||||
return new MiniYaml(null, root);
|
return new MiniYaml(null, root);
|
||||||
}
|
}
|
||||||
@@ -91,10 +144,13 @@ namespace OpenRA
|
|||||||
public readonly string PlayerPalette;
|
public readonly string PlayerPalette;
|
||||||
public readonly string[] Extensions;
|
public readonly string[] Extensions;
|
||||||
public readonly int WaterPaletteRotationBase = 0x60;
|
public readonly int WaterPaletteRotationBase = 0x60;
|
||||||
public readonly Dictionary<string, TerrainTypeInfo> Terrain = new Dictionary<string, TerrainTypeInfo>();
|
|
||||||
public readonly Dictionary<ushort, TileTemplate> Templates = new Dictionary<ushort, TileTemplate>();
|
public readonly Dictionary<ushort, TileTemplate> Templates = new Dictionary<ushort, TileTemplate>();
|
||||||
public readonly string[] EditorTemplateOrder;
|
public readonly string[] EditorTemplateOrder;
|
||||||
|
|
||||||
|
readonly TerrainTypeInfo[] terrainInfo;
|
||||||
|
readonly Dictionary<string, int> terrainIndexByType = new Dictionary<string, int>();
|
||||||
|
readonly int defaultWalkableTerrainIndex;
|
||||||
|
|
||||||
static readonly string[] Fields = { "Name", "Id", "SheetSize", "Palette", "Extensions" };
|
static readonly string[] Fields = { "Name", "Id", "SheetSize", "Palette", "Extensions" };
|
||||||
|
|
||||||
public TileSet(ModData modData, string filepath)
|
public TileSet(ModData modData, string filepath)
|
||||||
@@ -105,20 +161,83 @@ namespace OpenRA
|
|||||||
FieldLoader.Load(this, yaml["General"]);
|
FieldLoader.Load(this, yaml["General"]);
|
||||||
|
|
||||||
// TerrainTypes
|
// TerrainTypes
|
||||||
Terrain = yaml["Terrain"].ToDictionary().Values
|
terrainInfo = yaml["Terrain"].ToDictionary().Values
|
||||||
.Select(y => new TerrainTypeInfo(y)).ToDictionary(t => t.Type);
|
.Select(y => new TerrainTypeInfo(y))
|
||||||
|
.OrderBy(tt => tt.Type)
|
||||||
|
.ToArray();
|
||||||
|
for (var i = 0; i < terrainInfo.Length; i++)
|
||||||
|
{
|
||||||
|
var tt = terrainInfo[i].Type;
|
||||||
|
|
||||||
|
if (terrainIndexByType.ContainsKey(tt))
|
||||||
|
throw new InvalidDataException("Duplicate terrain type '{0}' in '{1}'.".F(tt, filepath));
|
||||||
|
|
||||||
|
terrainIndexByType.Add(tt, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultWalkableTerrainIndex = GetTerrainIndex("Clear");
|
||||||
|
|
||||||
// Templates
|
// Templates
|
||||||
Templates = yaml["Templates"].ToDictionary().Values
|
Templates = yaml["Templates"].ToDictionary().Values
|
||||||
.Select(y => new TileTemplate(y)).ToDictionary(t => t.Id);
|
.Select(y => new TileTemplate(this, y)).ToDictionary(t => t.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TileSet(string name, string id, string palette, string[] extensions)
|
public TileSet(string name, string id, string palette, string[] extensions, TerrainTypeInfo[] terrainInfo)
|
||||||
{
|
{
|
||||||
this.Name = name;
|
this.Name = name;
|
||||||
this.Id = id;
|
this.Id = id;
|
||||||
this.Palette = palette;
|
this.Palette = palette;
|
||||||
this.Extensions = extensions;
|
this.Extensions = extensions;
|
||||||
|
this.terrainInfo = terrainInfo;
|
||||||
|
|
||||||
|
for (var i = 0; i < terrainInfo.Length; i++)
|
||||||
|
{
|
||||||
|
var tt = terrainInfo[i].Type;
|
||||||
|
|
||||||
|
if (terrainIndexByType.ContainsKey(tt))
|
||||||
|
throw new InvalidDataException("Duplicate terrain type '{0}'.".F(tt));
|
||||||
|
|
||||||
|
terrainIndexByType.Add(tt, i);
|
||||||
|
}
|
||||||
|
defaultWalkableTerrainIndex = GetTerrainIndex("Clear");
|
||||||
|
}
|
||||||
|
|
||||||
|
public TerrainTypeInfo this[int index]
|
||||||
|
{
|
||||||
|
get { return terrainInfo[index]; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int TerrainsCount
|
||||||
|
{
|
||||||
|
get { return terrainInfo.Length; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryGetTerrainIndex(string type, out int index)
|
||||||
|
{
|
||||||
|
return terrainIndexByType.TryGetValue(type, out index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetTerrainIndex(string type)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
if (terrainIndexByType.TryGetValue(type, out index))
|
||||||
|
return index;
|
||||||
|
|
||||||
|
throw new InvalidDataException("Tileset '{0}' lacks terrain type '{1}'".F(Id, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetTerrainIndex(TileReference<ushort, byte> r)
|
||||||
|
{
|
||||||
|
var tpl = Templates[r.Type];
|
||||||
|
|
||||||
|
if (tpl.Contains(r.Index))
|
||||||
|
{
|
||||||
|
var ti = tpl[r.Index];
|
||||||
|
if (ti != -1)
|
||||||
|
return ti;
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultWalkableTerrainIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Save(string filepath)
|
public void Save(string filepath)
|
||||||
@@ -138,21 +257,16 @@ namespace OpenRA
|
|||||||
root.Add(new MiniYamlNode("General", null, gen));
|
root.Add(new MiniYamlNode("General", null, gen));
|
||||||
|
|
||||||
root.Add(new MiniYamlNode("Terrain", null,
|
root.Add(new MiniYamlNode("Terrain", null,
|
||||||
Terrain.Select(t => new MiniYamlNode("TerrainType@{0}".F(t.Value.Type), t.Value.Save())).ToList()));
|
terrainInfo.Select(t => new MiniYamlNode("TerrainType@{0}".F(t.Type), t.Save())).ToList()));
|
||||||
|
|
||||||
root.Add(new MiniYamlNode("Templates", null,
|
root.Add(new MiniYamlNode("Templates", null,
|
||||||
Templates.Select(t => new MiniYamlNode("Template@{0}".F(t.Value.Id), t.Value.Save())).ToList()));
|
Templates.Select(t => new MiniYamlNode("Template@{0}".F(t.Value.Id), t.Value.Save(this))).ToList()));
|
||||||
root.WriteToFile(filepath);
|
root.WriteToFile(filepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetTerrainType(TileReference<ushort, byte> r)
|
public TerrainTypeInfo GetTerrainInfo(TileReference<ushort, byte> r)
|
||||||
{
|
{
|
||||||
var tt = Templates[r.Type].Tiles;
|
return terrainInfo[GetTerrainIndex(r)];
|
||||||
string ret;
|
|
||||||
if (!tt.TryGetValue(r.Index, out ret))
|
|
||||||
return "Clear"; // Default walkable
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
CellContents CreateResourceCell(ResourceType t, CPos p)
|
CellContents CreateResourceCell(ResourceType t, CPos p)
|
||||||
{
|
{
|
||||||
world.Map.CustomTerrain[p.X, p.Y] = t.Info.TerrainType;
|
world.Map.CustomTerrain[p.X, p.Y] = world.TileSet.GetTerrainIndex(t.Info.TerrainType);
|
||||||
return new CellContents
|
return new CellContents
|
||||||
{
|
{
|
||||||
Type = t,
|
Type = t,
|
||||||
@@ -194,7 +194,7 @@ namespace OpenRA.Traits
|
|||||||
if (--content[p.X, p.Y].Density < 0)
|
if (--content[p.X, p.Y].Density < 0)
|
||||||
{
|
{
|
||||||
content[p.X, p.Y] = EmptyCell;
|
content[p.X, p.Y] = EmptyCell;
|
||||||
world.Map.CustomTerrain[p.X, p.Y] = null;
|
world.Map.CustomTerrain[p.X, p.Y] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dirty.Contains(p))
|
if (!dirty.Contains(p))
|
||||||
@@ -211,7 +211,7 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
// Clear cell
|
// Clear cell
|
||||||
content[p.X, p.Y] = EmptyCell;
|
content[p.X, p.Y] = EmptyCell;
|
||||||
world.Map.CustomTerrain[p.X, p.Y] = null;
|
world.Map.CustomTerrain[p.X, p.Y] = -1;
|
||||||
|
|
||||||
if (!dirty.Contains(p))
|
if (!dirty.Contains(p))
|
||||||
dirty.Add(p);
|
dirty.Add(p);
|
||||||
|
|||||||
@@ -88,15 +88,15 @@ namespace OpenRA
|
|||||||
public const int MaxRange = 50;
|
public const int MaxRange = 50;
|
||||||
static List<CVec>[] TilesByDistance = InitTilesByDistance(MaxRange);
|
static List<CVec>[] TilesByDistance = InitTilesByDistance(MaxRange);
|
||||||
|
|
||||||
public static string GetTerrainType(this World world, CPos cell)
|
public static int GetTerrainIndex(this World world, CPos cell)
|
||||||
{
|
{
|
||||||
var custom = world.Map.CustomTerrain[cell.X, cell.Y];
|
var custom = world.Map.CustomTerrain[cell.X, cell.Y];
|
||||||
return custom ?? world.TileSet.GetTerrainType(world.Map.MapTiles.Value[cell.X, cell.Y]);
|
return custom != -1 ? custom : world.TileSet.GetTerrainIndex(world.Map.MapTiles.Value[cell.X, cell.Y]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TerrainTypeInfo GetTerrainInfo(this World world, CPos cell)
|
public static TerrainTypeInfo GetTerrainInfo(this World world, CPos cell)
|
||||||
{
|
{
|
||||||
return world.TileSet.Terrain[world.GetTerrainType(cell)];
|
return world.TileSet[world.GetTerrainIndex(cell)];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CPos ClampToWorld(this World world, CPos xy)
|
public static CPos ClampToWorld(this World world, CPos xy)
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ namespace OpenRA.Mods.Cnc
|
|||||||
foreach (var kv in self.OccupiesSpace.OccupiedCells())
|
foreach (var kv in self.OccupiesSpace.OccupiedCells())
|
||||||
{
|
{
|
||||||
totalTiles++;
|
totalTiles++;
|
||||||
if (info.SafeTerrain.Contains(self.World.GetTerrainType(kv.First)))
|
if (info.SafeTerrain.Contains(self.World.GetTerrainInfo(kv.First).Type))
|
||||||
safeTiles++;
|
safeTiles++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ namespace OpenRA.Mods.RA.AI
|
|||||||
BuildingInfo rallypointTestBuilding;
|
BuildingInfo rallypointTestBuilding;
|
||||||
internal readonly HackyAIInfo Info;
|
internal readonly HackyAIInfo Info;
|
||||||
|
|
||||||
string[] resourceTypes;
|
HashSet<int> resourceTypeIndices;
|
||||||
|
|
||||||
RushFuzzy rushFuzzy = new RushFuzzy();
|
RushFuzzy rushFuzzy = new RushFuzzy();
|
||||||
|
|
||||||
@@ -152,8 +152,10 @@ namespace OpenRA.Mods.RA.AI
|
|||||||
|
|
||||||
random = new MersenneTwister((int)p.PlayerActor.ActorID);
|
random = new MersenneTwister((int)p.PlayerActor.ActorID);
|
||||||
|
|
||||||
resourceTypes = Map.Rules.Actors["world"].Traits.WithInterface<ResourceTypeInfo>()
|
resourceTypeIndices = new HashSet<int>(
|
||||||
.Select(t => t.TerrainType).ToArray();
|
Map.Rules.Actors["world"].Traits
|
||||||
|
.WithInterface<ResourceTypeInfo>()
|
||||||
|
.Select(t => world.TileSet.GetTerrainIndex(t.TerrainType)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GetPowerProvidedBy(ActorInfo building)
|
static int GetPowerProvidedBy(ActorInfo building)
|
||||||
@@ -364,7 +366,7 @@ namespace OpenRA.Mods.RA.AI
|
|||||||
|
|
||||||
case BuildingType.Refinery:
|
case BuildingType.Refinery:
|
||||||
var tilesPos = world.FindTilesInCircle(baseCenter, MaxBaseDistance)
|
var tilesPos = world.FindTilesInCircle(baseCenter, MaxBaseDistance)
|
||||||
.Where(a => resourceTypes.Contains(world.GetTerrainType(new CPos(a.X, a.Y))));
|
.Where(a => resourceTypeIndices.Contains(world.GetTerrainIndex(new CPos(a.X, a.Y))));
|
||||||
if (tilesPos.Any())
|
if (tilesPos.Any())
|
||||||
{
|
{
|
||||||
var pos = tilesPos.MinBy(a => (a.CenterPosition - baseCenter.CenterPosition).LengthSquared);
|
var pos = tilesPos.MinBy(a => (a.CenterPosition - baseCenter.CenterPosition).LengthSquared);
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ namespace OpenRA.Mods.RA.Air
|
|||||||
if (self.World.ActorMap.AnyUnitsAt(cell))
|
if (self.World.ActorMap.AnyUnitsAt(cell))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var type = self.World.GetTerrainType(cell);
|
var type = self.World.GetTerrainInfo(cell).Type;
|
||||||
return info.LandableTerrainTypes.Contains(type);
|
return info.LandableTerrainTypes.Contains(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -94,11 +94,11 @@ namespace OpenRA.Mods.RA
|
|||||||
self.World.Map.CustomTerrain[c.X, c.Y] = GetTerrainType(c);
|
self.World.Map.CustomTerrain[c.X, c.Y] = GetTerrainType(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
string GetTerrainType(CPos cell)
|
int GetTerrainType(CPos cell)
|
||||||
{
|
{
|
||||||
var dx = cell - self.Location;
|
var dx = cell - self.Location;
|
||||||
var index = dx.X + self.World.TileSet.Templates[template].Size.X * dx.Y;
|
var index = dx.X + self.World.TileSet.Templates[template].Size.X * dx.Y;
|
||||||
return self.World.TileSet.GetTerrainType(new TileReference<ushort, byte>(template, (byte)index));
|
return self.World.TileSet.GetTerrainIndex(new TileReference<ushort, byte>(template, (byte)index));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LinkNeighbouringBridges(World world, BridgeLayer bridges)
|
public void LinkNeighbouringBridges(World world, BridgeLayer bridges)
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ namespace OpenRA.Mods.RA.Buildings
|
|||||||
var cellOffset = new CVec(i % width, i / width + bibOffset);
|
var cellOffset = new CVec(i % width, i / width + bibOffset);
|
||||||
|
|
||||||
// Some mods may define terrain-specific bibs
|
// Some mods may define terrain-specific bibs
|
||||||
var terrain = self.World.GetTerrainType(location + cellOffset);
|
var terrain = self.World.GetTerrainInfo(location + cellOffset).Type;
|
||||||
var testSequence = info.Sequence + "-" + terrain;
|
var testSequence = info.Sequence + "-" + terrain;
|
||||||
var sequence = anim.HasSequence(testSequence) ? testSequence : info.Sequence;
|
var sequence = anim.HasSequence(testSequence) ? testSequence : info.Sequence;
|
||||||
anim.PlayFetchIndex(sequence, () => index);
|
anim.PlayFetchIndex(sequence, () => index);
|
||||||
|
|||||||
@@ -54,34 +54,34 @@ namespace OpenRA.Mods.RA.Buildings
|
|||||||
foreach (var c in FootprintUtils.Tiles(self))
|
foreach (var c in FootprintUtils.Tiles(self))
|
||||||
{
|
{
|
||||||
// Only place on allowed terrain types
|
// Only place on allowed terrain types
|
||||||
if (!info.TerrainTypes.Contains(self.World.GetTerrainType(c)))
|
if (!info.TerrainTypes.Contains(self.World.GetTerrainInfo(c).Type))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Don't place under other buildings or custom terrain
|
// Don't place under other buildings or custom terrain
|
||||||
if (bi.GetBuildingAt(c) != self || self.World.Map.CustomTerrain[c.X, c.Y] != null)
|
if (bi.GetBuildingAt(c) != self || self.World.Map.CustomTerrain[c.X, c.Y] != -1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var index = template.Tiles.Keys.Random(Game.CosmeticRandom);
|
var index = Game.CosmeticRandom.Next(template.TilesCount);
|
||||||
layer.AddTile(c, new TileReference<ushort, byte>(template.Id, index));
|
layer.AddTile(c, new TileReference<ushort, byte>(template.Id, (byte)index));
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var origin = self.Location + info.Offset;
|
var origin = self.Location + info.Offset;
|
||||||
foreach (var i in template.Tiles.Keys)
|
for (var i = 0; i < template.TilesCount; i++)
|
||||||
{
|
{
|
||||||
var c = origin + new CVec(i % template.Size.X, i / template.Size.X);
|
var c = origin + new CVec(i % template.Size.X, i / template.Size.X);
|
||||||
|
|
||||||
// Only place on allowed terrain types
|
// Only place on allowed terrain types
|
||||||
if (!info.TerrainTypes.Contains(self.World.GetTerrainType(c)))
|
if (!info.TerrainTypes.Contains(self.World.GetTerrainInfo(c).Type))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Don't place under other buildings or custom terrain
|
// Don't place under other buildings or custom terrain
|
||||||
if (bi.GetBuildingAt(c) != self || self.World.Map.CustomTerrain[c.X, c.Y] != null)
|
if (bi.GetBuildingAt(c) != self || self.World.Map.CustomTerrain[c.X, c.Y] != -1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
layer.AddTile(c, new TileReference<ushort, byte>(template.Id, i));
|
layer.AddTile(c, new TileReference<ushort, byte>(template.Id, (byte)i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ namespace OpenRA.Mods.RA.Buildings
|
|||||||
if (world.WorldActor.Trait<BuildingInfluence>().GetBuildingAt(a) != null) return false;
|
if (world.WorldActor.Trait<BuildingInfluence>().GetBuildingAt(a) != null) return false;
|
||||||
if (world.ActorMap.GetUnitsAt(a).Any(b => b != toIgnore)) return false;
|
if (world.ActorMap.GetUnitsAt(a).Any(b => b != toIgnore)) return false;
|
||||||
|
|
||||||
return world.Map.IsInMap(a) && bi.TerrainTypes.Contains(world.GetTerrainType(a));
|
return world.Map.IsInMap(a) && bi.TerrainTypes.Contains(world.GetTerrainInfo(a).Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool CanPlaceBuilding(this World world, string name, BuildingInfo building, CPos topLeft, Actor toIgnore)
|
public static bool CanPlaceBuilding(this World world, string name, BuildingInfo building, CPos topLeft, Actor toIgnore)
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ namespace OpenRA.Mods.RA
|
|||||||
{
|
{
|
||||||
if (!self.World.Map.IsInMap(cell.X, cell.Y)) return false;
|
if (!self.World.Map.IsInMap(cell.X, cell.Y)) return false;
|
||||||
|
|
||||||
var type = self.World.GetTerrainType(cell);
|
var type = self.World.GetTerrainInfo(cell).Type;
|
||||||
if (!info.TerrainTypes.Contains(type))
|
if (!info.TerrainTypes.Contains(type))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ namespace OpenRA.Mods.RA
|
|||||||
var p = self.World.ChooseRandomCell(self.World.SharedRandom);
|
var p = self.World.ChooseRandomCell(self.World.SharedRandom);
|
||||||
|
|
||||||
// Is this valid terrain?
|
// Is this valid terrain?
|
||||||
var terrainType = self.World.GetTerrainType(p);
|
var terrainType = self.World.GetTerrainInfo(p).Type;
|
||||||
if (!(inWater ? info.ValidWater : info.ValidGround).Contains(terrainType))
|
if (!(inWater ? info.ValidWater : info.ValidGround).Contains(terrainType))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ namespace OpenRA.Mods.RA.Effects
|
|||||||
|| (info.RangeLimit != 0 && ticks > info.RangeLimit) // Ran out of fuel
|
|| (info.RangeLimit != 0 && ticks > info.RangeLimit) // Ran out of fuel
|
||||||
|| (!info.High && world.ActorMap.GetUnitsAt(cell)
|
|| (!info.High && world.ActorMap.GetUnitsAt(cell)
|
||||||
.Any(a => a.HasTrait<IBlocksBullets>())) // Hit a wall
|
.Any(a => a.HasTrait<IBlocksBullets>())) // Hit a wall
|
||||||
|| (!string.IsNullOrEmpty(info.BoundToTerrainType) && world.GetTerrainType(cell) != info.BoundToTerrainType); // Hit incompatible terrain
|
|| (!string.IsNullOrEmpty(info.BoundToTerrainType) && world.GetTerrainInfo(cell).Type != info.BoundToTerrainType); // Hit incompatible terrain
|
||||||
|
|
||||||
if (shouldExplode)
|
if (shouldExplode)
|
||||||
Explode(world);
|
Explode(world);
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ namespace OpenRA.Mods.RA
|
|||||||
if (!self.World.Map.IsInMap(cell.X, cell.Y))
|
if (!self.World.Map.IsInMap(cell.X, cell.Y))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!info.AllowedTerrain.Contains(self.World.GetTerrainType(cell)))
|
if (!info.AllowedTerrain.Contains(self.World.GetTerrainInfo(cell).Type))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!checkTransientActors)
|
if (!checkTransientActors)
|
||||||
|
|||||||
@@ -48,16 +48,55 @@ namespace OpenRA.Mods.RA.Move
|
|||||||
var cost = nodesDict.ContainsKey("PathingCost")
|
var cost = nodesDict.ContainsKey("PathingCost")
|
||||||
? FieldLoader.GetValue<int>("cost", nodesDict["PathingCost"].Value)
|
? FieldLoader.GetValue<int>("cost", nodesDict["PathingCost"].Value)
|
||||||
: (int)(10000 / speed);
|
: (int)(10000 / speed);
|
||||||
ret.Add(t.Key, new TerrainInfo { Speed = speed, Cost = cost });
|
ret.Add(t.Key, new TerrainInfo(speed, cost));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TerrainInfo[] LoadTilesetSpeeds(TileSet tileSet)
|
||||||
|
{
|
||||||
|
var info = new TerrainInfo[tileSet.TerrainsCount];
|
||||||
|
for (var i = 0; i < info.Length; i++)
|
||||||
|
info[i] = TerrainInfo.Impassable;
|
||||||
|
|
||||||
|
foreach (var kvp in TerrainSpeeds)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
if (tileSet.TryGetTerrainIndex(kvp.Key, out index))
|
||||||
|
info[index] = kvp.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
public class TerrainInfo
|
public class TerrainInfo
|
||||||
{
|
{
|
||||||
public int Cost = int.MaxValue;
|
public static readonly TerrainInfo Impassable = new TerrainInfo();
|
||||||
public decimal Speed = 0;
|
|
||||||
|
public readonly int Cost;
|
||||||
|
public readonly decimal Speed;
|
||||||
|
|
||||||
|
public TerrainInfo()
|
||||||
|
{
|
||||||
|
Cost = int.MaxValue;
|
||||||
|
Speed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TerrainInfo(decimal speed, int cost)
|
||||||
|
{
|
||||||
|
Speed = speed;
|
||||||
|
Cost = cost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly Cache<TileSet, TerrainInfo[]> TilesetTerrainInfo;
|
||||||
|
public readonly Cache<TileSet, int> TilesetMovementClass;
|
||||||
|
|
||||||
|
public MobileInfo()
|
||||||
|
{
|
||||||
|
TilesetTerrainInfo = new Cache<TileSet, TerrainInfo[]>(LoadTilesetSpeeds);
|
||||||
|
TilesetMovementClass = new Cache<TileSet, int>(CalculateTilesetMovementClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int MovementCostForCell(World world, CPos cell)
|
public int MovementCostForCell(World world, CPos cell)
|
||||||
@@ -65,20 +104,22 @@ namespace OpenRA.Mods.RA.Move
|
|||||||
if (!world.Map.IsInMap(cell.X, cell.Y))
|
if (!world.Map.IsInMap(cell.X, cell.Y))
|
||||||
return int.MaxValue;
|
return int.MaxValue;
|
||||||
|
|
||||||
var type = world.GetTerrainType(cell);
|
var index = world.GetTerrainIndex(cell);
|
||||||
if (!TerrainSpeeds.ContainsKey(type))
|
if (index == -1)
|
||||||
return int.MaxValue;
|
return int.MaxValue;
|
||||||
|
|
||||||
return TerrainSpeeds[type].Cost;
|
return TilesetTerrainInfo[world.TileSet][index].Cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int CalculateTilesetMovementClass(TileSet tileset)
|
||||||
|
{
|
||||||
|
/* collect our ability to cross *all* terraintypes, in a bitvector */
|
||||||
|
return TilesetTerrainInfo[tileset].Select(ti => ti.Cost < int.MaxValue).ToBits();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetMovementClass(TileSet tileset)
|
public int GetMovementClass(TileSet tileset)
|
||||||
{
|
{
|
||||||
/* collect our ability to cross *all* terraintypes, in a bitvector */
|
return TilesetMovementClass[tileset];
|
||||||
var passability = tileset.Terrain.OrderBy(t => t.Key)
|
|
||||||
.Select(t => TerrainSpeeds.ContainsKey(t.Key) && TerrainSpeeds[t.Key].Cost < int.MaxValue);
|
|
||||||
|
|
||||||
return passability.ToBits();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly Dictionary<SubCell, WVec> SubCellOffsets = new Dictionary<SubCell, WVec>()
|
public static readonly Dictionary<SubCell, WVec> SubCellOffsets = new Dictionary<SubCell, WVec>()
|
||||||
@@ -440,12 +481,15 @@ namespace OpenRA.Mods.RA.Move
|
|||||||
|
|
||||||
public int MovementSpeedForCell(Actor self, CPos cell)
|
public int MovementSpeedForCell(Actor self, CPos cell)
|
||||||
{
|
{
|
||||||
var type = self.World.GetTerrainType(cell);
|
var index = self.World.GetTerrainIndex(cell);
|
||||||
|
if (index == -1)
|
||||||
if (!Info.TerrainSpeeds.ContainsKey(type))
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
decimal speed = Info.Speed * Info.TerrainSpeeds[type].Speed;
|
var speed = Info.TilesetTerrainInfo[self.World.TileSet][index].Speed;
|
||||||
|
if (speed == decimal.Zero)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
speed *= Info.Speed;
|
||||||
foreach (var t in self.TraitsImplementing<ISpeedModifier>())
|
foreach (var t in self.TraitsImplementing<ISpeedModifier>())
|
||||||
speed *= t.GetSpeedModifier();
|
speed *= t.GetSpeedModifier();
|
||||||
return (int)(speed / 100);
|
return (int)(speed / 100);
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace OpenRA.Mods.RA
|
|||||||
|
|
||||||
public RadarColorFromTerrain(Actor self, string terrain)
|
public RadarColorFromTerrain(Actor self, string terrain)
|
||||||
{
|
{
|
||||||
c = self.World.TileSet.Terrain[terrain].Color;
|
c = self.World.TileSet[self.World.TileSet.GetTerrainIndex(terrain)].Color;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool VisibleOnRadar(Actor self) { return true; }
|
public bool VisibleOnRadar(Actor self) { return true; }
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ namespace OpenRA.Mods.RA.Render
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
return cargo.CurrentAdjacentCells
|
return cargo.CurrentAdjacentCells
|
||||||
.Any(c => self.World.Map.IsInMap(c) && info.OpenTerrainTypes.Contains(self.World.GetTerrainType(c)));
|
.Any(c => self.World.Map.IsInMap(c) && info.OpenTerrainTypes.Contains(self.World.GetTerrainInfo(c).Type));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Open()
|
void Open()
|
||||||
|
|||||||
@@ -71,36 +71,18 @@ namespace OpenRA.Mods.RA
|
|||||||
var range = ((ChronoshiftPowerInfo)Info).Range;
|
var range = ((ChronoshiftPowerInfo)Info).Range;
|
||||||
var sourceTiles = self.World.FindTilesInCircle(xy, range);
|
var sourceTiles = self.World.FindTilesInCircle(xy, range);
|
||||||
var destTiles = self.World.FindTilesInCircle(sourceLocation, range);
|
var destTiles = self.World.FindTilesInCircle(sourceLocation, range);
|
||||||
var sourceTerrain = new List<string>();
|
|
||||||
var destTerrain = new List<string>();
|
|
||||||
|
|
||||||
int j = 0;
|
using (var se = sourceTiles.GetEnumerator())
|
||||||
foreach (var t in sourceTiles)
|
using (var de = destTiles.GetEnumerator())
|
||||||
|
while (se.MoveNext() && de.MoveNext())
|
||||||
{
|
{
|
||||||
j = j + 1;
|
var a = se.Current;
|
||||||
if (!self.Owner.Shroud.IsExplored(t))
|
var b = de.Current;
|
||||||
return false;
|
|
||||||
sourceTerrain.Add(self.World.GetTerrainType(t));
|
|
||||||
}
|
|
||||||
|
|
||||||
j = 0;
|
if (!self.Owner.Shroud.IsExplored(a) || !self.Owner.Shroud.IsExplored(b))
|
||||||
foreach (var t in destTiles)
|
|
||||||
{
|
|
||||||
j = j + 1;
|
|
||||||
if (!self.Owner.Shroud.IsExplored(t))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
self.World.GetTerrainType(t);
|
if (self.World.GetTerrainIndex(a) != self.World.GetTerrainIndex(b))
|
||||||
destTerrain.Add(self.World.GetTerrainType(t));
|
|
||||||
}
|
|
||||||
|
|
||||||
// HACK but I don't want to write a comparison function
|
|
||||||
if (sourceTerrain.Count != destTerrain.Count)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (int i = 0; i < sourceTerrain.Count; i++)
|
|
||||||
{
|
|
||||||
if (!sourceTerrain[i].Equals(destTerrain[i]))
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ namespace OpenRA.Mods.RA
|
|||||||
|
|
||||||
public void AddTile(CPos cell, TileReference<ushort, byte> tile)
|
public void AddTile(CPos cell, TileReference<ushort, byte> tile)
|
||||||
{
|
{
|
||||||
map.CustomTerrain[cell.X, cell.Y] = tileset.GetTerrainType(tile);
|
map.CustomTerrain[cell.X, cell.Y] = tileset.GetTerrainIndex(tile);
|
||||||
|
|
||||||
// Terrain tiles define their origin at the topleft
|
// Terrain tiles define their origin at the topleft
|
||||||
var s = theater.TileSprite(tile);
|
var s = theater.TileSprite(tile);
|
||||||
|
|||||||
@@ -59,10 +59,6 @@ namespace OpenRA.Mods.RA
|
|||||||
int[,] domains;
|
int[,] domains;
|
||||||
Dictionary<int, HashSet<int>> transientConnections;
|
Dictionary<int, HashSet<int>> transientConnections;
|
||||||
|
|
||||||
// Each terrain has an offset corresponding to its location in a
|
|
||||||
// movement class bitmask. This caches each offset.
|
|
||||||
Dictionary<string, int> terrainOffsets;
|
|
||||||
|
|
||||||
public MovementClassDomainIndex(World world, uint movementClass)
|
public MovementClassDomainIndex(World world, uint movementClass)
|
||||||
{
|
{
|
||||||
bounds = world.Map.Bounds;
|
bounds = world.Map.Bounds;
|
||||||
@@ -70,14 +66,6 @@ namespace OpenRA.Mods.RA
|
|||||||
domains = new int[(bounds.Width + bounds.X), (bounds.Height + bounds.Y)];
|
domains = new int[(bounds.Width + bounds.X), (bounds.Height + bounds.Y)];
|
||||||
transientConnections = new Dictionary<int, HashSet<int>>();
|
transientConnections = new Dictionary<int, HashSet<int>>();
|
||||||
|
|
||||||
terrainOffsets = new Dictionary<string, int>();
|
|
||||||
var terrains = world.TileSet.Terrain.OrderBy(t => t.Key).ToList();
|
|
||||||
foreach (var terrain in terrains)
|
|
||||||
{
|
|
||||||
var terrainOffset = terrains.FindIndex(x => x.Key == terrain.Key);
|
|
||||||
terrainOffsets[terrain.Key] = terrainOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
BuildDomains(world);
|
BuildDomains(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,8 +169,7 @@ namespace OpenRA.Mods.RA
|
|||||||
|
|
||||||
bool CanTraverseTile(World world, CPos p)
|
bool CanTraverseTile(World world, CPos p)
|
||||||
{
|
{
|
||||||
var currentTileType = WorldUtils.GetTerrainType(world, p);
|
var terrainOffset = world.GetTerrainIndex(p);
|
||||||
var terrainOffset = terrainOffsets[currentTileType];
|
|
||||||
return (movementClass & (1 << terrainOffset)) > 0;
|
return (movementClass & (1 << terrainOffset)) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -367,7 +367,8 @@ namespace OpenRA.TilesetBuilder
|
|||||||
name: tilesetName,
|
name: tilesetName,
|
||||||
id: tilesetID.ToUpper(),
|
id: tilesetID.ToUpper(),
|
||||||
palette: tilesetPalette.ToLower(),
|
palette: tilesetPalette.ToLower(),
|
||||||
extensions: new string[] { ext[0], ext[1] }
|
extensions: new string[] { ext[0], ext[1] },
|
||||||
|
terrainInfo: TerrainType
|
||||||
);
|
);
|
||||||
|
|
||||||
// List of files to add to the mix file
|
// List of files to add to the mix file
|
||||||
@@ -381,30 +382,25 @@ namespace OpenRA.TilesetBuilder
|
|||||||
foreach (var t in surface1.Templates)
|
foreach (var t in surface1.Templates)
|
||||||
fileList.Add(ExportTemplate(t, surface1.Templates.IndexOf(t), tileset.Extensions.First(), dir));
|
fileList.Add(ExportTemplate(t, surface1.Templates.IndexOf(t), tileset.Extensions.First(), dir));
|
||||||
|
|
||||||
// Add the terraintypes
|
|
||||||
foreach (var tt in TerrainType)
|
|
||||||
{
|
|
||||||
tileset.Terrain.Add(tt.Type, tt);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the templates
|
// Add the templates
|
||||||
ushort cur = 0;
|
ushort cur = 0;
|
||||||
foreach (var tp in surface1.Templates)
|
foreach (var tp in surface1.Templates)
|
||||||
{
|
{
|
||||||
|
var tiles = new int[tp.Width * tp.Height];
|
||||||
|
foreach (var t in tp.Cells)
|
||||||
|
{
|
||||||
|
string ttype = TerrainType[surface1.TerrainTypes[t.Key.X, t.Key.Y]].Type;
|
||||||
|
var idx = (t.Key.X - tp.Left) + tp.Width * (t.Key.Y - tp.Top);
|
||||||
|
tiles[idx] = tileset.GetTerrainIndex(ttype);
|
||||||
|
}
|
||||||
|
|
||||||
var template = new TileTemplate(
|
var template = new TileTemplate(
|
||||||
id: cur,
|
id: cur,
|
||||||
image: "{0}{1:00}".F(txtTilesetName.Text, cur),
|
image: "{0}{1:00}".F(txtTilesetName.Text, cur),
|
||||||
size: new int2(tp.Width, tp.Height)
|
size: new int2(tp.Width, tp.Height),
|
||||||
|
tiles: tiles
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach (var t in tp.Cells)
|
|
||||||
{
|
|
||||||
string ttype = "Clear";
|
|
||||||
ttype = TerrainType[surface1.TerrainTypes[t.Key.X, t.Key.Y]].Type;
|
|
||||||
var idx = (t.Key.X - tp.Left) + tp.Width * (t.Key.Y - tp.Top);
|
|
||||||
template.Tiles.Add((byte)idx, ttype);
|
|
||||||
}
|
|
||||||
|
|
||||||
tileset.Templates.Add(cur, template);
|
tileset.Templates.Add(cur, template);
|
||||||
cur++;
|
cur++;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user