Add ITerrainInfo interface.

This commit is contained in:
Paul Chote
2020-10-10 23:52:00 +01:00
committed by reaperrr
parent 0a374e2264
commit 87790069e9
30 changed files with 97 additions and 83 deletions

View File

@@ -283,7 +283,7 @@ namespace OpenRA
/// Initializes a new map created by the editor or importer.
/// The map will not receive a valid UID until after it has been saved and reloaded.
/// </summary>
public Map(ModData modData, TileSet tileset, int width, int height)
public Map(ModData modData, ITerrainInfo terrainInfo, int width, int height)
{
this.modData = modData;
var size = new Size(width, height);
@@ -293,7 +293,7 @@ namespace OpenRA
Author = "Your name here";
MapSize = new int2(size);
Tileset = tileset.Id;
Tileset = terrainInfo.Id;
// Empty rules that can be added to by the importers.
// Will be dropped on save if nothing is added to it
@@ -310,7 +310,7 @@ namespace OpenRA
Tiles.CellEntryChanged += UpdateRamp;
}
Tiles.Clear(tileset.DefaultTerrainTile);
Tiles.Clear(terrainInfo.DefaultTerrainTile);
PostInit();
}
@@ -431,14 +431,14 @@ namespace OpenRA
CustomTerrain[uv] = byte.MaxValue;
// Replace invalid tiles and cache ramp state
var tileset = Rules.TileSet;
var terrainInfo = Rules.TerrainInfo;
foreach (var uv in AllCells.MapCoords)
{
if (!tileset.TryGetTileInfo(Tiles[uv], out var info))
if (!terrainInfo.TryGetTerrainInfo(Tiles[uv], out var info))
{
ReplacedInvalidTerrainTiles[uv.ToCPos(this)] = Tiles[uv];
Tiles[uv] = tileset.DefaultTerrainTile;
info = tileset.GetTileInfo(tileset.DefaultTerrainTile);
Tiles[uv] = terrainInfo.DefaultTerrainTile;
info = terrainInfo.GetTerrainInfo(terrainInfo.DefaultTerrainTile);
}
Ramp[uv] = info.RampType;
@@ -449,7 +449,7 @@ namespace OpenRA
void UpdateRamp(CPos cell)
{
Ramp[cell] = Rules.TileSet.GetTileInfo(Tiles[cell]).RampType;
Ramp[cell] = Rules.TerrainInfo.GetTerrainInfo(Tiles[cell]).RampType;
}
void InitializeCellProjection()
@@ -536,8 +536,7 @@ namespace OpenRA
// The original games treat the top of cliffs the same way as the bottom
// This information isn't stored in the map data, so query the offset from the tileset
var temp = inverse.MaxBy(uv => uv.V);
var terrain = Tiles[temp];
return (byte)(Height[temp] - Rules.TileSet.Templates[terrain.Type][terrain.Index].Height);
return (byte)(Height[temp] - Rules.TerrainInfo.GetTerrainInfo(Tiles[temp]).Height);
}
// Try the next cell down if this is a cliff face
@@ -673,8 +672,8 @@ namespace OpenRA
public (Color Left, Color Right) GetTerrainColorPair(MPos uv)
{
Color left, right;
var tileset = Rules.TileSet;
var type = tileset.GetTileInfo(Tiles[uv]);
var terrainInfo = Rules.TerrainInfo;
var type = terrainInfo.GetTerrainInfo(Tiles[uv]);
if (type.MinColor != type.MaxColor)
{
left = Exts.ColorLerp(Game.CosmeticRandom.NextFloat(), type.MinColor, type.MaxColor);
@@ -683,9 +682,9 @@ namespace OpenRA
else
left = right = type.MinColor;
if (tileset.MinHeightColorBrightness != 1.0f || tileset.MaxHeightColorBrightness != 1.0f)
if (terrainInfo.MinHeightColorBrightness != 1.0f || terrainInfo.MaxHeightColorBrightness != 1.0f)
{
var scale = float2.Lerp(tileset.MinHeightColorBrightness, tileset.MaxHeightColorBrightness, Height[uv] * 1f / Grid.MaximumTerrainHeight);
var scale = float2.Lerp(terrainInfo.MinHeightColorBrightness, terrainInfo.MaxHeightColorBrightness, Height[uv] * 1f / Grid.MaximumTerrainHeight);
left = Color.FromArgb((int)(scale * left.R).Clamp(0, 255), (int)(scale * left.G).Clamp(0, 255), (int)(scale * left.B).Clamp(0, 255));
right = Color.FromArgb((int)(scale * right.R).Clamp(0, 255), (int)(scale * right.G).Clamp(0, 255), (int)(scale * right.B).Clamp(0, 255));
}
@@ -1071,8 +1070,7 @@ namespace OpenRA
if (terrainIndex == InvalidCachedTerrainIndex)
{
var custom = CustomTerrain[uv];
terrainIndex = cachedTerrainIndexes[uv] =
custom != byte.MaxValue ? custom : Rules.TileSet.GetTerrainIndex(Tiles[uv]);
terrainIndex = cachedTerrainIndexes[uv] = custom != byte.MaxValue ? custom : Rules.TerrainInfo.GetTerrainInfo(Tiles[uv]).TerrainType;
}
return (byte)terrainIndex;
@@ -1080,7 +1078,7 @@ namespace OpenRA
public TerrainTypeInfo GetTerrainInfo(CPos cell)
{
return Rules.TileSet[GetTerrainIndex(cell)];
return Rules.TerrainInfo.TerrainTypes[GetTerrainIndex(cell)];
}
public CPos Clamp(CPos cell)

View File

@@ -18,6 +18,22 @@ using OpenRA.Traits;
namespace OpenRA
{
public interface ITerrainInfo
{
string Id { get; }
TerrainTypeInfo[] TerrainTypes { get; }
TerrainTileInfo GetTerrainInfo(TerrainTile r);
bool TryGetTerrainInfo(TerrainTile r, out TerrainTileInfo info);
byte GetTerrainIndex(string type);
byte GetTerrainIndex(TerrainTile r);
TerrainTile DefaultTerrainTile { get; }
Color[] HeightDebugColors { get; }
IEnumerable<Color> RestrictedPlayerColors { get; }
float MinHeightColorBrightness { get; }
float MaxHeightColorBrightness { get; }
}
public class TerrainTileInfo
{
[FieldLoader.Ignore]
@@ -54,7 +70,7 @@ namespace OpenRA
readonly TerrainTileInfo[] tileInfo;
public TerrainTemplateInfo(TileSet tileSet, MiniYaml my)
public TerrainTemplateInfo(ITerrainInfo terrainInfo, MiniYaml my)
{
FieldLoader.Load(this, my);
@@ -66,12 +82,12 @@ namespace OpenRA
foreach (var node in nodes)
{
if (!int.TryParse(node.Key, out var key))
throw new YamlException("Tileset `{0}` template `{1}` defines a frame `{2}` that is not a valid integer.".F(tileSet.Id, Id, node.Key));
throw new YamlException("Tileset `{0}` template `{1}` defines a frame `{2}` that is not a valid integer.".F(terrainInfo.Id, Id, node.Key));
if (key < 0 || key >= tileInfo.Length)
throw new YamlException("Tileset `{0}` template `{1}` references frame {2}, but only [0..{3}] are valid for a {4}x{5} Size template.".F(tileSet.Id, Id, key, tileInfo.Length - 1, Size.X, Size.Y));
throw new YamlException("Tileset `{0}` template `{1}` references frame {2}, but only [0..{3}] are valid for a {4}x{5} Size template.".F(terrainInfo.Id, Id, key, tileInfo.Length - 1, Size.X, Size.Y));
tileInfo[key] = LoadTileInfo(tileSet, node.Value);
tileInfo[key] = LoadTileInfo(terrainInfo, node.Value);
}
}
else
@@ -82,30 +98,30 @@ namespace OpenRA
foreach (var node in nodes)
{
if (!int.TryParse(node.Key, out var key))
throw new YamlException("Tileset `{0}` template `{1}` defines a frame `{2}` that is not a valid integer.".F(tileSet.Id, Id, node.Key));
throw new YamlException("Tileset `{0}` template `{1}` defines a frame `{2}` that is not a valid integer.".F(terrainInfo.Id, Id, node.Key));
if (key != i++)
throw new YamlException("Tileset `{0}` template `{1}` is missing a definition for frame {2}.".F(tileSet.Id, Id, i - 1));
throw new YamlException("Tileset `{0}` template `{1}` is missing a definition for frame {2}.".F(terrainInfo.Id, Id, i - 1));
tileInfo[key] = LoadTileInfo(tileSet, node.Value);
tileInfo[key] = LoadTileInfo(terrainInfo, node.Value);
}
}
}
static TerrainTileInfo LoadTileInfo(TileSet tileSet, MiniYaml my)
static TerrainTileInfo LoadTileInfo(ITerrainInfo terrainInfo, MiniYaml my)
{
var tile = new TerrainTileInfo();
FieldLoader.Load(tile, my);
// Terrain type must be converted from a string to an index
tile.GetType().GetField("TerrainType").SetValue(tile, tileSet.GetTerrainIndex(my.Value));
tile.GetType().GetField("TerrainType").SetValue(tile, terrainInfo.GetTerrainIndex(my.Value));
// Fall back to the terrain-type color if necessary
var overrideColor = tileSet.TerrainInfo[tile.TerrainType].Color;
if (tile.MinColor == default(Color))
var overrideColor = terrainInfo.TerrainTypes[tile.TerrainType].Color;
if (tile.MinColor == default)
tile.GetType().GetField("MinColor").SetValue(tile, overrideColor);
if (tile.MaxColor == default(Color))
if (tile.MaxColor == default)
tile.GetType().GetField("MaxColor").SetValue(tile, overrideColor);
return tile;
@@ -124,7 +140,7 @@ namespace OpenRA
}
}
public class TileSet
public class TileSet : ITerrainInfo
{
public const string TerrainPaletteInternalName = "terrain";
@@ -245,6 +261,14 @@ namespace OpenRA
return info != null;
}
public TerrainTile DefaultTerrainTile { get { return new TerrainTile(Templates.First().Key, 0); } }
string ITerrainInfo.Id { get { return Id; } }
TerrainTypeInfo[] ITerrainInfo.TerrainTypes { get { return TerrainInfo; } }
TerrainTileInfo ITerrainInfo.GetTerrainInfo(TerrainTile r) { return GetTileInfo(r); }
bool ITerrainInfo.TryGetTerrainInfo(TerrainTile r, out TerrainTileInfo info) { return TryGetTileInfo(r, out info); }
Color[] ITerrainInfo.HeightDebugColors { get { return HeightDebugColors; } }
IEnumerable<Color> ITerrainInfo.RestrictedPlayerColors { get { return TerrainInfo.Where(ti => ti.RestrictPlayerColor).Select(ti => ti.Color); } }
float ITerrainInfo.MinHeightColorBrightness { get { return MinHeightColorBrightness; } }
float ITerrainInfo.MaxHeightColorBrightness { get { return MaxHeightColorBrightness; } }
TerrainTile ITerrainInfo.DefaultTerrainTile { get { return new TerrainTile(Templates.First().Key, 0); } }
}
}