Introduce a new type for representing map coordinates.
To resolve the ambiguity introduced when the introduction of isometric maps meant that cell and map coordinates were no longer equivalent, a new type has been introduced so they can each be represented separately.
This commit is contained in:
@@ -273,7 +273,8 @@ namespace OpenRA.Editor
|
|||||||
{
|
{
|
||||||
var ui = u * ChunkSize + i;
|
var ui = u * ChunkSize + i;
|
||||||
var vj = v * ChunkSize + j;
|
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);
|
var tile = TileSetRenderer.Data(tr.Type);
|
||||||
if (tile == null)
|
if (tile == null)
|
||||||
continue;
|
continue;
|
||||||
@@ -284,9 +285,9 @@ namespace OpenRA.Editor
|
|||||||
for (var y = 0; y < TileSetRenderer.TileSize; y++)
|
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();
|
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(),
|
var srcdata = resourceImage.LockBits(resourceImage.Bounds(),
|
||||||
ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
|
ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
|
||||||
using Eluant;
|
using Eluant;
|
||||||
using Eluant.ObjectBinding;
|
using Eluant.ObjectBinding;
|
||||||
using OpenRA.Scripting;
|
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 +(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 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 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; }
|
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 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 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 override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); }
|
||||||
|
|
||||||
public bool Equals(CPos other) { return other == this; }
|
public bool Equals(CPos other) { return other == this; }
|
||||||
@@ -50,6 +42,31 @@ namespace OpenRA
|
|||||||
|
|
||||||
public override string ToString() { return X + "," + Y; }
|
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
|
#region Scripting interface
|
||||||
|
|
||||||
public LuaValue Add(LuaRuntime runtime, LuaValue left, LuaValue right)
|
public LuaValue Add(LuaRuntime runtime, LuaValue left, LuaValue right)
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ namespace OpenRA.Graphics
|
|||||||
{
|
{
|
||||||
var mapX = x + b.Left;
|
var mapX = x + b.Left;
|
||||||
var mapY = y + b.Top;
|
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();
|
colors[y * stride + x] = type.Color.ToArgb();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,11 +74,11 @@ namespace OpenRA.Graphics
|
|||||||
{
|
{
|
||||||
var mapX = x + b.Left;
|
var mapX = x + b.Left;
|
||||||
var mapY = y + b.Top;
|
var mapY = y + b.Top;
|
||||||
if (map.MapResources.Value[mapX, mapY].Type == 0)
|
if (map.MapResources.Value[new MPos(mapX, mapY)].Type == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var res = resourceRules.Actors["world"].Traits.WithInterface<ResourceTypeInfo>()
|
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();
|
.Select(t => t.TerrainType).FirstOrDefault();
|
||||||
|
|
||||||
if (res == null)
|
if (res == null)
|
||||||
@@ -114,7 +114,7 @@ namespace OpenRA.Graphics
|
|||||||
{
|
{
|
||||||
var mapX = x + b.Left;
|
var mapX = x + b.Left;
|
||||||
var mapY = y + b.Top;
|
var mapY = y + b.Top;
|
||||||
var custom = map.CustomTerrain[mapX, mapY];
|
var custom = map.CustomTerrain[new MPos(mapX, mapY)];
|
||||||
if (custom == byte.MaxValue)
|
if (custom == byte.MaxValue)
|
||||||
continue;
|
continue;
|
||||||
colors[y * stride + x] = world.TileSet[custom].Color.ToArgb();
|
colors[y * stride + x] = world.TileSet[custom].Color.ToArgb();
|
||||||
@@ -148,9 +148,9 @@ namespace OpenRA.Graphics
|
|||||||
var color = t.Trait.RadarSignatureColor(t.Actor);
|
var color = t.Trait.RadarSignatureColor(t.Actor);
|
||||||
foreach (var cell in t.Trait.RadarSignatureCells(t.Actor))
|
foreach (var cell in t.Trait.RadarSignatureCells(t.Actor))
|
||||||
{
|
{
|
||||||
var uv = Map.CellToMap(map.TileShape, cell);
|
var uv = cell.ToMPos(map);
|
||||||
if (b.Contains(uv.X, uv.Y))
|
if (b.Contains(uv.U, uv.V))
|
||||||
colors[(uv.Y - b.Top) * stride + uv.X - b.Left] = color.ToArgb();
|
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 shroud = Color.Black.ToArgb();
|
||||||
var fog = Color.FromArgb(128, Color.Black).ToArgb();
|
var fog = Color.FromArgb(128, Color.Black).ToArgb();
|
||||||
var offset = new CVec(b.Left, b.Top);
|
|
||||||
|
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
@@ -184,11 +183,11 @@ namespace OpenRA.Graphics
|
|||||||
var fogObscured = world.FogObscuresTest(map.Cells);
|
var fogObscured = world.FogObscuresTest(map.Cells);
|
||||||
foreach (var uv in map.Cells.MapCoords)
|
foreach (var uv in map.Cells.MapCoords)
|
||||||
{
|
{
|
||||||
var bitmapUv = uv - offset;
|
var bitmapXy = new int2(uv.U - b.Left, uv.V - b.Top);
|
||||||
if (shroudObscured(uv.X, uv.Y))
|
if (shroudObscured(uv))
|
||||||
colors[bitmapUv.Y * stride + bitmapUv.X] = shroud;
|
colors[bitmapXy.Y * stride + bitmapXy.X] = shroud;
|
||||||
else if (fogObscured(uv.X, uv.Y))
|
else if (fogObscured(uv))
|
||||||
colors[bitmapUv.Y * stride + bitmapUv.X] = fog;
|
colors[bitmapXy.Y * stride + bitmapXy.X] = fog;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,12 +44,11 @@ namespace OpenRA.Graphics
|
|||||||
{
|
{
|
||||||
var verticesPerRow = 4 * map.Bounds.Width;
|
var verticesPerRow = 4 * map.Bounds.Width;
|
||||||
var cells = viewport.VisibleCells;
|
var cells = viewport.VisibleCells;
|
||||||
var shape = wr.World.Map.TileShape;
|
|
||||||
|
|
||||||
// Only draw the rows that are visible.
|
// Only draw the rows that are visible.
|
||||||
// VisibleCells is clamped to the map, so additional checks are unnecessary
|
// VisibleCells is clamped to the map, so additional checks are unnecessary
|
||||||
var firstRow = Map.CellToMap(shape, cells.TopLeft).Y - map.Bounds.Top;
|
var firstRow = cells.TopLeft.ToMPos(map).V - map.Bounds.Top;
|
||||||
var lastRow = Map.CellToMap(shape, cells.BottomRight).Y - map.Bounds.Top + 1;
|
var lastRow = cells.BottomRight.ToMPos(map).V - map.Bounds.Top + 1;
|
||||||
|
|
||||||
Game.Renderer.WorldSpriteRenderer.DrawVertexBuffer(
|
Game.Renderer.WorldSpriteRenderer.DrawVertexBuffer(
|
||||||
vertexBuffer, verticesPerRow * firstRow, verticesPerRow * (lastRow - firstRow),
|
vertexBuffer, verticesPerRow * firstRow, verticesPerRow * (lastRow - firstRow),
|
||||||
|
|||||||
@@ -94,8 +94,8 @@ namespace OpenRA.Graphics
|
|||||||
var b = map.Bounds;
|
var b = map.Bounds;
|
||||||
|
|
||||||
// Expand to corners of cells
|
// 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 tl = wr.ScreenPxPosition(map.CenterOfCell(new MPos(b.Left, b.Top).ToCPos(map)) - 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 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);
|
mapBounds = Rectangle.FromLTRB(tl.X, tl.Y, br.X, br.Y);
|
||||||
|
|
||||||
maxGroundHeight = wr.World.TileSet.MaxGroundHeight;
|
maxGroundHeight = wr.World.TileSet.MaxGroundHeight;
|
||||||
@@ -164,15 +164,15 @@ namespace OpenRA.Graphics
|
|||||||
var wbr = worldRenderer.Position(BottomRight);
|
var wbr = worldRenderer.Position(BottomRight);
|
||||||
|
|
||||||
// Visible rectangle in map coordinates
|
// 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 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
|
// 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
|
// 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);
|
cells = new CellRegion(map.TileShape, tl, br);
|
||||||
cellsDirty = false;
|
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
|
// Resolve an array index from cell coordinates
|
||||||
int Index(CPos cell)
|
int Index(CPos cell)
|
||||||
{
|
{
|
||||||
var uv = Map.CellToMap(Shape, cell);
|
return Index(cell.ToMPos(Shape));
|
||||||
return Index(uv.X, uv.Y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve an array index from map coordinates
|
// 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>
|
/// <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>
|
/// <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
|
get
|
||||||
{
|
{
|
||||||
return entries[Index(u, v)];
|
return entries[Index(uv)];
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
entries[Index(u, v)] = value;
|
entries[Index(uv)] = value;
|
||||||
|
|
||||||
if (CellEntryChanged != null)
|
if (CellEntryChanged != null)
|
||||||
CellEntryChanged(Map.MapToCell(Shape, new CPos(u, v)));
|
CellEntryChanged(uv.ToCPos(Shape));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,7 +122,7 @@ namespace OpenRA
|
|||||||
result.Clear(defaultValue);
|
result.Clear(defaultValue);
|
||||||
for (var j = 0; j < height; j++)
|
for (var j = 0; j < height; j++)
|
||||||
for (var i = 0; i < width; i++)
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ namespace OpenRA
|
|||||||
|
|
||||||
// Corners in map coordinates
|
// Corners in map coordinates
|
||||||
// These will only equal TopLeft and BottomRight for TileShape.Rectangular
|
// These will only equal TopLeft and BottomRight for TileShape.Rectangular
|
||||||
readonly CPos mapTopLeft;
|
readonly MPos mapTopLeft;
|
||||||
readonly CPos mapBottomRight;
|
readonly MPos mapBottomRight;
|
||||||
|
|
||||||
public CellRegion(TileShape shape, CPos topLeft, CPos bottomRight)
|
public CellRegion(TileShape shape, CPos topLeft, CPos bottomRight)
|
||||||
{
|
{
|
||||||
@@ -35,17 +35,15 @@ namespace OpenRA
|
|||||||
TopLeft = topLeft;
|
TopLeft = topLeft;
|
||||||
BottomRight = bottomRight;
|
BottomRight = bottomRight;
|
||||||
|
|
||||||
mapTopLeft = Map.CellToMap(shape, TopLeft);
|
mapTopLeft = TopLeft.ToMPos(shape);
|
||||||
mapBottomRight = Map.CellToMap(shape, BottomRight);
|
mapBottomRight = BottomRight.ToMPos(shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Expand the specified region with an additional cordon. This may expand the region outside the map borders.</summary>
|
/// <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)
|
public static CellRegion Expand(CellRegion region, int cordon)
|
||||||
{
|
{
|
||||||
var offset = new CVec(cordon, cordon);
|
var tl = new MPos(region.mapTopLeft.U - cordon, region.mapTopLeft.V - cordon).ToCPos(region.shape);
|
||||||
var tl = Map.MapToCell(region.shape, Map.CellToMap(region.shape, region.TopLeft) - offset);
|
var br = new MPos(region.mapBottomRight.U + cordon, region.mapBottomRight.V + cordon).ToCPos(region.shape);
|
||||||
var br = Map.MapToCell(region.shape, Map.CellToMap(region.shape, region.BottomRight) + offset);
|
|
||||||
|
|
||||||
return new CellRegion(region.shape, tl, br);
|
return new CellRegion(region.shape, tl, br);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,8 +81,8 @@ namespace OpenRA
|
|||||||
|
|
||||||
public bool Contains(CPos cell)
|
public bool Contains(CPos cell)
|
||||||
{
|
{
|
||||||
var uv = Map.CellToMap(shape, cell);
|
var uv = cell.ToMPos(shape);
|
||||||
return uv.X >= mapTopLeft.X && uv.X <= mapBottomRight.X && uv.Y >= mapTopLeft.Y && uv.Y <= mapBottomRight.Y;
|
return uv.U >= mapTopLeft.U && uv.U <= mapBottomRight.U && uv.V >= mapTopLeft.V && uv.V <= mapBottomRight.V;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapCoordsRegion MapCoords
|
public MapCoordsRegion MapCoords
|
||||||
@@ -128,25 +126,25 @@ namespace OpenRA
|
|||||||
u += 1;
|
u += 1;
|
||||||
|
|
||||||
// Check for column overflow
|
// Check for column overflow
|
||||||
if (u > r.mapBottomRight.X)
|
if (u > r.mapBottomRight.U)
|
||||||
{
|
{
|
||||||
v += 1;
|
v += 1;
|
||||||
u = r.mapTopLeft.X;
|
u = r.mapTopLeft.U;
|
||||||
|
|
||||||
// Check for row overflow
|
// Check for row overflow
|
||||||
if (v > r.mapBottomRight.Y)
|
if (v > r.mapBottomRight.V)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
current = Map.MapToCell(r.shape, new CPos(u, v));
|
current = new MPos(u, v).ToCPos(r.shape);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
// Enumerator starts *before* the first element in the sequence.
|
// Enumerator starts *before* the first element in the sequence.
|
||||||
u = r.mapTopLeft.X - 1;
|
u = r.mapTopLeft.U - 1;
|
||||||
v = r.mapTopLeft.Y;
|
v = r.mapTopLeft.V;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CPos Current { get { return current; } }
|
public CPos Current { get { return current; } }
|
||||||
@@ -154,12 +152,12 @@ namespace OpenRA
|
|||||||
public void Dispose() { }
|
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;
|
readonly CellRegion r;
|
||||||
CPos current;
|
MPos current;
|
||||||
|
|
||||||
public MapCoordsEnumerator(CellRegion region)
|
public MapCoordsEnumerator(CellRegion region)
|
||||||
: this()
|
: this()
|
||||||
@@ -170,30 +168,30 @@ namespace OpenRA
|
|||||||
|
|
||||||
public bool MoveNext()
|
public bool MoveNext()
|
||||||
{
|
{
|
||||||
var u = current.X + 1;
|
var u = current.U + 1;
|
||||||
var v = current.Y;
|
var v = current.V;
|
||||||
|
|
||||||
// Check for column overflow
|
// Check for column overflow
|
||||||
if (u > r.mapBottomRight.X)
|
if (u > r.mapBottomRight.U)
|
||||||
{
|
{
|
||||||
v += 1;
|
v += 1;
|
||||||
u = r.mapTopLeft.X;
|
u = r.mapTopLeft.U;
|
||||||
|
|
||||||
// Check for row overflow
|
// Check for row overflow
|
||||||
if (v > r.mapBottomRight.Y)
|
if (v > r.mapBottomRight.V)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
current = new CPos(u, v);
|
current = new MPos(u, v);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Reset()
|
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; } }
|
object IEnumerator.Current { get { return Current; } }
|
||||||
public void Dispose() { }
|
public void Dispose() { }
|
||||||
}
|
}
|
||||||
@@ -210,7 +208,7 @@ namespace OpenRA
|
|||||||
return new MapCoordsEnumerator(r);
|
return new MapCoordsEnumerator(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerator<CPos> IEnumerable<CPos>.GetEnumerator()
|
IEnumerator<MPos> IEnumerable<MPos>.GetEnumerator()
|
||||||
{
|
{
|
||||||
return GetEnumerator();
|
return GetEnumerator();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -367,13 +367,13 @@ namespace OpenRA
|
|||||||
|
|
||||||
cachedTileSet = Exts.Lazy(() => Rules.TileSets[Tileset]);
|
cachedTileSet = Exts.Lazy(() => Rules.TileSets[Tileset]);
|
||||||
|
|
||||||
var tl = Map.MapToCell(TileShape, new CPos(Bounds.Left, Bounds.Top));
|
var tl = new MPos(Bounds.Left, Bounds.Top).ToCPos(this);
|
||||||
var br = Map.MapToCell(TileShape, new CPos(Bounds.Right - 1, Bounds.Bottom - 1));
|
var br = new MPos(Bounds.Right - 1, Bounds.Bottom - 1).ToCPos(this);
|
||||||
Cells = new CellRegion(TileShape, tl, br);
|
Cells = new CellRegion(TileShape, tl, br);
|
||||||
|
|
||||||
CustomTerrain = new CellLayer<byte>(this);
|
CustomTerrain = new CellLayer<byte>(this);
|
||||||
foreach (var uv in Cells.MapCoords)
|
foreach (var uv in Cells.MapCoords)
|
||||||
CustomTerrain[uv.X, uv.Y] = byte.MaxValue;
|
CustomTerrain[uv] = byte.MaxValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Ruleset PreloadRules()
|
public Ruleset PreloadRules()
|
||||||
@@ -485,7 +485,7 @@ namespace OpenRA
|
|||||||
if (index == byte.MaxValue)
|
if (index == byte.MaxValue)
|
||||||
index = (byte)(i % 4 + (j % 4) * 4);
|
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;
|
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[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 type = s.ReadUInt8();
|
||||||
var density = 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++)
|
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.Type);
|
||||||
writer.Write(tile.Index);
|
writer.Write(tile.Index);
|
||||||
}
|
}
|
||||||
@@ -577,7 +577,7 @@ namespace OpenRA
|
|||||||
if (heightsOffset != 0)
|
if (heightsOffset != 0)
|
||||||
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++)
|
||||||
writer.Write(MapHeight.Value[i, j]);
|
writer.Write(MapHeight.Value[new MPos(i, j)]);
|
||||||
|
|
||||||
// Resource data
|
// Resource data
|
||||||
if (resourcesOffset != 0)
|
if (resourcesOffset != 0)
|
||||||
@@ -586,7 +586,7 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
for (var j = 0; j < MapSize.Y; j++)
|
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.Type);
|
||||||
writer.Write(tile.Index);
|
writer.Write(tile.Index);
|
||||||
}
|
}
|
||||||
@@ -599,13 +599,12 @@ namespace OpenRA
|
|||||||
|
|
||||||
public bool Contains(CPos cell)
|
public bool Contains(CPos cell)
|
||||||
{
|
{
|
||||||
var uv = CellToMap(TileShape, cell);
|
return Contains(cell.ToMPos(this));
|
||||||
return Contains(uv.X, uv.Y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
public WPos CenterOfCell(CPos cell)
|
||||||
@@ -648,46 +647,6 @@ namespace OpenRA
|
|||||||
return new CPos(u, v);
|
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)
|
public int FacingBetween(CPos cell, CPos towards, int fallbackfacing)
|
||||||
{
|
{
|
||||||
return Traits.Util.GetFacing(CenterOfCell(towards) - CenterOfCell(cell), fallbackfacing);
|
return Traits.Util.GetFacing(CenterOfCell(towards) - CenterOfCell(cell), fallbackfacing);
|
||||||
@@ -700,9 +659,9 @@ namespace OpenRA
|
|||||||
var oldMapHeight = MapHeight.Value;
|
var oldMapHeight = MapHeight.Value;
|
||||||
var newSize = new Size(width, height);
|
var newSize = new Size(width, height);
|
||||||
|
|
||||||
MapTiles = Exts.Lazy(() => CellLayer.Resize(oldMapTiles, newSize, oldMapTiles[0, 0]));
|
MapTiles = Exts.Lazy(() => CellLayer.Resize(oldMapTiles, newSize, oldMapTiles[MPos.Zero]));
|
||||||
MapResources = Exts.Lazy(() => CellLayer.Resize(oldMapResources, newSize, oldMapResources[0, 0]));
|
MapResources = Exts.Lazy(() => CellLayer.Resize(oldMapResources, newSize, oldMapResources[MPos.Zero]));
|
||||||
MapHeight = Exts.Lazy(() => CellLayer.Resize(oldMapHeight, newSize, oldMapHeight[0, 0]));
|
MapHeight = Exts.Lazy(() => CellLayer.Resize(oldMapHeight, newSize, oldMapHeight[MPos.Zero]));
|
||||||
MapSize = new int2(newSize);
|
MapSize = new int2(newSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -710,8 +669,8 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
Bounds = Rectangle.FromLTRB(left, top, right, bottom);
|
Bounds = Rectangle.FromLTRB(left, top, right, bottom);
|
||||||
|
|
||||||
var tl = Map.MapToCell(TileShape, new CPos(Bounds.Left, Bounds.Top));
|
var tl = new MPos(Bounds.Left, Bounds.Top).ToCPos(this);
|
||||||
var br = Map.MapToCell(TileShape, new CPos(Bounds.Right - 1, Bounds.Bottom - 1));
|
var br = new MPos(Bounds.Right - 1, Bounds.Bottom - 1).ToCPos(this);
|
||||||
Cells = new CellRegion(TileShape, tl, br);
|
Cells = new CellRegion(TileShape, tl, br);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -781,8 +740,8 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
for (var i = Bounds.Left; i < Bounds.Right; i++)
|
for (var i = Bounds.Left; i < Bounds.Right; i++)
|
||||||
{
|
{
|
||||||
var type = MapTiles.Value[i, j].Type;
|
var type = MapTiles.Value[new MPos(i, j)].Type;
|
||||||
var index = MapTiles.Value[i, j].Index;
|
var index = MapTiles.Value[new MPos(i, j)].Index;
|
||||||
if (!tileset.Templates.ContainsKey(type))
|
if (!tileset.Templates.ContainsKey(type))
|
||||||
{
|
{
|
||||||
Console.WriteLine("Unknown Tile ID {0}".F(type));
|
Console.WriteLine("Unknown Tile ID {0}".F(type));
|
||||||
@@ -794,18 +753,16 @@ namespace OpenRA
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
index = (byte)r.Next(0, template.TilesCount);
|
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)
|
public byte GetTerrainIndex(CPos cell)
|
||||||
{
|
{
|
||||||
var uv = Map.CellToMap(TileShape, cell);
|
var uv = cell.ToMPos(this);
|
||||||
var u = uv.X;
|
var custom = CustomTerrain[uv];
|
||||||
var v = uv.Y;
|
return custom != byte.MaxValue ? custom : cachedTileSet.Value.GetTerrainIndex(MapTiles.Value[uv]);
|
||||||
var custom = CustomTerrain[u, v];
|
|
||||||
return custom != byte.MaxValue ? custom : cachedTileSet.Value.GetTerrainIndex(MapTiles.Value[u, v]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TerrainTypeInfo GetTerrainInfo(CPos cell)
|
public TerrainTypeInfo GetTerrainInfo(CPos cell)
|
||||||
@@ -816,7 +773,7 @@ namespace OpenRA
|
|||||||
public CPos Clamp(CPos cell)
|
public CPos Clamp(CPos cell)
|
||||||
{
|
{
|
||||||
var bounds = new Rectangle(Bounds.X, Bounds.Y, Bounds.Width - 1, Bounds.Height - 1);
|
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)
|
public CPos ChooseRandomCell(MersenneTwister rand)
|
||||||
@@ -824,7 +781,7 @@ namespace OpenRA
|
|||||||
var x = rand.Next(Bounds.Left, Bounds.Right);
|
var x = rand.Next(Bounds.Left, Bounds.Right);
|
||||||
var y = rand.Next(Bounds.Top, Bounds.Bottom);
|
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)
|
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 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);
|
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)
|
public WRange DistanceToEdge(WPos pos, WVec dir)
|
||||||
|
|||||||
@@ -84,6 +84,7 @@
|
|||||||
<Compile Include="Activities\Activity.cs" />
|
<Compile Include="Activities\Activity.cs" />
|
||||||
<Compile Include="Activities\CallFunc.cs" />
|
<Compile Include="Activities\CallFunc.cs" />
|
||||||
<Compile Include="Actor.cs" />
|
<Compile Include="Actor.cs" />
|
||||||
|
<Compile Include="MPos.cs" />
|
||||||
<Compile Include="GameRules\Warhead.cs" />
|
<Compile Include="GameRules\Warhead.cs" />
|
||||||
<Compile Include="Graphics\QuadRenderer.cs" />
|
<Compile Include="Graphics\QuadRenderer.cs" />
|
||||||
<Compile Include="Download.cs" />
|
<Compile Include="Download.cs" />
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace OpenRA.Orders
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
var frozen = world.ScreenMap.FrozenActorsAt(world.RenderPlayer, mi)
|
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();
|
.WithHighestSelectionPriority();
|
||||||
target = frozen != null ? Target.FromFrozenActor(frozen) : Target.FromCell(world, xy);
|
target = frozen != null ? Target.FromFrozenActor(frozen) : Target.FromCell(world, xy);
|
||||||
}
|
}
|
||||||
@@ -74,7 +74,7 @@ namespace OpenRA.Orders
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
var frozen = world.ScreenMap.FrozenActorsAt(world.RenderPlayer, mi)
|
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();
|
.WithHighestSelectionPriority();
|
||||||
target = frozen != null ? Target.FromFrozenActor(frozen) : Target.FromCell(world, xy);
|
target = frozen != null ? Target.FromFrozenActor(frozen) : Target.FromCell(world, xy);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
public class FrozenActor
|
public class FrozenActor
|
||||||
{
|
{
|
||||||
public readonly CPos[] FootprintInMapCoords;
|
public readonly MPos[] Footprint;
|
||||||
public readonly CellRegion FootprintRegion;
|
public readonly CellRegion FootprintRegion;
|
||||||
public readonly WPos CenterPosition;
|
public readonly WPos CenterPosition;
|
||||||
public readonly Rectangle Bounds;
|
public readonly Rectangle Bounds;
|
||||||
@@ -40,10 +40,10 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
public bool Visible;
|
public bool Visible;
|
||||||
|
|
||||||
public FrozenActor(Actor self, CPos[] footprintInMapCoords, CellRegion footprintRegion)
|
public FrozenActor(Actor self, MPos[] footprint, CellRegion footprintRegion)
|
||||||
{
|
{
|
||||||
actor = self;
|
actor = self;
|
||||||
FootprintInMapCoords = footprintInMapCoords;
|
Footprint = footprint;
|
||||||
FootprintRegion = footprintRegion;
|
FootprintRegion = footprintRegion;
|
||||||
|
|
||||||
CenterPosition = self.CenterPosition;
|
CenterPosition = self.CenterPosition;
|
||||||
@@ -59,11 +59,11 @@ namespace OpenRA.Traits
|
|||||||
public void Tick(World world, Shroud shroud)
|
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.
|
// 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);
|
var isVisibleTest = shroud.IsVisibleTest(FootprintRegion);
|
||||||
Visible = true;
|
Visible = true;
|
||||||
foreach (var mapCoord in FootprintInMapCoords)
|
foreach (var uv in Footprint)
|
||||||
if (isVisibleTest(mapCoord.X, mapCoord.Y))
|
if (isVisibleTest(uv))
|
||||||
{
|
{
|
||||||
Visible = false;
|
Visible = false;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -57,12 +57,12 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
public int Hash { get; private set; }
|
public int Hash { get; private set; }
|
||||||
|
|
||||||
static readonly Func<int, int, bool> TruthPredicate = (u, v) => true;
|
static readonly Func<MPos, bool> TruthPredicate = _ => true;
|
||||||
readonly Func<int, int, bool> shroudEdgeTest;
|
readonly Func<MPos, bool> shroudEdgeTest;
|
||||||
readonly Func<int, int, bool> fastExploredTest;
|
readonly Func<MPos, bool> fastExploredTest;
|
||||||
readonly Func<int, int, bool> slowExploredTest;
|
readonly Func<MPos, bool> slowExploredTest;
|
||||||
readonly Func<int, int, bool> fastVisibleTest;
|
readonly Func<MPos, bool> fastVisibleTest;
|
||||||
readonly Func<int, int, bool> slowVisibleTest;
|
readonly Func<MPos, bool> slowVisibleTest;
|
||||||
|
|
||||||
public Shroud(Actor self)
|
public Shroud(Actor self)
|
||||||
{
|
{
|
||||||
@@ -81,7 +81,7 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
fogVisibilities = Exts.Lazy(() => self.TraitsImplementing<IFogVisibilityModifier>().ToArray());
|
fogVisibilities = Exts.Lazy(() => self.TraitsImplementing<IFogVisibilityModifier>().ToArray());
|
||||||
|
|
||||||
shroudEdgeTest = (u, v) => map.Contains(u, v);
|
shroudEdgeTest = map.Contains;
|
||||||
fastExploredTest = IsExploredCore;
|
fastExploredTest = IsExploredCore;
|
||||||
slowExploredTest = IsExplored;
|
slowExploredTest = IsExplored;
|
||||||
fastVisibleTest = IsVisibleCore;
|
fastVisibleTest = IsVisibleCore;
|
||||||
@@ -233,8 +233,8 @@ namespace OpenRA.Traits
|
|||||||
throw new ArgumentException("The map bounds of these shrouds do not match.", "s");
|
throw new ArgumentException("The map bounds of these shrouds do not match.", "s");
|
||||||
|
|
||||||
foreach (var uv in map.Cells.MapCoords)
|
foreach (var uv in map.Cells.MapCoords)
|
||||||
if (s.explored[uv.X, uv.Y])
|
if (s.explored[uv])
|
||||||
explored[uv.X, uv.Y] = true;
|
explored[uv] = true;
|
||||||
|
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
@@ -242,7 +242,7 @@ namespace OpenRA.Traits
|
|||||||
public void ExploreAll(World world)
|
public void ExploreAll(World world)
|
||||||
{
|
{
|
||||||
foreach (var uv in map.Cells.MapCoords)
|
foreach (var uv in map.Cells.MapCoords)
|
||||||
explored[uv.X, uv.Y] = true;
|
explored[uv] = true;
|
||||||
|
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
@@ -250,36 +250,35 @@ namespace OpenRA.Traits
|
|||||||
public void ResetExploration()
|
public void ResetExploration()
|
||||||
{
|
{
|
||||||
foreach (var uv in map.Cells.MapCoords)
|
foreach (var uv in map.Cells.MapCoords)
|
||||||
explored[uv.X, uv.Y] = visibleCount[uv.X, uv.Y] > 0;
|
explored[uv] = visibleCount[uv] > 0;
|
||||||
|
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsExplored(CPos cell)
|
public bool IsExplored(CPos cell)
|
||||||
{
|
{
|
||||||
var uv = Map.CellToMap(map.TileShape, cell);
|
return IsExplored(cell.ToMPos(map));
|
||||||
return IsExplored(uv.X, uv.Y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsExplored(int u, int v)
|
public bool IsExplored(MPos uv)
|
||||||
{
|
{
|
||||||
if (!map.Contains(u, v))
|
if (!map.Contains(uv))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!ShroudEnabled)
|
if (!ShroudEnabled)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return IsExploredCore(u, v);
|
return IsExploredCore(uv);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShroudEnabled { get { return !Disabled && self.World.LobbyInfo.GlobalSettings.Shroud; } }
|
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 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))
|
if (!map.Cells.Contains(region))
|
||||||
@@ -300,29 +299,29 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
public bool IsVisible(CPos cell)
|
public bool IsVisible(CPos cell)
|
||||||
{
|
{
|
||||||
var uv = Map.CellToMap(map.TileShape, cell);
|
var uv = cell.ToMPos(map);
|
||||||
return IsVisible(uv.X, uv.Y);
|
return IsVisible(uv);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsVisible(int u, int v)
|
bool IsVisible(MPos uv)
|
||||||
{
|
{
|
||||||
if (!map.Contains(u, v))
|
if (!map.Contains(uv))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!FogEnabled)
|
if (!FogEnabled)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return IsVisibleCore(u, v);
|
return IsVisibleCore(uv);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FogEnabled { get { return !Disabled && self.World.LobbyInfo.GlobalSettings.Fog; } }
|
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 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))
|
if (!map.Cells.Contains(region))
|
||||||
|
|||||||
@@ -133,9 +133,9 @@ namespace OpenRA.Widgets
|
|||||||
{
|
{
|
||||||
var preview = Preview();
|
var preview = Preview();
|
||||||
var tileShape = Game.ModData.Manifest.TileShape;
|
var tileShape = Game.ModData.Manifest.TileShape;
|
||||||
var point = Map.CellToMap(tileShape, cell);
|
var point = cell.ToMPos(tileShape);
|
||||||
var dx = (int)(previewScale * (point.X - preview.Bounds.Left));
|
var dx = (int)(previewScale * (point.U - preview.Bounds.Left));
|
||||||
var dy = (int)(previewScale * (point.Y - preview.Bounds.Top));
|
var dy = (int)(previewScale * (point.V - preview.Bounds.Top));
|
||||||
return new int2(mapRect.X + dx, mapRect.Y + dy);
|
return new int2(mapRect.X + dx, mapRect.Y + dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
public class World
|
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();
|
internal readonly TraitDictionary TraitDict = new TraitDictionary();
|
||||||
readonly HashSet<Actor> actors = new HashSet<Actor>();
|
readonly HashSet<Actor> actors = new HashSet<Actor>();
|
||||||
readonly List<IEffect> effects = new List<IEffect>();
|
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 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(Actor a) { return RenderPlayer != null && !RenderPlayer.Shroud.IsExplored(a); }
|
||||||
public bool ShroudObscures(CPos p) { return RenderPlayer != null && !RenderPlayer.Shroud.IsExplored(p); }
|
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;
|
var rp = RenderPlayer;
|
||||||
if (rp == null)
|
if (rp == null)
|
||||||
return FalsePredicate;
|
return FalsePredicate;
|
||||||
var predicate = rp.Shroud.IsVisibleTest(region);
|
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;
|
var rp = RenderPlayer;
|
||||||
if (rp == null)
|
if (rp == null)
|
||||||
return FalsePredicate;
|
return FalsePredicate;
|
||||||
var predicate = rp.Shroud.IsExploredTest(region);
|
var predicate = rp.Shroud.IsExploredTest(region);
|
||||||
return (u, v) => !predicate(u, v);
|
return uv => !predicate(uv);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsReplay
|
public bool IsReplay
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
[Sync] public int VisibilityHash;
|
[Sync] public int VisibilityHash;
|
||||||
|
|
||||||
readonly bool startsRevealed;
|
readonly bool startsRevealed;
|
||||||
readonly CPos[] footprintInMapsCoords;
|
readonly MPos[] footprint;
|
||||||
readonly CellRegion footprintRegion;
|
readonly CellRegion footprintRegion;
|
||||||
|
|
||||||
readonly Lazy<IToolTip> tooltip;
|
readonly Lazy<IToolTip> tooltip;
|
||||||
@@ -44,9 +44,9 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
{
|
{
|
||||||
// Spawned actors (e.g. building husks) shouldn't be revealed
|
// Spawned actors (e.g. building husks) shouldn't be revealed
|
||||||
startsRevealed = info.StartsRevealed && !init.Contains<ParentActorInit>();
|
startsRevealed = info.StartsRevealed && !init.Contains<ParentActorInit>();
|
||||||
var footprint = FootprintUtils.Tiles(init.Self).ToList();
|
var footprintCells = FootprintUtils.Tiles(init.Self).ToList();
|
||||||
footprintInMapsCoords = footprint.Select(cell => Map.CellToMap(init.World.Map.TileShape, cell)).ToArray();
|
footprint = footprintCells.Select(cell => cell.ToMPos(init.World.Map)).ToArray();
|
||||||
footprintRegion = CellRegion.BoundingRegion(init.World.Map.TileShape, footprint);
|
footprintRegion = CellRegion.BoundingRegion(init.World.Map.TileShape, footprintCells);
|
||||||
tooltip = Exts.Lazy(() => init.Self.TraitsImplementing<IToolTip>().FirstOrDefault());
|
tooltip = Exts.Lazy(() => init.Self.TraitsImplementing<IToolTip>().FirstOrDefault());
|
||||||
tooltip = Exts.Lazy(() => init.Self.TraitsImplementing<IToolTip>().FirstOrDefault());
|
tooltip = Exts.Lazy(() => init.Self.TraitsImplementing<IToolTip>().FirstOrDefault());
|
||||||
health = Exts.Lazy(() => init.Self.TraitOrDefault<Health>());
|
health = Exts.Lazy(() => init.Self.TraitOrDefault<Health>());
|
||||||
@@ -69,11 +69,11 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
foreach (var p in self.World.Players)
|
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.
|
// 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 isVisibleTest = p.Shroud.IsVisibleTest(footprintRegion);
|
||||||
var isVisible = false;
|
var isVisible = false;
|
||||||
foreach (var mapCoord in footprintInMapsCoords)
|
foreach (var uv in footprint)
|
||||||
if (isVisibleTest(mapCoord.X, mapCoord.Y))
|
if (isVisibleTest(uv))
|
||||||
{
|
{
|
||||||
isVisible = true;
|
isVisible = true;
|
||||||
break;
|
break;
|
||||||
@@ -89,7 +89,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
foreach (var p in self.World.Players)
|
foreach (var p in self.World.Players)
|
||||||
{
|
{
|
||||||
visible[p] |= startsRevealed;
|
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;
|
initialized = true;
|
||||||
|
|||||||
@@ -334,7 +334,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
defaultCellInfoLayer = new CellLayer<CellInfo>(map);
|
defaultCellInfoLayer = new CellLayer<CellInfo>(map);
|
||||||
for (var v = 0; v < mapSize.Height; v++)
|
for (var v = 0; v < mapSize.Height; v++)
|
||||||
for (var u = 0; u < mapSize.Width; u++)
|
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);
|
result.CopyValuesFrom(defaultCellInfoLayer);
|
||||||
|
|||||||
@@ -36,12 +36,12 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
var shroudObscured = world.ShroudObscuresTest(wr.Viewport.VisibleCells);
|
var shroudObscured = world.ShroudObscuresTest(wr.Viewport.VisibleCells);
|
||||||
foreach (var uv in wr.Viewport.VisibleCells.MapCoords)
|
foreach (var uv in wr.Viewport.VisibleCells.MapCoords)
|
||||||
{
|
{
|
||||||
if (shroudObscured(uv.X, uv.Y))
|
if (shroudObscured(uv))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var c = render[uv.X, uv.Y];
|
var c = render[uv];
|
||||||
if (c.Sprite != null)
|
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
|
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;
|
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;
|
return notVisibleEdges;
|
||||||
|
|
||||||
var cell = Map.MapToCell(map.TileShape, new CPos(u, v));
|
var cell = uv.ToCPos(map);
|
||||||
Func<CPos, bool> isCellVisible = c =>
|
Func<CPos, bool> isCellVisible = c => isVisible(c.ToMPos(map));
|
||||||
{
|
|
||||||
var uv = Map.CellToMap(map.TileShape, c);
|
|
||||||
return isVisible(uv.X, uv.Y);
|
|
||||||
};
|
|
||||||
|
|
||||||
// If a side is shrouded then we also count the corners
|
// If a side is shrouded then we also count the corners
|
||||||
var edge = Edges.None;
|
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
|
// 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)
|
foreach (var uv in CellRegion.Expand(w.Map.Cells, 1).MapCoords)
|
||||||
{
|
{
|
||||||
var u = uv.X;
|
var screen = wr.ScreenPosition(w.Map.CenterOfCell(uv.ToCPos(map)));
|
||||||
var v = uv.Y;
|
|
||||||
var screen = wr.ScreenPosition(w.Map.CenterOfCell(Map.MapToCell(map.TileShape, uv)));
|
|
||||||
var variant = (byte)Game.CosmeticRandom.Next(info.ShroudVariants.Length);
|
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
|
// 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);
|
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);
|
var visibleUnderFog = shroud.IsVisibleTest(updatedRegion);
|
||||||
foreach (var uv in updatedRegion.MapCoords)
|
foreach (var uv in updatedRegion.MapCoords)
|
||||||
{
|
{
|
||||||
var u = uv.X;
|
var shrouded = GetEdges(uv, visibleUnderShroud);
|
||||||
var v = uv.Y;
|
var fogged = GetEdges(uv, visibleUnderFog);
|
||||||
var shrouded = GetEdges(u, v, visibleUnderShroud);
|
var shroudTile = tiles[uv];
|
||||||
var fogged = GetEdges(u, v, visibleUnderFog);
|
|
||||||
var shroudTile = tiles[u, v];
|
|
||||||
var variant = shroudTile.Variant;
|
var variant = shroudTile.Variant;
|
||||||
shroudTile.Shroud = GetTile(shroudSprites, shrouded, variant);
|
shroudTile.Shroud = GetTile(shroudSprites, shrouded, variant);
|
||||||
shroudTile.Fog = GetTile(fogSprites, fogged, 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)
|
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)
|
if (t.Shroud != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -84,10 +84,10 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
foreach (var uv in wr.Viewport.VisibleCells.MapCoords)
|
foreach (var uv in wr.Viewport.VisibleCells.MapCoords)
|
||||||
{
|
{
|
||||||
var lr = Game.Renderer.WorldLineRenderer;
|
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 height = (int)wr.World.Map.MapHeight.Value[uv];
|
||||||
var tile = wr.World.Map.MapTiles.Value[uv.X, uv.Y];
|
var tile = wr.World.Map.MapTiles.Value[uv];
|
||||||
|
|
||||||
TerrainTileInfo tileInfo = null;
|
TerrainTileInfo tileInfo = null;
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
void UpdateTerrainCell(CPos cell)
|
void UpdateTerrainCell(CPos cell)
|
||||||
{
|
{
|
||||||
var stride = radarSheet.Size.Width;
|
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 terrain = world.Map.GetTerrainInfo(cell);
|
||||||
|
|
||||||
var dx = terrainSprite.Bounds.Left - world.Map.Bounds.Left;
|
var dx = terrainSprite.Bounds.Left - world.Map.Bounds.Left;
|
||||||
@@ -102,7 +102,7 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
fixed (byte* colorBytes = &radarData[0])
|
fixed (byte* colorBytes = &radarData[0])
|
||||||
{
|
{
|
||||||
var colors = (int*)colorBytes;
|
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)
|
void UpdateShroudCell(CPos cell)
|
||||||
{
|
{
|
||||||
var stride = radarSheet.Size.Width;
|
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 dx = shroudSprite.Bounds.Left - world.Map.Bounds.Left;
|
||||||
var dy = shroudSprite.Bounds.Top - world.Map.Bounds.Top;
|
var dy = shroudSprite.Bounds.Top - world.Map.Bounds.Top;
|
||||||
|
|
||||||
@@ -125,7 +125,7 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
fixed (byte* colorBytes = &radarData[0])
|
fixed (byte* colorBytes = &radarData[0])
|
||||||
{
|
{
|
||||||
var colors = (int*)colorBytes;
|
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);
|
var color = t.Trait.RadarSignatureColor(t.Actor);
|
||||||
foreach (var cell in t.Trait.RadarSignatureCells(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))
|
if (world.Map.Bounds.Contains(uv.U, uv.V))
|
||||||
colors[(uv.Y + dy) * stride + uv.X + dx] = color.ToArgb();
|
colors[(uv.V + dy) * stride + uv.U + dx] = color.ToArgb();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -329,10 +329,9 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
|
|
||||||
int2 CellToMinimapPixel(CPos p)
|
int2 CellToMinimapPixel(CPos p)
|
||||||
{
|
{
|
||||||
var mapOrigin = new CVec(world.Map.Bounds.Left, world.Map.Bounds.Top);
|
var uv = p.ToMPos(world.Map);
|
||||||
var mapOffset = Map.CellToMap(world.Map.TileShape, p) - mapOrigin;
|
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();
|
||||||
return new int2(mapRect.X, mapRect.Y) + (previewScale * new float2(mapOffset.X, mapOffset.Y)).ToInt2();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CPos MinimapPixelToCell(int2 p)
|
CPos MinimapPixelToCell(int2 p)
|
||||||
@@ -340,7 +339,7 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
var viewOrigin = new float2(mapRect.X, mapRect.Y);
|
var viewOrigin = new float2(mapRect.X, mapRect.Y);
|
||||||
var mapOrigin = new float2(world.Map.Bounds.Left, world.Map.Bounds.Top);
|
var mapOrigin = new float2(world.Map.Bounds.Left, world.Map.Bounds.Top);
|
||||||
var fcell = mapOrigin + (1f / previewScale) * (p - viewOrigin);
|
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