diff --git a/OpenRA.Game/Player.cs b/OpenRA.Game/Player.cs index bb09eac700..f53e9a0895 100644 --- a/OpenRA.Game/Player.cs +++ b/OpenRA.Game/Player.cs @@ -159,13 +159,13 @@ namespace OpenRA public bool CanTargetActor(Actor a) { - if (HasFogVisibility) + if (HasFogVisibility && fogVisibilities.Any(f => f.IsVisible(a))) return true; return CanViewActor(a); } - public bool HasFogVisibility { get { return fogVisibilities.Any(f => f.HasFogVisibility(this)); } } + public bool HasFogVisibility { get { return fogVisibilities.Any(f => f.HasFogVisibility()); } } #region Scripting interface diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 800317fdf4..de5252edbf 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -189,7 +189,12 @@ namespace OpenRA.Traits public interface IDefaultVisibilityInfo : ITraitInfo { } public interface IDefaultVisibility { bool IsVisible(Actor self, Player byPlayer); } public interface IVisibilityModifier { bool IsVisible(Actor self, Player byPlayer); } - public interface IFogVisibilityModifier { bool HasFogVisibility(Player byPlayer); } + + public interface IFogVisibilityModifier + { + bool IsVisible(Actor actor); + bool HasFogVisibility(); + } public interface IRadarColorModifier { Color RadarColorOverride(Actor self); } diff --git a/OpenRA.Mods.RA/Effects/GpsDot.cs b/OpenRA.Mods.RA/Effects/GpsDot.cs index ded339f9ef..d8515b5380 100644 --- a/OpenRA.Mods.RA/Effects/GpsDot.cs +++ b/OpenRA.Mods.RA/Effects/GpsDot.cs @@ -10,6 +10,7 @@ using System; using System.Collections.Generic; +using System.Linq; using OpenRA.Effects; using OpenRA.Graphics; using OpenRA.Mods.Common.Traits; @@ -36,6 +37,8 @@ namespace OpenRA.Mods.RA.Effects readonly GpsDotInfo info; readonly Animation anim; + readonly Dictionary showToPlayer = new Dictionary(); + Lazy huf; Lazy fuf; Lazy disguise; @@ -43,8 +46,6 @@ namespace OpenRA.Mods.RA.Effects Cache watcher; Cache frozen; - bool show = false; - public GpsDot(Actor self, GpsDotInfo info) { this.self = self; @@ -61,9 +62,16 @@ namespace OpenRA.Mods.RA.Effects watcher = new Cache(p => p.PlayerActor.Trait()); frozen = new Cache(p => p.PlayerActor.Trait()); + + showToPlayer = self.World.Players.ToDictionary(x => x, x => false); } - bool ShouldShowIndicator() + public bool IsDotVisible(Player toPlayer) + { + return showToPlayer[toPlayer]; + } + + bool ShouldShowIndicator(Player toPlayer) { if (cloak.Value != null && cloak.Value.Cloaked) return false; @@ -71,20 +79,21 @@ namespace OpenRA.Mods.RA.Effects if (disguise.Value != null && disguise.Value.Disguised) return false; - if (huf.Value != null && !huf.Value.IsVisible(self, self.World.RenderPlayer)) + if (huf.Value != null && !huf.Value.IsVisible(self, toPlayer) + && toPlayer.Shroud.IsExplored(self.CenterPosition)) return true; if (fuf.Value == null) return false; - var f = frozen[self.World.RenderPlayer].FromID(self.ActorID); + var f = frozen[toPlayer].FromID(self.ActorID); if (f == null) return false; if (f.HasRenderables || f.NeedRenderables) return false; - return f.Visible; + return f.Visible && !f.Shrouded; } public void Tick(World world) @@ -92,17 +101,19 @@ namespace OpenRA.Mods.RA.Effects if (self.Disposed) world.AddFrameEndTask(w => w.Remove(this)); - show = false; - if (!self.IsInWorld || self.IsDead || self.World.RenderPlayer == null) + if (!self.IsInWorld || self.IsDead) return; - var gps = watcher[self.World.RenderPlayer]; - show = (gps.Granted || gps.GrantedAllies) && ShouldShowIndicator(); + foreach (var player in self.World.Players) + { + var gps = watcher[player]; + showToPlayer[player] = (gps.Granted || gps.GrantedAllies) && ShouldShowIndicator(player); + } } public IEnumerable Render(WorldRenderer wr) { - if (!show || self.Disposed) + if (self.World.RenderPlayer == null || !showToPlayer[self.World.RenderPlayer] || self.Disposed) return SpriteRenderable.None; var palette = wr.Palette(info.IndicatorPalettePrefix + self.Owner.InternalName); diff --git a/OpenRA.Mods.RA/Traits/SupportPowers/GpsPower.cs b/OpenRA.Mods.RA/Traits/SupportPowers/GpsPower.cs index e8612a11dc..16ca4eb1ea 100644 --- a/OpenRA.Mods.RA/Traits/SupportPowers/GpsPower.cs +++ b/OpenRA.Mods.RA/Traits/SupportPowers/GpsPower.cs @@ -76,10 +76,19 @@ namespace OpenRA.Mods.RA.Traits Owner.Shroud.ExploreAll(Owner.World); } - public bool HasFogVisibility(Player byPlayer) + public bool HasFogVisibility() { return Granted || GrantedAllies; } + + public bool IsVisible(Actor actor) + { + var gpsDot = actor.TraitOrDefault(); + if (gpsDot == null) + return false; + + return gpsDot.IsDotVisible(Owner); + } } class GpsPowerInfo : SupportPowerInfo