From 45ccf0035e7f2850c2fcdacf71aac1b30396a250 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 13 Dec 2013 17:49:58 +1300 Subject: [PATCH 1/2] Only render the frozen actors that are visible. Fixes #4300. --- OpenRA.Game/Traits/Player/FrozenActorLayer.cs | 2 +- OpenRA.Game/Traits/World/ScreenMap.cs | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/OpenRA.Game/Traits/Player/FrozenActorLayer.cs b/OpenRA.Game/Traits/Player/FrozenActorLayer.cs index c39ed2de71..8992e21001 100755 --- a/OpenRA.Game/Traits/Player/FrozenActorLayer.cs +++ b/OpenRA.Game/Traits/Player/FrozenActorLayer.cs @@ -136,7 +136,7 @@ namespace OpenRA.Traits public virtual IEnumerable Render(Actor self, WorldRenderer wr) { - return frozen.Values + return world.ScreenMap.FrozenActorsInBox(owner, wr.Viewport.TopLeft, wr.Viewport.BottomRight) .Where(f => f.Visible) .SelectMany(ff => ff.Render(wr)); } diff --git a/OpenRA.Game/Traits/World/ScreenMap.cs b/OpenRA.Game/Traits/World/ScreenMap.cs index 6cc274a4dc..2e7c676cbf 100755 --- a/OpenRA.Game/Traits/World/ScreenMap.cs +++ b/OpenRA.Game/Traits/World/ScreenMap.cs @@ -161,5 +161,27 @@ namespace OpenRA.Traits return actorsInBox.Distinct(); } + + public IEnumerable FrozenActorsInBox(Player p, int2 a, int2 b) + { + return FrozenActorsInBox(p, Rectangle.FromLTRB(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y), Math.Max(a.X, b.X), Math.Max(a.Y, b.Y))); + } + + public IEnumerable FrozenActorsInBox(Player p, Rectangle r) + { + var left = (r.Left / info.BinSize).Clamp(0, cols - 1); + var right = (r.Right / info.BinSize).Clamp(0, cols - 1); + var top = (r.Top / info.BinSize).Clamp(0, rows - 1); + var bottom = (r.Bottom / info.BinSize).Clamp(0, rows - 1); + + var frozenInBox = new List(); + for (var j = top; j <= bottom; j++) + for (var i = left; i <= right; i++) + frozenInBox.AddRange(frozen[p][j * cols + i] + .Where(kv => kv.Key.IsValid && kv.Value.IntersectsWith(r)) + .Select(kv => kv.Key)); + + return frozenInBox.Distinct(); + } } } From 393b1bbc0a9ae32e07f942b988428bad645c6245 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 13 Dec 2013 22:32:45 +1300 Subject: [PATCH 2/2] Remove ContrailFader when complete. Fixes #4302. --- OpenRA.Game/Graphics/ContrailRenderable.cs | 2 ++ OpenRA.Mods.RA/Effects/ContrailFader.cs | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/OpenRA.Game/Graphics/ContrailRenderable.cs b/OpenRA.Game/Graphics/ContrailRenderable.cs index bfd3f2c8b7..ed87b44026 100644 --- a/OpenRA.Game/Graphics/ContrailRenderable.cs +++ b/OpenRA.Game/Graphics/ContrailRenderable.cs @@ -15,6 +15,8 @@ namespace OpenRA.Graphics { public struct ContrailRenderable : IRenderable { + public int Length { get { return trail.Length; } } + readonly World world; // Store trail positions in a circular buffer diff --git a/OpenRA.Mods.RA/Effects/ContrailFader.cs b/OpenRA.Mods.RA/Effects/ContrailFader.cs index 9957a02bd1..04f65ac001 100755 --- a/OpenRA.Mods.RA/Effects/ContrailFader.cs +++ b/OpenRA.Mods.RA/Effects/ContrailFader.cs @@ -18,6 +18,7 @@ namespace OpenRA.Mods.RA.Effects { WPos pos; ContrailRenderable trail; + int ticks; public ContrailFader(WPos pos, ContrailRenderable trail) { @@ -27,6 +28,9 @@ namespace OpenRA.Mods.RA.Effects public void Tick(World world) { + if (ticks++ == trail.Length) + world.AddFrameEndTask(w => w.Remove(this)); + trail.Update(pos); }