Merge pull request #7229 from RoosterDragon/map-coords
Introduce a new type for representing map coordinates.
This commit is contained in:
@@ -273,7 +273,8 @@ namespace OpenRA.Editor
|
||||
{
|
||||
var ui = u * ChunkSize + i;
|
||||
var vj = v * ChunkSize + j;
|
||||
var tr = Map.MapTiles.Value[ui, vj];
|
||||
var uv = new MPos(ui, vj);
|
||||
var tr = Map.MapTiles.Value[uv];
|
||||
var tile = TileSetRenderer.Data(tr.Type);
|
||||
if (tile == null)
|
||||
continue;
|
||||
@@ -284,9 +285,9 @@ namespace OpenRA.Editor
|
||||
for (var y = 0; y < TileSetRenderer.TileSize; y++)
|
||||
p[(j * TileSetRenderer.TileSize + y) * stride + i * TileSetRenderer.TileSize + x] = Palette.GetColor(rawImage[x + TileSetRenderer.TileSize * y]).ToArgb();
|
||||
|
||||
if (Map.MapResources.Value[ui, vj].Type != 0)
|
||||
if (Map.MapResources.Value[uv].Type != 0)
|
||||
{
|
||||
var resourceImage = ResourceTemplates[Map.MapResources.Value[ui, vj].Type].Bitmap;
|
||||
var resourceImage = ResourceTemplates[Map.MapResources.Value[uv].Type].Bitmap;
|
||||
var srcdata = resourceImage.LockBits(resourceImage.Bounds(),
|
||||
ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using Eluant;
|
||||
using Eluant.ObjectBinding;
|
||||
using OpenRA.Scripting;
|
||||
@@ -28,7 +27,6 @@ namespace OpenRA
|
||||
public static CPos operator +(CVec a, CPos b) { return new CPos(a.X + b.X, a.Y + b.Y); }
|
||||
public static CPos operator +(CPos a, CVec b) { return new CPos(a.X + b.X, a.Y + b.Y); }
|
||||
public static CPos operator -(CPos a, CVec b) { return new CPos(a.X - b.X, a.Y - b.Y); }
|
||||
|
||||
public static CVec operator -(CPos a, CPos b) { return new CVec(a.X - b.X, a.Y - b.Y); }
|
||||
|
||||
public static bool operator ==(CPos me, CPos other) { return me.X == other.X && me.Y == other.Y; }
|
||||
@@ -37,12 +35,6 @@ namespace OpenRA
|
||||
public static CPos Max(CPos a, CPos b) { return new CPos(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); }
|
||||
public static CPos Min(CPos a, CPos b) { return new CPos(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); }
|
||||
|
||||
public CPos Clamp(Rectangle r)
|
||||
{
|
||||
return new CPos(Math.Min(r.Right, Math.Max(X, r.Left)),
|
||||
Math.Min(r.Bottom, Math.Max(Y, r.Top)));
|
||||
}
|
||||
|
||||
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); }
|
||||
|
||||
public bool Equals(CPos other) { return other == this; }
|
||||
@@ -50,6 +42,31 @@ namespace OpenRA
|
||||
|
||||
public override string ToString() { return X + "," + Y; }
|
||||
|
||||
public MPos ToMPos(Map map)
|
||||
{
|
||||
return ToMPos(map.TileShape);
|
||||
}
|
||||
|
||||
public MPos ToMPos(TileShape shape)
|
||||
{
|
||||
if (shape == TileShape.Rectangle)
|
||||
return new MPos(X, Y);
|
||||
|
||||
// Convert from diamond cell (x, y) position to rectangular map position (u, v)
|
||||
// - The staggered rows make this fiddly (hint: draw a diagram!)
|
||||
// (a) Consider the relationships:
|
||||
// - +1x (even -> odd) adds (0, 1) to (u, v)
|
||||
// - +1x (odd -> even) adds (1, 1) to (u, v)
|
||||
// - +1y (even -> odd) adds (-1, 1) to (u, v)
|
||||
// - +1y (odd -> even) adds (0, 1) to (u, v)
|
||||
// (b) Therefore:
|
||||
// - ax + by adds (a - b)/2 to u (only even increments count)
|
||||
// - ax + by adds a + b to v
|
||||
var u = (X - Y) / 2;
|
||||
var v = X + Y;
|
||||
return new MPos(u, v);
|
||||
}
|
||||
|
||||
#region Scripting interface
|
||||
|
||||
public LuaValue Add(LuaRuntime runtime, LuaValue left, LuaValue right)
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace OpenRA.Graphics
|
||||
{
|
||||
var mapX = x + b.Left;
|
||||
var mapY = y + b.Top;
|
||||
var type = tileset[tileset.GetTerrainIndex(mapTiles[mapX, mapY])];
|
||||
var type = tileset[tileset.GetTerrainIndex(mapTiles[new MPos(mapX, mapY)])];
|
||||
colors[y * stride + x] = type.Color.ToArgb();
|
||||
}
|
||||
}
|
||||
@@ -74,11 +74,11 @@ namespace OpenRA.Graphics
|
||||
{
|
||||
var mapX = x + b.Left;
|
||||
var mapY = y + b.Top;
|
||||
if (map.MapResources.Value[mapX, mapY].Type == 0)
|
||||
if (map.MapResources.Value[new MPos(mapX, mapY)].Type == 0)
|
||||
continue;
|
||||
|
||||
var res = resourceRules.Actors["world"].Traits.WithInterface<ResourceTypeInfo>()
|
||||
.Where(t => t.ResourceType == map.MapResources.Value[mapX, mapY].Type)
|
||||
.Where(t => t.ResourceType == map.MapResources.Value[new MPos(mapX, mapY)].Type)
|
||||
.Select(t => t.TerrainType).FirstOrDefault();
|
||||
|
||||
if (res == null)
|
||||
@@ -114,7 +114,7 @@ namespace OpenRA.Graphics
|
||||
{
|
||||
var mapX = x + b.Left;
|
||||
var mapY = y + b.Top;
|
||||
var custom = map.CustomTerrain[mapX, mapY];
|
||||
var custom = map.CustomTerrain[new MPos(mapX, mapY)];
|
||||
if (custom == byte.MaxValue)
|
||||
continue;
|
||||
colors[y * stride + x] = world.TileSet[custom].Color.ToArgb();
|
||||
@@ -148,9 +148,9 @@ namespace OpenRA.Graphics
|
||||
var color = t.Trait.RadarSignatureColor(t.Actor);
|
||||
foreach (var cell in t.Trait.RadarSignatureCells(t.Actor))
|
||||
{
|
||||
var uv = Map.CellToMap(map.TileShape, cell);
|
||||
if (b.Contains(uv.X, uv.Y))
|
||||
colors[(uv.Y - b.Top) * stride + uv.X - b.Left] = color.ToArgb();
|
||||
var uv = cell.ToMPos(map);
|
||||
if (b.Contains(uv.U, uv.V))
|
||||
colors[(uv.V - b.Top) * stride + uv.U - b.Left] = color.ToArgb();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -174,7 +174,6 @@ namespace OpenRA.Graphics
|
||||
|
||||
var shroud = Color.Black.ToArgb();
|
||||
var fog = Color.FromArgb(128, Color.Black).ToArgb();
|
||||
var offset = new CVec(b.Left, b.Top);
|
||||
|
||||
unsafe
|
||||
{
|
||||
@@ -184,11 +183,11 @@ namespace OpenRA.Graphics
|
||||
var fogObscured = world.FogObscuresTest(map.Cells);
|
||||
foreach (var uv in map.Cells.MapCoords)
|
||||
{
|
||||
var bitmapUv = uv - offset;
|
||||
if (shroudObscured(uv.X, uv.Y))
|
||||
colors[bitmapUv.Y * stride + bitmapUv.X] = shroud;
|
||||
else if (fogObscured(uv.X, uv.Y))
|
||||
colors[bitmapUv.Y * stride + bitmapUv.X] = fog;
|
||||
var bitmapXy = new int2(uv.U - b.Left, uv.V - b.Top);
|
||||
if (shroudObscured(uv))
|
||||
colors[bitmapXy.Y * stride + bitmapXy.X] = shroud;
|
||||
else if (fogObscured(uv))
|
||||
colors[bitmapXy.Y * stride + bitmapXy.X] = fog;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,12 +44,11 @@ namespace OpenRA.Graphics
|
||||
{
|
||||
var verticesPerRow = 4 * map.Bounds.Width;
|
||||
var cells = viewport.VisibleCells;
|
||||
var shape = wr.World.Map.TileShape;
|
||||
|
||||
// Only draw the rows that are visible.
|
||||
// VisibleCells is clamped to the map, so additional checks are unnecessary
|
||||
var firstRow = Map.CellToMap(shape, cells.TopLeft).Y - map.Bounds.Top;
|
||||
var lastRow = Map.CellToMap(shape, cells.BottomRight).Y - map.Bounds.Top + 1;
|
||||
var firstRow = cells.TopLeft.ToMPos(map).V - map.Bounds.Top;
|
||||
var lastRow = cells.BottomRight.ToMPos(map).V - map.Bounds.Top + 1;
|
||||
|
||||
Game.Renderer.WorldSpriteRenderer.DrawVertexBuffer(
|
||||
vertexBuffer, verticesPerRow * firstRow, verticesPerRow * (lastRow - firstRow),
|
||||
|
||||
@@ -94,8 +94,8 @@ namespace OpenRA.Graphics
|
||||
var b = map.Bounds;
|
||||
|
||||
// Expand to corners of cells
|
||||
var tl = wr.ScreenPxPosition(map.CenterOfCell(Map.MapToCell(map.TileShape, new CPos(b.Left, b.Top))) - new WVec(512, 512, 0));
|
||||
var br = wr.ScreenPxPosition(map.CenterOfCell(Map.MapToCell(map.TileShape, new CPos(b.Right, b.Bottom))) + new WVec(511, 511, 0));
|
||||
var tl = wr.ScreenPxPosition(map.CenterOfCell(new MPos(b.Left, b.Top).ToCPos(map)) - new WVec(512, 512, 0));
|
||||
var br = wr.ScreenPxPosition(map.CenterOfCell(new MPos(b.Right, b.Bottom).ToCPos(map)) + new WVec(511, 511, 0));
|
||||
mapBounds = Rectangle.FromLTRB(tl.X, tl.Y, br.X, br.Y);
|
||||
|
||||
maxGroundHeight = wr.World.TileSet.MaxGroundHeight;
|
||||
@@ -164,15 +164,15 @@ namespace OpenRA.Graphics
|
||||
var wbr = worldRenderer.Position(BottomRight);
|
||||
|
||||
// Visible rectangle in map coordinates
|
||||
var ctl = new CPos(wtl.X / 1024, wtl.Y / 1024);
|
||||
var ctl = new MPos(wtl.X / 1024, wtl.Y / 1024);
|
||||
var dy = map.TileShape == TileShape.Diamond ? 512 : 1024;
|
||||
var cbr = new CPos((wbr.X + 1023) / 1024, (wbr.Y + dy - 1) / dy);
|
||||
var cbr = new MPos((wbr.X + 1023) / 1024, (wbr.Y + dy - 1) / dy);
|
||||
|
||||
// Add a 1 cell cordon to prevent holes, then convert back to cell coordinates
|
||||
var tl = map.Clamp(Map.MapToCell(map.TileShape, ctl - new CVec(1, 1)));
|
||||
var tl = map.Clamp(new MPos(ctl.U - 1, ctl.V - 1).ToCPos(map));
|
||||
|
||||
// Also need to account for height of cells in rows below the bottom
|
||||
var br = map.Clamp(Map.MapToCell(map.TileShape, cbr + new CVec(1, 2 + maxGroundHeight / 2)));
|
||||
var br = map.Clamp(new MPos(cbr.U + 1, cbr.V + 2 + maxGroundHeight / 2).ToCPos(map));
|
||||
|
||||
cells = new CellRegion(map.TileShape, tl, br);
|
||||
cellsDirty = false;
|
||||
|
||||
64
OpenRA.Game/MPos.cs
Normal file
64
OpenRA.Game/MPos.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 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;
|
||||
using System.Drawing;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
public struct MPos : IEquatable<MPos>
|
||||
{
|
||||
public readonly int U, V;
|
||||
|
||||
public MPos(int u, int v) { U = u; V = v; }
|
||||
public static readonly MPos Zero = new MPos(0, 0);
|
||||
|
||||
public static bool operator ==(MPos me, MPos other) { return me.U == other.U && me.V == other.V; }
|
||||
public static bool operator !=(MPos me, MPos other) { return !(me == other); }
|
||||
|
||||
public override int GetHashCode() { return U.GetHashCode() ^ V.GetHashCode(); }
|
||||
|
||||
public bool Equals(MPos other) { return other == this; }
|
||||
public override bool Equals(object obj) { return obj is MPos && Equals((MPos)obj); }
|
||||
|
||||
public MPos Clamp(Rectangle r)
|
||||
{
|
||||
return new MPos(Math.Min(r.Right, Math.Max(U, r.Left)),
|
||||
Math.Min(r.Bottom, Math.Max(V, r.Top)));
|
||||
}
|
||||
|
||||
public override string ToString() { return U + "," + V; }
|
||||
|
||||
public CPos ToCPos(Map map)
|
||||
{
|
||||
return ToCPos(map.TileShape);
|
||||
}
|
||||
|
||||
public CPos ToCPos(TileShape shape)
|
||||
{
|
||||
if (shape == TileShape.Rectangle)
|
||||
return new CPos(U, V);
|
||||
|
||||
// Convert from rectangular map position to diamond cell position
|
||||
// - The staggered rows make this fiddly (hint: draw a diagram!)
|
||||
// (a) Consider the relationships:
|
||||
// - +1u (even -> odd) adds (1, -1) to (x, y)
|
||||
// - +1v (even -> odd) adds (1, 0) to (x, y)
|
||||
// - +1v (odd -> even) adds (0, 1) to (x, y)
|
||||
// (b) Therefore:
|
||||
// - au + 2bv adds (a + b) to (x, y)
|
||||
// - a correction factor is added if v is odd
|
||||
var offset = (V & 1) == 1 ? 1 : 0;
|
||||
var y = (V - offset) / 2 - U;
|
||||
var x = V - y;
|
||||
return new CPos(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,14 +48,13 @@ namespace OpenRA
|
||||
// Resolve an array index from cell coordinates
|
||||
int Index(CPos cell)
|
||||
{
|
||||
var uv = Map.CellToMap(Shape, cell);
|
||||
return Index(uv.X, uv.Y);
|
||||
return Index(cell.ToMPos(Shape));
|
||||
}
|
||||
|
||||
// Resolve an array index from map coordinates
|
||||
int Index(int u, int v)
|
||||
int Index(MPos uv)
|
||||
{
|
||||
return v * Size.Width + u;
|
||||
return uv.V * Size.Width + uv.U;
|
||||
}
|
||||
|
||||
/// <summary>Gets or sets the <see cref="OpenRA.CellLayer"/> using cell coordinates</summary>
|
||||
@@ -76,19 +75,19 @@ namespace OpenRA
|
||||
}
|
||||
|
||||
/// <summary>Gets or sets the layer contents using raw map coordinates (not CPos!)</summary>
|
||||
public T this[int u, int v]
|
||||
public T this[MPos uv]
|
||||
{
|
||||
get
|
||||
{
|
||||
return entries[Index(u, v)];
|
||||
return entries[Index(uv)];
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
entries[Index(u, v)] = value;
|
||||
entries[Index(uv)] = value;
|
||||
|
||||
if (CellEntryChanged != null)
|
||||
CellEntryChanged(Map.MapToCell(Shape, new CPos(u, v)));
|
||||
CellEntryChanged(uv.ToCPos(Shape));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +122,7 @@ namespace OpenRA
|
||||
result.Clear(defaultValue);
|
||||
for (var j = 0; j < height; j++)
|
||||
for (var i = 0; i < width; i++)
|
||||
result[i, j] = layer[i, j];
|
||||
result[new MPos(i, j)] = layer[new MPos(i, j)];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -26,8 +26,8 @@ namespace OpenRA
|
||||
|
||||
// Corners in map coordinates
|
||||
// These will only equal TopLeft and BottomRight for TileShape.Rectangular
|
||||
readonly CPos mapTopLeft;
|
||||
readonly CPos mapBottomRight;
|
||||
readonly MPos mapTopLeft;
|
||||
readonly MPos mapBottomRight;
|
||||
|
||||
public CellRegion(TileShape shape, CPos topLeft, CPos bottomRight)
|
||||
{
|
||||
@@ -35,17 +35,15 @@ namespace OpenRA
|
||||
TopLeft = topLeft;
|
||||
BottomRight = bottomRight;
|
||||
|
||||
mapTopLeft = Map.CellToMap(shape, TopLeft);
|
||||
mapBottomRight = Map.CellToMap(shape, BottomRight);
|
||||
mapTopLeft = TopLeft.ToMPos(shape);
|
||||
mapBottomRight = BottomRight.ToMPos(shape);
|
||||
}
|
||||
|
||||
/// <summary>Expand the specified region with an additional cordon. This may expand the region outside the map borders.</summary>
|
||||
public static CellRegion Expand(CellRegion region, int cordon)
|
||||
{
|
||||
var offset = new CVec(cordon, cordon);
|
||||
var tl = Map.MapToCell(region.shape, Map.CellToMap(region.shape, region.TopLeft) - offset);
|
||||
var br = Map.MapToCell(region.shape, Map.CellToMap(region.shape, region.BottomRight) + offset);
|
||||
|
||||
var tl = new MPos(region.mapTopLeft.U - cordon, region.mapTopLeft.V - cordon).ToCPos(region.shape);
|
||||
var br = new MPos(region.mapBottomRight.U + cordon, region.mapBottomRight.V + cordon).ToCPos(region.shape);
|
||||
return new CellRegion(region.shape, tl, br);
|
||||
}
|
||||
|
||||
@@ -83,8 +81,8 @@ namespace OpenRA
|
||||
|
||||
public bool Contains(CPos cell)
|
||||
{
|
||||
var uv = Map.CellToMap(shape, cell);
|
||||
return uv.X >= mapTopLeft.X && uv.X <= mapBottomRight.X && uv.Y >= mapTopLeft.Y && uv.Y <= mapBottomRight.Y;
|
||||
var uv = cell.ToMPos(shape);
|
||||
return uv.U >= mapTopLeft.U && uv.U <= mapBottomRight.U && uv.V >= mapTopLeft.V && uv.V <= mapBottomRight.V;
|
||||
}
|
||||
|
||||
public MapCoordsRegion MapCoords
|
||||
@@ -128,25 +126,25 @@ namespace OpenRA
|
||||
u += 1;
|
||||
|
||||
// Check for column overflow
|
||||
if (u > r.mapBottomRight.X)
|
||||
if (u > r.mapBottomRight.U)
|
||||
{
|
||||
v += 1;
|
||||
u = r.mapTopLeft.X;
|
||||
u = r.mapTopLeft.U;
|
||||
|
||||
// Check for row overflow
|
||||
if (v > r.mapBottomRight.Y)
|
||||
if (v > r.mapBottomRight.V)
|
||||
return false;
|
||||
}
|
||||
|
||||
current = Map.MapToCell(r.shape, new CPos(u, v));
|
||||
current = new MPos(u, v).ToCPos(r.shape);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
// Enumerator starts *before* the first element in the sequence.
|
||||
u = r.mapTopLeft.X - 1;
|
||||
v = r.mapTopLeft.Y;
|
||||
u = r.mapTopLeft.U - 1;
|
||||
v = r.mapTopLeft.V;
|
||||
}
|
||||
|
||||
public CPos Current { get { return current; } }
|
||||
@@ -154,12 +152,12 @@ namespace OpenRA
|
||||
public void Dispose() { }
|
||||
}
|
||||
|
||||
public struct MapCoordsRegion : IEnumerable<CPos>
|
||||
public struct MapCoordsRegion : IEnumerable<MPos>
|
||||
{
|
||||
public struct MapCoordsEnumerator : IEnumerator<CPos>
|
||||
public struct MapCoordsEnumerator : IEnumerator<MPos>
|
||||
{
|
||||
readonly CellRegion r;
|
||||
CPos current;
|
||||
MPos current;
|
||||
|
||||
public MapCoordsEnumerator(CellRegion region)
|
||||
: this()
|
||||
@@ -170,30 +168,30 @@ namespace OpenRA
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
var u = current.X + 1;
|
||||
var v = current.Y;
|
||||
var u = current.U + 1;
|
||||
var v = current.V;
|
||||
|
||||
// Check for column overflow
|
||||
if (u > r.mapBottomRight.X)
|
||||
if (u > r.mapBottomRight.U)
|
||||
{
|
||||
v += 1;
|
||||
u = r.mapTopLeft.X;
|
||||
u = r.mapTopLeft.U;
|
||||
|
||||
// Check for row overflow
|
||||
if (v > r.mapBottomRight.Y)
|
||||
if (v > r.mapBottomRight.V)
|
||||
return false;
|
||||
}
|
||||
|
||||
current = new CPos(u, v);
|
||||
current = new MPos(u, v);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
current = new CPos(r.mapTopLeft.X - 1, r.mapTopLeft.Y);
|
||||
current = new MPos(r.mapTopLeft.U - 1, r.mapTopLeft.V);
|
||||
}
|
||||
|
||||
public CPos Current { get { return current; } }
|
||||
public MPos Current { get { return current; } }
|
||||
object IEnumerator.Current { get { return Current; } }
|
||||
public void Dispose() { }
|
||||
}
|
||||
@@ -210,7 +208,7 @@ namespace OpenRA
|
||||
return new MapCoordsEnumerator(r);
|
||||
}
|
||||
|
||||
IEnumerator<CPos> IEnumerable<CPos>.GetEnumerator()
|
||||
IEnumerator<MPos> IEnumerable<MPos>.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
@@ -367,13 +367,13 @@ namespace OpenRA
|
||||
|
||||
cachedTileSet = Exts.Lazy(() => Rules.TileSets[Tileset]);
|
||||
|
||||
var tl = Map.MapToCell(TileShape, new CPos(Bounds.Left, Bounds.Top));
|
||||
var br = Map.MapToCell(TileShape, new CPos(Bounds.Right - 1, Bounds.Bottom - 1));
|
||||
var tl = new MPos(Bounds.Left, Bounds.Top).ToCPos(this);
|
||||
var br = new MPos(Bounds.Right - 1, Bounds.Bottom - 1).ToCPos(this);
|
||||
Cells = new CellRegion(TileShape, tl, br);
|
||||
|
||||
CustomTerrain = new CellLayer<byte>(this);
|
||||
foreach (var uv in Cells.MapCoords)
|
||||
CustomTerrain[uv.X, uv.Y] = byte.MaxValue;
|
||||
CustomTerrain[uv] = byte.MaxValue;
|
||||
}
|
||||
|
||||
public Ruleset PreloadRules()
|
||||
@@ -485,7 +485,7 @@ namespace OpenRA
|
||||
if (index == byte.MaxValue)
|
||||
index = (byte)(i % 4 + (j % 4) * 4);
|
||||
|
||||
tiles[i, j] = new TerrainTile(tile, index);
|
||||
tiles[new MPos(i, j)] = new TerrainTile(tile, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -506,7 +506,7 @@ namespace OpenRA
|
||||
s.Position = header.HeightsOffset;
|
||||
for (var i = 0; i < MapSize.X; i++)
|
||||
for (var j = 0; j < MapSize.Y; j++)
|
||||
tiles[i, j] = s.ReadUInt8().Clamp((byte)0, maxHeight);
|
||||
tiles[new MPos(i, j)] = s.ReadUInt8().Clamp((byte)0, maxHeight);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -529,7 +529,7 @@ namespace OpenRA
|
||||
{
|
||||
var type = s.ReadUInt8();
|
||||
var density = s.ReadUInt8();
|
||||
resources[i, j] = new ResourceTile(type, density);
|
||||
resources[new MPos(i, j)] = new ResourceTile(type, density);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -566,7 +566,7 @@ namespace OpenRA
|
||||
{
|
||||
for (var j = 0; j < MapSize.Y; j++)
|
||||
{
|
||||
var tile = MapTiles.Value[i, j];
|
||||
var tile = MapTiles.Value[new MPos(i, j)];
|
||||
writer.Write(tile.Type);
|
||||
writer.Write(tile.Index);
|
||||
}
|
||||
@@ -577,7 +577,7 @@ namespace OpenRA
|
||||
if (heightsOffset != 0)
|
||||
for (var i = 0; i < MapSize.X; i++)
|
||||
for (var j = 0; j < MapSize.Y; j++)
|
||||
writer.Write(MapHeight.Value[i, j]);
|
||||
writer.Write(MapHeight.Value[new MPos(i, j)]);
|
||||
|
||||
// Resource data
|
||||
if (resourcesOffset != 0)
|
||||
@@ -586,7 +586,7 @@ namespace OpenRA
|
||||
{
|
||||
for (var j = 0; j < MapSize.Y; j++)
|
||||
{
|
||||
var tile = MapResources.Value[i, j];
|
||||
var tile = MapResources.Value[new MPos(i, j)];
|
||||
writer.Write(tile.Type);
|
||||
writer.Write(tile.Index);
|
||||
}
|
||||
@@ -599,13 +599,12 @@ namespace OpenRA
|
||||
|
||||
public bool Contains(CPos cell)
|
||||
{
|
||||
var uv = CellToMap(TileShape, cell);
|
||||
return Contains(uv.X, uv.Y);
|
||||
return Contains(cell.ToMPos(this));
|
||||
}
|
||||
|
||||
public bool Contains(int u, int v)
|
||||
public bool Contains(MPos uv)
|
||||
{
|
||||
return Bounds.Contains(u, v);
|
||||
return Bounds.Contains(uv.U, uv.V);
|
||||
}
|
||||
|
||||
public WPos CenterOfCell(CPos cell)
|
||||
@@ -648,46 +647,6 @@ namespace OpenRA
|
||||
return new CPos(u, v);
|
||||
}
|
||||
|
||||
public static CPos MapToCell(TileShape shape, CPos map)
|
||||
{
|
||||
if (shape == TileShape.Rectangle)
|
||||
return map;
|
||||
|
||||
// Convert from rectangular map position to diamond cell position
|
||||
// - The staggered rows make this fiddly (hint: draw a diagram!)
|
||||
// (a) Consider the relationships:
|
||||
// - +1u (even -> odd) adds (1, -1) to (x, y)
|
||||
// - +1v (even -> odd) adds (1, 0) to (x, y)
|
||||
// - +1v (odd -> even) adds (0, 1) to (x, y)
|
||||
// (b) Therefore:
|
||||
// - au + 2bv adds (a + b) to (x, y)
|
||||
// - a correction factor is added if v is odd
|
||||
var offset = (map.Y & 1) == 1 ? 1 : 0;
|
||||
var y = (map.Y - offset) / 2 - map.X;
|
||||
var x = map.Y - y;
|
||||
return new CPos(x, y);
|
||||
}
|
||||
|
||||
public static CPos CellToMap(TileShape shape, CPos cell)
|
||||
{
|
||||
if (shape == TileShape.Rectangle)
|
||||
return cell;
|
||||
|
||||
// Convert from diamond cell (x, y) position to rectangular map position (u, v)
|
||||
// - The staggered rows make this fiddly (hint: draw a diagram!)
|
||||
// (a) Consider the relationships:
|
||||
// - +1x (even -> odd) adds (0, 1) to (u, v)
|
||||
// - +1x (odd -> even) adds (1, 1) to (u, v)
|
||||
// - +1y (even -> odd) adds (-1, 1) to (u, v)
|
||||
// - +1y (odd -> even) adds (0, 1) to (u, v)
|
||||
// (b) Therefore:
|
||||
// - ax + by adds (a - b)/2 to u (only even increments count)
|
||||
// - ax + by adds a + b to v
|
||||
var u = (cell.X - cell.Y) / 2;
|
||||
var v = cell.X + cell.Y;
|
||||
return new CPos(u, v);
|
||||
}
|
||||
|
||||
public int FacingBetween(CPos cell, CPos towards, int fallbackfacing)
|
||||
{
|
||||
return Traits.Util.GetFacing(CenterOfCell(towards) - CenterOfCell(cell), fallbackfacing);
|
||||
@@ -700,9 +659,9 @@ namespace OpenRA
|
||||
var oldMapHeight = MapHeight.Value;
|
||||
var newSize = new Size(width, height);
|
||||
|
||||
MapTiles = Exts.Lazy(() => CellLayer.Resize(oldMapTiles, newSize, oldMapTiles[0, 0]));
|
||||
MapResources = Exts.Lazy(() => CellLayer.Resize(oldMapResources, newSize, oldMapResources[0, 0]));
|
||||
MapHeight = Exts.Lazy(() => CellLayer.Resize(oldMapHeight, newSize, oldMapHeight[0, 0]));
|
||||
MapTiles = Exts.Lazy(() => CellLayer.Resize(oldMapTiles, newSize, oldMapTiles[MPos.Zero]));
|
||||
MapResources = Exts.Lazy(() => CellLayer.Resize(oldMapResources, newSize, oldMapResources[MPos.Zero]));
|
||||
MapHeight = Exts.Lazy(() => CellLayer.Resize(oldMapHeight, newSize, oldMapHeight[MPos.Zero]));
|
||||
MapSize = new int2(newSize);
|
||||
}
|
||||
|
||||
@@ -710,8 +669,8 @@ namespace OpenRA
|
||||
{
|
||||
Bounds = Rectangle.FromLTRB(left, top, right, bottom);
|
||||
|
||||
var tl = Map.MapToCell(TileShape, new CPos(Bounds.Left, Bounds.Top));
|
||||
var br = Map.MapToCell(TileShape, new CPos(Bounds.Right - 1, Bounds.Bottom - 1));
|
||||
var tl = new MPos(Bounds.Left, Bounds.Top).ToCPos(this);
|
||||
var br = new MPos(Bounds.Right - 1, Bounds.Bottom - 1).ToCPos(this);
|
||||
Cells = new CellRegion(TileShape, tl, br);
|
||||
}
|
||||
|
||||
@@ -781,8 +740,8 @@ namespace OpenRA
|
||||
{
|
||||
for (var i = Bounds.Left; i < Bounds.Right; i++)
|
||||
{
|
||||
var type = MapTiles.Value[i, j].Type;
|
||||
var index = MapTiles.Value[i, j].Index;
|
||||
var type = MapTiles.Value[new MPos(i, j)].Type;
|
||||
var index = MapTiles.Value[new MPos(i, j)].Index;
|
||||
if (!tileset.Templates.ContainsKey(type))
|
||||
{
|
||||
Console.WriteLine("Unknown Tile ID {0}".F(type));
|
||||
@@ -794,18 +753,16 @@ namespace OpenRA
|
||||
continue;
|
||||
|
||||
index = (byte)r.Next(0, template.TilesCount);
|
||||
MapTiles.Value[i, j] = new TerrainTile(type, index);
|
||||
MapTiles.Value[new MPos(i, j)] = new TerrainTile(type, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public byte GetTerrainIndex(CPos cell)
|
||||
{
|
||||
var uv = Map.CellToMap(TileShape, cell);
|
||||
var u = uv.X;
|
||||
var v = uv.Y;
|
||||
var custom = CustomTerrain[u, v];
|
||||
return custom != byte.MaxValue ? custom : cachedTileSet.Value.GetTerrainIndex(MapTiles.Value[u, v]);
|
||||
var uv = cell.ToMPos(this);
|
||||
var custom = CustomTerrain[uv];
|
||||
return custom != byte.MaxValue ? custom : cachedTileSet.Value.GetTerrainIndex(MapTiles.Value[uv]);
|
||||
}
|
||||
|
||||
public TerrainTypeInfo GetTerrainInfo(CPos cell)
|
||||
@@ -816,7 +773,7 @@ namespace OpenRA
|
||||
public CPos Clamp(CPos cell)
|
||||
{
|
||||
var bounds = new Rectangle(Bounds.X, Bounds.Y, Bounds.Width - 1, Bounds.Height - 1);
|
||||
return MapToCell(TileShape, CellToMap(TileShape, cell).Clamp(bounds));
|
||||
return cell.ToMPos(this).Clamp(bounds).ToCPos(this);
|
||||
}
|
||||
|
||||
public CPos ChooseRandomCell(MersenneTwister rand)
|
||||
@@ -824,7 +781,7 @@ namespace OpenRA
|
||||
var x = rand.Next(Bounds.Left, Bounds.Right);
|
||||
var y = rand.Next(Bounds.Top, Bounds.Bottom);
|
||||
|
||||
return MapToCell(TileShape, new CPos(x, y));
|
||||
return new MPos(x, y).ToCPos(this);
|
||||
}
|
||||
|
||||
public CPos ChooseRandomEdgeCell(MersenneTwister rand)
|
||||
@@ -835,7 +792,7 @@ namespace OpenRA
|
||||
var x = isX ? rand.Next(Bounds.Left, Bounds.Right) : (edge ? Bounds.Left : Bounds.Right);
|
||||
var y = !isX ? rand.Next(Bounds.Top, Bounds.Bottom) : (edge ? Bounds.Top : Bounds.Bottom);
|
||||
|
||||
return MapToCell(TileShape, new CPos(x, y));
|
||||
return new MPos(x, y).ToCPos(this);
|
||||
}
|
||||
|
||||
public WRange DistanceToEdge(WPos pos, WVec dir)
|
||||
|
||||
@@ -84,6 +84,7 @@
|
||||
<Compile Include="Activities\Activity.cs" />
|
||||
<Compile Include="Activities\CallFunc.cs" />
|
||||
<Compile Include="Actor.cs" />
|
||||
<Compile Include="MPos.cs" />
|
||||
<Compile Include="GameRules\Warhead.cs" />
|
||||
<Compile Include="Graphics\QuadRenderer.cs" />
|
||||
<Compile Include="Download.cs" />
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace OpenRA.Orders
|
||||
else
|
||||
{
|
||||
var frozen = world.ScreenMap.FrozenActorsAt(world.RenderPlayer, mi)
|
||||
.Where(a => a.Info.Traits.Contains<ITargetableInfo>() && !a.FootprintInMapCoords.All(uv => world.ShroudObscures(uv.X, uv.Y)))
|
||||
.Where(a => a.Info.Traits.Contains<ITargetableInfo>() && !a.Footprint.All(world.ShroudObscures))
|
||||
.WithHighestSelectionPriority();
|
||||
target = frozen != null ? Target.FromFrozenActor(frozen) : Target.FromCell(world, xy);
|
||||
}
|
||||
@@ -74,7 +74,7 @@ namespace OpenRA.Orders
|
||||
else
|
||||
{
|
||||
var frozen = world.ScreenMap.FrozenActorsAt(world.RenderPlayer, mi)
|
||||
.Where(a => a.Info.Traits.Contains<ITargetableInfo>() && !a.FootprintInMapCoords.All(uv => world.ShroudObscures(uv.X, uv.Y)))
|
||||
.Where(a => a.Info.Traits.Contains<ITargetableInfo>() && !a.Footprint.All(world.ShroudObscures))
|
||||
.WithHighestSelectionPriority();
|
||||
target = frozen != null ? Target.FromFrozenActor(frozen) : Target.FromCell(world, xy);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace OpenRA.Traits
|
||||
|
||||
public class FrozenActor
|
||||
{
|
||||
public readonly CPos[] FootprintInMapCoords;
|
||||
public readonly MPos[] Footprint;
|
||||
public readonly CellRegion FootprintRegion;
|
||||
public readonly WPos CenterPosition;
|
||||
public readonly Rectangle Bounds;
|
||||
@@ -40,10 +40,10 @@ namespace OpenRA.Traits
|
||||
|
||||
public bool Visible;
|
||||
|
||||
public FrozenActor(Actor self, CPos[] footprintInMapCoords, CellRegion footprintRegion)
|
||||
public FrozenActor(Actor self, MPos[] footprint, CellRegion footprintRegion)
|
||||
{
|
||||
actor = self;
|
||||
FootprintInMapCoords = footprintInMapCoords;
|
||||
Footprint = footprint;
|
||||
FootprintRegion = footprintRegion;
|
||||
|
||||
CenterPosition = self.CenterPosition;
|
||||
@@ -59,11 +59,11 @@ namespace OpenRA.Traits
|
||||
public void Tick(World world, Shroud shroud)
|
||||
{
|
||||
// We are doing the following LINQ manually to avoid allocating an extra delegate since this is a hot path.
|
||||
// Visible = !FootprintInMapCoords.Any(mapCoord => shroud.IsVisibleTest(FootprintRegion)(mapCoord.X, mapCoord.Y));
|
||||
// Visible = !Footprint.Any(shroud.IsVisibleTest(FootprintRegion));
|
||||
var isVisibleTest = shroud.IsVisibleTest(FootprintRegion);
|
||||
Visible = true;
|
||||
foreach (var mapCoord in FootprintInMapCoords)
|
||||
if (isVisibleTest(mapCoord.X, mapCoord.Y))
|
||||
foreach (var uv in Footprint)
|
||||
if (isVisibleTest(uv))
|
||||
{
|
||||
Visible = false;
|
||||
break;
|
||||
|
||||
@@ -57,12 +57,12 @@ namespace OpenRA.Traits
|
||||
|
||||
public int Hash { get; private set; }
|
||||
|
||||
static readonly Func<int, int, bool> TruthPredicate = (u, v) => true;
|
||||
readonly Func<int, int, bool> shroudEdgeTest;
|
||||
readonly Func<int, int, bool> fastExploredTest;
|
||||
readonly Func<int, int, bool> slowExploredTest;
|
||||
readonly Func<int, int, bool> fastVisibleTest;
|
||||
readonly Func<int, int, bool> slowVisibleTest;
|
||||
static readonly Func<MPos, bool> TruthPredicate = _ => true;
|
||||
readonly Func<MPos, bool> shroudEdgeTest;
|
||||
readonly Func<MPos, bool> fastExploredTest;
|
||||
readonly Func<MPos, bool> slowExploredTest;
|
||||
readonly Func<MPos, bool> fastVisibleTest;
|
||||
readonly Func<MPos, bool> slowVisibleTest;
|
||||
|
||||
public Shroud(Actor self)
|
||||
{
|
||||
@@ -81,7 +81,7 @@ namespace OpenRA.Traits
|
||||
|
||||
fogVisibilities = Exts.Lazy(() => self.TraitsImplementing<IFogVisibilityModifier>().ToArray());
|
||||
|
||||
shroudEdgeTest = (u, v) => map.Contains(u, v);
|
||||
shroudEdgeTest = map.Contains;
|
||||
fastExploredTest = IsExploredCore;
|
||||
slowExploredTest = IsExplored;
|
||||
fastVisibleTest = IsVisibleCore;
|
||||
@@ -233,8 +233,8 @@ namespace OpenRA.Traits
|
||||
throw new ArgumentException("The map bounds of these shrouds do not match.", "s");
|
||||
|
||||
foreach (var uv in map.Cells.MapCoords)
|
||||
if (s.explored[uv.X, uv.Y])
|
||||
explored[uv.X, uv.Y] = true;
|
||||
if (s.explored[uv])
|
||||
explored[uv] = true;
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
@@ -242,7 +242,7 @@ namespace OpenRA.Traits
|
||||
public void ExploreAll(World world)
|
||||
{
|
||||
foreach (var uv in map.Cells.MapCoords)
|
||||
explored[uv.X, uv.Y] = true;
|
||||
explored[uv] = true;
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
@@ -250,36 +250,35 @@ namespace OpenRA.Traits
|
||||
public void ResetExploration()
|
||||
{
|
||||
foreach (var uv in map.Cells.MapCoords)
|
||||
explored[uv.X, uv.Y] = visibleCount[uv.X, uv.Y] > 0;
|
||||
explored[uv] = visibleCount[uv] > 0;
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
public bool IsExplored(CPos cell)
|
||||
{
|
||||
var uv = Map.CellToMap(map.TileShape, cell);
|
||||
return IsExplored(uv.X, uv.Y);
|
||||
return IsExplored(cell.ToMPos(map));
|
||||
}
|
||||
|
||||
public bool IsExplored(int u, int v)
|
||||
public bool IsExplored(MPos uv)
|
||||
{
|
||||
if (!map.Contains(u, v))
|
||||
if (!map.Contains(uv))
|
||||
return false;
|
||||
|
||||
if (!ShroudEnabled)
|
||||
return true;
|
||||
|
||||
return IsExploredCore(u, v);
|
||||
return IsExploredCore(uv);
|
||||
}
|
||||
|
||||
bool ShroudEnabled { get { return !Disabled && self.World.LobbyInfo.GlobalSettings.Shroud; } }
|
||||
|
||||
bool IsExploredCore(int u, int v)
|
||||
bool IsExploredCore(MPos uv)
|
||||
{
|
||||
return explored[u, v] && (generatedShroudCount[u, v] == 0 || visibleCount[u, v] > 0);
|
||||
return explored[uv] && (generatedShroudCount[uv] == 0 || visibleCount[uv] > 0);
|
||||
}
|
||||
|
||||
public Func<int, int, bool> IsExploredTest(CellRegion region)
|
||||
public Func<MPos, bool> IsExploredTest(CellRegion region)
|
||||
{
|
||||
// If the region to test extends outside the map we must use the slow test that checks the map boundary every time.
|
||||
if (!map.Cells.Contains(region))
|
||||
@@ -300,29 +299,29 @@ namespace OpenRA.Traits
|
||||
|
||||
public bool IsVisible(CPos cell)
|
||||
{
|
||||
var uv = Map.CellToMap(map.TileShape, cell);
|
||||
return IsVisible(uv.X, uv.Y);
|
||||
var uv = cell.ToMPos(map);
|
||||
return IsVisible(uv);
|
||||
}
|
||||
|
||||
bool IsVisible(int u, int v)
|
||||
bool IsVisible(MPos uv)
|
||||
{
|
||||
if (!map.Contains(u, v))
|
||||
if (!map.Contains(uv))
|
||||
return false;
|
||||
|
||||
if (!FogEnabled)
|
||||
return true;
|
||||
|
||||
return IsVisibleCore(u, v);
|
||||
return IsVisibleCore(uv);
|
||||
}
|
||||
|
||||
bool FogEnabled { get { return !Disabled && self.World.LobbyInfo.GlobalSettings.Fog; } }
|
||||
|
||||
bool IsVisibleCore(int u, int v)
|
||||
bool IsVisibleCore(MPos uv)
|
||||
{
|
||||
return visibleCount[u, v] > 0;
|
||||
return visibleCount[uv] > 0;
|
||||
}
|
||||
|
||||
public Func<int, int, bool> IsVisibleTest(CellRegion region)
|
||||
public Func<MPos, bool> IsVisibleTest(CellRegion region)
|
||||
{
|
||||
// If the region to test extends outside the map we must use the slow test that checks the map boundary every time.
|
||||
if (!map.Cells.Contains(region))
|
||||
|
||||
@@ -133,9 +133,9 @@ namespace OpenRA.Widgets
|
||||
{
|
||||
var preview = Preview();
|
||||
var tileShape = Game.ModData.Manifest.TileShape;
|
||||
var point = Map.CellToMap(tileShape, cell);
|
||||
var dx = (int)(previewScale * (point.X - preview.Bounds.Left));
|
||||
var dy = (int)(previewScale * (point.Y - preview.Bounds.Top));
|
||||
var point = cell.ToMPos(tileShape);
|
||||
var dx = (int)(previewScale * (point.U - preview.Bounds.Left));
|
||||
var dy = (int)(previewScale * (point.V - preview.Bounds.Top));
|
||||
return new int2(mapRect.X + dx, mapRect.Y + dy);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace OpenRA
|
||||
{
|
||||
public class World
|
||||
{
|
||||
static readonly Func<int, int, bool> FalsePredicate = (u, v) => false;
|
||||
static readonly Func<MPos, bool> FalsePredicate = _ => false;
|
||||
internal readonly TraitDictionary TraitDict = new TraitDictionary();
|
||||
readonly HashSet<Actor> actors = new HashSet<Actor>();
|
||||
readonly List<IEffect> effects = new List<IEffect>();
|
||||
@@ -65,24 +65,24 @@ namespace OpenRA
|
||||
public bool FogObscures(CPos p) { return RenderPlayer != null && !RenderPlayer.Shroud.IsVisible(p); }
|
||||
public bool ShroudObscures(Actor a) { return RenderPlayer != null && !RenderPlayer.Shroud.IsExplored(a); }
|
||||
public bool ShroudObscures(CPos p) { return RenderPlayer != null && !RenderPlayer.Shroud.IsExplored(p); }
|
||||
public bool ShroudObscures(int u, int v) { return RenderPlayer != null && !RenderPlayer.Shroud.IsExplored(u, v); }
|
||||
public bool ShroudObscures(MPos uv) { return RenderPlayer != null && !RenderPlayer.Shroud.IsExplored(uv); }
|
||||
|
||||
public Func<int, int, bool> FogObscuresTest(CellRegion region)
|
||||
public Func<MPos, bool> FogObscuresTest(CellRegion region)
|
||||
{
|
||||
var rp = RenderPlayer;
|
||||
if (rp == null)
|
||||
return FalsePredicate;
|
||||
var predicate = rp.Shroud.IsVisibleTest(region);
|
||||
return (u, v) => !predicate(u, v);
|
||||
return uv => !predicate(uv);
|
||||
}
|
||||
|
||||
public Func<int, int, bool> ShroudObscuresTest(CellRegion region)
|
||||
public Func<MPos, bool> ShroudObscuresTest(CellRegion region)
|
||||
{
|
||||
var rp = RenderPlayer;
|
||||
if (rp == null)
|
||||
return FalsePredicate;
|
||||
var predicate = rp.Shroud.IsExploredTest(region);
|
||||
return (u, v) => !predicate(u, v);
|
||||
return uv => !predicate(uv);
|
||||
}
|
||||
|
||||
public bool IsReplay
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Sync] public int VisibilityHash;
|
||||
|
||||
readonly bool startsRevealed;
|
||||
readonly CPos[] footprintInMapsCoords;
|
||||
readonly MPos[] footprint;
|
||||
readonly CellRegion footprintRegion;
|
||||
|
||||
readonly Lazy<IToolTip> tooltip;
|
||||
@@ -44,9 +44,9 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
// Spawned actors (e.g. building husks) shouldn't be revealed
|
||||
startsRevealed = info.StartsRevealed && !init.Contains<ParentActorInit>();
|
||||
var footprint = FootprintUtils.Tiles(init.Self).ToList();
|
||||
footprintInMapsCoords = footprint.Select(cell => Map.CellToMap(init.World.Map.TileShape, cell)).ToArray();
|
||||
footprintRegion = CellRegion.BoundingRegion(init.World.Map.TileShape, footprint);
|
||||
var footprintCells = FootprintUtils.Tiles(init.Self).ToList();
|
||||
footprint = footprintCells.Select(cell => cell.ToMPos(init.World.Map)).ToArray();
|
||||
footprintRegion = CellRegion.BoundingRegion(init.World.Map.TileShape, footprintCells);
|
||||
tooltip = Exts.Lazy(() => init.Self.TraitsImplementing<IToolTip>().FirstOrDefault());
|
||||
tooltip = Exts.Lazy(() => init.Self.TraitsImplementing<IToolTip>().FirstOrDefault());
|
||||
health = Exts.Lazy(() => init.Self.TraitOrDefault<Health>());
|
||||
@@ -69,11 +69,11 @@ namespace OpenRA.Mods.Common.Traits
|
||||
foreach (var p in self.World.Players)
|
||||
{
|
||||
// We are doing the following LINQ manually to avoid allocating an extra delegate since this is a hot path.
|
||||
// var isVisible = footprintInMapsCoords.Any(mapCoord => p.Shroud.IsVisibleTest(footprintRegion)(mapCoord.X, mapCoord.Y));
|
||||
// var isVisible = footprint.Any(p.Shroud.IsVisibleTest(footprintRegion));
|
||||
var isVisibleTest = p.Shroud.IsVisibleTest(footprintRegion);
|
||||
var isVisible = false;
|
||||
foreach (var mapCoord in footprintInMapsCoords)
|
||||
if (isVisibleTest(mapCoord.X, mapCoord.Y))
|
||||
foreach (var uv in footprint)
|
||||
if (isVisibleTest(uv))
|
||||
{
|
||||
isVisible = true;
|
||||
break;
|
||||
@@ -89,7 +89,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
foreach (var p in self.World.Players)
|
||||
{
|
||||
visible[p] |= startsRevealed;
|
||||
p.PlayerActor.Trait<FrozenActorLayer>().Add(frozen[p] = new FrozenActor(self, footprintInMapsCoords, footprintRegion));
|
||||
p.PlayerActor.Trait<FrozenActorLayer>().Add(frozen[p] = new FrozenActor(self, footprint, footprintRegion));
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
|
||||
@@ -334,7 +334,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
defaultCellInfoLayer = new CellLayer<CellInfo>(map);
|
||||
for (var v = 0; v < mapSize.Height; v++)
|
||||
for (var u = 0; u < mapSize.Width; u++)
|
||||
defaultCellInfoLayer[u, v] = new CellInfo(int.MaxValue, Map.MapToCell(map.TileShape, new CPos(u, v)), false);
|
||||
defaultCellInfoLayer[new MPos(u, v)] = new CellInfo(int.MaxValue, new MPos(u, v).ToCPos(map), false);
|
||||
}
|
||||
|
||||
result.CopyValuesFrom(defaultCellInfoLayer);
|
||||
|
||||
@@ -36,12 +36,12 @@ namespace OpenRA.Mods.Common.Traits
|
||||
var shroudObscured = world.ShroudObscuresTest(wr.Viewport.VisibleCells);
|
||||
foreach (var uv in wr.Viewport.VisibleCells.MapCoords)
|
||||
{
|
||||
if (shroudObscured(uv.X, uv.Y))
|
||||
if (shroudObscured(uv))
|
||||
continue;
|
||||
|
||||
var c = render[uv.X, uv.Y];
|
||||
var c = render[uv];
|
||||
if (c.Sprite != null)
|
||||
new SpriteRenderable(c.Sprite, wr.World.Map.CenterOfCell(Map.MapToCell(world.Map.TileShape, uv)),
|
||||
new SpriteRenderable(c.Sprite, wr.World.Map.CenterOfCell(uv.ToCPos(world.Map)),
|
||||
WVec.Zero, -511, c.Type.Palette, 1f, true).Render(wr); // TODO ZOffset is ignored
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,17 +151,13 @@ namespace OpenRA.Mods.Common.Traits
|
||||
notVisibleEdges = info.UseExtendedIndex ? Edges.AllSides : Edges.AllCorners;
|
||||
}
|
||||
|
||||
Edges GetEdges(int u, int v, Func<int, int, bool> isVisible)
|
||||
Edges GetEdges(MPos uv, Func<MPos, bool> isVisible)
|
||||
{
|
||||
if (!isVisible(u, v))
|
||||
if (!isVisible(uv))
|
||||
return notVisibleEdges;
|
||||
|
||||
var cell = Map.MapToCell(map.TileShape, new CPos(u, v));
|
||||
Func<CPos, bool> isCellVisible = c =>
|
||||
{
|
||||
var uv = Map.CellToMap(map.TileShape, c);
|
||||
return isVisible(uv.X, uv.Y);
|
||||
};
|
||||
var cell = uv.ToCPos(map);
|
||||
Func<CPos, bool> isCellVisible = c => isVisible(c.ToMPos(map));
|
||||
|
||||
// If a side is shrouded then we also count the corners
|
||||
var edge = Edges.None;
|
||||
@@ -208,18 +204,16 @@ namespace OpenRA.Mods.Common.Traits
|
||||
// Adds a 1-cell border around the border to cover any sprites peeking outside the map
|
||||
foreach (var uv in CellRegion.Expand(w.Map.Cells, 1).MapCoords)
|
||||
{
|
||||
var u = uv.X;
|
||||
var v = uv.Y;
|
||||
var screen = wr.ScreenPosition(w.Map.CenterOfCell(Map.MapToCell(map.TileShape, uv)));
|
||||
var screen = wr.ScreenPosition(w.Map.CenterOfCell(uv.ToCPos(map)));
|
||||
var variant = (byte)Game.CosmeticRandom.Next(info.ShroudVariants.Length);
|
||||
tiles[u, v] = new ShroudTile(screen, variant);
|
||||
tiles[uv] = new ShroudTile(screen, variant);
|
||||
|
||||
// Set the cells outside the border so they don't need to be touched again
|
||||
if (!map.Contains(u, v))
|
||||
if (!map.Contains(uv))
|
||||
{
|
||||
var shroudTile = tiles[u, v];
|
||||
var shroudTile = tiles[uv];
|
||||
shroudTile.Shroud = GetTile(shroudSprites, notVisibleEdges, variant);
|
||||
tiles[u, v] = shroudTile;
|
||||
tiles[uv] = shroudTile;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,15 +257,13 @@ namespace OpenRA.Mods.Common.Traits
|
||||
var visibleUnderFog = shroud.IsVisibleTest(updatedRegion);
|
||||
foreach (var uv in updatedRegion.MapCoords)
|
||||
{
|
||||
var u = uv.X;
|
||||
var v = uv.Y;
|
||||
var shrouded = GetEdges(u, v, visibleUnderShroud);
|
||||
var fogged = GetEdges(u, v, visibleUnderFog);
|
||||
var shroudTile = tiles[u, v];
|
||||
var shrouded = GetEdges(uv, visibleUnderShroud);
|
||||
var fogged = GetEdges(uv, visibleUnderFog);
|
||||
var shroudTile = tiles[uv];
|
||||
var variant = shroudTile.Variant;
|
||||
shroudTile.Shroud = GetTile(shroudSprites, shrouded, variant);
|
||||
shroudTile.Fog = GetTile(fogSprites, fogged, variant);
|
||||
tiles[u, v] = shroudTile;
|
||||
tiles[uv] = shroudTile;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,7 +286,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
foreach (var uv in CellRegion.Expand(wr.Viewport.VisibleCells, 1).MapCoords)
|
||||
{
|
||||
var t = tiles[uv.X, uv.Y];
|
||||
var t = tiles[uv];
|
||||
|
||||
if (t.Shroud != null)
|
||||
{
|
||||
|
||||
@@ -84,10 +84,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
foreach (var uv in wr.Viewport.VisibleCells.MapCoords)
|
||||
{
|
||||
var lr = Game.Renderer.WorldLineRenderer;
|
||||
var pos = wr.World.Map.CenterOfCell(Map.MapToCell(wr.World.Map.TileShape, uv));
|
||||
var pos = wr.World.Map.CenterOfCell(uv.ToCPos(wr.World.Map));
|
||||
|
||||
var height = (int)wr.World.Map.MapHeight.Value[uv.X, uv.Y];
|
||||
var tile = wr.World.Map.MapTiles.Value[uv.X, uv.Y];
|
||||
var height = (int)wr.World.Map.MapHeight.Value[uv];
|
||||
var tile = wr.World.Map.MapTiles.Value[uv];
|
||||
|
||||
TerrainTileInfo tileInfo = null;
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
void UpdateTerrainCell(CPos cell)
|
||||
{
|
||||
var stride = radarSheet.Size.Width;
|
||||
var uv = Map.CellToMap(world.Map.TileShape, cell);
|
||||
var uv = cell.ToMPos(world.Map);
|
||||
var terrain = world.Map.GetTerrainInfo(cell);
|
||||
|
||||
var dx = terrainSprite.Bounds.Left - world.Map.Bounds.Left;
|
||||
@@ -102,7 +102,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
fixed (byte* colorBytes = &radarData[0])
|
||||
{
|
||||
var colors = (int*)colorBytes;
|
||||
colors[(uv.Y + dy) * stride + uv.X + dx] = terrain.Color.ToArgb();
|
||||
colors[(uv.V + dy) * stride + uv.U + dx] = terrain.Color.ToArgb();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,7 +110,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
void UpdateShroudCell(CPos cell)
|
||||
{
|
||||
var stride = radarSheet.Size.Width;
|
||||
var uv = Map.CellToMap(world.Map.TileShape, cell);
|
||||
var uv = cell.ToMPos(world.Map);
|
||||
var dx = shroudSprite.Bounds.Left - world.Map.Bounds.Left;
|
||||
var dy = shroudSprite.Bounds.Top - world.Map.Bounds.Top;
|
||||
|
||||
@@ -125,7 +125,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
fixed (byte* colorBytes = &radarData[0])
|
||||
{
|
||||
var colors = (int*)colorBytes;
|
||||
colors[(uv.Y + dy) * stride + uv.X + dx] = color;
|
||||
colors[(uv.V + dy) * stride + uv.U + dx] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -291,10 +291,10 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
var color = t.Trait.RadarSignatureColor(t.Actor);
|
||||
foreach (var cell in t.Trait.RadarSignatureCells(t.Actor))
|
||||
{
|
||||
var uv = Map.CellToMap(world.Map.TileShape, cell);
|
||||
var uv = cell.ToMPos(world.Map);
|
||||
|
||||
if (world.Map.Bounds.Contains(uv.X, uv.Y))
|
||||
colors[(uv.Y + dy) * stride + uv.X + dx] = color.ToArgb();
|
||||
if (world.Map.Bounds.Contains(uv.U, uv.V))
|
||||
colors[(uv.V + dy) * stride + uv.U + dx] = color.ToArgb();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -329,10 +329,9 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
|
||||
int2 CellToMinimapPixel(CPos p)
|
||||
{
|
||||
var mapOrigin = new CVec(world.Map.Bounds.Left, world.Map.Bounds.Top);
|
||||
var mapOffset = Map.CellToMap(world.Map.TileShape, p) - mapOrigin;
|
||||
|
||||
return new int2(mapRect.X, mapRect.Y) + (previewScale * new float2(mapOffset.X, mapOffset.Y)).ToInt2();
|
||||
var uv = p.ToMPos(world.Map);
|
||||
var mapOffset = new float2(uv.U - world.Map.Bounds.Left, uv.V - world.Map.Bounds.Top);
|
||||
return new int2(mapRect.X, mapRect.Y) + (previewScale * mapOffset).ToInt2();
|
||||
}
|
||||
|
||||
CPos MinimapPixelToCell(int2 p)
|
||||
@@ -340,7 +339,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
var viewOrigin = new float2(mapRect.X, mapRect.Y);
|
||||
var mapOrigin = new float2(world.Map.Bounds.Left, world.Map.Bounds.Top);
|
||||
var fcell = mapOrigin + (1f / previewScale) * (p - viewOrigin);
|
||||
return Map.MapToCell(world.Map.TileShape, new CPos((int)fcell.X, (int)fcell.Y));
|
||||
return new MPos((int)fcell.X, (int)fcell.Y).ToCPos(world.Map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user