From 45ccf0035e7f2850c2fcdacf71aac1b30396a250 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 13 Dec 2013 17:49:58 +1300 Subject: [PATCH] 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(); + } } }