diff --git a/OpenRA.Game/Traits/Player/FrozenActorLayer.cs b/OpenRA.Game/Traits/Player/FrozenActorLayer.cs index 850d69d865..bbb099ca2d 100755 --- a/OpenRA.Game/Traits/Player/FrozenActorLayer.cs +++ b/OpenRA.Game/Traits/Player/FrozenActorLayer.cs @@ -84,6 +84,8 @@ namespace OpenRA.Traits } return Renderables; } + + public bool HasRenderables { get { return Renderables != null; } } } public class FrozenActorLayer : IRender, ITick, ISync diff --git a/OpenRA.Mods.RA/Effects/GpsDot.cs b/OpenRA.Mods.RA/Effects/GpsDot.cs index 9e9e3e1b34..d336e46b65 100644 --- a/OpenRA.Mods.RA/Effects/GpsDot.cs +++ b/OpenRA.Mods.RA/Effects/GpsDot.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using OpenRA.Effects; +using OpenRA.FileFormats; using OpenRA.Graphics; using OpenRA.Traits; @@ -32,9 +33,12 @@ namespace OpenRA.Mods.RA.Effects GpsDotInfo info; Animation anim; - GpsWatcher watcher; - HiddenUnderFog huf; - Spy spy; + Lazy huf; + Lazy fuf; + Lazy spy; + Cache watcher; + Cache frozen; + bool show = false; public GpsDot(Actor self, GpsDotInfo info) @@ -45,36 +49,45 @@ namespace OpenRA.Mods.RA.Effects anim.PlayRepeating(info.String); self.World.AddFrameEndTask(w => w.Add(this)); + + huf = Lazy.New(() => self.TraitOrDefault()); + fuf = Lazy.New(() => self.TraitOrDefault()); + spy = Lazy.New(() => self.TraitOrDefault()); + watcher = new Cache(p => p.PlayerActor.Trait()); + frozen = new Cache(p => p.PlayerActor.Trait()); + } + + bool ShouldShowIndicator() + { + // Can be granted at runtime via a crate, so can't cache + var cloak = self.TraitOrDefault(); + if (cloak != null && cloak.Cloaked) + return false; + + if (spy.Value != null && spy.Value.Disguised) + return false; + + if (huf.Value != null && !huf.Value.IsVisible(self, self.World.RenderPlayer)) + return true; + + if (fuf.Value == null) + return false; + + var f = frozen[self.World.RenderPlayer].FromID(self.ActorID); + return f.Visible && !f.HasRenderables; } - bool firstTick = true; public void Tick(World world) { if (self.Destroyed) world.AddFrameEndTask(w => w.Remove(this)); - if (!self.IsInWorld || self.Destroyed) + show = false; + if (!self.IsInWorld || self.Destroyed || self.World.RenderPlayer == null) return; - // Can be granted at runtime via a crate, so can't cache - var cloak = self.TraitOrDefault(); - - if (firstTick) - { - huf = self.TraitOrDefault(); - spy = self.TraitOrDefault(); - firstTick = false; - } - - // Can change with the Shroud selector for observers so don't cache. - if (self.World.RenderPlayer != null) - watcher = self.World.RenderPlayer.PlayerActor.Trait(); - - var hasGps = (watcher != null && (watcher.Granted || watcher.GrantedAllies)); - var hasDot = (huf != null && !huf.IsVisible(self, self.World.RenderPlayer)); - var dotHidden = (cloak != null && cloak.Cloaked) || (spy != null && spy.Disguised); - - show = hasGps && hasDot && !dotHidden; + var gps = watcher[self.World.RenderPlayer]; + show = (gps.Granted || gps.GrantedAllies) && ShouldShowIndicator(); } public IEnumerable Render(WorldRenderer wr) @@ -82,7 +95,7 @@ namespace OpenRA.Mods.RA.Effects if (!show || self.Destroyed) return SpriteRenderable.None; - var palette = wr.Palette(info.IndicatorPalettePrefix+self.Owner.InternalName); + var palette = wr.Palette(info.IndicatorPalettePrefix + self.Owner.InternalName); return anim.Render(self.CenterPosition, palette); } } diff --git a/mods/ra/bits/gpsdot.shp b/mods/ra/bits/gpsdot.shp index cc42692f55..40c47ee7ec 100644 Binary files a/mods/ra/bits/gpsdot.shp and b/mods/ra/bits/gpsdot.shp differ diff --git a/mods/ra/rules/defaults.yaml b/mods/ra/rules/defaults.yaml index d105ef291a..081acf3827 100644 --- a/mods/ra/rules/defaults.yaml +++ b/mods/ra/rules/defaults.yaml @@ -237,6 +237,8 @@ Range: 3 BodyOrientation: FrozenUnderFog: + GpsDot: + String:Structure ^Wall: AppearsOnRadar: @@ -292,6 +294,7 @@ -CapturableBar: FrozenUnderFog: StartsRevealed: true + -GpsDot: ^AmmoBox: Inherits: ^TechBuilding diff --git a/mods/ra/sequences/misc.yaml b/mods/ra/sequences/misc.yaml index d8a96aa2c1..f45fe3f9ed 100644 --- a/mods/ra/sequences/misc.yaml +++ b/mods/ra/sequences/misc.yaml @@ -394,3 +394,5 @@ gpsdot: Start: 4 Harvester: Start: 5 + Structure: + Start: 6