Merge pull request #10120 from RoosterDragon/gps-dot-perf
Fix broken GPS and frozen actor behaviour
This commit is contained in:
@@ -42,8 +42,11 @@ namespace OpenRA.Traits
|
||||
|
||||
public bool Visible = true;
|
||||
public bool Shrouded { get; private set; }
|
||||
public bool NeedRenderables { get; private set; }
|
||||
public bool IsRendering { get; private set; }
|
||||
public bool NeedRenderables { get; set; }
|
||||
public IRenderable[] Renderables = NoRenderables;
|
||||
static readonly IRenderable[] NoRenderables = new IRenderable[0];
|
||||
|
||||
int flashTicks;
|
||||
|
||||
public FrozenActor(Actor self, PPos[] footprint, Shroud shroud, bool startsRevealed)
|
||||
{
|
||||
@@ -69,11 +72,6 @@ namespace OpenRA.Traits
|
||||
public ActorInfo Info { get { return actor.Info; } }
|
||||
public Actor Actor { get { return !actor.IsDead ? actor : null; } }
|
||||
|
||||
static readonly IRenderable[] NoRenderables = new IRenderable[0];
|
||||
|
||||
int flashTicks;
|
||||
IRenderable[] renderables = NoRenderables;
|
||||
|
||||
public void Tick()
|
||||
{
|
||||
UpdateVisibility();
|
||||
@@ -103,8 +101,7 @@ namespace OpenRA.Traits
|
||||
Shrouded = false;
|
||||
}
|
||||
|
||||
if (Visible && !wasVisible)
|
||||
NeedRenderables = true;
|
||||
NeedRenderables = Visible && !wasVisible;
|
||||
}
|
||||
|
||||
public void Flash()
|
||||
@@ -114,31 +111,20 @@ namespace OpenRA.Traits
|
||||
|
||||
public IEnumerable<IRenderable> Render(WorldRenderer wr)
|
||||
{
|
||||
if (NeedRenderables)
|
||||
{
|
||||
NeedRenderables = false;
|
||||
if (!actor.Disposed)
|
||||
{
|
||||
IsRendering = true;
|
||||
renderables = actor.Render(wr).ToArray();
|
||||
IsRendering = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (Shrouded)
|
||||
return NoRenderables;
|
||||
|
||||
if (flashTicks > 0 && flashTicks % 2 == 0)
|
||||
{
|
||||
var highlight = wr.Palette("highlight");
|
||||
return renderables.Concat(renderables.Where(r => !r.IsDecoration)
|
||||
return Renderables.Concat(Renderables.Where(r => !r.IsDecoration)
|
||||
.Select(r => r.WithPalette(highlight)));
|
||||
}
|
||||
|
||||
return renderables;
|
||||
return Renderables;
|
||||
}
|
||||
|
||||
public bool HasRenderables { get { return !Shrouded && renderables.Any(); } }
|
||||
public bool HasRenderables { get { return !Shrouded && Renderables.Any(); } }
|
||||
|
||||
public bool ShouldBeRemoved(Player owner)
|
||||
{
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public object Create(ActorInitializer init) { return new FrozenUnderFog(init, this); }
|
||||
}
|
||||
|
||||
public class FrozenUnderFog : IRenderModifier, IDefaultVisibility, ITick, ISync
|
||||
public class FrozenUnderFog : IRenderModifier, IDefaultVisibility, ITick, ITickRender, ISync
|
||||
{
|
||||
[Sync] public int VisibilityHash;
|
||||
|
||||
@@ -41,6 +41,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
ITooltip tooltip;
|
||||
Health health;
|
||||
bool initialized;
|
||||
bool isRendering;
|
||||
|
||||
class FrozenState
|
||||
{
|
||||
@@ -143,11 +144,35 @@ namespace OpenRA.Mods.Common.Traits
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
public void TickRender(WorldRenderer wr, Actor self)
|
||||
{
|
||||
if (!initialized)
|
||||
return;
|
||||
|
||||
IRenderable[] renderables = null;
|
||||
foreach (var player in self.World.Players)
|
||||
{
|
||||
var frozen = stateByPlayer[player].FrozenActor;
|
||||
if (!frozen.NeedRenderables)
|
||||
continue;
|
||||
|
||||
if (renderables == null)
|
||||
{
|
||||
isRendering = true;
|
||||
renderables = self.Render(wr).ToArray();
|
||||
isRendering = false;
|
||||
}
|
||||
|
||||
frozen.NeedRenderables = false;
|
||||
frozen.Renderables = renderables;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IRenderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<IRenderable> r)
|
||||
{
|
||||
return
|
||||
IsVisible(self, self.World.RenderPlayer) ||
|
||||
(initialized && stateByPlayer[self.World.RenderPlayer].FrozenActor.IsRendering) ?
|
||||
(initialized && isRendering) ?
|
||||
r : SpriteRenderable.None;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,14 +37,23 @@ namespace OpenRA.Mods.RA.Effects
|
||||
readonly GpsDotInfo info;
|
||||
readonly Animation anim;
|
||||
|
||||
readonly Dictionary<Player, bool> showToPlayer = new Dictionary<Player, bool>();
|
||||
readonly Dictionary<Player, DotState> stateByPlayer = new Dictionary<Player, DotState>();
|
||||
readonly Lazy<HiddenUnderFog> huf;
|
||||
readonly Lazy<FrozenUnderFog> fuf;
|
||||
readonly Lazy<Disguise> disguise;
|
||||
readonly Lazy<Cloak> cloak;
|
||||
readonly Cache<Player, FrozenActorLayer> frozen;
|
||||
|
||||
Lazy<HiddenUnderFog> huf;
|
||||
Lazy<FrozenUnderFog> fuf;
|
||||
Lazy<Disguise> disguise;
|
||||
Lazy<Cloak> cloak;
|
||||
Cache<Player, GpsWatcher> watcher;
|
||||
Cache<Player, FrozenActorLayer> frozen;
|
||||
class DotState
|
||||
{
|
||||
public readonly GpsWatcher Gps;
|
||||
public bool IsTargetable;
|
||||
public bool ShouldRender;
|
||||
public DotState(GpsWatcher gps)
|
||||
{
|
||||
Gps = gps;
|
||||
}
|
||||
}
|
||||
|
||||
public GpsDot(Actor self, GpsDotInfo info)
|
||||
{
|
||||
@@ -60,19 +69,20 @@ namespace OpenRA.Mods.RA.Effects
|
||||
disguise = Exts.Lazy(() => self.TraitOrDefault<Disguise>());
|
||||
cloak = Exts.Lazy(() => self.TraitOrDefault<Cloak>());
|
||||
|
||||
watcher = new Cache<Player, GpsWatcher>(p => p.PlayerActor.Trait<GpsWatcher>());
|
||||
frozen = new Cache<Player, FrozenActorLayer>(p => p.PlayerActor.Trait<FrozenActorLayer>());
|
||||
|
||||
showToPlayer = self.World.Players.ToDictionary(x => x, x => false);
|
||||
stateByPlayer = self.World.Players.ToDictionary(p => p, p => new DotState(p.PlayerActor.Trait<GpsWatcher>()));
|
||||
}
|
||||
|
||||
public bool IsDotVisible(Player toPlayer)
|
||||
{
|
||||
return showToPlayer[toPlayer];
|
||||
return stateByPlayer[toPlayer].IsTargetable;
|
||||
}
|
||||
|
||||
bool ShouldShowIndicator(Player toPlayer)
|
||||
bool IsTargetableBy(Player toPlayer, out bool shouldRenderIndicator)
|
||||
{
|
||||
shouldRenderIndicator = false;
|
||||
|
||||
if (cloak.Value != null && cloak.Value.Cloaked)
|
||||
return false;
|
||||
|
||||
@@ -81,19 +91,27 @@ namespace OpenRA.Mods.RA.Effects
|
||||
|
||||
if (huf.Value != null && !huf.Value.IsVisible(self, toPlayer)
|
||||
&& toPlayer.Shroud.IsExplored(self.CenterPosition))
|
||||
{
|
||||
var f1 = FrozenActorForPlayer(toPlayer);
|
||||
shouldRenderIndicator = f1 == null || !f1.HasRenderables;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fuf.Value == null)
|
||||
return false;
|
||||
|
||||
var f = frozen[toPlayer].FromID(self.ActorID);
|
||||
if (f == null)
|
||||
var f2 = FrozenActorForPlayer(toPlayer);
|
||||
if (f2 == null)
|
||||
return false;
|
||||
|
||||
if (f.HasRenderables || f.NeedRenderables)
|
||||
return false;
|
||||
shouldRenderIndicator = !f2.HasRenderables;
|
||||
|
||||
return f.Visible && !f.Shrouded;
|
||||
return f2.Visible && !f2.Shrouded;
|
||||
}
|
||||
|
||||
FrozenActor FrozenActorForPlayer(Player player)
|
||||
{
|
||||
return frozen[player].FromID(self.ActorID);
|
||||
}
|
||||
|
||||
public void Tick(World world)
|
||||
@@ -106,14 +124,17 @@ namespace OpenRA.Mods.RA.Effects
|
||||
|
||||
foreach (var player in self.World.Players)
|
||||
{
|
||||
var gps = watcher[player];
|
||||
showToPlayer[player] = (gps.Granted || gps.GrantedAllies) && ShouldShowIndicator(player);
|
||||
var state = stateByPlayer[player];
|
||||
var shouldRender = false;
|
||||
var targetable = (state.Gps.Granted || state.Gps.GrantedAllies) && IsTargetableBy(player, out shouldRender);
|
||||
state.IsTargetable = targetable;
|
||||
state.ShouldRender = targetable && shouldRender;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IRenderable> Render(WorldRenderer wr)
|
||||
{
|
||||
if (self.World.RenderPlayer == null || !showToPlayer[self.World.RenderPlayer] || self.Disposed)
|
||||
if (self.World.RenderPlayer == null || !stateByPlayer[self.World.RenderPlayer].ShouldRender || self.Disposed)
|
||||
return SpriteRenderable.None;
|
||||
|
||||
var palette = wr.Palette(info.IndicatorPalettePrefix + self.Owner.InternalName);
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace OpenRA.Mods.RA.Traits
|
||||
foreach (var i in atek.World.ActorsWithTrait<GpsWatcher>())
|
||||
i.Trait.RefreshGranted();
|
||||
|
||||
if ((Granted || GrantedAllies) && atek.Owner.IsAlliedWith(atek.World.RenderPlayer))
|
||||
if ((Granted || GrantedAllies) && atek.Owner.IsAlliedWith(Owner))
|
||||
atek.Owner.Shroud.ExploreAll(atek.World);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user