Add MapGrid class

MapGrid is a mod Manifest field which includes (and thus makes redundant) TileSize, TileShape, SubCells info and MaximumTerrainHeight.
This commit is contained in:
Pavel Penev
2015-09-14 01:55:00 +03:00
parent 699a7f8227
commit 642468ce0c
28 changed files with 164 additions and 157 deletions

View File

@@ -44,7 +44,7 @@ namespace OpenRA
public MPos ToMPos(Map map) public MPos ToMPos(Map map)
{ {
return ToMPos(map.TileShape); return ToMPos(map.Grid.Type);
} }
public MPos ToMPos(TileShape shape) public MPos ToMPos(TileShape shape)

View File

@@ -20,12 +20,12 @@ namespace OpenRA.Graphics
{ {
public static Bitmap TerrainBitmap(TileSet tileset, Map map, bool actualSize = false) public static Bitmap TerrainBitmap(TileSet tileset, Map map, bool actualSize = false)
{ {
var isDiamond = map.TileShape == TileShape.Diamond; var isDiamond = map.Grid.Type == TileShape.Diamond;
var b = map.Bounds; var b = map.Bounds;
// Fudge the heightmap offset by adding as much extra as we need / can. // Fudge the heightmap offset by adding as much extra as we need / can.
// This tries to correct for our incorrect assumption that MPos == PPos // This tries to correct for our incorrect assumption that MPos == PPos
var heightOffset = Math.Min(map.MaximumTerrainHeight, map.MapSize.Y - b.Bottom); var heightOffset = Math.Min(map.Grid.MaximumTerrainHeight, map.MapSize.Y - b.Bottom);
var width = b.Width; var width = b.Width;
var height = b.Height + heightOffset; var height = b.Height + heightOffset;
@@ -81,12 +81,12 @@ namespace OpenRA.Graphics
static Bitmap AddStaticResources(TileSet tileset, Map map, Ruleset resourceRules, Bitmap terrainBitmap) static Bitmap AddStaticResources(TileSet tileset, Map map, Ruleset resourceRules, Bitmap terrainBitmap)
{ {
var terrain = new Bitmap(terrainBitmap); var terrain = new Bitmap(terrainBitmap);
var isDiamond = map.TileShape == TileShape.Diamond; var isDiamond = map.Grid.Type == TileShape.Diamond;
var b = map.Bounds; var b = map.Bounds;
// Fudge the heightmap offset by adding as much extra as we need / can // Fudge the heightmap offset by adding as much extra as we need / can
// This tries to correct for our incorrect assumption that MPos == PPos // This tries to correct for our incorrect assumption that MPos == PPos
var heightOffset = Math.Min(map.MaximumTerrainHeight, map.MapSize.Y - b.Bottom); var heightOffset = Math.Min(map.Grid.MaximumTerrainHeight, map.MapSize.Y - b.Bottom);
var width = b.Width; var width = b.Width;
var height = b.Height + heightOffset; var height = b.Height + heightOffset;

View File

@@ -71,7 +71,7 @@ namespace OpenRA.Graphics
{ {
var pos = sprite == null ? float2.Zero : var pos = sprite == null ? float2.Zero :
worldRenderer.ScreenPosition(map.CenterOfCell(cell)) + sprite.Offset - 0.5f * sprite.Size; worldRenderer.ScreenPosition(map.CenterOfCell(cell)) + sprite.Offset - 0.5f * sprite.Size;
Update(cell.ToMPos(map.TileShape), sprite, pos); Update(cell.ToMPos(map.Grid.Type), sprite, pos);
} }
public void Update(MPos uv, Sprite sprite, float2 pos) public void Update(MPos uv, Sprite sprite, float2 pos)

View File

@@ -92,15 +92,15 @@ namespace OpenRA.Graphics
public Viewport(WorldRenderer wr, Map map) public Viewport(WorldRenderer wr, Map map)
{ {
worldRenderer = wr; worldRenderer = wr;
var grid = Game.ModData.Manifest.Get<MapGrid>();
// Calculate map bounds in world-px // Calculate map bounds in world-px
if (wr.World.Type == WorldType.Editor) if (wr.World.Type == WorldType.Editor)
{ {
// The full map is visible in the editor // The full map is visible in the editor
var ts = Game.ModData.Manifest.TileSize; var width = map.MapSize.X * grid.TileSize.Width;
var width = map.MapSize.X * ts.Width; var height = map.MapSize.Y * grid.TileSize.Height;
var height = map.MapSize.Y * ts.Height; if (wr.World.Map.Grid.Type == TileShape.Diamond)
if (wr.World.Map.TileShape == TileShape.Diamond)
height /= 2; height /= 2;
mapBounds = new Rectangle(0, 0, width, height); mapBounds = new Rectangle(0, 0, width, height);
@@ -115,23 +115,22 @@ namespace OpenRA.Graphics
} }
Zoom = Game.Settings.Graphics.PixelDouble ? 2 : 1; Zoom = Game.Settings.Graphics.PixelDouble ? 2 : 1;
tileSize = Game.ModData.Manifest.TileSize; tileSize = grid.TileSize;
} }
public CPos ViewToWorld(int2 view) public CPos ViewToWorld(int2 view)
{ {
var world = worldRenderer.Viewport.ViewToWorldPx(view); var world = worldRenderer.Viewport.ViewToWorldPx(view);
var map = worldRenderer.World.Map; var map = worldRenderer.World.Map;
var ts = Game.ModData.Manifest.TileSize; var candidates = CandidateMouseoverCells(world).ToList();
var candidates = CandidateMouseoverCells(world);
var tileSet = worldRenderer.World.TileSet; var tileSet = worldRenderer.World.TileSet;
foreach (var uv in candidates) foreach (var uv in candidates)
{ {
// Coarse filter to nearby cells // Coarse filter to nearby cells
var p = map.CenterOfCell(uv.ToCPos(map.TileShape)); var p = map.CenterOfCell(uv.ToCPos(map.Grid.Type));
var s = worldRenderer.ScreenPxPosition(p); var s = worldRenderer.ScreenPxPosition(p);
if (Math.Abs(s.X - world.X) <= ts.Width && Math.Abs(s.Y - world.Y) <= ts.Height) if (Math.Abs(s.X - world.X) <= tileSize.Width && Math.Abs(s.Y - world.Y) <= tileSize.Height)
{ {
var ramp = 0; var ramp = 0;
if (map.Contains(uv)) if (map.Contains(uv))
@@ -153,11 +152,11 @@ namespace OpenRA.Graphics
// Mouse is not directly over a cell (perhaps on a cliff) // Mouse is not directly over a cell (perhaps on a cliff)
// Try and find the closest cell // Try and find the closest cell
if (candidates.Any()) if (candidates.Count > 0)
{ {
return candidates.OrderBy(uv => return candidates.OrderBy(uv =>
{ {
var p = map.CenterOfCell(uv.ToCPos(map.TileShape)); var p = map.CenterOfCell(uv.ToCPos(map.Grid.Type));
var s = worldRenderer.ScreenPxPosition(p); var s = worldRenderer.ScreenPxPosition(p);
var dx = Math.Abs(s.X - world.X); var dx = Math.Abs(s.X - world.X);
var dy = Math.Abs(s.Y - world.Y); var dy = Math.Abs(s.Y - world.Y);
@@ -177,8 +176,8 @@ namespace OpenRA.Graphics
var minPos = worldRenderer.ProjectedPosition(world); var minPos = worldRenderer.ProjectedPosition(world);
// Find all the cells that could potentially have been clicked // Find all the cells that could potentially have been clicked
var a = map.CellContaining(minPos - new WVec(1024, 0, 0)).ToMPos(map.TileShape); var a = map.CellContaining(minPos - new WVec(1024, 0, 0)).ToMPos(map.Grid.Type);
var b = map.CellContaining(minPos + new WVec(512, 512 * map.MaximumTerrainHeight, 0)).ToMPos(map.TileShape); var b = map.CellContaining(minPos + new WVec(512, 512 * map.Grid.MaximumTerrainHeight, 0)).ToMPos(map.Grid.Type);
for (var v = b.V; v >= a.V; v--) for (var v = b.V; v >= a.V; v--)
for (var u = b.U; u >= a.U; u--) for (var u = b.U; u >= a.U; u--)
@@ -244,7 +243,7 @@ namespace OpenRA.Graphics
// Diamond tile shapes don't have straight edges, and so we need // Diamond tile shapes don't have straight edges, and so we need
// an additional cell margin to include the cells that are half // an additional cell margin to include the cells that are half
// visible on each edge. // visible on each edge.
if (map.TileShape == TileShape.Diamond) if (map.Grid.Type == TileShape.Diamond)
{ {
tl = new PPos(tl.U - 1, tl.V - 1); tl = new PPos(tl.U - 1, tl.V - 1);
br = new PPos(br.U + 1, br.V + 1); br = new PPos(br.U + 1, br.V + 1);

View File

@@ -25,6 +25,7 @@ namespace OpenRA.Graphics
static readonly int[][] RangeCircleStartRotations = Exts.MakeArray(RangeCircleSegments, i => WRot.FromFacing(8 * i).AsMatrix()); static readonly int[][] RangeCircleStartRotations = Exts.MakeArray(RangeCircleSegments, i => WRot.FromFacing(8 * i).AsMatrix());
static readonly int[][] RangeCircleEndRotations = Exts.MakeArray(RangeCircleSegments, i => WRot.FromFacing(8 * i + 6).AsMatrix()); static readonly int[][] RangeCircleEndRotations = Exts.MakeArray(RangeCircleSegments, i => WRot.FromFacing(8 * i + 6).AsMatrix());
public readonly Size TileSize;
public readonly World World; public readonly World World;
public readonly Theater Theater; public readonly Theater Theater;
public Viewport Viewport { get; private set; } public Viewport Viewport { get; private set; }
@@ -40,6 +41,7 @@ namespace OpenRA.Graphics
internal WorldRenderer(World world) internal WorldRenderer(World world)
{ {
World = world; World = world;
TileSize = World.Map.Grid.TileSize;
Viewport = new Viewport(this, world.Map); Viewport = new Viewport(this, world.Map);
createPaletteReference = CreatePaletteReference; createPaletteReference = CreatePaletteReference;
@@ -231,8 +233,7 @@ namespace OpenRA.Graphics
// Conversion between world and screen coordinates // Conversion between world and screen coordinates
public float2 ScreenPosition(WPos pos) public float2 ScreenPosition(WPos pos)
{ {
var ts = Game.ModData.Manifest.TileSize; return new float2(TileSize.Width * pos.X / 1024f, TileSize.Height * (pos.Y - pos.Z) / 1024f);
return new float2(ts.Width * pos.X / 1024f, ts.Height * (pos.Y - pos.Z) / 1024f);
} }
public int2 ScreenPxPosition(WPos pos) public int2 ScreenPxPosition(WPos pos)
@@ -245,10 +246,9 @@ namespace OpenRA.Graphics
// For scaling vectors to pixel sizes in the voxel renderer // For scaling vectors to pixel sizes in the voxel renderer
public void ScreenVectorComponents(WVec vec, out float x, out float y, out float z) public void ScreenVectorComponents(WVec vec, out float x, out float y, out float z)
{ {
var ts = Game.ModData.Manifest.TileSize; x = TileSize.Width * vec.X / 1024f;
x = ts.Width * vec.X / 1024f; y = TileSize.Height * vec.Y / 1024f;
y = ts.Height * vec.Y / 1024f; z = TileSize.Height * vec.Z / 1024f;
z = ts.Height * vec.Z / 1024f;
} }
// For scaling vectors to pixel sizes in the voxel renderer // For scaling vectors to pixel sizes in the voxel renderer
@@ -269,8 +269,7 @@ namespace OpenRA.Graphics
public float ScreenZPosition(WPos pos, int offset) public float ScreenZPosition(WPos pos, int offset)
{ {
var ts = Game.ModData.Manifest.TileSize; return ZPosition(pos, offset) * TileSize.Height / 1024f;
return ZPosition(pos, offset) * ts.Height / 1024f;
} }
static int ZPosition(WPos pos, int offset) static int ZPosition(WPos pos, int offset)
@@ -284,8 +283,7 @@ namespace OpenRA.Graphics
/// </summary> /// </summary>
public WPos ProjectedPosition(int2 screenPx) public WPos ProjectedPosition(int2 screenPx)
{ {
var ts = Game.ModData.Manifest.TileSize; return new WPos(1024 * screenPx.X / TileSize.Width, 1024 * screenPx.Y / TileSize.Height, 0);
return new WPos(1024 * screenPx.X / ts.Width, 1024 * screenPx.Y / ts.Height, 0);
} }
public void Dispose() public void Dispose()

View File

@@ -38,7 +38,7 @@ namespace OpenRA
public CPos ToCPos(Map map) public CPos ToCPos(Map map)
{ {
return ToCPos(map.TileShape); return ToCPos(map.Grid.Type);
} }
public CPos ToCPos(TileShape shape) public CPos ToCPos(TileShape shape)

View File

@@ -10,14 +10,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using OpenRA.Primitives; using OpenRA.Primitives;
namespace OpenRA namespace OpenRA
{ {
public enum TileShape { Rectangle, Diamond }
public interface IGlobalModData { } public interface IGlobalModData { }
public sealed class SpriteSequenceFormat : IGlobalModData public sealed class SpriteSequenceFormat : IGlobalModData
@@ -47,31 +45,13 @@ namespace OpenRA
public readonly MiniYaml LobbyDefaults; public readonly MiniYaml LobbyDefaults;
public readonly Dictionary<string, Pair<string, int>> Fonts; public readonly Dictionary<string, Pair<string, int>> Fonts;
public readonly Size TileSize = new Size(24, 24);
public readonly TileShape TileShape = TileShape.Rectangle;
public readonly byte MaximumTerrainHeight = 0;
public readonly string[] SpriteFormats = { }; public readonly string[] SpriteFormats = { };
[Desc("(x,y,z) offset of the full cell and each sub-cell", "X & Y should be between -512 ... 512 and Z >= 0")]
public readonly WVec[] SubCellOffsets =
{
new WVec(0, 0, 0), // full cell - index 0
new WVec(-299, -256, 0), // top left - index 1
new WVec(256, -256, 0), // top right - index 2
new WVec(0, 0, 0), // center - index 3
new WVec(-299, 256, 0), // bottom left - index 4
new WVec(256, 256, 0), // bottom right - index 5
};
[Desc("Default subcell index used if SubCellInit is absent", "0 - full cell, 1 - first sub-cell")]
public readonly int SubCellDefaultIndex = 3;
readonly string[] reservedModuleNames = { "Metadata", "Folders", "MapFolders", "Packages", "Rules", readonly string[] reservedModuleNames = { "Metadata", "Folders", "MapFolders", "Packages", "Rules",
"Sequences", "VoxelSequences", "Cursors", "Chrome", "Assemblies", "ChromeLayout", "Weapons", "Sequences", "VoxelSequences", "Cursors", "Chrome", "Assemblies", "ChromeLayout", "Weapons",
"Voices", "Notifications", "Music", "Translations", "TileSets", "ChromeMetrics", "Missions", "Voices", "Notifications", "Music", "Translations", "TileSets", "ChromeMetrics", "Missions",
"ServerTraits", "LoadScreen", "LobbyDefaults", "Fonts", "TileSize", "MaximumTerrainHeight", "ServerTraits", "LoadScreen", "LobbyDefaults", "Fonts", "SupportsMapsFrom", "SpriteFormats" };
"TileShape", "SubCells", "SupportsMapsFrom", "SpriteFormats" };
readonly TypeDictionary modules = new TypeDictionary(); readonly TypeDictionary modules = new TypeDictionary();
readonly Dictionary<string, MiniYaml> yaml; readonly Dictionary<string, MiniYaml> yaml;
@@ -118,33 +98,6 @@ namespace OpenRA
return Pair.New(nd["Font"].Value, Exts.ParseIntegerInvariant(nd["Size"].Value)); return Pair.New(nd["Font"].Value, Exts.ParseIntegerInvariant(nd["Size"].Value));
}); });
if (yaml.ContainsKey("TileSize"))
TileSize = FieldLoader.GetValue<Size>("TileSize", yaml["TileSize"].Value);
if (yaml.ContainsKey("TileShape"))
TileShape = FieldLoader.GetValue<TileShape>("TileShape", yaml["TileShape"].Value);
if (yaml.ContainsKey("MaximumTerrainHeight"))
MaximumTerrainHeight = FieldLoader.GetValue<byte>("MaximumTerrainHeight", yaml["MaximumTerrainHeight"].Value);
if (yaml.ContainsKey("SubCells"))
{
var subcells = yaml["SubCells"].ToDictionary();
// Read (x,y,z) offset (relative to cell center) pairs for positioning subcells
if (subcells.ContainsKey("Offsets"))
SubCellOffsets = FieldLoader.GetValue<WVec[]>("Offsets", subcells["Offsets"].Value);
if (subcells.ContainsKey("DefaultIndex"))
SubCellDefaultIndex = FieldLoader.GetValue<int>("DefaultIndex", subcells["DefaultIndex"].Value);
else // Otherwise set the default subcell index to the middle subcell entry
SubCellDefaultIndex = SubCellOffsets.Length / 2;
}
// Validate default index - 0 for no subcells, otherwise > 1 & <= subcell count (offset triples count - 1)
if (SubCellDefaultIndex < (SubCellOffsets.Length > 1 ? 1 : 0) || SubCellDefaultIndex >= SubCellOffsets.Length)
throw new InvalidDataException("Subcell default index must be a valid index into the offset triples and must be greater than 0 for mods with subcells");
// Allow inherited mods to import parent maps. // Allow inherited mods to import parent maps.
var compat = new List<string>(); var compat = new List<string>();
compat.Add(mod); compat.Add(mod);

View File

@@ -26,7 +26,7 @@ namespace OpenRA
readonly T[] entries; readonly T[] entries;
public CellLayer(Map map) public CellLayer(Map map)
: this(map.TileShape, new Size(map.MapSize.X, map.MapSize.Y)) { } : this(map.Grid.Type, new Size(map.MapSize.X, map.MapSize.Y)) { }
public CellLayer(TileShape shape, Size size) public CellLayer(TileShape shape, Size size)
{ {

View File

@@ -151,8 +151,7 @@ namespace OpenRA
}; };
public const int MaxTilesInCircleRange = 50; public const int MaxTilesInCircleRange = 50;
public readonly TileShape TileShape; public readonly MapGrid Grid;
public readonly byte MaximumTerrainHeight;
[FieldLoader.Ignore] public readonly WVec[] SubCellOffsets; [FieldLoader.Ignore] public readonly WVec[] SubCellOffsets;
public readonly SubCell DefaultSubCell; public readonly SubCell DefaultSubCell;
@@ -275,7 +274,7 @@ namespace OpenRA
public Map(TileSet tileset, int width, int height) public Map(TileSet tileset, int width, int height)
{ {
var size = new Size(width, height); var size = new Size(width, height);
var tileShape = Game.ModData.Manifest.TileShape; Grid = Game.ModData.Manifest.Get<MapGrid>();
var tileRef = new TerrainTile(tileset.Templates.First().Key, (byte)0); var tileRef = new TerrainTile(tileset.Templates.First().Key, (byte)0);
Title = "Name your map here"; Title = "Name your map here";
@@ -287,29 +286,27 @@ namespace OpenRA
Videos = new MapVideos(); Videos = new MapVideos();
Options = new MapOptions(); Options = new MapOptions();
MapResources = Exts.Lazy(() => new CellLayer<ResourceTile>(tileShape, size)); MapResources = Exts.Lazy(() => new CellLayer<ResourceTile>(Grid.Type, size));
MapTiles = Exts.Lazy(() => MapTiles = Exts.Lazy(() =>
{ {
var ret = new CellLayer<TerrainTile>(tileShape, size); var ret = new CellLayer<TerrainTile>(Grid.Type, size);
ret.Clear(tileRef); ret.Clear(tileRef);
if (MaximumTerrainHeight > 0) if (Grid.MaximumTerrainHeight > 0)
ret.CellEntryChanged += UpdateProjection; ret.CellEntryChanged += UpdateProjection;
return ret; return ret;
}); });
MapHeight = Exts.Lazy(() => MapHeight = Exts.Lazy(() =>
{ {
var ret = new CellLayer<byte>(tileShape, size); var ret = new CellLayer<byte>(Grid.Type, size);
ret.Clear(0); ret.Clear(0);
if (MaximumTerrainHeight > 0) if (Grid.MaximumTerrainHeight > 0)
ret.CellEntryChanged += UpdateProjection; ret.CellEntryChanged += UpdateProjection;
return ret; return ret;
}); });
SpawnPoints = Exts.Lazy(() => new CPos[0]); SpawnPoints = Exts.Lazy(() => new CPos[0]);
TileShape = tileShape;
MaximumTerrainHeight = Game.ModData.Manifest.MaximumTerrainHeight;
PostInit(); PostInit();
} }
@@ -374,12 +371,11 @@ namespace OpenRA
MapResources = Exts.Lazy(LoadResourceTiles); MapResources = Exts.Lazy(LoadResourceTiles);
MapHeight = Exts.Lazy(LoadMapHeight); MapHeight = Exts.Lazy(LoadMapHeight);
TileShape = Game.ModData.Manifest.TileShape; Grid = Game.ModData.Manifest.Get<MapGrid>();
MaximumTerrainHeight = Game.ModData.Manifest.MaximumTerrainHeight;
SubCellOffsets = Game.ModData.Manifest.SubCellOffsets; SubCellOffsets = Grid.SubCellOffsets;
LastSubCell = (SubCell)(SubCellOffsets.Length - 1); LastSubCell = (SubCell)(SubCellOffsets.Length - 1);
DefaultSubCell = (SubCell)Game.ModData.Manifest.SubCellDefaultIndex; DefaultSubCell = (SubCell)Grid.SubCellDefaultIndex;
if (Container.Exists("map.png")) if (Container.Exists("map.png"))
using (var dataStream = Container.GetContent("map.png")) using (var dataStream = Container.GetContent("map.png"))
@@ -417,7 +413,7 @@ namespace OpenRA
var tl = new MPos(0, 0).ToCPos(this); var tl = new MPos(0, 0).ToCPos(this);
var br = new MPos(MapSize.X - 1, MapSize.Y - 1).ToCPos(this); var br = new MPos(MapSize.X - 1, MapSize.Y - 1).ToCPos(this);
AllCells = new CellRegion(TileShape, tl, br); AllCells = new CellRegion(Grid.Type, tl, br);
var btl = new PPos(Bounds.Left, Bounds.Top); var btl = new PPos(Bounds.Left, Bounds.Top);
var bbr = new PPos(Bounds.Right - 1, Bounds.Bottom - 1); var bbr = new PPos(Bounds.Right - 1, Bounds.Bottom - 1);
@@ -427,10 +423,10 @@ namespace OpenRA
foreach (var uv in AllCells.MapCoords) foreach (var uv in AllCells.MapCoords)
CustomTerrain[uv] = byte.MaxValue; CustomTerrain[uv] = byte.MaxValue;
var leftDelta = TileShape == TileShape.Diamond ? new WVec(-512, 0, 0) : new WVec(-512, -512, 0); var leftDelta = Grid.Type == TileShape.Diamond ? new WVec(-512, 0, 0) : new WVec(-512, -512, 0);
var topDelta = TileShape == TileShape.Diamond ? new WVec(0, -512, 0) : new WVec(512, -512, 0); var topDelta = Grid.Type == TileShape.Diamond ? new WVec(0, -512, 0) : new WVec(512, -512, 0);
var rightDelta = TileShape == TileShape.Diamond ? new WVec(512, 0, 0) : new WVec(512, 512, 0); var rightDelta = Grid.Type == TileShape.Diamond ? new WVec(512, 0, 0) : new WVec(512, 512, 0);
var bottomDelta = TileShape == TileShape.Diamond ? new WVec(0, 512, 0) : new WVec(-512, 512, 0); var bottomDelta = Grid.Type == TileShape.Diamond ? new WVec(0, 512, 0) : new WVec(-512, 512, 0);
CellCorners = CellCornerHalfHeights.Select(ramp => new WVec[] CellCorners = CellCornerHalfHeights.Select(ramp => new WVec[]
{ {
leftDelta + new WVec(0, 0, 512 * ramp[0]), leftDelta + new WVec(0, 0, 512 * ramp[0]),
@@ -453,7 +449,7 @@ namespace OpenRA
// Initialize collections // Initialize collections
foreach (var cell in AllCells) foreach (var cell in AllCells)
{ {
var uv = cell.ToMPos(TileShape); var uv = cell.ToMPos(Grid.Type);
cellProjection[uv] = new PPos[0]; cellProjection[uv] = new PPos[0];
inverseCellProjection[uv] = new List<MPos>(); inverseCellProjection[uv] = new List<MPos>();
} }
@@ -467,9 +463,9 @@ namespace OpenRA
{ {
MPos uv; MPos uv;
if (MaximumTerrainHeight == 0) if (Grid.MaximumTerrainHeight == 0)
{ {
uv = cell.ToMPos(TileShape); uv = cell.ToMPos(Grid.Type);
cellProjection[cell] = new[] { (PPos)uv }; cellProjection[cell] = new[] { (PPos)uv };
var inverse = inverseCellProjection[uv]; var inverse = inverseCellProjection[uv];
inverse.Clear(); inverse.Clear();
@@ -480,7 +476,7 @@ namespace OpenRA
if (!initializedCellProjection) if (!initializedCellProjection)
InitializeCellProjection(); InitializeCellProjection();
uv = cell.ToMPos(TileShape); uv = cell.ToMPos(Grid.Type);
// Remove old reverse projection // Remove old reverse projection
foreach (var puv in cellProjection[uv]) foreach (var puv in cellProjection[uv])
@@ -635,7 +631,7 @@ namespace OpenRA
} }
} }
if (MaximumTerrainHeight > 0) if (Grid.MaximumTerrainHeight > 0)
tiles.CellEntryChanged += UpdateProjection; tiles.CellEntryChanged += UpdateProjection;
return tiles; return tiles;
@@ -652,11 +648,11 @@ namespace OpenRA
s.Position = header.HeightsOffset; s.Position = header.HeightsOffset;
for (var i = 0; i < MapSize.X; i++) for (var i = 0; i < MapSize.X; i++)
for (var j = 0; j < MapSize.Y; j++) for (var j = 0; j < MapSize.Y; j++)
tiles[new MPos(i, j)] = s.ReadUInt8().Clamp((byte)0, MaximumTerrainHeight); tiles[new MPos(i, j)] = s.ReadUInt8().Clamp((byte)0, Grid.MaximumTerrainHeight);
} }
} }
if (MaximumTerrainHeight > 0) if (Grid.MaximumTerrainHeight > 0)
tiles.CellEntryChanged += UpdateProjection; tiles.CellEntryChanged += UpdateProjection;
return tiles; return tiles;
@@ -701,8 +697,8 @@ namespace OpenRA
// Data offsets // Data offsets
var tilesOffset = 17; var tilesOffset = 17;
var heightsOffset = MaximumTerrainHeight > 0 ? 3 * MapSize.X * MapSize.Y + 17 : 0; var heightsOffset = Grid.MaximumTerrainHeight > 0 ? 3 * MapSize.X * MapSize.Y + 17 : 0;
var resourcesOffset = (MaximumTerrainHeight > 0 ? 4 : 3) * MapSize.X * MapSize.Y + 17; var resourcesOffset = (Grid.MaximumTerrainHeight > 0 ? 4 : 3) * MapSize.X * MapSize.Y + 17;
writer.Write((uint)tilesOffset); writer.Write((uint)tilesOffset);
writer.Write((uint)heightsOffset); writer.Write((uint)heightsOffset);
@@ -751,7 +747,7 @@ namespace OpenRA
// .ToMPos() returns the same result if the X and Y coordinates // .ToMPos() returns the same result if the X and Y coordinates
// are switched. X < Y is invalid in the Diamond coordinate system, // are switched. X < Y is invalid in the Diamond coordinate system,
// so we pre-filter these to avoid returning the wrong result // so we pre-filter these to avoid returning the wrong result
if (TileShape == TileShape.Diamond && cell.X < cell.Y) if (Grid.Type == TileShape.Diamond && cell.X < cell.Y)
return false; return false;
return Contains(cell.ToMPos(this)); return Contains(cell.ToMPos(this));
@@ -767,7 +763,7 @@ namespace OpenRA
bool ContainsAllProjectedCellsCovering(MPos uv) bool ContainsAllProjectedCellsCovering(MPos uv)
{ {
if (MaximumTerrainHeight == 0) if (Grid.MaximumTerrainHeight == 0)
return Contains((PPos)uv); return Contains((PPos)uv);
foreach (var puv in ProjectedCellsCovering(uv)) foreach (var puv in ProjectedCellsCovering(uv))
@@ -783,7 +779,7 @@ namespace OpenRA
public WPos CenterOfCell(CPos cell) public WPos CenterOfCell(CPos cell)
{ {
if (TileShape == TileShape.Rectangle) if (Grid.Type == TileShape.Rectangle)
return new WPos(1024 * cell.X + 512, 1024 * cell.Y + 512, 0); return new WPos(1024 * cell.X + 512, 1024 * cell.Y + 512, 0);
// Convert from diamond cell position (x, y) to world position (u, v): // Convert from diamond cell position (x, y) to world position (u, v):
@@ -815,7 +811,7 @@ namespace OpenRA
public CPos CellContaining(WPos pos) public CPos CellContaining(WPos pos)
{ {
if (TileShape == TileShape.Rectangle) if (Grid.Type == TileShape.Rectangle)
return new CPos(pos.X / 1024, pos.Y / 1024); return new CPos(pos.X / 1024, pos.Y / 1024);
// Convert from world position to diamond cell position: // Convert from world position to diamond cell position:
@@ -834,7 +830,7 @@ namespace OpenRA
public PPos ProjectedCellCovering(WPos pos) public PPos ProjectedCellCovering(WPos pos)
{ {
var projectedPos = pos - new WVec(0, pos.Z, pos.Z); var projectedPos = pos - new WVec(0, pos.Z, pos.Z);
return (PPos)CellContaining(projectedPos).ToMPos(TileShape); return (PPos)CellContaining(projectedPos).ToMPos(Grid.Type);
} }
static readonly PPos[] NoProjectedCells = { }; static readonly PPos[] NoProjectedCells = { };
@@ -881,7 +877,7 @@ namespace OpenRA
var tl = new MPos(0, 0).ToCPos(this); var tl = new MPos(0, 0).ToCPos(this);
var br = new MPos(MapSize.X - 1, MapSize.Y - 1).ToCPos(this); var br = new MPos(MapSize.X - 1, MapSize.Y - 1).ToCPos(this);
AllCells = new CellRegion(TileShape, tl, br); AllCells = new CellRegion(Grid.Type, tl, br);
} }
public void SetBounds(PPos tl, PPos br) public void SetBounds(PPos tl, PPos br)
@@ -896,7 +892,7 @@ namespace OpenRA
// for diamond cells. // for diamond cells.
var wtop = tl.V * 1024; var wtop = tl.V * 1024;
var wbottom = (br.V + 1) * 1024; var wbottom = (br.V + 1) * 1024;
if (TileShape == TileShape.Diamond) if (Grid.Type == TileShape.Diamond)
{ {
wtop /= 2; wtop /= 2;
wbottom /= 2; wbottom /= 2;
@@ -995,7 +991,7 @@ namespace OpenRA
public MPos Clamp(MPos uv) public MPos Clamp(MPos uv)
{ {
if (MaximumTerrainHeight == 0) if (Grid.MaximumTerrainHeight == 0)
return (MPos)Clamp((PPos)uv); return (MPos)Clamp((PPos)uv);
// Already in bounds, so don't need to do anything. // Already in bounds, so don't need to do anything.
@@ -1030,7 +1026,7 @@ namespace OpenRA
if (!unProjected.Any()) if (!unProjected.Any())
{ {
// Adjust V until we find a cell that works // Adjust V until we find a cell that works
for (var x = 2; x <= 2 * MaximumTerrainHeight; x++) for (var x = 2; x <= 2 * Grid.MaximumTerrainHeight; x++)
{ {
var dv = ((x & 1) == 1 ? 1 : -1) * x / 2; var dv = ((x & 1) == 1 ? 1 : -1) * x / 2;
var test = new PPos(projected.U, projected.V + dv); var test = new PPos(projected.U, projected.V + dv);
@@ -1070,12 +1066,12 @@ namespace OpenRA
cells = Unproject(new PPos(u, v)); cells = Unproject(new PPos(u, v));
} while (!cells.Any()); } while (!cells.Any());
return cells.Random(rand).ToCPos(TileShape); return cells.Random(rand).ToCPos(Grid.Type);
} }
public CPos ChooseClosestEdgeCell(CPos cell) public CPos ChooseClosestEdgeCell(CPos cell)
{ {
return ChooseClosestEdgeCell(cell.ToMPos(TileShape)).ToCPos(TileShape); return ChooseClosestEdgeCell(cell.ToMPos(Grid.Type)).ToCPos(Grid.Type);
} }
public MPos ChooseClosestEdgeCell(MPos uv) public MPos ChooseClosestEdgeCell(MPos uv)
@@ -1101,7 +1097,7 @@ namespace OpenRA
if (!unProjected.Any()) if (!unProjected.Any())
{ {
// Adjust V until we find a cell that works // Adjust V until we find a cell that works
for (var x = 2; x <= 2 * MaximumTerrainHeight; x++) for (var x = 2; x <= 2 * Grid.MaximumTerrainHeight; x++)
{ {
var dv = ((x & 1) == 1 ? 1 : -1) * x / 2; var dv = ((x & 1) == 1 ? 1 : -1) * x / 2;
var test = new PPos(edge.U, edge.V + dv); var test = new PPos(edge.U, edge.V + dv);
@@ -1137,7 +1133,7 @@ namespace OpenRA
cells = Unproject(new PPos(u, v)); cells = Unproject(new PPos(u, v));
} while (!cells.Any()); } while (!cells.Any());
return cells.Random(rand).ToCPos(TileShape); return cells.Random(rand).ToCPos(Grid.Type);
} }
public WDist DistanceToEdge(WPos pos, WVec dir) public WDist DistanceToEdge(WPos pos, WVec dir)

View File

@@ -0,0 +1,45 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System.Drawing;
using System.IO;
namespace OpenRA
{
public enum TileShape { Rectangle, Diamond }
public class MapGrid : IGlobalModData
{
public readonly TileShape Type = TileShape.Rectangle;
public readonly Size TileSize = new Size(24, 24);
public readonly byte MaximumTerrainHeight = 0;
public readonly byte SubCellDefaultIndex = byte.MaxValue;
public readonly WVec[] SubCellOffsets =
{
new WVec(0, 0, 0), // full cell - index 0
new WVec(-299, -256, 0), // top left - index 1
new WVec(256, -256, 0), // top right - index 2
new WVec(0, 0, 0), // center - index 3
new WVec(-299, 256, 0), // bottom left - index 4
new WVec(256, 256, 0), // bottom right - index 5
};
public MapGrid(MiniYaml yaml)
{
FieldLoader.Load(this, yaml);
// The default subcell index defaults to the middle entry
if (SubCellDefaultIndex == byte.MaxValue)
SubCellDefaultIndex = (byte)(SubCellOffsets.Length / 2);
else if (SubCellDefaultIndex < (SubCellOffsets.Length > 1 ? 1 : 0) || SubCellDefaultIndex >= SubCellOffsets.Length)
throw new InvalidDataException("Subcell default index must be a valid index into the offset triples and must be greater than 0 for mods with subcells");
}
}
}

View File

@@ -42,7 +42,8 @@ namespace OpenRA
// been projected into this region if they have height > 0. // been projected into this region if they have height > 0.
// Each height step is equivalent to 512 WRange units, which is one MPos // Each height step is equivalent to 512 WRange units, which is one MPos
// step for diamond cells, but only half a MPos step for classic cells. Doh! // step for diamond cells, but only half a MPos step for classic cells. Doh!
var heightOffset = map.TileShape == TileShape.Diamond ? map.MaximumTerrainHeight : map.MaximumTerrainHeight / 2; var maxHeight = map.Grid.MaximumTerrainHeight;
var heightOffset = map.Grid.Type == TileShape.Diamond ? maxHeight : maxHeight / 2;
// Use the MapHeight data array to clamp the bottom coordinate so it doesn't overflow the map // Use the MapHeight data array to clamp the bottom coordinate so it doesn't overflow the map
mapBottomRight = map.MapHeight.Value.Clamp(new MPos(bottomRight.U, bottomRight.V + heightOffset)); mapBottomRight = map.MapHeight.Value.Clamp(new MPos(bottomRight.U, bottomRight.V + heightOffset));

View File

@@ -94,6 +94,7 @@
<Compile Include="LogProxy.cs" /> <Compile Include="LogProxy.cs" />
<Compile Include="FileFormats\IdxReader.cs" /> <Compile Include="FileFormats\IdxReader.cs" />
<Compile Include="FileSystem\BagFile.cs" /> <Compile Include="FileSystem\BagFile.cs" />
<Compile Include="Map\MapGrid.cs" />
<Compile Include="Map\MapPlayers.cs" /> <Compile Include="Map\MapPlayers.cs" />
<Compile Include="ContentInstaller.cs" /> <Compile Include="ContentInstaller.cs" />
<Compile Include="MPos.cs" /> <Compile Include="MPos.cs" />

View File

@@ -36,9 +36,9 @@ namespace OpenRA.Traits
public ScreenMap(World world, ScreenMapInfo info) public ScreenMap(World world, ScreenMapInfo info)
{ {
var ts = Game.ModData.Manifest.TileSize; var size = world.Map.Grid.TileSize;
var width = world.Map.MapSize.X * ts.Width; var width = world.Map.MapSize.X * size.Width;
var height = world.Map.MapSize.Y * ts.Height; var height = world.Map.MapSize.Y * size.Height;
partitionedFrozenActors = new Cache<Player, SpatiallyPartitioned<FrozenActor>>( partitionedFrozenActors = new Cache<Player, SpatiallyPartitioned<FrozenActor>>(
_ => new SpatiallyPartitioned<FrozenActor>(width, height, info.BinSize)); _ => new SpatiallyPartitioned<FrozenActor>(width, height, info.BinSize));
partitionedActors = new SpatiallyPartitioned<Actor>(width, height, info.BinSize); partitionedActors = new SpatiallyPartitioned<Actor>(width, height, info.BinSize);

View File

@@ -48,7 +48,8 @@ namespace OpenRA.Mods.Common.Widgets
preview.IsVisible = () => editorWidget.CurrentBrush == this; preview.IsVisible = () => editorWidget.CurrentBrush == this;
preview.Template = world.TileSet.Templates.First(t => t.Value.Id == template).Value; preview.Template = world.TileSet.Templates.First(t => t.Value.Id == template).Value;
bounds = worldRenderer.Theater.TemplateBounds(preview.Template, Game.ModData.Manifest.TileSize, world.Map.TileShape); var grid = world.Map.Grid;
bounds = worldRenderer.Theater.TemplateBounds(preview.Template, grid.TileSize, grid.Type);
// The preview widget may be rendered by the higher-level code before it is ticked. // The preview widget may be rendered by the higher-level code before it is ticked.
// Force a manual tick to ensure the bounds are set correctly for this first draw. // Force a manual tick to ensure the bounds are set correctly for this first draw.
@@ -106,7 +107,7 @@ namespace OpenRA.Mods.Common.Widgets
continue; continue;
mapTiles[c] = new TerrainTile(Template, index); mapTiles[c] = new TerrainTile(Template, index);
mapHeight[c] = (byte)(baseHeight + template[index].Height).Clamp(0, map.MaximumTerrainHeight); mapHeight[c] = (byte)(baseHeight + template[index].Height).Clamp(0, map.Grid.MaximumTerrainHeight);
} }
} }
} }

View File

@@ -106,8 +106,7 @@ namespace OpenRA.Mods.Common.Graphics
{ {
var groundPos = voxel.pos - new WVec(0, 0, wr.World.Map.DistanceAboveTerrain(voxel.pos).Length); var groundPos = voxel.pos - new WVec(0, 0, wr.World.Map.DistanceAboveTerrain(voxel.pos).Length);
var ts = Game.ModData.Manifest.TileSize; var groundZ = wr.World.Map.Grid.TileSize.Height * (groundPos.Z - voxel.pos.Z) / 1024f;
var groundZ = ts.Height * (groundPos.Z - voxel.pos.Z) / 1024f;
var pxOrigin = wr.ScreenPosition(voxel.pos); var pxOrigin = wr.ScreenPosition(voxel.pos);
var shadowOrigin = pxOrigin - groundZ * (new float2(renderProxy.ShadowDirection, 1)); var shadowOrigin = pxOrigin - groundZ * (new float2(renderProxy.ShadowDirection, 1));

View File

@@ -26,7 +26,7 @@ namespace OpenRA.Mods.Common.Pathfinder
CellLayer<CellInfo>.CreateInstance( CellLayer<CellInfo>.CreateInstance(
mpos => new CellInfo(int.MaxValue, int.MaxValue, mpos.ToCPos(map), CellStatus.Unvisited), mpos => new CellInfo(int.MaxValue, int.MaxValue, mpos.ToCPos(map), CellStatus.Unvisited),
new Size(map.MapSize.X, map.MapSize.Y), new Size(map.MapSize.X, map.MapSize.Y),
map.TileShape); map.Grid.Type);
} }
public PooledCellInfoLayer Get() public PooledCellInfoLayer Get()

View File

@@ -66,7 +66,7 @@ namespace OpenRA.Mods.Common.Traits
foreach (var pr in Players.Players.Values) foreach (var pr in Players.Players.Values)
wr.UpdatePalettesForPlayer(pr.Name, pr.Color, false); wr.UpdatePalettesForPlayer(pr.Name, pr.Color, false);
var ts = Game.ModData.Manifest.TileSize; var ts = world.Map.Grid.TileSize;
var width = world.Map.MapSize.X * ts.Width; var width = world.Map.MapSize.X * ts.Width;
var height = world.Map.MapSize.Y * ts.Height; var height = world.Map.MapSize.Y * ts.Height;
screenMap = new SpatiallyPartitioned<EditorActorPreview>(width, height, info.BinSize); screenMap = new SpatiallyPartitioned<EditorActorPreview>(width, height, info.BinSize);

View File

@@ -52,7 +52,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
internal static void ConvertPxToRange(ref string input, int scaleMult, int scaleDiv) internal static void ConvertPxToRange(ref string input, int scaleMult, int scaleDiv)
{ {
var value = Exts.ParseIntegerInvariant(input); var value = Exts.ParseIntegerInvariant(input);
var ts = Game.ModData.Manifest.TileSize; var ts = Game.ModData.Manifest.Get<MapGrid>().TileSize;
var world = value * 1024 * scaleMult / (scaleDiv * ts.Height); var world = value * 1024 * scaleMult / (scaleDiv * ts.Height);
var cells = world / 1024; var cells = world / 1024;
var subcells = world - 1024 * cells; var subcells = world - 1024 * cells;
@@ -69,7 +69,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
internal static void ConvertInt2ToWVec(ref string input) internal static void ConvertInt2ToWVec(ref string input)
{ {
var offset = FieldLoader.GetValue<int2>("(value)", input); var offset = FieldLoader.GetValue<int2>("(value)", input);
var ts = Game.ModData.Manifest.TileSize; var ts = Game.ModData.Manifest.Get<MapGrid>().TileSize;
var world = new WVec(offset.X * 1024 / ts.Width, offset.Y * 1024 / ts.Height, 0); var world = new WVec(offset.X * 1024 / ts.Width, offset.Y * 1024 / ts.Height, 0);
input = world.ToString(); input = world.ToString();
} }

View File

@@ -67,12 +67,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var frame = sequence.Frames != null ? sequence.Frames.Last() : resource.MaxDensity - 1; var frame = sequence.Frames != null ? sequence.Frames.Last() : resource.MaxDensity - 1;
layerPreview.GetSprite = () => sequence.GetSprite(frame); layerPreview.GetSprite = () => sequence.GetSprite(frame);
var tileWidth = Game.ModData.Manifest.TileSize.Width; var tileSize = Game.ModData.Manifest.Get<MapGrid>().TileSize;
var tileHeight = Game.ModData.Manifest.TileSize.Height; layerPreview.Bounds.Width = tileSize.Width;
layerPreview.Bounds.Width = tileWidth; layerPreview.Bounds.Height = tileSize.Height;
layerPreview.Bounds.Height = tileHeight; newResourcePreviewTemplate.Bounds.Width = tileSize.Width + (layerPreview.Bounds.X * 2);
newResourcePreviewTemplate.Bounds.Width = tileWidth + (layerPreview.Bounds.X * 2); newResourcePreviewTemplate.Bounds.Height = tileSize.Height + (layerPreview.Bounds.Y * 2);
newResourcePreviewTemplate.Bounds.Height = tileHeight + (layerPreview.Bounds.Y * 2);
newResourcePreviewTemplate.IsVisible = () => true; newResourcePreviewTemplate.IsVisible = () => true;
newResourcePreviewTemplate.GetTooltipText = () => resource.Name; newResourcePreviewTemplate.GetTooltipText = () => resource.Name;

View File

@@ -60,7 +60,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
width = Math.Max(2, width); width = Math.Max(2, width);
height = Math.Max(2, height); height = Math.Max(2, height);
var maxTerrainHeight = Game.ModData.Manifest.MaximumTerrainHeight; var maxTerrainHeight = world.Map.Grid.MaximumTerrainHeight;
var tileset = modRules.TileSets[tilesetDropDown.Text]; var tileset = modRules.TileSets[tilesetDropDown.Text];
var map = new Map(tileset, width + 2, height + maxTerrainHeight + 2); var map = new Map(tileset, width + 2, height + maxTerrainHeight + 2);

View File

@@ -68,7 +68,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var preview = item.Get<TerrainTemplatePreviewWidget>("TILE_PREVIEW"); var preview = item.Get<TerrainTemplatePreviewWidget>("TILE_PREVIEW");
var template = tileset.Templates[tileId]; var template = tileset.Templates[tileId];
var bounds = worldRenderer.Theater.TemplateBounds(template, Game.ModData.Manifest.TileSize, worldRenderer.World.Map.TileShape); var grid = worldRenderer.World.Map.Grid;
var bounds = worldRenderer.Theater.TemplateBounds(template, grid.TileSize, grid.Type);
// Scale templates to fit within the panel // Scale templates to fit within the panel
var scale = 1f; var scale = 1f;

View File

@@ -62,6 +62,7 @@ namespace OpenRA.Mods.Common.Widgets
readonly Color spawnColor, spawnContrastColor; readonly Color spawnColor, spawnContrastColor;
readonly int2 spawnLabelOffset; readonly int2 spawnLabelOffset;
readonly int cellWidth; readonly int cellWidth;
readonly TileShape shape;
public Func<MapPreview> Preview = () => null; public Func<MapPreview> Preview = () => null;
public Func<Dictionary<CPos, SpawnOccupant>> SpawnOccupants = () => new Dictionary<CPos, SpawnOccupant>(); public Func<Dictionary<CPos, SpawnOccupant>> SpawnOccupants = () => new Dictionary<CPos, SpawnOccupant>();
@@ -83,7 +84,8 @@ namespace OpenRA.Mods.Common.Widgets
spawnContrastColor = ChromeMetrics.Get<Color>("SpawnContrastColor"); spawnContrastColor = ChromeMetrics.Get<Color>("SpawnContrastColor");
spawnLabelOffset = ChromeMetrics.Get<int2>("SpawnLabelOffset"); spawnLabelOffset = ChromeMetrics.Get<int2>("SpawnLabelOffset");
cellWidth = Game.ModData.Manifest.TileShape == TileShape.Diamond ? 2 : 1; shape = Game.ModData.Manifest.Get<MapGrid>().Type;
cellWidth = shape == TileShape.Diamond ? 2 : 1;
} }
protected MapPreviewWidget(MapPreviewWidget other) protected MapPreviewWidget(MapPreviewWidget other)
@@ -106,6 +108,7 @@ namespace OpenRA.Mods.Common.Widgets
spawnContrastColor = ChromeMetrics.Get<Color>("SpawnContrastColor"); spawnContrastColor = ChromeMetrics.Get<Color>("SpawnContrastColor");
spawnLabelOffset = ChromeMetrics.Get<int2>("SpawnLabelOffset"); spawnLabelOffset = ChromeMetrics.Get<int2>("SpawnLabelOffset");
shape = other.shape;
cellWidth = other.cellWidth; cellWidth = other.cellWidth;
} }
@@ -138,8 +141,7 @@ namespace OpenRA.Mods.Common.Widgets
public int2 ConvertToPreview(CPos cell) public int2 ConvertToPreview(CPos cell)
{ {
var preview = Preview(); var preview = Preview();
var tileShape = Game.ModData.Manifest.TileShape; var point = cell.ToMPos(shape);
var point = cell.ToMPos(tileShape);
var dx = (int)(previewScale * cellWidth * (point.U - preview.Bounds.Left)); var dx = (int)(previewScale * cellWidth * (point.U - preview.Bounds.Left));
var dy = (int)(previewScale * (point.V - preview.Bounds.Top)); var dy = (int)(previewScale * (point.V - preview.Bounds.Top));

View File

@@ -64,7 +64,7 @@ namespace OpenRA.Mods.Common.Widgets
this.worldRenderer = worldRenderer; this.worldRenderer = worldRenderer;
radarPings = world.WorldActor.TraitOrDefault<RadarPings>(); radarPings = world.WorldActor.TraitOrDefault<RadarPings>();
isDiamond = world.Map.TileShape == TileShape.Diamond; isDiamond = world.Map.Grid.Type == TileShape.Diamond;
cellWidth = isDiamond ? 2 : 1; cellWidth = isDiamond ? 2 : 1;
previewWidth = world.Map.MapSize.X; previewWidth = world.Map.MapSize.X;
previewHeight = world.Map.MapSize.Y; previewHeight = world.Map.MapSize.Y;
@@ -379,7 +379,7 @@ namespace OpenRA.Mods.Common.Widgets
if (!world.Map.Contains(cell.First)) if (!world.Map.Contains(cell.First))
continue; continue;
var uv = cell.First.ToMPos(world.Map.TileShape); var uv = cell.First.ToMPos(world.Map.Grid.Type);
var color = cell.Second.ToArgb(); var color = cell.Second.ToArgb();
if (isDiamond) if (isDiamond)
{ {

View File

@@ -41,8 +41,9 @@ namespace OpenRA.Mods.Common.Widgets
if (template == null) if (template == null)
return; return;
var ts = Game.ModData.Manifest.TileSize; var grid = Game.ModData.Manifest.Get<MapGrid>();
var shape = Game.ModData.Manifest.TileShape; var ts = grid.TileSize;
var shape = grid.Type;
bounds = worldRenderer.Theater.TemplateBounds(template, ts, shape); bounds = worldRenderer.Theater.TemplateBounds(template, ts, shape);
} }
} }
@@ -70,8 +71,9 @@ namespace OpenRA.Mods.Common.Widgets
if (template == null) if (template == null)
return; return;
var ts = Game.ModData.Manifest.TileSize; var grid = Game.ModData.Manifest.Get<MapGrid>();
var shape = Game.ModData.Manifest.TileShape; var ts = grid.TileSize;
var shape = grid.Type;
var scale = GetScale(); var scale = GetScale();
var sb = new Rectangle((int)(scale * bounds.X), (int)(scale * bounds.Y), (int)(scale * bounds.Width), (int)(scale * bounds.Height)); var sb = new Rectangle((int)(scale * bounds.X), (int)(scale * bounds.Y), (int)(scale * bounds.Width), (int)(scale * bounds.Height));

View File

@@ -201,6 +201,10 @@ Fonts:
Missions: Missions:
./mods/cnc/missions.yaml ./mods/cnc/missions.yaml
MapGrid:
TileSize: 24,24
Type: Rectangle
SupportsMapsFrom: cnc SupportsMapsFrom: cnc
SpriteFormats: ShpTD, TmpTD, ShpTS, TmpRA SpriteFormats: ShpTD, TmpTD, ShpTS, TmpRA

View File

@@ -49,7 +49,9 @@ Sequences:
TileSets: TileSets:
./mods/d2k/tilesets/arrakis.yaml ./mods/d2k/tilesets/arrakis.yaml
TileSize: 32,32 MapGrid:
TileSize: 32,32
Type: Rectangle
Cursors: Cursors:
./mods/d2k/cursors.yaml ./mods/d2k/cursors.yaml

View File

@@ -201,6 +201,10 @@ Fonts:
Missions: Missions:
./mods/ra/missions.yaml ./mods/ra/missions.yaml
MapGrid:
TileSize: 24,24
Type: Rectangle
SupportsMapsFrom: ra SupportsMapsFrom: ra
SpriteFormats: ShpTD, TmpRA, TmpTD, ShpTS SpriteFormats: ShpTD, TmpRA, TmpTD, ShpTS

View File

@@ -111,12 +111,12 @@ TileSets:
./mods/ts/tilesets/temperate.yaml ./mods/ts/tilesets/temperate.yaml
./mods/ts/tilesets/snow.yaml ./mods/ts/tilesets/snow.yaml
TileSize: 48,24 MapGrid:
TileShape: Diamond TileSize: 48,24
SubCells: Type: Diamond
Offsets: 0,0,0, -256,128,0, 0,-128,0, 256,128,0 MaximumTerrainHeight: 16
DefaultIndex: 2 SubCellOffsets: 0,0,0, -256,128,0, 0,-128,0, 256,128,0
MaximumTerrainHeight: 16 SubCellDefaultIndex: 2
Cursors: Cursors:
./mods/ts/cursors.yaml ./mods/ts/cursors.yaml