diff --git a/OpenRA.Game/Graphics/Animation.cs b/OpenRA.Game/Graphics/Animation.cs index 99fa370093..df6581eb81 100644 --- a/OpenRA.Game/Graphics/Animation.cs +++ b/OpenRA.Game/Graphics/Animation.cs @@ -9,6 +9,7 @@ #endregion using System; +using System.Collections.Generic; namespace OpenRA.Graphics { @@ -44,6 +45,16 @@ namespace OpenRA.Graphics } } + public IEnumerable Render(WPos pos, int zOffset, PaletteReference palette, float scale) + { + yield return new SpriteRenderable(Image, pos, zOffset, palette, scale); + } + + public IEnumerable Render(WPos pos, PaletteReference palette) + { + return Render(pos, 0, palette, 1f); + } + public void Play(string sequenceName) { PlayThen(sequenceName, null); diff --git a/OpenRA.Game/Graphics/AnimationWithOffset.cs b/OpenRA.Game/Graphics/AnimationWithOffset.cs index 338fbcf956..cc9ce31334 100644 --- a/OpenRA.Game/Graphics/AnimationWithOffset.cs +++ b/OpenRA.Game/Graphics/AnimationWithOffset.cs @@ -9,6 +9,7 @@ #endregion using System; +using System.Collections.Generic; using OpenRA.Traits; namespace OpenRA.Graphics @@ -34,19 +35,14 @@ namespace OpenRA.Graphics this.ZOffset = zOffset; } - public IRenderable Image(Actor self, WorldRenderer wr, PaletteReference pal) - { - return Image(self, wr, pal, 1f); - } - - public IRenderable Image(Actor self, WorldRenderer wr, PaletteReference pal, float scale) + public IEnumerable Render(Actor self, WorldRenderer wr, PaletteReference pal, float scale) { var p = self.CenterPosition; if (OffsetFunc != null) p += OffsetFunc(); var z = (ZOffset != null) ? ZOffset(p) : 0; - return new SpriteRenderable(Animation.Image, p, z, pal, scale); + return Animation.Render(p, z, pal, scale); } public static implicit operator AnimationWithOffset(Animation a) diff --git a/OpenRA.Game/Graphics/Renderable.cs b/OpenRA.Game/Graphics/Renderable.cs index 49d7d14ccf..923385a473 100644 --- a/OpenRA.Game/Graphics/Renderable.cs +++ b/OpenRA.Game/Graphics/Renderable.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using System.Drawing; +using System.Linq; namespace OpenRA.Graphics { @@ -47,6 +48,8 @@ namespace OpenRA.Graphics public struct SpriteRenderable : IRenderable { + public static readonly IEnumerable None = new IRenderable[0].AsEnumerable(); + readonly Sprite sprite; readonly WPos pos; readonly int zOffset; diff --git a/OpenRA.Game/Traits/Render/RenderSimple.cs b/OpenRA.Game/Traits/Render/RenderSimple.cs index 76f9acaeb9..42e3eae6c3 100755 --- a/OpenRA.Game/Traits/Render/RenderSimple.cs +++ b/OpenRA.Game/Traits/Render/RenderSimple.cs @@ -25,7 +25,7 @@ namespace OpenRA.Traits var anim = new Animation(RenderSimple.GetImage(ai), () => 0); anim.PlayRepeating("idle"); - yield return new SpriteRenderable(anim.Image, WPos.Zero, 0, pr, 1f); + return anim.Render(WPos.Zero, pr); } } diff --git a/OpenRA.Game/Traits/Render/RenderSprites.cs b/OpenRA.Game/Traits/Render/RenderSprites.cs index e3b4d8543c..cbd8844d48 100755 --- a/OpenRA.Game/Traits/Render/RenderSprites.cs +++ b/OpenRA.Game/Traits/Render/RenderSprites.cs @@ -90,8 +90,13 @@ namespace OpenRA.Traits } foreach (var a in anims.Values) - if (a.DisableFunc == null || !a.DisableFunc()) - yield return a.Image(self, wr, palette, Info.Scale); + { + if (a.DisableFunc != null && a.DisableFunc()) + continue; + + foreach (var r in a.Render(self, wr, palette, Info.Scale)) + yield return r; + } } public virtual void Tick(Actor self) diff --git a/OpenRA.Mods.Cnc/Effects/IonCannon.cs b/OpenRA.Mods.Cnc/Effects/IonCannon.cs index c8e8e18e7d..8bf2e38284 100644 --- a/OpenRA.Mods.Cnc/Effects/IonCannon.cs +++ b/OpenRA.Mods.Cnc/Effects/IonCannon.cs @@ -34,7 +34,7 @@ namespace OpenRA.Mods.Cnc.Effects public IEnumerable Render(WorldRenderer wr) { - yield return new SpriteRenderable(anim.Image, target.CenterPosition, 1, wr.Palette("effect"), 1.0f); + return anim.Render(target.CenterPosition, 1, wr.Palette("effect"), 1.0f); } void Finish(World world) diff --git a/OpenRA.Mods.RA/Cloak.cs b/OpenRA.Mods.RA/Cloak.cs index aef6315148..6e6a08f6a9 100644 --- a/OpenRA.Mods.RA/Cloak.cs +++ b/OpenRA.Mods.RA/Cloak.cs @@ -66,8 +66,6 @@ namespace OpenRA.Mods.RA if (!canCloak) Uncloak(); } - static readonly IRenderable[] Nothing = { }; - public IEnumerable ModifyRender(Actor self, WorldRenderer wr, IEnumerable r) { if (remainingTime > 0) @@ -79,7 +77,7 @@ namespace OpenRA.Mods.RA else return r.Select(a => a.WithPalette(wr.Palette(info.Palette))); else - return Nothing; + return SpriteRenderable.None; } public void Tick(Actor self) diff --git a/OpenRA.Mods.RA/Effects/Corpse.cs b/OpenRA.Mods.RA/Effects/Corpse.cs index 1ed99b46ac..c4c301877f 100644 --- a/OpenRA.Mods.RA/Effects/Corpse.cs +++ b/OpenRA.Mods.RA/Effects/Corpse.cs @@ -33,7 +33,7 @@ namespace OpenRA.Mods.RA.Effects public IEnumerable Render(WorldRenderer wr) { - yield return new SpriteRenderable(Anim.Image, Pos, 0, wr.Palette(PaletteName), 1f); + return Anim.Render(Pos, wr.Palette(PaletteName)); } } } diff --git a/OpenRA.Mods.RA/Effects/CrateEffect.cs b/OpenRA.Mods.RA/Effects/CrateEffect.cs index e12c14726f..52fbae7f80 100644 --- a/OpenRA.Mods.RA/Effects/CrateEffect.cs +++ b/OpenRA.Mods.RA/Effects/CrateEffect.cs @@ -34,9 +34,10 @@ namespace OpenRA.Mods.RA.Effects public IEnumerable Render(WorldRenderer wr) { - if (a.IsInWorld) - yield return new SpriteRenderable(anim.Image, - a.CenterPosition, 0, wr.Palette("effect"), 1f); + if (!a.IsInWorld) + return SpriteRenderable.None; + + return anim.Render(a.CenterPosition, wr.Palette("effect")); } } } diff --git a/OpenRA.Mods.RA/Effects/Explosion.cs b/OpenRA.Mods.RA/Effects/Explosion.cs index 0a8e953e21..d0d2507bad 100644 --- a/OpenRA.Mods.RA/Effects/Explosion.cs +++ b/OpenRA.Mods.RA/Effects/Explosion.cs @@ -31,7 +31,7 @@ namespace OpenRA.Mods.RA.Effects public IEnumerable Render(WorldRenderer wr) { - yield return new SpriteRenderable(anim.Image, pos, 0, wr.Palette("effect"), 1f); + return anim.Render(pos, wr.Palette("effect")); } } } diff --git a/OpenRA.Mods.RA/Effects/GpsDot.cs b/OpenRA.Mods.RA/Effects/GpsDot.cs index ac3bfd4e32..9e9e3e1b34 100644 --- a/OpenRA.Mods.RA/Effects/GpsDot.cs +++ b/OpenRA.Mods.RA/Effects/GpsDot.cs @@ -80,10 +80,10 @@ namespace OpenRA.Mods.RA.Effects public IEnumerable Render(WorldRenderer wr) { if (!show || self.Destroyed) - yield break; + return SpriteRenderable.None; var palette = wr.Palette(info.IndicatorPalettePrefix+self.Owner.InternalName); - yield return new SpriteRenderable(anim.Image, self.CenterPosition, 0, palette, 1f); + return anim.Render(self.CenterPosition, palette); } } } diff --git a/OpenRA.Mods.RA/Effects/GpsSatellite.cs b/OpenRA.Mods.RA/Effects/GpsSatellite.cs index fb4a464360..0cadb1db3b 100644 --- a/OpenRA.Mods.RA/Effects/GpsSatellite.cs +++ b/OpenRA.Mods.RA/Effects/GpsSatellite.cs @@ -37,7 +37,7 @@ namespace OpenRA.Mods.RA.Effects public IEnumerable Render(WorldRenderer wr) { - yield return new SpriteRenderable(Anim.Image, Pos, 0, wr.Palette("effect"), 1f); + return Anim.Render(Pos, wr.Palette("effect")); } } } diff --git a/OpenRA.Mods.RA/Effects/NukeLaunch.cs b/OpenRA.Mods.RA/Effects/NukeLaunch.cs index c228048335..746469297f 100755 --- a/OpenRA.Mods.RA/Effects/NukeLaunch.cs +++ b/OpenRA.Mods.RA/Effects/NukeLaunch.cs @@ -75,7 +75,7 @@ namespace OpenRA.Mods.RA.Effects public IEnumerable Render(WorldRenderer wr) { - yield return new SpriteRenderable(anim.Image, pos, 0, wr.Palette("effect"), 1f); + return anim.Render(pos, wr.Palette("effect")); } } } diff --git a/OpenRA.Mods.RA/Effects/Parachute.cs b/OpenRA.Mods.RA/Effects/Parachute.cs index bc20073810..9939f0f74a 100644 --- a/OpenRA.Mods.RA/Effects/Parachute.cs +++ b/OpenRA.Mods.RA/Effects/Parachute.cs @@ -76,7 +76,8 @@ namespace OpenRA.Mods.RA.Effects yield return c.WithPos(pos); } - yield return new SpriteRenderable(paraAnim.Image, pos + parachuteOffset, 1, rc.First().Palette, 1f); + foreach (var r in paraAnim.Render(pos + parachuteOffset, 1, rc.First().Palette, 1f)) + yield return r; } } } diff --git a/OpenRA.Mods.RA/Effects/PowerdownIndicator.cs b/OpenRA.Mods.RA/Effects/PowerdownIndicator.cs index 1dcd292bb7..6405ba0d3d 100644 --- a/OpenRA.Mods.RA/Effects/PowerdownIndicator.cs +++ b/OpenRA.Mods.RA/Effects/PowerdownIndicator.cs @@ -36,9 +36,10 @@ namespace OpenRA.Mods.RA.Effects public IEnumerable Render(WorldRenderer wr) { - if (!a.Destroyed && a.Owner.IsAlliedWith(a.World.RenderPlayer)) - yield return new SpriteRenderable(anim.Image, a.CenterPosition, 0, - wr.Palette("chrome"), 1f); + if (a.Destroyed || a.Owner.IsAlliedWith(a.World.RenderPlayer)) + return SpriteRenderable.None; + + return anim.Render(a.CenterPosition, wr.Palette("chrome")); } } } diff --git a/OpenRA.Mods.RA/Effects/RallyPoint.cs b/OpenRA.Mods.RA/Effects/RallyPoint.cs index 2032a20dd7..247d215891 100755 --- a/OpenRA.Mods.RA/Effects/RallyPoint.cs +++ b/OpenRA.Mods.RA/Effects/RallyPoint.cs @@ -50,14 +50,15 @@ namespace OpenRA.Mods.RA.Effects public IEnumerable Render(WorldRenderer wr) { - if (building.IsInWorld && building.Owner == building.World.LocalPlayer - && building.World.Selection.Actors.Contains(building)) - { - var pos = cachedLocation.CenterPosition; - var palette = wr.Palette(palettePrefix+building.Owner.InternalName); - yield return new SpriteRenderable(circles.Image, pos, 0, palette, 1f); - yield return new SpriteRenderable(flag.Image, pos, 0, palette, 1f); - } + if (building.Owner != building.World.LocalPlayer) + return SpriteRenderable.None; + + if (!building.IsInWorld || !building.World.Selection.Actors.Contains(building)) + return SpriteRenderable.None; + + var pos = cachedLocation.CenterPosition; + var palette = wr.Palette(palettePrefix+building.Owner.InternalName); + return circles.Render(pos, palette).Concat(flag.Render(pos, palette)); } } } diff --git a/OpenRA.Mods.RA/Effects/RepairIndicator.cs b/OpenRA.Mods.RA/Effects/RepairIndicator.cs index 0d2fa4e8e5..6cca5290d7 100755 --- a/OpenRA.Mods.RA/Effects/RepairIndicator.cs +++ b/OpenRA.Mods.RA/Effects/RepairIndicator.cs @@ -44,11 +44,11 @@ namespace OpenRA.Mods.RA.Effects public IEnumerable Render(WorldRenderer wr) { - if (!building.Destroyed) - { - yield return new SpriteRenderable(anim.Image, building.CenterPosition, 0, - wr.Palette(palettePrefix+player.InternalName), 1f); - } + if (building.Destroyed) + return SpriteRenderable.None; + + return anim.Render(building.CenterPosition, + wr.Palette(palettePrefix+player.InternalName)); } } } diff --git a/OpenRA.Mods.RA/Effects/SatelliteLaunch.cs b/OpenRA.Mods.RA/Effects/SatelliteLaunch.cs index 7c70600b57..8e3e0fecd6 100644 --- a/OpenRA.Mods.RA/Effects/SatelliteLaunch.cs +++ b/OpenRA.Mods.RA/Effects/SatelliteLaunch.cs @@ -39,7 +39,7 @@ namespace OpenRA.Mods.RA.Effects public IEnumerable Render(WorldRenderer wr) { - yield return new SpriteRenderable(doors.Image, pos, 0, wr.Palette("effect"), 1f); + return doors.Render(pos, wr.Palette("effect")); } } } diff --git a/OpenRA.Mods.RA/Effects/Smoke.cs b/OpenRA.Mods.RA/Effects/Smoke.cs index 0686a91d99..b9e19cf006 100644 --- a/OpenRA.Mods.RA/Effects/Smoke.cs +++ b/OpenRA.Mods.RA/Effects/Smoke.cs @@ -28,14 +28,14 @@ namespace OpenRA.Mods.RA.Effects () => world.AddFrameEndTask(w => w.Remove(this))); } - public void Tick( World world ) + public void Tick(World world) { Anim.Tick(); } public IEnumerable Render(WorldRenderer wr) { - yield return new SpriteRenderable(Anim.Image, Pos, 0, wr.Palette("effect"), 1f); + return Anim.Render(Pos, wr.Palette("effect")); } } } diff --git a/OpenRA.Mods.RA/Render/RenderBuildingWarFactory.cs b/OpenRA.Mods.RA/Render/RenderBuildingWarFactory.cs index 23e55b5cde..56b99dafd2 100755 --- a/OpenRA.Mods.RA/Render/RenderBuildingWarFactory.cs +++ b/OpenRA.Mods.RA/Render/RenderBuildingWarFactory.cs @@ -29,12 +29,10 @@ namespace OpenRA.Mods.RA.Render public override IEnumerable RenderPreview(ActorInfo building, PaletteReference pr) { var p = BaseBuildingPreview(building, pr); - foreach (var r in p) - yield return r; - var anim = new Animation(RenderSprites.GetImage(building), () => 0); anim.PlayRepeating("idle-top"); - yield return new SpriteRenderable(anim.Image, WPos.Zero, 0, pr, 1f); + + return p.Concat(anim.Render(WPos.Zero, pr)); } } diff --git a/OpenRA.Mods.RA/Render/RenderEditorOnly.cs b/OpenRA.Mods.RA/Render/RenderEditorOnly.cs index a6bbfdc0cd..516abc04bc 100644 --- a/OpenRA.Mods.RA/Render/RenderEditorOnly.cs +++ b/OpenRA.Mods.RA/Render/RenderEditorOnly.cs @@ -23,7 +23,6 @@ namespace OpenRA.Mods.RA.Render { public RenderEditorOnly(Actor self) : base(self, () => 0) { } - static readonly IRenderable[] Nothing = { }; - public override IEnumerable Render(Actor self, WorldRenderer wr) { return Nothing; } + public override IEnumerable Render(Actor self, WorldRenderer wr) { return SpriteRenderable.None; } } } diff --git a/OpenRA.Mods.RA/Render/WithMuzzleFlash.cs b/OpenRA.Mods.RA/Render/WithMuzzleFlash.cs index 7e4cc7afc3..f7945d75ac 100644 --- a/OpenRA.Mods.RA/Render/WithMuzzleFlash.cs +++ b/OpenRA.Mods.RA/Render/WithMuzzleFlash.cs @@ -62,8 +62,13 @@ namespace OpenRA.Mods.RA.Render public IEnumerable Render(Actor self, WorldRenderer wr) { foreach (var a in muzzleFlashes.Values) - if (a.DisableFunc == null || !a.DisableFunc()) - yield return a.Image(self, wr, wr.Palette("effect")); + { + if (a.DisableFunc != null && a.DisableFunc()) + continue; + + foreach (var r in a.Render(self, wr, wr.Palette("effect"), 1f)) + yield return r; + } } public void Tick(Actor self)