From c428cad70c7eba4dd477c1214944da5ff8a866f7 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Wed, 10 Apr 2013 00:35:39 +1200 Subject: [PATCH] Refactor per-player shrouds & fix shellmap shroud. --- OpenRA.Game/Graphics/Minimap.cs | 11 +-- OpenRA.Game/Graphics/ShroudRenderer.cs | 99 +++++++++++-------- OpenRA.Game/Graphics/TerrainRenderer.cs | 4 +- OpenRA.Game/Graphics/Viewport.cs | 2 +- OpenRA.Game/Graphics/WorldRenderer.cs | 2 +- OpenRA.Game/Player.cs | 5 + OpenRA.Game/Traits/SelectionDecorations.cs | 6 +- OpenRA.Game/Traits/TraitsInterfaces.cs | 2 +- OpenRA.Game/Traits/World/ResourceLayer.cs | 2 +- OpenRA.Game/Traits/World/Shroud.cs | 27 +++-- .../WorldInteractionControllerWidget.cs | 2 +- OpenRA.Game/World.cs | 26 +++-- OpenRA.Game/WorldUtils.cs | 2 +- OpenRA.Mods.RA/Buildings/BaseProvider.cs | 4 +- OpenRA.Mods.RA/Buildings/BibLayer.cs | 2 +- OpenRA.Mods.RA/Cloak.cs | 13 +-- OpenRA.Mods.RA/Effects/Bullet.cs | 3 +- OpenRA.Mods.RA/Effects/Contrail.cs | 4 +- OpenRA.Mods.RA/Effects/GpsDot.cs | 2 +- OpenRA.Mods.RA/Effects/Missile.cs | 2 +- OpenRA.Mods.RA/MPStartLocations.cs | 9 +- OpenRA.Mods.RA/Modifiers/FrozenUnderFog.cs | 6 +- OpenRA.Mods.RA/Modifiers/HiddenUnderFog.cs | 6 +- OpenRA.Mods.RA/ProductionBar.cs | 2 +- OpenRA.Mods.RA/SmokeTrailWhenDamaged.cs | 2 +- .../Logic/ObserverShroudSelectorLogic.cs | 10 +- OpenRA.Mods.RA/Widgets/WorldTooltipWidget.cs | 2 +- OpenRA.Mods.RA/World/SmudgeLayer.cs | 4 +- mods/cnc-classic/rules/system.yaml | 1 - mods/cnc/rules/system.yaml | 1 - mods/d2k/rules/system.yaml | 1 - mods/ra-classic/rules/system.yaml | 1 - mods/ra/rules/system.yaml | 1 - 33 files changed, 146 insertions(+), 120 deletions(-) diff --git a/OpenRA.Game/Graphics/Minimap.cs b/OpenRA.Game/Graphics/Minimap.cs index 38c23a069d..c3487d3877 100644 --- a/OpenRA.Game/Graphics/Minimap.cs +++ b/OpenRA.Game/Graphics/Minimap.cs @@ -139,7 +139,7 @@ namespace OpenRA.Graphics foreach (var t in world.ActorsWithTrait()) { - if (!world.RenderedShroud.IsVisible(t.Actor)) + if (world.ShroudObscures(t.Actor)) continue; var color = t.Trait.RadarSignatureColor(t.Actor); @@ -158,7 +158,7 @@ namespace OpenRA.Graphics var map = world.Map; var size = Exts.NextPowerOf2(Math.Max(map.Bounds.Width, map.Bounds.Height)); var bitmap = new Bitmap(size, size); - if (world.RenderedShroud.Disabled) + if (world.RenderPlayer == null) return bitmap; var bitmapData = bitmap.LockBits(bitmap.Bounds(), @@ -174,11 +174,10 @@ namespace OpenRA.Graphics for (var x = 0; x < map.Bounds.Width; x++) for (var y = 0; y < map.Bounds.Height; y++) { - var mapX = x + map.Bounds.Left; - var mapY = y + map.Bounds.Top; - if (!world.RenderedShroud.IsExplored(mapX, mapY)) + var p = new CPos(x + map.Bounds.Left, y + map.Bounds.Top); + if (world.ShroudObscures(p)) *(c + (y * bitmapData.Stride >> 2) + x) = shroud; - else if (!world.RenderedShroud.IsVisible(mapX,mapY)) + else if (world.FogObscures(p)) *(c + (y * bitmapData.Stride >> 2) + x) = fog; } } diff --git a/OpenRA.Game/Graphics/ShroudRenderer.cs b/OpenRA.Game/Graphics/ShroudRenderer.cs index 592a5af055..0ee74d8378 100644 --- a/OpenRA.Game/Graphics/ShroudRenderer.cs +++ b/OpenRA.Game/Graphics/ShroudRenderer.cs @@ -15,21 +15,12 @@ namespace OpenRA.Graphics { public class ShroudRenderer { - World world; - Traits.Shroud shroud { - get { - return world.RenderedShroud; - } - } - + Map map; Sprite[] shadowBits = Game.modData.SpriteLoader.LoadAllSprites("shadow"); Sprite[,] sprites, fogSprites; - Map map; - public ShroudRenderer(World world) { - this.world = world; this.map = world.Map; sprites = new Sprite[map.MapSize.X, map.MapSize.Y]; @@ -56,58 +47,58 @@ namespace OpenRA.Graphics new byte[] { 46 }, }; - Sprite ChooseShroud(int i, int j) + Sprite ChooseShroud(Shroud s, int i, int j) { - if( !shroud.IsExplored( i, j ) ) return shadowBits[ 0xf ]; + if (!s.IsExplored(i, j)) + return shadowBits[0xf]; // bits are for unexploredness: up, right, down, left var v = 0; // bits are for unexploredness: TL, TR, BR, BL var u = 0; - if( !shroud.IsExplored( i, j - 1 ) ) { v |= 1; u |= 3; } - if( !shroud.IsExplored( i + 1, j ) ) { v |= 2; u |= 6; } - if( !shroud.IsExplored( i, j + 1 ) ) { v |= 4; u |= 12; } - if( !shroud.IsExplored( i - 1, j ) ) { v |= 8; u |= 9; } + if (!s.IsExplored(i, j - 1)) { v |= 1; u |= 3; } + if (!s.IsExplored(i + 1, j)) { v |= 2; u |= 6; } + if (!s.IsExplored(i, j + 1)) { v |= 4; u |= 12; } + if (!s.IsExplored(i - 1, j)) { v |= 8; u |= 9; } var uSides = u; + if (!s.IsExplored(i - 1, j - 1)) u |= 1; + if (!s.IsExplored(i + 1, j - 1)) u |= 2; + if (!s.IsExplored(i + 1, j + 1)) u |= 4; + if (!s.IsExplored(i - 1, j + 1)) u |= 8; - if( !shroud.IsExplored( i - 1, j - 1 ) ) u |= 1; - if( !shroud.IsExplored( i + 1, j - 1 ) ) u |= 2; - if( !shroud.IsExplored( i + 1, j + 1 ) ) u |= 4; - if( !shroud.IsExplored( i - 1, j + 1 ) ) u |= 8; - - return shadowBits[ SpecialShroudTiles[ u ^ uSides ][ v ] ]; + return shadowBits[SpecialShroudTiles[u ^ uSides][v]]; } - Sprite ChooseFog(int i, int j) + Sprite ChooseFog(Shroud s, int i, int j) { - if (!shroud.IsVisible(i,j)) return shadowBits[0xf]; - if (!shroud.IsExplored(i, j)) return shadowBits[0xf]; + if (!s.IsVisible(i, j)) return shadowBits[0xf]; + if (!s.IsExplored(i, j)) return shadowBits[0xf]; // bits are for unexploredness: up, right, down, left var v = 0; // bits are for unexploredness: TL, TR, BR, BL var u = 0; - if (!shroud.IsVisible(i, j - 1)) { v |= 1; u |= 3; } - if (!shroud.IsVisible(i + 1, j)) { v |= 2; u |= 6; } - if (!shroud.IsVisible(i, j + 1)) { v |= 4; u |= 12; } - if (!shroud.IsVisible(i - 1, j)) { v |= 8; u |= 9; } + if (!s.IsVisible(i, j - 1)) { v |= 1; u |= 3; } + if (!s.IsVisible(i + 1, j)) { v |= 2; u |= 6; } + if (!s.IsVisible(i, j + 1)) { v |= 4; u |= 12; } + if (!s.IsVisible(i - 1, j)) { v |= 8; u |= 9; } var uSides = u; - if (!shroud.IsVisible(i - 1, j - 1)) u |= 1; - if (!shroud.IsVisible(i + 1, j - 1)) u |= 2; - if (!shroud.IsVisible(i + 1, j + 1)) u |= 4; - if (!shroud.IsVisible(i - 1, j + 1)) u |= 8; + if (!s.IsVisible(i - 1, j - 1)) u |= 1; + if (!s.IsVisible(i + 1, j - 1)) u |= 2; + if (!s.IsVisible(i + 1, j + 1)) u |= 4; + if (!s.IsVisible(i - 1, j + 1)) u |= 8; return shadowBits[SpecialShroudTiles[u ^ uSides][v]]; } bool initializePalettes = true; PaletteReference fogPalette, shroudPalette; - internal void Draw(WorldRenderer wr) + internal void Draw(WorldRenderer wr, Player renderPlayer) { if (initializePalettes) { @@ -116,18 +107,42 @@ namespace OpenRA.Graphics initializePalettes = false; } - if (shroud != null && shroud.dirty) + if (renderPlayer == null) { - shroud.dirty = false; - for (int i = map.Bounds.Left; i < map.Bounds.Right; i++) - for (int j = map.Bounds.Top; j < map.Bounds.Bottom; j++) - sprites[i, j] = ChooseShroud(i, j); + // Players with no shroud see the whole map so we only need to set the edges + var b = map.Bounds; + for (int i = b.Left; i < b.Right; i++) + for (int j = b.Top; j < b.Bottom; j++) + { + var v = 0; + var u = 0; - for (int i = map.Bounds.Left; i < map.Bounds.Right; i++) - for (int j = map.Bounds.Top; j < map.Bounds.Bottom; j++) - fogSprites[i, j] = ChooseFog(i, j); + if (j == b.Top) { v |= 1; u |= 3; } + if (i == b.Right - 1) { v |= 2; u |= 6; } + if (j == b.Bottom - 1) { v |= 4; u |= 12; } + if (i == b.Left) { v |= 8; u |= 9; } + + var uSides = u; + if (i == b.Left && j == b.Top) u |= 1; + if (i == b.Right - 1 && j == b.Top) u |= 2; + if (i == b.Right - 1 && j == b.Bottom - 1) u |= 4; + if (i == b.Left && j == b.Bottom - 1) u |= 8; + + sprites[i, j] = fogSprites[i, j] = shadowBits[SpecialShroudTiles[u ^ uSides][v]]; + } } + else + { + renderPlayer.Shroud.dirty = false; + for (int i = map.Bounds.Left; i < map.Bounds.Right; i++) + for (int j = map.Bounds.Top; j < map.Bounds.Bottom; j++) + sprites[i, j] = ChooseShroud(renderPlayer.Shroud, i, j); + + for (int i = map.Bounds.Left; i < map.Bounds.Right; i++) + for (int j = map.Bounds.Top; j < map.Bounds.Bottom; j++) + fogSprites[i, j] = ChooseFog(renderPlayer.Shroud, i, j); + } var clipRect = Game.viewport.WorldBounds(wr.world); DrawShroud(wr, clipRect, sprites, shroudPalette); if (wr.world.WorldActor.HasTrait()) diff --git a/OpenRA.Game/Graphics/TerrainRenderer.cs b/OpenRA.Game/Graphics/TerrainRenderer.cs index 1e17aac0a2..08882935e3 100644 --- a/OpenRA.Game/Graphics/TerrainRenderer.cs +++ b/OpenRA.Game/Graphics/TerrainRenderer.cs @@ -72,9 +72,9 @@ namespace OpenRA.Graphics if (firstRow < 0) firstRow = 0; if (lastRow > map.Bounds.Height) lastRow = map.Bounds.Height; - if (world.RenderedPlayer != null && !world.RenderedShroud.Disabled && world.RenderedShroud.Bounds.HasValue) + if (world.VisibleBounds.HasValue) { - var r = world.RenderedShroud.Bounds.Value; + var r = world.VisibleBounds.Value; if (firstRow < r.Top - map.Bounds.Top) firstRow = r.Top - map.Bounds.Top; diff --git a/OpenRA.Game/Graphics/Viewport.cs b/OpenRA.Game/Graphics/Viewport.cs index b3add5a4d4..e7623d5697 100755 --- a/OpenRA.Game/Graphics/Viewport.cs +++ b/OpenRA.Game/Graphics/Viewport.cs @@ -196,7 +196,7 @@ namespace OpenRA.Graphics cachedScroll = scrollPosition; } - var b = world.RenderedShroud.Bounds; + var b = world.VisibleBounds; return (b.HasValue) ? Rectangle.Intersect(cachedRect, b.Value) : cachedRect; } } diff --git a/OpenRA.Game/Graphics/WorldRenderer.cs b/OpenRA.Game/Graphics/WorldRenderer.cs index c0f19ef77a..ddbbf0f9b5 100644 --- a/OpenRA.Game/Graphics/WorldRenderer.cs +++ b/OpenRA.Game/Graphics/WorldRenderer.cs @@ -127,7 +127,7 @@ namespace OpenRA.Graphics if (world.OrderGenerator != null) world.OrderGenerator.RenderAfterWorld(this, world); - shroudRenderer.Draw( this ); + shroudRenderer.Draw(this, world.RenderPlayer); Game.Renderer.DisableScissor(); foreach (var g in world.Selection.Actors.Where(a => !a.Destroyed) diff --git a/OpenRA.Game/Player.cs b/OpenRA.Game/Player.cs index 74c7853efb..95132cc81d 100644 --- a/OpenRA.Game/Player.cs +++ b/OpenRA.Game/Player.cs @@ -92,5 +92,10 @@ namespace OpenRA } public Dictionary Stances = new Dictionary(); + public bool IsAlliedWith(Player p) + { + // Observers are considered as allies + return p == null || Stances[p] == Stance.Ally; + } } } diff --git a/OpenRA.Game/Traits/SelectionDecorations.cs b/OpenRA.Game/Traits/SelectionDecorations.cs index bd1111957a..85dac3c42c 100644 --- a/OpenRA.Game/Traits/SelectionDecorations.cs +++ b/OpenRA.Game/Traits/SelectionDecorations.cs @@ -54,7 +54,8 @@ namespace OpenRA.Traits void DrawPips(WorldRenderer wr, Actor self, float2 basePosition) { - if (self.Owner != self.World.RenderedPlayer) return; + if (self.Owner != self.World.RenderPlayer) + return; var pipSources = self.TraitsImplementing(); if (pipSources.Count() == 0) @@ -95,7 +96,8 @@ namespace OpenRA.Traits void DrawTags(WorldRenderer wr, Actor self, float2 basePosition) { - if (self.Owner != self.World.RenderedPlayer) return; + if (self.Owner != self.World.RenderPlayer) + return; // If a mod wants to implement a unit with multiple tags, then they are placed on multiple rows var tagxyBase = basePosition + new float2(-16, 2); // Correct for the offset in the shp file diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index d04f5d5bde..437bf80096 100755 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -86,7 +86,7 @@ namespace OpenRA.Traits Color RadarSignatureColor(Actor self); } - public interface IVisibilityModifier { bool IsVisible(Shroud s, Actor self); } + public interface IVisibilityModifier { bool IsVisible(Actor self, Player byPlayer); } public interface IRadarColorModifier { Color RadarColorOverride(Actor self); } public interface IHasLocation { PPos PxPosition { get; } } diff --git a/OpenRA.Game/Traits/World/ResourceLayer.cs b/OpenRA.Game/Traits/World/ResourceLayer.cs index a9ab4f2bea..4b10b173fc 100644 --- a/OpenRA.Game/Traits/World/ResourceLayer.cs +++ b/OpenRA.Game/Traits/World/ResourceLayer.cs @@ -40,7 +40,7 @@ namespace OpenRA.Traits for (int x = clip.Left; x < clip.Right; x++) for (int y = clip.Top; y < clip.Bottom; y++) { - if (!world.RenderedShroud.IsExplored(new CPos(x, y))) + if (world.ShroudObscures(new CPos(x, y))) continue; var c = content[x, y]; diff --git a/OpenRA.Game/Traits/World/Shroud.cs b/OpenRA.Game/Traits/World/Shroud.cs index 7089d9c09e..8682ac9ef3 100644 --- a/OpenRA.Game/Traits/World/Shroud.cs +++ b/OpenRA.Game/Traits/World/Shroud.cs @@ -23,7 +23,6 @@ namespace OpenRA.Traits public class Shroud : ISync { Map map; - World world; [Sync] public Player Owner; public int[,] visibleCells; @@ -38,11 +37,6 @@ namespace OpenRA.Traits set { disabled = value; Dirty(); } } - public bool Observing - { - get { return world.IsShellmap || (world.LocalPlayer == null && Owner == null);; } - } - public Rectangle? Bounds { get { return Disabled ? null : exploredBounds; } @@ -52,7 +46,6 @@ namespace OpenRA.Traits public Shroud(World world) { - this.world = world; map = world.Map; visibleCells = new int[map.MapSize.X, map.MapSize.Y]; exploredCells = new bool[map.MapSize.X, map.MapSize.Y]; @@ -274,16 +267,24 @@ namespace OpenRA.Traits if (!map.IsInMap(x, y)) return false; - if (Disabled || Observing) + if (Disabled) return true; return foggedCells[x,y]; } + public bool IsExplored(Actor a) + { + if (Owner == null) + return true; + + return GetVisOrigins(a).Any(o => IsExplored(o)); + } + public bool IsVisible(CPos xy) { return IsVisible(xy.X, xy.Y); } public bool IsVisible(int x, int y) { - if (Disabled || Observing) + if (Disabled) return true; // Visibility is allowed to extend beyond the map cordon so that @@ -298,16 +299,14 @@ namespace OpenRA.Traits public bool IsVisible(Actor a) { // I need to pass in the current shroud, otherwise we're just checking that true==true - if (a.TraitsImplementing().Any(t => !t.IsVisible(this, a))) + if (a.TraitsImplementing().Any(t => !t.IsVisible(a, Owner))) return false; - if(Owner == null) return true; - - return Disabled || Observing || a.Owner.Stances[Owner] == Stance.Ally || GetVisOrigins(a).Any(o => IsExplored(o)); + return Disabled || a.Owner.Stances[Owner] == Stance.Ally || IsExplored(a); } public bool IsTargetable(Actor a) { - if (a.TraitsImplementing().Any(t => !t.IsVisible(this, a))) + if (a.TraitsImplementing().Any(t => !t.IsVisible(a, Owner))) return false; return GetVisOrigins(a).Any(o => IsVisible(o)); diff --git a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs index da73e51725..b58609031b 100644 --- a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs +++ b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs @@ -184,7 +184,7 @@ namespace OpenRA.Widgets IEnumerable SelectActorsInBox(World world, PPos a, PPos b, Func cond) { return world.FindUnits(a, b) - .Where(x => x.HasTrait() && world.RenderedShroud.IsVisible(x) && cond(x)) + .Where(x => x.HasTrait() && !world.FogObscures(x) && cond(x)) .GroupBy(x => x.GetSelectionPriority()) .OrderByDescending(g => g.Key) .Select(g => g.AsEnumerable()) diff --git a/OpenRA.Game/World.cs b/OpenRA.Game/World.cs index 4d7647a1c1..e9a8d17816 100644 --- a/OpenRA.Game/World.cs +++ b/OpenRA.Game/World.cs @@ -10,6 +10,7 @@ using System; using System.Collections.Generic; +using System.Drawing; using System.Linq; using OpenRA.Effects; using OpenRA.FileFormats; @@ -40,11 +41,25 @@ namespace OpenRA public void AddPlayer(Player p) { Players.Add(p); } public Player LocalPlayer { get; private set; } - public readonly Shroud LocalShroud; public bool Observer { get { return LocalPlayer == null; } } - public Player RenderedPlayer; - public Shroud RenderedShroud { get { return RenderedPlayer != null ? RenderedPlayer.Shroud : LocalShroud; } } - + + Player renderPlayer; + public Player RenderPlayer + { + get { return renderPlayer; } + set + { + renderPlayer = value; + if (renderPlayer != null) + renderPlayer.Shroud.Dirty(); + } + } + + public Rectangle? VisibleBounds { get { return renderPlayer != null ? renderPlayer.Shroud.Bounds : null; } } + 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 ShroudObscures(Actor a) { return renderPlayer != null && !renderPlayer.Shroud.IsExplored(a); } + public bool ShroudObscures(CPos p) { return renderPlayer != null && !renderPlayer.Shroud.IsExplored(p); } public void SetLocalPlayer(string pr) { @@ -52,7 +67,7 @@ namespace OpenRA return; LocalPlayer = Players.FirstOrDefault(p => p.InternalName == pr); - RenderedPlayer = LocalPlayer; + RenderPlayer = LocalPlayer; } public readonly Actor WorldActor; @@ -104,7 +119,6 @@ namespace OpenRA SharedRandom = new XRandom(orderManager.LobbyInfo.GlobalSettings.RandomSeed); WorldActor = CreateActor( "World", new TypeDictionary() ); - LocalShroud = WorldActor.Trait(); ActorMap = new ActorMap(this); // Add players diff --git a/OpenRA.Game/WorldUtils.cs b/OpenRA.Game/WorldUtils.cs index 3fb087a324..0c43535154 100755 --- a/OpenRA.Game/WorldUtils.cs +++ b/OpenRA.Game/WorldUtils.cs @@ -24,7 +24,7 @@ namespace OpenRA public static IEnumerable FindUnitsAtMouse(this World world, int2 mouseLocation) { var loc = Game.viewport.ViewToWorldPx(mouseLocation); - return FindUnits(world, loc, loc).Where(a => world.RenderedShroud.IsVisible(a)); + return FindUnits(world, loc, loc).Where(a => !world.FogObscures(a)); } public static IEnumerable FindUnits(this World world, PPos a, PPos b) diff --git a/OpenRA.Mods.RA/Buildings/BaseProvider.cs b/OpenRA.Mods.RA/Buildings/BaseProvider.cs index 8278d74744..0622f5a441 100755 --- a/OpenRA.Mods.RA/Buildings/BaseProvider.cs +++ b/OpenRA.Mods.RA/Buildings/BaseProvider.cs @@ -60,7 +60,7 @@ namespace OpenRA.Mods.RA.Buildings public void RenderBeforeWorld(WorldRenderer wr, Actor self) { // Visible to player and allies - if (self.World.RenderedPlayer != null && self.Owner.Stances[self.World.RenderedPlayer] != Stance.Ally) + if (!self.Owner.IsAlliedWith(self.World.RenderPlayer)) return; wr.DrawRangeCircleWithContrast( @@ -73,7 +73,7 @@ namespace OpenRA.Mods.RA.Buildings public float GetValue() { // Visible to player and allies - if (self.World.RenderedPlayer != null && self.Owner.Stances[self.World.RenderedPlayer] != Stance.Ally) + if (!self.Owner.IsAlliedWith(self.World.RenderPlayer)) return 0f; // Ready or delay disabled diff --git a/OpenRA.Mods.RA/Buildings/BibLayer.cs b/OpenRA.Mods.RA/Buildings/BibLayer.cs index efa1d48742..d5f33a2243 100755 --- a/OpenRA.Mods.RA/Buildings/BibLayer.cs +++ b/OpenRA.Mods.RA/Buildings/BibLayer.cs @@ -78,7 +78,7 @@ namespace OpenRA.Mods.RA.Buildings { if (!cliprect.Contains(kv.Key.X, kv.Key.Y)) continue; - if (!world.RenderedShroud.IsExplored(kv.Key)) + if (world.ShroudObscures(kv.Key)) continue; bibSprites[kv.Value.type - 1][kv.Value.index].DrawAt(wr, kv.Key.ToPPos().ToFloat2(), "terrain"); diff --git a/OpenRA.Mods.RA/Cloak.cs b/OpenRA.Mods.RA/Cloak.cs index 3bef1e3b8d..ea823c9a23 100644 --- a/OpenRA.Mods.RA/Cloak.cs +++ b/OpenRA.Mods.RA/Cloak.cs @@ -73,7 +73,7 @@ namespace OpenRA.Mods.RA if (remainingTime > 0) return r; - if (Cloaked && IsVisible(self.World.RenderedShroud, self)) + if (Cloaked && IsVisible(self, self.World.RenderPlayer)) if (string.IsNullOrEmpty(info.Palette)) return r; else @@ -97,17 +97,12 @@ namespace OpenRA.Mods.RA } } - public bool IsVisible(Shroud s, Actor self) + public bool IsVisible(Actor self, Player byPlayer) { - if (!Cloaked) + if (!Cloaked || self.Owner.IsAlliedWith(byPlayer)) return true; - if (s.Observing) - return true; - if (s.Owner != null) - if (self.Owner == s.Owner || self.Owner.Stances[s.Owner] == Stance.Ally) - return true; - + // TODO: Change this to be per-player? A cloak detector revealing to everyone is dumb return self.World.ActorsWithTrait().Any(a => a.Actor.Owner.Stances[self.Owner] != Stance.Ally && (self.Location - a.Actor.Location).Length < a.Actor.Info.Traits.Get().Range); diff --git a/OpenRA.Mods.RA/Effects/Bullet.cs b/OpenRA.Mods.RA/Effects/Bullet.cs index 5939ed008a..0850180d61 100755 --- a/OpenRA.Mods.RA/Effects/Bullet.cs +++ b/OpenRA.Mods.RA/Effects/Bullet.cs @@ -160,7 +160,8 @@ namespace OpenRA.Mods.RA.Effects var altitude = float2.Lerp(Args.srcAltitude, Args.destAltitude, at); var pos = float2.Lerp(Args.src.ToFloat2(), Args.dest.ToFloat2(), at) - new float2(0, altitude); - if (Args.firedBy.World.RenderedShroud.IsVisible(((PPos) pos.ToInt2()).ToCPos())) + var cell = ((PPos)pos.ToInt2()).ToCPos(); + if (!Args.firedBy.World.FogObscures(cell)) { if (Info.High || Info.Angle > 0) { diff --git a/OpenRA.Mods.RA/Effects/Contrail.cs b/OpenRA.Mods.RA/Effects/Contrail.cs index 4c0b3ffb4a..6776b2db00 100755 --- a/OpenRA.Mods.RA/Effects/Contrail.cs +++ b/OpenRA.Mods.RA/Effects/Contrail.cs @@ -93,8 +93,8 @@ namespace OpenRA.Mods.RA var conPos = WPos.Average(positions[i], positions[i-1], positions[i-2], positions[i-3]); var nextPos = WPos.Average(positions[i-1], positions[i-2], positions[i-3], positions[i-4]); - if (self.World.RenderedShroud.IsVisible(new CPos(conPos)) || - self.World.RenderedShroud.IsVisible(new CPos(nextPos))) + if (!self.World.FogObscures(new CPos(conPos)) && + !self.World.FogObscures(new CPos(nextPos))) { Game.Renderer.WorldLineRenderer.DrawLine(wr.ScreenPosition(conPos), wr.ScreenPosition(nextPos), trailStart, trailEnd); diff --git a/OpenRA.Mods.RA/Effects/GpsDot.cs b/OpenRA.Mods.RA/Effects/GpsDot.cs index 7b63f440dc..c9da29dc8b 100644 --- a/OpenRA.Mods.RA/Effects/GpsDot.cs +++ b/OpenRA.Mods.RA/Effects/GpsDot.cs @@ -69,7 +69,7 @@ namespace OpenRA.Mods.RA.Effects } var hasGps = (watcher != null && (watcher.Granted || watcher.GrantedAllies)); - var hasDot = (huf != null && !huf.IsVisible(self.World.RenderedShroud, self)); // WRONG (why?) + var hasDot = (huf != null && !huf.IsVisible(self, self.World.RenderPlayer)); var dotHidden = (cloak != null && cloak.Cloaked) || (spy != null && spy.Disguised); show = hasGps && hasDot && !dotHidden; diff --git a/OpenRA.Mods.RA/Effects/Missile.cs b/OpenRA.Mods.RA/Effects/Missile.cs index f04ec2cecd..88bedf524a 100755 --- a/OpenRA.Mods.RA/Effects/Missile.cs +++ b/OpenRA.Mods.RA/Effects/Missile.cs @@ -158,7 +158,7 @@ namespace OpenRA.Mods.RA.Effects public IEnumerable Render(WorldRenderer wr) { - if (Args.firedBy.World.RenderedShroud.IsVisible(PxPosition.ToCPos())) + if (!Args.firedBy.World.FogObscures(PxPosition.ToCPos())) yield return new Renderable(anim.Image, PxPosition.ToFloat2() - 0.5f * anim.Image.size - new float2(0, Altitude), wr.Palette(Args.weapon.Underwater ? "shadow" : "effect"), PxPosition.Y); diff --git a/OpenRA.Mods.RA/MPStartLocations.cs b/OpenRA.Mods.RA/MPStartLocations.cs index 64fa49e993..a64af630f4 100755 --- a/OpenRA.Mods.RA/MPStartLocations.cs +++ b/OpenRA.Mods.RA/MPStartLocations.cs @@ -47,10 +47,11 @@ namespace OpenRA.Mods.RA } // Explore allied shroud - foreach (var p in Start) - if ((world.LocalPlayer != null ) &&(p.Key == world.LocalPlayer || p.Key.Stances[world.LocalPlayer] == Stance.Ally)) - world.WorldActor.Trait().Explore(world, p.Value, - world.WorldActor.Info.Traits.Get().InitialExploreRange); + var explore = world.WorldActor.Info.Traits.Get().InitialExploreRange; + foreach (var p in Start.Keys) + foreach (var q in world.Players) + if (p.IsAlliedWith(q)) + q.Shroud.Explore(world, Start[p], explore); // Set viewport if (world.LocalPlayer != null && Start.ContainsKey(world.LocalPlayer)) diff --git a/OpenRA.Mods.RA/Modifiers/FrozenUnderFog.cs b/OpenRA.Mods.RA/Modifiers/FrozenUnderFog.cs index c4f823be48..22b207ade7 100644 --- a/OpenRA.Mods.RA/Modifiers/FrozenUnderFog.cs +++ b/OpenRA.Mods.RA/Modifiers/FrozenUnderFog.cs @@ -19,15 +19,15 @@ namespace OpenRA.Mods.RA class FrozenUnderFog : IRenderModifier, IVisibilityModifier { - public bool IsVisible(Shroud s, Actor self) + public bool IsVisible(Actor self, Player byPlayer) { - return Shroud.GetVisOrigins(self).Any(o => s.IsVisible(o)); + return byPlayer == null || Shroud.GetVisOrigins(self).Any(o => byPlayer.Shroud.IsVisible(o)); } Renderable[] cache = { }; public IEnumerable ModifyRender(Actor self, WorldRenderer wr, IEnumerable r) { - if (IsVisible(self.World.RenderedShroud, self)) + if (IsVisible(self, self.World.RenderPlayer)) cache = r.ToArray(); return cache; } diff --git a/OpenRA.Mods.RA/Modifiers/HiddenUnderFog.cs b/OpenRA.Mods.RA/Modifiers/HiddenUnderFog.cs index cba548f4e4..0686b0941a 100644 --- a/OpenRA.Mods.RA/Modifiers/HiddenUnderFog.cs +++ b/OpenRA.Mods.RA/Modifiers/HiddenUnderFog.cs @@ -19,15 +19,15 @@ namespace OpenRA.Mods.RA class HiddenUnderFog : IRenderModifier, IVisibilityModifier { - public bool IsVisible(Shroud s, Actor self) + public bool IsVisible(Actor self, Player byPlayer) { - return Shroud.GetVisOrigins(self).Any(o => s.IsVisible(o)); + return byPlayer == null || Shroud.GetVisOrigins(self).Any(o => byPlayer.Shroud.IsVisible(o)); } static Renderable[] Nothing = { }; public IEnumerable ModifyRender(Actor self, WorldRenderer wr, IEnumerable r) { - return IsVisible(self.World.RenderedShroud, self) ? r : Nothing; + return IsVisible(self, self.World.RenderPlayer) ? r : Nothing; } } } diff --git a/OpenRA.Mods.RA/ProductionBar.cs b/OpenRA.Mods.RA/ProductionBar.cs index 840b0c0153..198f82bcf5 100644 --- a/OpenRA.Mods.RA/ProductionBar.cs +++ b/OpenRA.Mods.RA/ProductionBar.cs @@ -29,7 +29,7 @@ namespace OpenRA.Mods.RA public float GetValue() { // only people we like should see our production status. - if (self.World.RenderedPlayer != null && self.Owner.Stances[self.World.RenderedPlayer] != Stance.Ally) + if (!self.Owner.IsAlliedWith(self.World.RenderPlayer)) return 0; var queue = self.TraitsImplementing().FirstOrDefault(q => q.CurrentItem() != null); diff --git a/OpenRA.Mods.RA/SmokeTrailWhenDamaged.cs b/OpenRA.Mods.RA/SmokeTrailWhenDamaged.cs index 229b329f59..a6d9ac9668 100644 --- a/OpenRA.Mods.RA/SmokeTrailWhenDamaged.cs +++ b/OpenRA.Mods.RA/SmokeTrailWhenDamaged.cs @@ -41,7 +41,7 @@ namespace OpenRA.Mods.RA { var position = self.CenterPosition; if (position.Z > 0 && self.GetDamageState() >= DamageState.Heavy && - self.World.RenderedShroud.IsVisible(new CPos(position))) + !self.World.FogObscures(new CPos(position))) { var offset = info.Offset.Rotate(coords.QuantizeOrientation(self, self.Orientation)); var pos = PPos.FromWPosHackZ(position + coords.LocalToWorld(offset)); diff --git a/OpenRA.Mods.RA/Widgets/Logic/ObserverShroudSelectorLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/ObserverShroudSelectorLogic.cs index ba2b14c402..0e2d3e3636 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/ObserverShroudSelectorLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/ObserverShroudSelectorLogic.cs @@ -40,16 +40,16 @@ namespace OpenRA.Mods.RA.Widgets.Logic { var views = world.Players.Where(p => !p.NonCombatant).ToDictionary(p => p.PlayerName, p => new CameraOption("{0}'s view".F(p.PlayerName), - () => world.RenderedPlayer == p, - () => { world.RenderedPlayer = p; world.RenderedShroud.Dirty(); } + () => world.RenderPlayer == p, + () => world.RenderPlayer = p )); views.Add("", new CameraOption("World view", - () => world.RenderedPlayer == null, - () => { world.RenderedPlayer = null; world.RenderedShroud.Dirty(); } + () => world.RenderPlayer == null, + () => world.RenderPlayer = null )); var shroudSelector = widget.Get("SHROUD_SELECTOR"); - shroudSelector.GetText = () => views[world.RenderedPlayer == null ? "" : world.RenderedPlayer.PlayerName].Label; + shroudSelector.GetText = () => views[world.RenderPlayer == null ? "" : world.RenderPlayer.PlayerName].Label; shroudSelector.OnMouseDown = _ => { Func setupItem = (option, template) => diff --git a/OpenRA.Mods.RA/Widgets/WorldTooltipWidget.cs b/OpenRA.Mods.RA/Widgets/WorldTooltipWidget.cs index b81810dbe1..b52b092474 100755 --- a/OpenRA.Mods.RA/Widgets/WorldTooltipWidget.cs +++ b/OpenRA.Mods.RA/Widgets/WorldTooltipWidget.cs @@ -33,7 +33,7 @@ namespace OpenRA.Mods.RA.Widgets var cell = Game.viewport.ViewToWorld(Viewport.LastMousePos); if (!world.Map.IsInMap(cell)) return; - if (world.LocalPlayer != null && !world.RenderedShroud.IsExplored(cell)) + if (world.LocalPlayer != null && world.ShroudObscures(cell)) { var utext = "Unexplored Terrain"; var usz = Game.Renderer.Fonts["Bold"].Measure(utext) + new int2(20, 24); diff --git a/OpenRA.Mods.RA/World/SmudgeLayer.cs b/OpenRA.Mods.RA/World/SmudgeLayer.cs index 440560d7c6..61b62ef802 100755 --- a/OpenRA.Mods.RA/World/SmudgeLayer.cs +++ b/OpenRA.Mods.RA/World/SmudgeLayer.cs @@ -78,12 +78,12 @@ namespace OpenRA.Mods.RA public void Render( WorldRenderer wr ) { var cliprect = Game.viewport.WorldBounds(world); - var localPlayer = world.LocalPlayer; foreach (var kv in tiles) { if (!cliprect.Contains(kv.Key.X,kv.Key.Y)) continue; - if (localPlayer != null && !world.RenderedShroud.IsExplored(kv.Key)) + + if (world.ShroudObscures(kv.Key)) continue; smudgeSprites[kv.Value.type- 1][kv.Value.index].DrawAt(wr, kv.Key.ToPPos().ToFloat2(), "terrain"); diff --git a/mods/cnc-classic/rules/system.yaml b/mods/cnc-classic/rules/system.yaml index 35a79a5e8a..3e88c7bcd6 100644 --- a/mods/cnc-classic/rules/system.yaml +++ b/mods/cnc-classic/rules/system.yaml @@ -204,7 +204,6 @@ World: SpawnMPUnits: SpatialBins: BinSize: 4 - Shroud: PathFinder: ValidateOrder: DebugPauseState: diff --git a/mods/cnc/rules/system.yaml b/mods/cnc/rules/system.yaml index 737f98935f..2f84a6608e 100644 --- a/mods/cnc/rules/system.yaml +++ b/mods/cnc/rules/system.yaml @@ -306,7 +306,6 @@ World: MPStartLocations: SpatialBins: BinSize: 4 - Shroud: Fog: CrateSpawner: Minimum: 1 diff --git a/mods/d2k/rules/system.yaml b/mods/d2k/rules/system.yaml index 4ae5a989c6..d79a233cbf 100644 --- a/mods/d2k/rules/system.yaml +++ b/mods/d2k/rules/system.yaml @@ -388,7 +388,6 @@ World: Faction: ordos SpatialBins: BinSize: 4 - Shroud: Fog: PathFinder: ValidateOrder: diff --git a/mods/ra-classic/rules/system.yaml b/mods/ra-classic/rules/system.yaml index 6eccd968ca..c3775aafc4 100644 --- a/mods/ra-classic/rules/system.yaml +++ b/mods/ra-classic/rules/system.yaml @@ -236,7 +236,6 @@ World: SpawnMPUnits: SpatialBins: BinSize: 4 - Shroud: PathFinder: ValidateOrder: DebugPauseState: diff --git a/mods/ra/rules/system.yaml b/mods/ra/rules/system.yaml index 03c595e238..5553568e19 100644 --- a/mods/ra/rules/system.yaml +++ b/mods/ra/rules/system.yaml @@ -621,7 +621,6 @@ World: SpawnMPUnits: SpatialBins: BinSize: 4 - Shroud: Fog: PathFinder: ValidateOrder: