Convert some keys users of CellLayer to index via map-coords for efficiency.
This commit is contained in:
@@ -182,13 +182,13 @@ namespace OpenRA.Graphics
|
|||||||
var stride = bitmapData.Stride / 4;
|
var stride = bitmapData.Stride / 4;
|
||||||
var shroudObscured = world.ShroudObscuresTest(map.Cells);
|
var shroudObscured = world.ShroudObscuresTest(map.Cells);
|
||||||
var fogObscured = world.FogObscuresTest(map.Cells);
|
var fogObscured = world.FogObscuresTest(map.Cells);
|
||||||
foreach (var cell in map.Cells)
|
foreach (var uv in map.Cells.MapCoords)
|
||||||
{
|
{
|
||||||
var uv = Map.CellToMap(map.TileShape, cell) - offset;
|
var bitmapUv = uv - offset;
|
||||||
if (shroudObscured(cell))
|
if (shroudObscured(uv.X, uv.Y))
|
||||||
colors[uv.Y * stride + uv.X] = shroud;
|
colors[bitmapUv.Y * stride + bitmapUv.X] = shroud;
|
||||||
else if (fogObscured(cell))
|
else if (fogObscured(uv.X, uv.Y))
|
||||||
colors[uv.Y * stride + uv.X] = fog;
|
colors[bitmapUv.Y * stride + bitmapUv.X] = fog;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -366,8 +366,8 @@ namespace OpenRA
|
|||||||
Cells = new CellRegion(TileShape, tl, br);
|
Cells = new CellRegion(TileShape, tl, br);
|
||||||
|
|
||||||
CustomTerrain = new CellLayer<byte>(this);
|
CustomTerrain = new CellLayer<byte>(this);
|
||||||
foreach (var cell in Cells)
|
foreach (var uv in Cells.MapCoords)
|
||||||
CustomTerrain[cell] = byte.MaxValue;
|
CustomTerrain[uv.X, uv.Y] = byte.MaxValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Ruleset PreloadRules()
|
public Ruleset PreloadRules()
|
||||||
@@ -597,7 +597,12 @@ namespace OpenRA
|
|||||||
public bool Contains(CPos cell)
|
public bool Contains(CPos cell)
|
||||||
{
|
{
|
||||||
var uv = CellToMap(TileShape, cell);
|
var uv = CellToMap(TileShape, cell);
|
||||||
return Bounds.Contains(uv.X, uv.Y);
|
return Contains(uv.X, uv.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Contains(int u, int v)
|
||||||
|
{
|
||||||
|
return Bounds.Contains(u, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
public WPos CenterOfCell(CPos cell)
|
public WPos CenterOfCell(CPos cell)
|
||||||
@@ -795,8 +800,11 @@ namespace OpenRA
|
|||||||
|
|
||||||
public byte GetTerrainIndex(CPos cell)
|
public byte GetTerrainIndex(CPos cell)
|
||||||
{
|
{
|
||||||
var custom = CustomTerrain[cell];
|
var uv = Map.CellToMap(TileShape, cell);
|
||||||
return custom != byte.MaxValue ? custom : cachedTileSet.Value.GetTerrainIndex(MapTiles.Value[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]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TerrainTypeInfo GetTerrainInfo(CPos cell)
|
public TerrainTypeInfo GetTerrainInfo(CPos cell)
|
||||||
|
|||||||
@@ -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.Footprint.All(c => world.ShroudObscures(c)))
|
.Where(a => a.Info.Traits.Contains<ITargetableInfo>() && !a.FootprintInMapCoords.All(uv => world.ShroudObscures(uv.X, uv.Y)))
|
||||||
.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.Footprint.All(c => world.ShroudObscures(c)))
|
.Where(a => a.Info.Traits.Contains<ITargetableInfo>() && !a.FootprintInMapCoords.All(uv => world.ShroudObscures(uv.X, uv.Y)))
|
||||||
.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[] Footprint;
|
public readonly CPos[] FootprintInMapCoords;
|
||||||
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[] footprint, CellRegion footprintRegion)
|
public FrozenActor(Actor self, CPos[] footprintInMapCoords, CellRegion footprintRegion)
|
||||||
{
|
{
|
||||||
actor = self;
|
actor = self;
|
||||||
Footprint = footprint;
|
FootprintInMapCoords = footprintInMapCoords;
|
||||||
FootprintRegion = footprintRegion;
|
FootprintRegion = footprintRegion;
|
||||||
|
|
||||||
CenterPosition = self.CenterPosition;
|
CenterPosition = self.CenterPosition;
|
||||||
@@ -58,7 +58,17 @@ namespace OpenRA.Traits
|
|||||||
int flashTicks;
|
int flashTicks;
|
||||||
public void Tick(World world, Shroud shroud)
|
public void Tick(World world, Shroud shroud)
|
||||||
{
|
{
|
||||||
Visible = !Footprint.Any(shroud.IsVisibleTest(FootprintRegion));
|
// 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));
|
||||||
|
var isVisibleTest = shroud.IsVisibleTest(FootprintRegion);
|
||||||
|
Visible = true;
|
||||||
|
foreach (var mapCoord in FootprintInMapCoords)
|
||||||
|
if (isVisibleTest(mapCoord.X, mapCoord.Y))
|
||||||
|
{
|
||||||
|
Visible = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (flashTicks > 0)
|
if (flashTicks > 0)
|
||||||
flashTicks--;
|
flashTicks--;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,12 +57,12 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
public int Hash { get; private set; }
|
public int Hash { get; private set; }
|
||||||
|
|
||||||
static readonly Func<CPos, bool> TruthPredicate = cell => true;
|
static readonly Func<int, int, bool> TruthPredicate = (u, v) => true;
|
||||||
readonly Func<CPos, bool> shroudEdgeTest;
|
readonly Func<int, int, bool> shroudEdgeTest;
|
||||||
readonly Func<CPos, bool> fastExploredTest;
|
readonly Func<int, int, bool> fastExploredTest;
|
||||||
readonly Func<CPos, bool> slowExploredTest;
|
readonly Func<int, int, bool> slowExploredTest;
|
||||||
readonly Func<CPos, bool> fastVisibleTest;
|
readonly Func<int, int, bool> fastVisibleTest;
|
||||||
readonly Func<CPos, bool> slowVisibleTest;
|
readonly Func<int, int, 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 = cell => map.Contains(cell);
|
shroudEdgeTest = (u, v) => map.Contains(u, v);
|
||||||
fastExploredTest = IsExploredCore;
|
fastExploredTest = IsExploredCore;
|
||||||
slowExploredTest = IsExplored;
|
slowExploredTest = IsExplored;
|
||||||
fastVisibleTest = IsVisibleCore;
|
fastVisibleTest = IsVisibleCore;
|
||||||
@@ -232,49 +232,54 @@ namespace OpenRA.Traits
|
|||||||
if (map.Bounds != s.map.Bounds)
|
if (map.Bounds != s.map.Bounds)
|
||||||
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 cell in map.Cells)
|
foreach (var uv in map.Cells.MapCoords)
|
||||||
if (s.explored[cell])
|
if (s.explored[uv.X, uv.Y])
|
||||||
explored[cell] = true;
|
explored[uv.X, uv.Y] = true;
|
||||||
|
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ExploreAll(World world)
|
public void ExploreAll(World world)
|
||||||
{
|
{
|
||||||
foreach (var cell in map.Cells)
|
foreach (var uv in map.Cells.MapCoords)
|
||||||
explored[cell] = true;
|
explored[uv.X, uv.Y] = true;
|
||||||
|
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetExploration()
|
public void ResetExploration()
|
||||||
{
|
{
|
||||||
foreach (var cell in map.Cells)
|
foreach (var uv in map.Cells.MapCoords)
|
||||||
explored[cell] = visibleCount[cell] > 0;
|
explored[uv.X, uv.Y] = visibleCount[uv.X, uv.Y] > 0;
|
||||||
|
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsExplored(CPos cell)
|
public bool IsExplored(CPos cell)
|
||||||
{
|
{
|
||||||
if (!map.Contains(cell))
|
var uv = Map.CellToMap(map.TileShape, cell);
|
||||||
|
return IsExplored(uv.X, uv.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsExplored(int u, int v)
|
||||||
|
{
|
||||||
|
if (!map.Contains(u, v))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!ShroudEnabled)
|
if (!ShroudEnabled)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return IsExploredCore(cell);
|
return IsExploredCore(u, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShroudEnabled { get { return !Disabled && self.World.LobbyInfo.GlobalSettings.Shroud; } }
|
bool ShroudEnabled { get { return !Disabled && self.World.LobbyInfo.GlobalSettings.Shroud; } }
|
||||||
|
|
||||||
bool IsExploredCore(CPos cell)
|
bool IsExploredCore(int u, int v)
|
||||||
{
|
{
|
||||||
var uv = Map.CellToMap(map.TileShape, cell);
|
return explored[u, v] && (generatedShroudCount[u, v] == 0 || visibleCount[u, v] > 0);
|
||||||
return explored[uv.X, uv.Y] && (generatedShroudCount[uv.X, uv.Y] == 0 || visibleCount[uv.X, uv.Y] > 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Func<CPos, bool> IsExploredTest(CellRegion region)
|
public Func<int, int, 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))
|
||||||
@@ -295,23 +300,29 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
public bool IsVisible(CPos cell)
|
public bool IsVisible(CPos cell)
|
||||||
{
|
{
|
||||||
if (!map.Contains(cell))
|
var uv = Map.CellToMap(map.TileShape, cell);
|
||||||
|
return IsVisible(uv.X, uv.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsVisible(int u, int v)
|
||||||
|
{
|
||||||
|
if (!map.Contains(u, v))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!FogEnabled)
|
if (!FogEnabled)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return IsVisibleCore(cell);
|
return IsVisibleCore(u, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FogEnabled { get { return !Disabled && self.World.LobbyInfo.GlobalSettings.Fog; } }
|
bool FogEnabled { get { return !Disabled && self.World.LobbyInfo.GlobalSettings.Fog; } }
|
||||||
|
|
||||||
bool IsVisibleCore(CPos cell)
|
bool IsVisibleCore(int u, int v)
|
||||||
{
|
{
|
||||||
return visibleCount[cell] > 0;
|
return visibleCount[u, v] > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Func<CPos, bool> IsVisibleTest(CellRegion region)
|
public Func<int, int, 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))
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
public class World
|
public class World
|
||||||
{
|
{
|
||||||
static readonly Func<CPos, bool> FalsePredicate = cell => false;
|
static readonly Func<int, int, bool> FalsePredicate = (u, v) => 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,23 +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 Func<CPos, bool> FogObscuresTest(CellRegion region)
|
public Func<int, int, 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 cell => !predicate(cell);
|
return (u, v) => !predicate(u, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Func<CPos, bool> ShroudObscuresTest(CellRegion region)
|
public Func<int, int, 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 cell => !predicate(cell);
|
return (u, v) => !predicate(u, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsReplay
|
public bool IsReplay
|
||||||
|
|||||||
@@ -151,23 +151,30 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
notVisibleEdges = info.UseExtendedIndex ? Edges.AllSides : Edges.AllCorners;
|
notVisibleEdges = info.UseExtendedIndex ? Edges.AllSides : Edges.AllCorners;
|
||||||
}
|
}
|
||||||
|
|
||||||
Edges GetEdges(CPos p, Func<CPos, bool> isVisible)
|
Edges GetEdges(int u, int v, Func<int, int, bool> isVisible)
|
||||||
{
|
{
|
||||||
if (!isVisible(p))
|
if (!isVisible(u, v))
|
||||||
return notVisibleEdges;
|
return notVisibleEdges;
|
||||||
|
|
||||||
// If a side is shrouded then we also count the corners
|
var cell = Map.MapToCell(map.TileShape, new CPos(u, v));
|
||||||
var u = Edges.None;
|
Func<CPos, bool> isCellVisible = c =>
|
||||||
if (!isVisible(p + new CVec(0, -1))) u |= Edges.Top;
|
{
|
||||||
if (!isVisible(p + new CVec(1, 0))) u |= Edges.Right;
|
var uv = Map.CellToMap(map.TileShape, c);
|
||||||
if (!isVisible(p + new CVec(0, 1))) u |= Edges.Bottom;
|
return isVisible(uv.X, uv.Y);
|
||||||
if (!isVisible(p + new CVec(-1, 0))) u |= Edges.Left;
|
};
|
||||||
|
|
||||||
var ucorner = u & Edges.AllCorners;
|
// If a side is shrouded then we also count the corners
|
||||||
if (!isVisible(p + new CVec(-1, -1))) u |= Edges.TopLeft;
|
var edge = Edges.None;
|
||||||
if (!isVisible(p + new CVec(1, -1))) u |= Edges.TopRight;
|
if (!isCellVisible(cell + new CVec(0, -1))) edge |= Edges.Top;
|
||||||
if (!isVisible(p + new CVec(1, 1))) u |= Edges.BottomRight;
|
if (!isCellVisible(cell + new CVec(1, 0))) edge |= Edges.Right;
|
||||||
if (!isVisible(p + new CVec(-1, 1))) u |= Edges.BottomLeft;
|
if (!isCellVisible(cell + new CVec(0, 1))) edge |= Edges.Bottom;
|
||||||
|
if (!isCellVisible(cell + new CVec(-1, 0))) edge |= Edges.Left;
|
||||||
|
|
||||||
|
var ucorner = edge & Edges.AllCorners;
|
||||||
|
if (!isCellVisible(cell + new CVec(-1, -1))) edge |= Edges.TopLeft;
|
||||||
|
if (!isCellVisible(cell + new CVec(1, -1))) edge |= Edges.TopRight;
|
||||||
|
if (!isCellVisible(cell + new CVec(1, 1))) edge |= Edges.BottomRight;
|
||||||
|
if (!isCellVisible(cell + new CVec(-1, 1))) edge |= Edges.BottomLeft;
|
||||||
|
|
||||||
// RA provides a set of frames for tiles with shrouded
|
// RA provides a set of frames for tiles with shrouded
|
||||||
// corners but unshrouded edges. We want to detect this
|
// corners but unshrouded edges. We want to detect this
|
||||||
@@ -175,7 +182,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
// in other combinations. The XOR turns off the corner
|
// in other combinations. The XOR turns off the corner
|
||||||
// bits that are enabled twice, which gives the behavior
|
// bits that are enabled twice, which gives the behavior
|
||||||
// we want here.
|
// we want here.
|
||||||
return info.UseExtendedIndex ? u ^ ucorner : u & Edges.AllCorners;
|
return info.UseExtendedIndex ? edge ^ ucorner : edge & Edges.AllCorners;
|
||||||
}
|
}
|
||||||
|
|
||||||
Edges GetObserverEdges(CPos p)
|
Edges GetObserverEdges(CPos p)
|
||||||
@@ -199,18 +206,20 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
{
|
{
|
||||||
// Initialize tile cache
|
// Initialize tile cache
|
||||||
// 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 cell in CellRegion.Expand(w.Map.Cells, 1))
|
foreach (var uv in CellRegion.Expand(w.Map.Cells, 1).MapCoords)
|
||||||
{
|
{
|
||||||
var screen = wr.ScreenPosition(w.Map.CenterOfCell(cell));
|
var u = uv.X;
|
||||||
|
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[cell] = new ShroudTile(screen, variant);
|
tiles[u, v] = 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(cell))
|
if (!map.Contains(u, v))
|
||||||
{
|
{
|
||||||
var shroudTile = tiles[cell];
|
var shroudTile = tiles[u, v];
|
||||||
shroudTile.Shroud = GetTile(shroudSprites, notVisibleEdges, variant);
|
shroudTile.Shroud = GetTile(shroudSprites, notVisibleEdges, variant);
|
||||||
tiles[cell] = shroudTile;
|
tiles[u, v] = shroudTile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,15 +261,17 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
{
|
{
|
||||||
var visibleUnderShroud = shroud.IsExploredTest(updatedRegion);
|
var visibleUnderShroud = shroud.IsExploredTest(updatedRegion);
|
||||||
var visibleUnderFog = shroud.IsVisibleTest(updatedRegion);
|
var visibleUnderFog = shroud.IsVisibleTest(updatedRegion);
|
||||||
foreach (var cell in updatedRegion)
|
foreach (var uv in updatedRegion.MapCoords)
|
||||||
{
|
{
|
||||||
var shrouded = GetEdges(cell, visibleUnderShroud);
|
var u = uv.X;
|
||||||
var fogged = GetEdges(cell, visibleUnderFog);
|
var v = uv.Y;
|
||||||
var shroudTile = tiles[cell];
|
var shrouded = GetEdges(u, v, visibleUnderShroud);
|
||||||
|
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[cell] = shroudTile;
|
tiles[u, v] = shroudTile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,9 +292,9 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
{
|
{
|
||||||
Update(shroud, wr.Viewport.VisibleCells);
|
Update(shroud, wr.Viewport.VisibleCells);
|
||||||
|
|
||||||
foreach (var cell in CellRegion.Expand(wr.Viewport.VisibleCells, 1))
|
foreach (var uv in CellRegion.Expand(wr.Viewport.VisibleCells, 1).MapCoords)
|
||||||
{
|
{
|
||||||
var t = tiles[cell];
|
var t = tiles[uv.X, uv.Y];
|
||||||
|
|
||||||
if (t.Shroud != null)
|
if (t.Shroud != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -81,13 +81,13 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
var rightDelta = ts == TileShape.Diamond ? new WVec(512, 0, 0) : new WVec(512, 512, 0);
|
var rightDelta = ts == TileShape.Diamond ? new WVec(512, 0, 0) : new WVec(512, 512, 0);
|
||||||
var bottomDelta = ts == TileShape.Diamond ? new WVec(0, 512, 0) : new WVec(-512, 512, 0);
|
var bottomDelta = ts == TileShape.Diamond ? new WVec(0, 512, 0) : new WVec(-512, 512, 0);
|
||||||
|
|
||||||
foreach (var cell in wr.Viewport.VisibleCells)
|
foreach (var uv in wr.Viewport.VisibleCells.MapCoords)
|
||||||
{
|
{
|
||||||
var lr = Game.Renderer.WorldLineRenderer;
|
var lr = Game.Renderer.WorldLineRenderer;
|
||||||
var pos = wr.world.Map.CenterOfCell(cell);
|
var pos = wr.world.Map.CenterOfCell(Map.MapToCell(wr.world.Map.TileShape, uv));
|
||||||
|
|
||||||
var height = (int)wr.world.Map.MapHeight.Value[cell];
|
var height = (int)wr.world.Map.MapHeight.Value[uv.X, uv.Y];
|
||||||
var tile = wr.world.Map.MapTiles.Value[cell];
|
var tile = wr.world.Map.MapTiles.Value[uv.X, uv.Y];
|
||||||
|
|
||||||
TerrainTileInfo tileInfo = null;
|
TerrainTileInfo tileInfo = null;
|
||||||
|
|
||||||
|
|||||||
@@ -332,8 +332,8 @@ namespace OpenRA.Mods.RA.Move
|
|||||||
defaultCellInfoLayer.Shape != map.TileShape)
|
defaultCellInfoLayer.Shape != map.TileShape)
|
||||||
{
|
{
|
||||||
defaultCellInfoLayer = new CellLayer<CellInfo>(map);
|
defaultCellInfoLayer = new CellLayer<CellInfo>(map);
|
||||||
foreach (var cell in map.Cells)
|
foreach (var uv in map.Cells.MapCoords)
|
||||||
defaultCellInfoLayer[cell] = new CellInfo(int.MaxValue, cell, false);
|
defaultCellInfoLayer[uv.X, uv.Y] = new CellInfo(int.MaxValue, Map.MapToCell(map.TileShape, uv), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
result.CopyValuesFrom(defaultCellInfoLayer);
|
result.CopyValuesFrom(defaultCellInfoLayer);
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ namespace OpenRA.Mods.RA.Traits
|
|||||||
[Sync] public int VisibilityHash;
|
[Sync] public int VisibilityHash;
|
||||||
|
|
||||||
readonly bool startsRevealed;
|
readonly bool startsRevealed;
|
||||||
readonly CPos[] footprint;
|
readonly CPos[] footprintInMapsCoords;
|
||||||
readonly CellRegion footprintRegion;
|
readonly CellRegion footprintRegion;
|
||||||
|
|
||||||
readonly Lazy<IToolTip> tooltip;
|
readonly Lazy<IToolTip> tooltip;
|
||||||
@@ -45,7 +45,8 @@ namespace OpenRA.Mods.RA.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>();
|
||||||
footprint = FootprintUtils.Tiles(init.self).ToArray();
|
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);
|
footprintRegion = CellRegion.BoundingRegion(init.world.Map.TileShape, footprint);
|
||||||
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());
|
||||||
@@ -68,7 +69,17 @@ namespace OpenRA.Mods.RA.Traits
|
|||||||
VisibilityHash = 0;
|
VisibilityHash = 0;
|
||||||
foreach (var p in self.World.Players)
|
foreach (var p in self.World.Players)
|
||||||
{
|
{
|
||||||
var isVisible = footprint.Any(p.Shroud.IsVisibleTest(footprintRegion));
|
// 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 isVisibleTest = p.Shroud.IsVisibleTest(footprintRegion);
|
||||||
|
var isVisible = false;
|
||||||
|
foreach (var mapCoord in footprintInMapsCoords)
|
||||||
|
if (isVisibleTest(mapCoord.X, mapCoord.Y))
|
||||||
|
{
|
||||||
|
isVisible = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
visible[p] = isVisible;
|
visible[p] = isVisible;
|
||||||
if (isVisible)
|
if (isVisible)
|
||||||
VisibilityHash += p.ClientIndex;
|
VisibilityHash += p.ClientIndex;
|
||||||
@@ -79,7 +90,7 @@ namespace OpenRA.Mods.RA.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, footprint, footprintRegion));
|
p.PlayerActor.Trait<FrozenActorLayer>().Add(frozen[p] = new FrozenActor(self, footprintInMapsCoords, footprintRegion));
|
||||||
}
|
}
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
|||||||
@@ -35,14 +35,14 @@ namespace OpenRA.Mods.RA.Traits
|
|||||||
public void Render(WorldRenderer wr)
|
public void Render(WorldRenderer wr)
|
||||||
{
|
{
|
||||||
var shroudObscured = world.ShroudObscuresTest(wr.Viewport.VisibleCells);
|
var shroudObscured = world.ShroudObscuresTest(wr.Viewport.VisibleCells);
|
||||||
foreach (var cell in wr.Viewport.VisibleCells)
|
foreach (var uv in wr.Viewport.VisibleCells.MapCoords)
|
||||||
{
|
{
|
||||||
if (shroudObscured(cell))
|
if (shroudObscured(uv.X, uv.Y))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var c = render[cell];
|
var c = render[uv.X, uv.Y];
|
||||||
if (c.Sprite != null)
|
if (c.Sprite != null)
|
||||||
new SpriteRenderable(c.Sprite, wr.world.Map.CenterOfCell(cell),
|
new SpriteRenderable(c.Sprite, wr.world.Map.CenterOfCell(Map.MapToCell(world.Map.TileShape, uv)),
|
||||||
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user