diff --git a/OpenRA.Game/Graphics/WorldRenderer.cs b/OpenRA.Game/Graphics/WorldRenderer.cs index f7dfa758af..375b00a1d7 100644 --- a/OpenRA.Game/Graphics/WorldRenderer.cs +++ b/OpenRA.Game/Graphics/WorldRenderer.cs @@ -87,7 +87,7 @@ namespace OpenRA.Graphics worldRenderables = worldRenderables.OrderBy(r => r, comparer); // Effects are drawn on top of all actors - // TODO: Allow effects to be interleaved with actors + // HACK: Effects aren't interleaved with actors. var effectRenderables = world.Effects .SelectMany(e => e.Render(this)); @@ -138,11 +138,25 @@ namespace OpenRA.Graphics Game.Renderer.DisableScissor(); - foreach (var g in world.Selection.Actors.Where(a => !a.Destroyed) + var overlayRenderables = world.Selection.Actors.Where(a => !a.Destroyed) .SelectMany(a => a.TraitsImplementing()) - .GroupBy(prs => prs.GetType())) - foreach (var t in g) - t.RenderAfterWorld(this); + .SelectMany(t => t.RenderAfterWorld(this)) + .ToList(); + + Game.Renderer.WorldVoxelRenderer.BeginFrame(); + for (var i = 0; i < overlayRenderables.Count; i++) + overlayRenderables[i].BeforeRender(this); + Game.Renderer.WorldVoxelRenderer.EndFrame(); + + // HACK: Keep old grouping behaviour + foreach (var g in overlayRenderables.GroupBy(prs => prs.GetType())) + foreach (var r in g) + r.Render(this); + + if (devTrait.Value != null && devTrait.Value.ShowDebugGeometry) + foreach (var g in overlayRenderables.GroupBy(prs => prs.GetType())) + foreach (var r in g) + r.RenderDebugGeometry(this); if (!world.IsShellmap && Game.Settings.Game.AlwaysShowStatusBars) { diff --git a/OpenRA.Game/Traits/DrawLineToTarget.cs b/OpenRA.Game/Traits/DrawLineToTarget.cs index 125c68f4cc..3decc07df2 100644 --- a/OpenRA.Game/Traits/DrawLineToTarget.cs +++ b/OpenRA.Game/Traits/DrawLineToTarget.cs @@ -58,25 +58,21 @@ namespace OpenRA.Traits lifetime = Info.Ticks; } - public void RenderAfterWorld(WorldRenderer wr) + public IEnumerable RenderAfterWorld(WorldRenderer wr) { var force = Game.GetModifierKeys().HasModifier(Modifiers.Alt); if ((lifetime <= 0 || --lifetime <= 0) && !force) - return; + yield break; if (targets == null || targets.Count == 0) - return; + yield break; - var from = wr.ScreenPxPosition(self.CenterPosition); foreach (var target in targets) { if (target.Type == TargetType.Invalid) continue; - var to = wr.ScreenPxPosition(target.CenterPosition); - Game.Renderer.WorldLineRenderer.DrawLine(from, to, c, c); - wr.DrawTargetMarker(c, from); - wr.DrawTargetMarker(c, to); + yield return new TargetLineRenderable(new [] { self.CenterPosition, target.CenterPosition }, c); } } diff --git a/OpenRA.Game/Traits/Selectable.cs b/OpenRA.Game/Traits/Selectable.cs index b89d25405b..69433f3353 100644 --- a/OpenRA.Game/Traits/Selectable.cs +++ b/OpenRA.Game/Traits/Selectable.cs @@ -52,16 +52,16 @@ namespace OpenRA.Traits } } - public void RenderAfterWorld(WorldRenderer wr) + public IEnumerable RenderAfterWorld(WorldRenderer wr) { if (!Info.Selectable) - return; + yield break; - new SelectionBoxRenderable(self, Color.White).Render(wr); - new SelectionBarsRenderable(self).Render(wr); + yield return new SelectionBoxRenderable(self, Color.White); + yield return new SelectionBarsRenderable(self); if (self.World.LocalPlayer != null && self.World.LocalPlayer.PlayerActor.Trait().PathDebug) - new TargetLineRenderable(ActivityTargetPath(), Color.Green).Render(wr); + yield return new TargetLineRenderable(ActivityTargetPath(), Color.Green); } } } diff --git a/OpenRA.Game/Traits/SelectionDecorations.cs b/OpenRA.Game/Traits/SelectionDecorations.cs index db0043765c..233624e1d8 100644 --- a/OpenRA.Game/Traits/SelectionDecorations.cs +++ b/OpenRA.Game/Traits/SelectionDecorations.cs @@ -8,6 +8,7 @@ */ #endregion +using System.Collections.Generic; using System.Linq; using OpenRA.Graphics; @@ -35,51 +36,56 @@ namespace OpenRA.Traits Info = info; } - public void RenderAfterWorld(WorldRenderer wr) + public IEnumerable RenderAfterWorld(WorldRenderer wr) { if (self.World.FogObscures(self)) - return; + yield break; + var b = self.Bounds.Value; var pos = wr.ScreenPxPosition(self.CenterPosition); - var bounds = self.Bounds.Value; - bounds.Offset(pos.X, pos.Y); + var tl = wr.Viewport.WorldToViewPx(pos + new int2(b.Left, b.Top)); + var bl = wr.Viewport.WorldToViewPx(pos + new int2(b.Left, b.Bottom)); + var tm = wr.Viewport.WorldToViewPx(pos + new int2((b.Left + b.Right) / 2, b.Top)); - var xy = new int2(bounds.Left, bounds.Top); - var xY = new int2(bounds.Left, bounds.Bottom); + foreach (var r in DrawControlGroup(wr, self, tl)) + yield return r; - DrawControlGroup(wr, self, xy); - DrawPips(wr, self, xY); - DrawTags(wr, self, new int2((bounds.Left + bounds.Right) / 2, bounds.Top)); + foreach (var r in DrawPips(wr, self, bl)) + yield return r; + + foreach (var r in DrawTags(wr, self, tm)) + yield return r; } - void DrawControlGroup(WorldRenderer wr, Actor self, int2 basePosition) + IEnumerable DrawControlGroup(WorldRenderer wr, Actor self, int2 basePosition) { var group = self.World.Selection.GetControlGroupForActor(self); - if (group == null) return; + if (group == null) + yield break; var pipImages = new Animation(self.World, "pips"); var pal = wr.Palette(Info.Palette); pipImages.PlayFetchIndex("groups", () => (int)group); pipImages.Tick(); - var pos = wr.Viewport.WorldToViewPx(basePosition) - (0.5f * pipImages.Image.size).ToInt2() + new int2(9, 5); - Game.Renderer.SpriteRenderer.DrawSprite(pipImages.Image, pos, pal); + var pos = basePosition - (0.5f * pipImages.Image.size).ToInt2() + new int2(9, 5); + yield return new UISpriteRenderable(pipImages.Image, pos, 0, pal, 1f); } - void DrawPips(WorldRenderer wr, Actor self, int2 basePosition) + IEnumerable DrawPips(WorldRenderer wr, Actor self, int2 basePosition) { if (!self.Owner.IsAlliedWith(self.World.RenderPlayer)) - return; + yield break; var pipSources = self.TraitsImplementing(); if (!pipSources.Any()) - return; + yield break; var pipImages = new Animation(self.World, "pips"); pipImages.PlayRepeating(pipStrings[0]); var pipSize = pipImages.Image.size.ToInt2(); - var pipxyBase = wr.Viewport.WorldToViewPx(basePosition) + new int2(1 - pipSize.X / 2, - (3 + pipSize.Y / 2)); + var pipxyBase = basePosition + new int2(1 - pipSize.X / 2, - (3 + pipSize.Y / 2)); var pipxyOffset = new int2(0, 0); var pal = wr.Palette(Info.Palette); var width = self.Bounds.Value.Width; @@ -101,7 +107,7 @@ namespace OpenRA.Traits pipImages.PlayRepeating(pipStrings[(int)pip]); pipxyOffset += new int2(pipSize.X, 0); - Game.Renderer.SpriteRenderer.DrawSprite(pipImages.Image, pipxyBase + pipxyOffset, pal); + yield return new UISpriteRenderable(pipImages.Image, pipxyBase + pipxyOffset, 0, pal, 1f); } // Increment row @@ -110,15 +116,14 @@ namespace OpenRA.Traits } } - void DrawTags(WorldRenderer wr, Actor self, int2 basePosition) + IEnumerable DrawTags(WorldRenderer wr, Actor self, int2 basePosition) { if (!self.Owner.IsAlliedWith(self.World.RenderPlayer)) - return; + yield break; var tagImages = new Animation(self.World, "pips"); var pal = wr.Palette(Info.Palette); var tagxyOffset = new int2(0, 6); - var tagBase = wr.Viewport.WorldToViewPx(basePosition); foreach (var tags in self.TraitsImplementing()) { @@ -128,8 +133,8 @@ namespace OpenRA.Traits continue; tagImages.PlayRepeating(tagStrings[(int)tag]); - var pos = tagBase + tagxyOffset - (0.5f * tagImages.Image.size).ToInt2(); - Game.Renderer.SpriteRenderer.DrawSprite(tagImages.Image, pos, pal); + var pos = basePosition + tagxyOffset - (0.5f * tagImages.Image.size).ToInt2(); + yield return new UISpriteRenderable(tagImages.Image, pos, 0, pal, 1f); // Increment row tagxyOffset.Y += 8; diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 563acaeece..d5bf7c3dca 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -225,7 +225,7 @@ namespace OpenRA.Traits public interface IPostRender { void RenderAfterWorld(WorldRenderer wr, Actor self); } public interface IRenderShroud { void RenderShroud(WorldRenderer wr, Shroud shroud); } - public interface IPostRenderSelection { void RenderAfterWorld(WorldRenderer wr); } + public interface IPostRenderSelection { IEnumerable RenderAfterWorld(WorldRenderer wr); } public interface IBodyOrientation { WAngle CameraPitch { get; } diff --git a/OpenRA.Mods.RA/Buildings/BaseProvider.cs b/OpenRA.Mods.RA/Buildings/BaseProvider.cs index 55754486db..4738cc211a 100755 --- a/OpenRA.Mods.RA/Buildings/BaseProvider.cs +++ b/OpenRA.Mods.RA/Buildings/BaseProvider.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, @@ -8,6 +8,7 @@ */ #endregion +using System.Collections.Generic; using System.Drawing; using OpenRA.Graphics; using OpenRA.Mods.RA.Graphics; @@ -62,20 +63,19 @@ namespace OpenRA.Mods.RA.Buildings return self.Owner == self.World.RenderPlayer || (allyBuildRadius && self.Owner.IsAlliedWith(self.World.RenderPlayer)); } - // Range circle - public void RenderAfterWorld(WorldRenderer wr) + public IEnumerable RenderAfterWorld(WorldRenderer wr) { // Visible to player and allies if (!ValidRenderPlayer()) - return; + yield break; - new RangeCircleRenderable( + yield return new RangeCircleRenderable( self.CenterPosition, WRange.FromCells(Info.Range), 0, Color.FromArgb(128, Ready() ? Color.White : Color.Red), Color.FromArgb(96, Color.Black) - ).Render(wr); + ); } // Selection bar diff --git a/OpenRA.Mods.RA/Minelayer.cs b/OpenRA.Mods.RA/Minelayer.cs index e434e15e1c..603d4f9dea 100644 --- a/OpenRA.Mods.RA/Minelayer.cs +++ b/OpenRA.Mods.RA/Minelayer.cs @@ -114,15 +114,15 @@ namespace OpenRA.Mods.RA yield return new CPos(i, j); } - public void RenderAfterWorld(WorldRenderer wr) + public IEnumerable RenderAfterWorld(WorldRenderer wr) { if (self.Owner != self.World.LocalPlayer || Minefield == null) - return; + yield break; var pal = wr.Palette("terrain"); foreach (var c in Minefield) - new SpriteRenderable(tile, self.World.Map.CenterOfCell(c), - WVec.Zero, -511, pal, 1f, true).Render(wr); + yield return new SpriteRenderable(tile, self.World.Map.CenterOfCell(c), + WVec.Zero, -511, pal, 1f, true); } class MinefieldOrderGenerator : IOrderGenerator diff --git a/OpenRA.Mods.RA/Orders/PlaceBuildingOrderGenerator.cs b/OpenRA.Mods.RA/Orders/PlaceBuildingOrderGenerator.cs index 199837eac9..c5e1143b7f 100644 --- a/OpenRA.Mods.RA/Orders/PlaceBuildingOrderGenerator.cs +++ b/OpenRA.Mods.RA/Orders/PlaceBuildingOrderGenerator.cs @@ -89,7 +89,8 @@ namespace OpenRA.Mods.RA.Orders var actorInfo = rules.Actors[Building]; foreach (var dec in actorInfo.Traits.WithInterface()) - dec.Render(wr, world, actorInfo, world.Map.CenterOfCell(xy)); + foreach (var r in dec.Render(wr, world, actorInfo, world.Map.CenterOfCell(xy))) + r.Render(wr); var cells = new Dictionary(); // Linebuild for walls. diff --git a/OpenRA.Mods.RA/Render/RenderBuilding.cs b/OpenRA.Mods.RA/Render/RenderBuilding.cs index b0d6efc02c..416866cc84 100755 --- a/OpenRA.Mods.RA/Render/RenderBuilding.cs +++ b/OpenRA.Mods.RA/Render/RenderBuilding.cs @@ -9,6 +9,7 @@ #endregion using System; +using System.Collections.Generic; using System.Linq; using OpenRA.Graphics; using OpenRA.Mods.RA.Activities; @@ -23,13 +24,14 @@ namespace OpenRA.Mods.RA.Render public override object Create(ActorInitializer init) { return new RenderBuilding(init, this);} - public void Render(WorldRenderer wr, World w, ActorInfo ai, WPos centerPosition) + public IEnumerable Render(WorldRenderer wr, World w, ActorInfo ai, WPos centerPosition) { if (!ai.Traits.Get().RequiresBaseProvider) - return; + yield break; foreach (var a in w.ActorsWithTrait()) - a.Trait.RenderAfterWorld(wr); + foreach (var r in a.Trait.RenderAfterWorld(wr)) + yield return r; } } diff --git a/OpenRA.Mods.RA/RenderDetectionCircle.cs b/OpenRA.Mods.RA/RenderDetectionCircle.cs index 962a409f64..861ff7b892 100644 --- a/OpenRA.Mods.RA/RenderDetectionCircle.cs +++ b/OpenRA.Mods.RA/RenderDetectionCircle.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, @@ -8,6 +8,7 @@ */ #endregion +using System.Collections.Generic; using System.Drawing; using OpenRA.Graphics; using OpenRA.Mods.RA.Graphics; @@ -26,18 +27,18 @@ namespace OpenRA.Mods.RA public RenderDetectionCircle(Actor self) { this.self = self; } - public void RenderAfterWorld(WorldRenderer wr) + public IEnumerable RenderAfterWorld(WorldRenderer wr) { if (self.Owner != self.World.LocalPlayer) - return; + yield break; - new RangeCircleRenderable( + yield return new RangeCircleRenderable( self.CenterPosition, WRange.FromCells(self.Info.Traits.Get().Range), 0, Color.FromArgb(128, Color.LimeGreen), Color.FromArgb(96, Color.Black) - ).Render(wr); + ); } } } diff --git a/OpenRA.Mods.RA/RenderJammerCircle.cs b/OpenRA.Mods.RA/RenderJammerCircle.cs index c473d13e7b..3a5e4c8c1d 100644 --- a/OpenRA.Mods.RA/RenderJammerCircle.cs +++ b/OpenRA.Mods.RA/RenderJammerCircle.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2013 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, @@ -8,6 +8,7 @@ */ #endregion +using System.Collections.Generic; using System.Drawing; using OpenRA.Graphics; using OpenRA.Mods.RA.Graphics; @@ -18,19 +19,36 @@ namespace OpenRA.Mods.RA //todo: remove all the Render*Circle duplication class RenderJammerCircleInfo : ITraitInfo, IPlaceBuildingDecoration { - public void Render(WorldRenderer wr, World w, ActorInfo ai, WPos centerPosition) + public IEnumerable Render(WorldRenderer wr, World w, ActorInfo ai, WPos centerPosition) { var jamsMissiles = ai.Traits.GetOrDefault(); if (jamsMissiles != null) - RenderJammerCircle.DrawRangeCircle(wr, centerPosition, jamsMissiles.Range, Color.Red); + { + yield return new RangeCircleRenderable( + centerPosition, + WRange.FromCells(jamsMissiles.Range), + 0, + Color.FromArgb(128, Color.Red), + Color.FromArgb(96, Color.Black) + ); + } var jamsRadar = ai.Traits.GetOrDefault(); if (jamsRadar != null) - RenderJammerCircle.DrawRangeCircle(wr, centerPosition, jamsRadar.Range, Color.Blue); + { + yield return new RangeCircleRenderable( + centerPosition, + WRange.FromCells(jamsRadar.Range), + 0, + Color.FromArgb(128, Color.Blue), + Color.FromArgb(96, Color.Black) + ); + } foreach (var a in w.ActorsWithTrait()) if (a.Actor.Owner == a.Actor.World.LocalPlayer) - a.Trait.RenderAfterWorld(wr); + foreach (var r in a.Trait.RenderAfterWorld(wr)) + yield return r; } public object Create(ActorInitializer init) { return new RenderJammerCircle(init.self); } @@ -42,29 +60,34 @@ namespace OpenRA.Mods.RA public RenderJammerCircle(Actor self) { this.self = self; } - public void RenderAfterWorld(WorldRenderer wr) + public IEnumerable RenderAfterWorld(WorldRenderer wr) { if (self.Owner != self.World.LocalPlayer) - return; + yield break; var jamsMissiles = self.Info.Traits.GetOrDefault(); if (jamsMissiles != null) - DrawRangeCircle(wr, self.CenterPosition, jamsMissiles.Range, Color.Red); + { + yield return new RangeCircleRenderable( + self.CenterPosition, + WRange.FromCells(jamsMissiles.Range), + 0, + Color.FromArgb(128, Color.Red), + Color.FromArgb(96, Color.Black) + ); + } var jamsRadar = self.Info.Traits.GetOrDefault(); if (jamsRadar != null) - DrawRangeCircle(wr, self.CenterPosition, jamsRadar.Range, Color.Blue); - } - - public static void DrawRangeCircle(WorldRenderer wr, WPos pos, int range, Color color) - { - new RangeCircleRenderable( - pos, - WRange.FromCells(range), - 0, - Color.FromArgb(128, color), - Color.FromArgb(96, Color.Black) - ).Render(wr); + { + yield return new RangeCircleRenderable( + self.CenterPosition, + WRange.FromCells(jamsRadar.Range), + 0, + Color.FromArgb(128, Color.Blue), + Color.FromArgb(96, Color.Black) + ); + } } } } diff --git a/OpenRA.Mods.RA/RenderRangeCircle.cs b/OpenRA.Mods.RA/RenderRangeCircle.cs index 728c40c8a6..1b71520788 100644 --- a/OpenRA.Mods.RA/RenderRangeCircle.cs +++ b/OpenRA.Mods.RA/RenderRangeCircle.cs @@ -8,6 +8,7 @@ */ #endregion +using System.Collections.Generic; using System.Drawing; using System.Linq; using OpenRA.Graphics; @@ -18,7 +19,7 @@ namespace OpenRA.Mods.RA { public interface IPlaceBuildingDecoration { - void Render(WorldRenderer wr, World w, ActorInfo ai, WPos centerPosition); + IEnumerable Render(WorldRenderer wr, World w, ActorInfo ai, WPos centerPosition); } [Desc("Draw a circle indicating my weapon's range.")] @@ -29,7 +30,7 @@ namespace OpenRA.Mods.RA [Desc("Range to draw if no armaments are available")] public readonly WRange FallbackRange = WRange.Zero; - public void Render(WorldRenderer wr, World w, ActorInfo ai, WPos centerPosition) + public IEnumerable Render(WorldRenderer wr, World w, ActorInfo ai, WPos centerPosition) { var armaments = ai.Traits.WithInterface(); var range = FallbackRange; @@ -38,20 +39,21 @@ namespace OpenRA.Mods.RA range = armaments.Select(a => w.Map.Rules.Weapons[a.Weapon.ToLowerInvariant()].Range).Max(); if (range == WRange.Zero) - return; + yield break; - new RangeCircleRenderable( + yield return new RangeCircleRenderable( centerPosition, range, 0, Color.FromArgb(128, Color.Yellow), Color.FromArgb(96, Color.Black) - ).Render(wr); + ); foreach (var a in w.ActorsWithTrait()) if (a.Actor.Owner == a.Actor.World.LocalPlayer) if (a.Actor.Info.Traits.Get().RangeCircleType == RangeCircleType) - a.Trait.RenderAfterWorld(wr); + foreach (var r in a.Trait.RenderAfterWorld(wr)) + yield return r; } public object Create(ActorInitializer init) { return new RenderRangeCircle(init.self); } @@ -68,18 +70,18 @@ namespace OpenRA.Mods.RA attack = self.Trait(); } - public void RenderAfterWorld(WorldRenderer wr) + public IEnumerable RenderAfterWorld(WorldRenderer wr) { if (self.Owner != self.World.LocalPlayer) - return; + yield break; - new RangeCircleRenderable( + yield return new RangeCircleRenderable( self.CenterPosition, attack.GetMaximumRange(), 0, Color.FromArgb(128, Color.Yellow), Color.FromArgb(96, Color.Black) - ).Render(wr); + ); } } } diff --git a/OpenRA.Mods.RA/RenderShroudCircle.cs b/OpenRA.Mods.RA/RenderShroudCircle.cs index 9dbfaf68d1..3b7779e270 100644 --- a/OpenRA.Mods.RA/RenderShroudCircle.cs +++ b/OpenRA.Mods.RA/RenderShroudCircle.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, @@ -8,6 +8,7 @@ */ #endregion +using System.Collections.Generic; using System.Drawing; using OpenRA.Graphics; using OpenRA.Mods.RA.Graphics; @@ -17,19 +18,20 @@ namespace OpenRA.Mods.RA { class RenderShroudCircleInfo : ITraitInfo, IPlaceBuildingDecoration { - public void Render(WorldRenderer wr, World w, ActorInfo ai, WPos centerPosition) + public IEnumerable Render(WorldRenderer wr, World w, ActorInfo ai, WPos centerPosition) { - new RangeCircleRenderable( + yield return new RangeCircleRenderable( centerPosition, ai.Traits.Get().Range, 0, Color.FromArgb(128, Color.Cyan), Color.FromArgb(96, Color.Black) - ).Render(wr); + ); foreach (var a in w.ActorsWithTrait()) if (a.Actor.Owner == a.Actor.World.LocalPlayer) - a.Trait.RenderAfterWorld(wr); + foreach (var r in a.Trait.RenderAfterWorld(wr)) + yield return r; } public object Create(ActorInitializer init) { return new RenderShroudCircle(init.self); } @@ -41,18 +43,18 @@ namespace OpenRA.Mods.RA public RenderShroudCircle(Actor self) { this.self = self; } - public void RenderAfterWorld(WorldRenderer wr) + public IEnumerable RenderAfterWorld(WorldRenderer wr) { if (self.Owner != self.World.LocalPlayer) - return; + yield break; - new RangeCircleRenderable( + yield return new RangeCircleRenderable( self.CenterPosition, self.Info.Traits.Get().Range, 0, Color.FromArgb(128, Color.Cyan), Color.FromArgb(96, Color.Black) - ).Render(wr); + ); } } }