diff --git a/OpenRA.Game/Graphics/Minimap.cs b/OpenRA.Game/Graphics/Minimap.cs index b0642a4d91..5b011317aa 100644 --- a/OpenRA.Game/Graphics/Minimap.cs +++ b/OpenRA.Game/Graphics/Minimap.cs @@ -180,8 +180,8 @@ namespace OpenRA.Graphics { var colors = (int*)bitmapData.Scan0; var stride = bitmapData.Stride / 4; - var shroudObscured = world.ShroudObscuresTest(map.CellsInsideBounds); - var fogObscured = world.FogObscuresTest(map.CellsInsideBounds); + var shroudObscured = world.ShroudObscuresTest; + var fogObscured = world.FogObscuresTest; foreach (var uv in map.CellsInsideBounds.MapCoords) { var bitmapXy = new int2(uv.U - b.Left, uv.V - b.Top); diff --git a/OpenRA.Game/Traits/Player/FrozenActorLayer.cs b/OpenRA.Game/Traits/Player/FrozenActorLayer.cs index 20bbc54487..30c7cb3378 100644 --- a/OpenRA.Game/Traits/Player/FrozenActorLayer.cs +++ b/OpenRA.Game/Traits/Player/FrozenActorLayer.cs @@ -42,12 +42,16 @@ namespace OpenRA.Traits public bool NeedRenderables; public bool IsRendering { get; private set; } - public FrozenActor(Actor self, MPos[] footprint, CellRegion footprintRegion, Shroud shroud) + public FrozenActor(Actor self, MPos[] footprint, Shroud shroud) { actor = self; - isVisibleTest = shroud.IsVisibleTest(footprintRegion); + isVisibleTest = shroud.IsVisibleTest; + + // Consider all cells inside the map area (ignoring the current map bounds) + Footprint = footprint + .Where(m => shroud.Contains(m)) + .ToArray(); - Footprint = footprint; CenterPosition = self.CenterPosition; Bounds = self.Bounds; @@ -80,11 +84,13 @@ namespace OpenRA.Traits // Visible = !Footprint.Any(isVisibleTest); Visible = true; foreach (var uv in Footprint) + { if (isVisibleTest(uv)) { Visible = false; break; } + } if (Visible && !wasVisible) NeedRenderables = true; diff --git a/OpenRA.Game/Traits/World/Shroud.cs b/OpenRA.Game/Traits/World/Shroud.cs index 452bea039f..25e04cb5fb 100644 --- a/OpenRA.Game/Traits/World/Shroud.cs +++ b/OpenRA.Game/Traits/World/Shroud.cs @@ -44,10 +44,8 @@ namespace OpenRA.Traits static readonly Func TruthPredicate = _ => true; readonly Func shroudEdgeTest; - readonly Func fastExploredTest; - readonly Func slowExploredTest; - readonly Func fastVisibleTest; - readonly Func slowVisibleTest; + readonly Func isExploredTest; + readonly Func isVisibleTest; public Shroud(Actor self) { @@ -67,10 +65,8 @@ namespace OpenRA.Traits fogVisibilities = Exts.Lazy(() => self.TraitsImplementing().ToArray()); shroudEdgeTest = map.Contains; - fastExploredTest = IsExploredCore; - slowExploredTest = IsExplored; - fastVisibleTest = IsVisibleCore; - slowVisibleTest = IsVisible; + isExploredTest = IsExploredCore; + isVisibleTest = IsVisibleCore; } void Invalidate(IEnumerable changed) @@ -329,18 +325,16 @@ namespace OpenRA.Traits return explored[uv] && (generatedShroudCount[uv] == 0 || visibleCount[uv] > 0); } - public Func IsExploredTest(CellRegion region) + public Func IsExploredTest { - // If the region to test extends outside the map we must use the slow test that checks the map boundary every time. - if (!map.CellsInsideBounds.Contains(region)) - return slowExploredTest; + get + { + // If shroud isn't enabled, then we can see everything inside the map. + if (!ShroudEnabled) + return shroudEdgeTest; - // If shroud isn't enabled, then we can see everything inside the map. - if (!ShroudEnabled) - return shroudEdgeTest; - - // If shroud is enabled, we can use the fast test that just does the core check. - return fastExploredTest; + return isExploredTest; + } } public bool IsExplored(Actor a) @@ -377,18 +371,17 @@ namespace OpenRA.Traits return visibleCount[uv] > 0; } - public Func IsVisibleTest(CellRegion region) + public Func IsVisibleTest { - // If the region to test extends outside the map we must use the slow test that checks the map boundary every time. - if (!map.CellsInsideBounds.Contains(region)) - return slowVisibleTest; + get + { + // If fog isn't enabled, then we can see everything. + if (!FogEnabled) + return TruthPredicate; - // If fog isn't enabled, then we can see everything. - if (!FogEnabled) - return TruthPredicate; - - // If fog is enabled, we can use the fast test that just does the core check. - return fastVisibleTest; + // If fog is enabled, we can use the fast test that just does the core check. + return isVisibleTest; + } } // Actors are hidden under shroud, but not under fog by default @@ -415,5 +408,12 @@ namespace OpenRA.Traits { return fogVisibilities.Value.Any(f => f.HasFogVisibility(self.Owner)); } + + public bool Contains(MPos uv) + { + // Check that uv is inside the map area. There is nothing special + // about explored here: any of the CellLayers would have been suitable. + return explored.Contains(uv); + } } } diff --git a/OpenRA.Game/World.cs b/OpenRA.Game/World.cs index 674d76a3b4..7ec04d1f72 100644 --- a/OpenRA.Game/World.cs +++ b/OpenRA.Game/World.cs @@ -73,27 +73,37 @@ namespace OpenRA public bool FogObscures(Actor a) { return RenderPlayer != null && !RenderPlayer.Shroud.IsVisible(a); } public bool FogObscures(CPos p) { return RenderPlayer != null && !RenderPlayer.Shroud.IsVisible(p); } public bool FogObscures(WPos pos) { return RenderPlayer != null && !RenderPlayer.Shroud.IsVisible(pos); } + public bool FogObscures(MPos uv) { return RenderPlayer != null && !RenderPlayer.Shroud.IsVisible(uv); } + 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(WPos pos) { return RenderPlayer != null && !RenderPlayer.Shroud.IsExplored(pos); } public bool ShroudObscures(MPos uv) { return RenderPlayer != null && !RenderPlayer.Shroud.IsExplored(uv); } - public Func FogObscuresTest(CellRegion region) + public Func FogObscuresTest { - var rp = RenderPlayer; - if (rp == null) - return FalsePredicate; - var predicate = rp.Shroud.IsVisibleTest(region); - return uv => !predicate(uv); + get + { + var rp = RenderPlayer; + if (rp == null) + return FalsePredicate; + + var predicate = rp.Shroud.IsVisibleTest; + return uv => !predicate(uv); + } } - public Func ShroudObscuresTest(CellRegion region) + public Func ShroudObscuresTest { - var rp = RenderPlayer; - if (rp == null) - return FalsePredicate; - var predicate = rp.Shroud.IsExploredTest(region); - return uv => !predicate(uv); + get + { + var rp = RenderPlayer; + if (rp == null) + return FalsePredicate; + + var predicate = rp.Shroud.IsExploredTest; + return uv => !predicate(uv); + } } public bool IsReplay diff --git a/OpenRA.Mods.Common/Traits/Modifiers/FrozenUnderFog.cs b/OpenRA.Mods.Common/Traits/Modifiers/FrozenUnderFog.cs index 64fedb9817..154c852257 100644 --- a/OpenRA.Mods.Common/Traits/Modifiers/FrozenUnderFog.cs +++ b/OpenRA.Mods.Common/Traits/Modifiers/FrozenUnderFog.cs @@ -30,7 +30,6 @@ namespace OpenRA.Mods.Common.Traits readonly bool startsRevealed; readonly MPos[] footprint; - readonly CellRegion footprintRegion; readonly Lazy tooltip; readonly Lazy health; @@ -46,7 +45,6 @@ namespace OpenRA.Mods.Common.Traits startsRevealed = info.StartsRevealed && !init.Contains(); 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().FirstOrDefault()); health = Exts.Lazy(() => init.Self.TraitOrDefault()); @@ -71,7 +69,7 @@ namespace OpenRA.Mods.Common.Traits FrozenActor frozenActor; if (!initialized) { - frozen[player] = frozenActor = new FrozenActor(self, footprint, footprintRegion, player.Shroud); + frozen[player] = frozenActor = new FrozenActor(self, footprint, player.Shroud); frozen[player].NeedRenderables = frozenActor.NeedRenderables = startsRevealed; player.PlayerActor.Trait().Add(frozenActor); isVisible = visible[player] |= startsRevealed; diff --git a/OpenRA.Mods.Common/Traits/World/ResourceLayer.cs b/OpenRA.Mods.Common/Traits/World/ResourceLayer.cs index 5827cdb329..13198a388d 100644 --- a/OpenRA.Mods.Common/Traits/World/ResourceLayer.cs +++ b/OpenRA.Mods.Common/Traits/World/ResourceLayer.cs @@ -33,7 +33,7 @@ namespace OpenRA.Mods.Common.Traits public void Render(WorldRenderer wr) { - var shroudObscured = world.ShroudObscuresTest(wr.Viewport.VisibleCells); + var shroudObscured = world.ShroudObscuresTest; foreach (var uv in wr.Viewport.VisibleCells.MapCoords) { if (shroudObscured(uv)) diff --git a/OpenRA.Mods.Common/Widgets/RadarWidget.cs b/OpenRA.Mods.Common/Widgets/RadarWidget.cs index 1b0d2cd500..cba460d644 100644 --- a/OpenRA.Mods.Common/Widgets/RadarWidget.cs +++ b/OpenRA.Mods.Common/Widgets/RadarWidget.cs @@ -122,6 +122,9 @@ namespace OpenRA.Mods.Common.Widgets void UpdateShroudCell(CPos cell) { + if (!world.Map.Contains(cell)) + return; + var stride = radarSheet.Size.Width; var uv = cell.ToMPos(world.Map); var dx = shroudSprite.Bounds.Left - world.Map.Bounds.Left;