diff --git a/OpenRA.Game/Graphics/WorldRenderer.cs b/OpenRA.Game/Graphics/WorldRenderer.cs index a2c506dd81..93bbf7102d 100644 --- a/OpenRA.Game/Graphics/WorldRenderer.cs +++ b/OpenRA.Game/Graphics/WorldRenderer.cs @@ -32,22 +32,11 @@ namespace OpenRA.Graphics uiOverlay = new UiOverlay(); palette = new HardwarePalette(world.Map); } - - public void DrawLine(float2 start, float2 end, Color startColor, Color endColor) - { - Game.Renderer.LineRenderer.DrawLine(start,end,startColor,endColor); - } public int GetPaletteIndex(string name) { return palette.GetPaletteIndex(name); } public Palette GetPalette(string name) { return palette.GetPalette(name); } public void AddPalette(string name, Palette pal) { palette.AddPalette(name, pal); } public void UpdatePalette(string name, Palette pal) { palette.UpdatePalette(name, pal); } - - void DrawSpriteList(IEnumerable images) - { - foreach (var image in images) - Game.Renderer.SpriteRenderer.DrawSprite(image.Sprite, image.Pos, image.Palette); - } class SpriteComparer : IComparer { @@ -109,8 +98,8 @@ namespace OpenRA.Graphics Game.Renderer.Device.EnableScissor(bounds.Left, bounds.Top, bounds.Width, bounds.Height); terrainRenderer.Draw(Game.viewport); - - DrawSpriteList(worldSprites); + foreach (var image in worldSprites) + Game.Renderer.SpriteRenderer.DrawSprite(image.Sprite, image.Pos, image.Palette); uiOverlay.Draw(world); Game.Renderer.SpriteRenderer.Flush(); DrawBandBox(); @@ -174,10 +163,10 @@ namespace OpenRA.Graphics Game.Renderer.LineRenderer.DrawLine(a, a + c, Color.White, Color.White); foreach (var u in world.SelectActorsInBox(selbox.Value.First, selbox.Value.Second)) - DrawSelectionBox(u, Color.Yellow, false); + DrawSelectionBox(u, Color.Yellow); } - public void DrawSelectionBox(Actor selectedUnit, Color c, bool drawHealthBar) + public void DrawSelectionBox(Actor selectedUnit, Color c) { var bounds = selectedUnit.GetBounds(true); @@ -195,140 +184,8 @@ namespace OpenRA.Graphics Game.Renderer.LineRenderer.DrawLine(xY, xY + new float2(0, -4), c, c); Game.Renderer.LineRenderer.DrawLine(XY, XY + new float2(-4, 0), c, c); Game.Renderer.LineRenderer.DrawLine(XY, XY + new float2(0, -4), c, c); - - if (drawHealthBar) - { - DrawHealthBar(selectedUnit, xy, Xy); - DrawControlGroup(selectedUnit, xy); - - // Only display pips and tags to the owner - if (selectedUnit.Owner == world.LocalPlayer) - { - DrawPips(selectedUnit, xY); - DrawTags(selectedUnit, new float2(.5f * (bounds.Left + bounds.Right ), xy.Y)); - } - } - - if (Game.Settings.PathDebug) - DrawUnitPath(selectedUnit); - } - - void DrawUnitPath(Actor selectedUnit) - { - var mobile = selectedUnit.traits.WithInterface().FirstOrDefault(); - if (mobile != null) - { - var unit = selectedUnit.traits.Get(); - var alt = (unit != null)? new float2(0, -unit.Altitude) : float2.Zero; - var path = mobile.GetCurrentPath(selectedUnit); - var start = selectedUnit.CenterLocation + alt; - - var c = Color.Green; - - foreach (var step in path) - { - var stp = step + alt; - DrawLine(stp + new float2(-1, -1), stp + new float2(-1, 1), c, c); - DrawLine(stp + new float2(-1, 1), stp + new float2(1, 1), c, c); - DrawLine(stp + new float2(1, 1), stp + new float2(1, -1), c, c); - DrawLine(stp + new float2(1, -1), stp + new float2(-1, -1), c, c); - DrawLine(start, stp, c, c); - start = stp; - } - } - } - - void DrawHealthBar(Actor selectedUnit, float2 xy, float2 Xy) - { - var c = Color.Gray; - Game.Renderer.LineRenderer.DrawLine(xy + new float2(0, -2), xy + new float2(0, -4), c, c); - Game.Renderer.LineRenderer.DrawLine(Xy + new float2(0, -2), Xy + new float2(0, -4), c, c); - - var healthAmount = (float)selectedUnit.Health / selectedUnit.Info.Traits.Get().HP; - var healthColor = (healthAmount < selectedUnit.World.Defaults.ConditionRed) ? Color.Red - : (healthAmount < selectedUnit.World.Defaults.ConditionYellow) ? Color.Yellow - : Color.LimeGreen; - - var healthColor2 = Color.FromArgb( - 255, - healthColor.R / 2, - healthColor.G / 2, - healthColor.B / 2); - - var z = float2.Lerp(xy, Xy, healthAmount); - - Game.Renderer.LineRenderer.DrawLine(z + new float2(0, -4), Xy + new float2(0, -4), c, c); - Game.Renderer.LineRenderer.DrawLine(z + new float2(0, -2), Xy + new float2(0, -2), c, c); - - Game.Renderer.LineRenderer.DrawLine(xy + new float2(0, -3), z + new float2(0, -3), healthColor, healthColor); - Game.Renderer.LineRenderer.DrawLine(xy + new float2(0, -2), z + new float2(0, -2), healthColor2, healthColor2); - Game.Renderer.LineRenderer.DrawLine(xy + new float2(0, -4), z + new float2(0, -4), healthColor2, healthColor2); - } - - // depends on the order of pips in TraitsInterfaces.cs! - static readonly string[] pipStrings = { "pip-empty", "pip-green", "pip-yellow", "pip-red", "pip-gray" }; - static readonly string[] tagStrings = { "", "tag-fake", "tag-primary" }; - - void DrawControlGroup(Actor selectedUnit, float2 basePosition) - { - var group = Game.controller.selection.GetControlGroupForActor(selectedUnit); - if (group == null) return; - - var pipImages = new Animation("pips"); - pipImages.PlayFetchIndex("groups", () => (int)group); - pipImages.Tick(); - Game.Renderer.SpriteRenderer.DrawSprite(pipImages.Image, basePosition + new float2(-8, 1), "chrome"); - } - - void DrawPips(Actor selectedUnit, float2 basePosition) - { - // If a mod wants to implement a unit with multiple pip sources, then they are placed on multiple rows - var pipxyBase = basePosition + new float2(-12, -7); // Correct for the offset in the shp file - var pipxyOffset = new float2(0, 0); // Correct for offset due to multiple columns/rows - - foreach (var pips in selectedUnit.traits.WithInterface()) - { - foreach (var pip in pips.GetPips(selectedUnit)) - { - if (pipxyOffset.X+5 > selectedUnit.GetBounds(false).Width) - { - pipxyOffset.X = 0; - pipxyOffset.Y -= 4; - } - var pipImages = new Animation("pips"); - pipImages.PlayRepeating(pipStrings[(int)pip]); - Game.Renderer.SpriteRenderer.DrawSprite(pipImages.Image, pipxyBase + pipxyOffset, "chrome"); - pipxyOffset += new float2(4, 0); - } - // Increment row - pipxyOffset.X = 0; - pipxyOffset.Y -= 5; - } } - void DrawTags(Actor selectedUnit, float2 basePosition) - { - // If a mod wants to implement a unit with multiple tags, then they are placed on multiple rows - var tagxyBase = basePosition + new float2(-16, 2); // Correct for the offset in the shp file - var tagxyOffset = new float2(0, 0); // Correct for offset due to multiple rows - - foreach (var tags in selectedUnit.traits.WithInterface()) - { - foreach (var tag in tags.GetTags()) - { - if (tag == TagType.None) - continue; - - var tagImages = new Animation("pips"); - tagImages.PlayRepeating(tagStrings[(int)tag]); - Game.Renderer.SpriteRenderer.DrawSprite(tagImages.Image, tagxyBase + tagxyOffset, "chrome"); - - // Increment row - tagxyOffset.Y += 8; - } - } - } - public void DrawLocus(Color c, int2[] cells) { var dict = cells.ToDictionary(a => a, a => 0); diff --git a/OpenRA.Game/Orders/UnitOrderGenerator.cs b/OpenRA.Game/Orders/UnitOrderGenerator.cs index 92cb9b33b4..e66c0d8a9a 100644 --- a/OpenRA.Game/Orders/UnitOrderGenerator.cs +++ b/OpenRA.Game/Orders/UnitOrderGenerator.cs @@ -39,10 +39,8 @@ namespace OpenRA.Orders { foreach (var a in Game.controller.selection.Actors) { - world.WorldRenderer.DrawSelectionBox(a, Color.White, true); - if (a.Owner == world.LocalPlayer) - foreach (var t in a.traits.WithInterface()) - t.Render(a); + foreach (var t in a.traits.WithInterface()) + t.Render(a); } } diff --git a/OpenRA.Game/Traits/Selectable.cs b/OpenRA.Game/Traits/Selectable.cs index 2e82ddb22a..6d636702cd 100755 --- a/OpenRA.Game/Traits/Selectable.cs +++ b/OpenRA.Game/Traits/Selectable.cs @@ -8,6 +8,10 @@ */ #endregion +using System.Drawing; +using OpenRA.Graphics; +using System.Linq; + namespace OpenRA.Traits { public class SelectableInfo : TraitInfo @@ -19,5 +23,159 @@ namespace OpenRA.Traits public readonly float Radius = 10; } - public class Selectable {} + public class Selectable : IRenderSelection + { + // depends on the order of pips in TraitsInterfaces.cs! + static readonly string[] pipStrings = { "pip-empty", "pip-green", "pip-yellow", "pip-red", "pip-gray" }; + static readonly string[] tagStrings = { "", "tag-fake", "tag-primary" }; + + public void Render (Actor self) + { + var bounds = self.GetBounds(true); + + var xy = new float2(bounds.Left, bounds.Top); + var Xy = new float2(bounds.Right, bounds.Top); + var xY = new float2(bounds.Left, bounds.Bottom); + var XY = new float2(bounds.Right, bounds.Bottom); + + DrawSelectionBox(self, xy, Xy, xY, XY, Color.White); + DrawHealthBar(self, xy, Xy); + DrawControlGroup(self, xy); + DrawPips(self, xY); + DrawTags(self, new float2(.5f * (bounds.Left + bounds.Right), bounds.Top)); + DrawUnitPath(self); + } + + void DrawSelectionBox(Actor self, float2 xy, float2 Xy, float2 xY, float2 XY, Color c) + { + Game.Renderer.LineRenderer.DrawLine(xy, xy + new float2(4, 0), c, c); + Game.Renderer.LineRenderer.DrawLine(xy, xy + new float2(0, 4), c, c); + Game.Renderer.LineRenderer.DrawLine(Xy, Xy + new float2(-4, 0), c, c); + Game.Renderer.LineRenderer.DrawLine(Xy, Xy + new float2(0, 4), c, c); + + Game.Renderer.LineRenderer.DrawLine(xY, xY + new float2(4, 0), c, c); + Game.Renderer.LineRenderer.DrawLine(xY, xY + new float2(0, -4), c, c); + Game.Renderer.LineRenderer.DrawLine(XY, XY + new float2(-4, 0), c, c); + Game.Renderer.LineRenderer.DrawLine(XY, XY + new float2(0, -4), c, c); + } + + void DrawHealthBar(Actor self, float2 xy, float2 Xy) + { + var c = Color.Gray; + Game.Renderer.LineRenderer.DrawLine(xy + new float2(0, -2), xy + new float2(0, -4), c, c); + Game.Renderer.LineRenderer.DrawLine(Xy + new float2(0, -2), Xy + new float2(0, -4), c, c); + + var healthAmount = (float)self.Health / self.Info.Traits.Get().HP; + var healthColor = (healthAmount < self.World.Defaults.ConditionRed) ? Color.Red + : (healthAmount < self.World.Defaults.ConditionYellow) ? Color.Yellow + : Color.LimeGreen; + + var healthColor2 = Color.FromArgb( + 255, + healthColor.R / 2, + healthColor.G / 2, + healthColor.B / 2); + + var z = float2.Lerp(xy, Xy, healthAmount); + + Game.Renderer.LineRenderer.DrawLine(z + new float2(0, -4), Xy + new float2(0, -4), c, c); + Game.Renderer.LineRenderer.DrawLine(z + new float2(0, -2), Xy + new float2(0, -2), c, c); + + Game.Renderer.LineRenderer.DrawLine(xy + new float2(0, -3), z + new float2(0, -3), healthColor, healthColor); + Game.Renderer.LineRenderer.DrawLine(xy + new float2(0, -2), z + new float2(0, -2), healthColor2, healthColor2); + Game.Renderer.LineRenderer.DrawLine(xy + new float2(0, -4), z + new float2(0, -4), healthColor2, healthColor2); + } + + void DrawControlGroup(Actor self, float2 basePosition) + { + var group = Game.controller.selection.GetControlGroupForActor(self); + if (group == null) return; + + var pipImages = new Animation("pips"); + pipImages.PlayFetchIndex("groups", () => (int)group); + pipImages.Tick(); + Game.Renderer.SpriteRenderer.DrawSprite(pipImages.Image, basePosition + new float2(-8, 1), "chrome"); + } + + void DrawPips(Actor self, float2 basePosition) + { + if (self.Owner != self.World.LocalPlayer) return; + + // If a mod wants to implement a unit with multiple pip sources, then they are placed on multiple rows + var pipxyBase = basePosition + new float2(-12, -7); // Correct for the offset in the shp file + var pipxyOffset = new float2(0, 0); // Correct for offset due to multiple columns/rows + + foreach (var pips in self.traits.WithInterface()) + { + foreach (var pip in pips.GetPips(self)) + { + if (pipxyOffset.X+5 > self.GetBounds(false).Width) + { + pipxyOffset.X = 0; + pipxyOffset.Y -= 4; + } + var pipImages = new Animation("pips"); + pipImages.PlayRepeating(pipStrings[(int)pip]); + Game.Renderer.SpriteRenderer.DrawSprite(pipImages.Image, pipxyBase + pipxyOffset, "chrome"); + pipxyOffset += new float2(4, 0); + } + // Increment row + pipxyOffset.X = 0; + pipxyOffset.Y -= 5; + } + } + + void DrawTags(Actor self, float2 basePosition) + { + if (self.Owner != self.World.LocalPlayer) return; + + // If a mod wants to implement a unit with multiple tags, then they are placed on multiple rows + var tagxyBase = basePosition + new float2(-16, 2); // Correct for the offset in the shp file + var tagxyOffset = new float2(0, 0); // Correct for offset due to multiple rows + + foreach (var tags in self.traits.WithInterface()) + { + foreach (var tag in tags.GetTags()) + { + if (tag == TagType.None) + continue; + + var tagImages = new Animation("pips"); + tagImages.PlayRepeating(tagStrings[(int)tag]); + Game.Renderer.SpriteRenderer.DrawSprite(tagImages.Image, tagxyBase + tagxyOffset, "chrome"); + + // Increment row + tagxyOffset.Y += 8; + } + } + } + + void DrawUnitPath(Actor self) + { + if (!Game.Settings.PathDebug) return; + + var mobile = self.traits.WithInterface().FirstOrDefault(); + if (mobile != null) + { + var unit = self.traits.Get(); + var alt = (unit != null)? new float2(0, -unit.Altitude) : float2.Zero; + var path = mobile.GetCurrentPath(self); + var start = self.CenterLocation + alt; + + var c = Color.Green; + + foreach (var step in path) + { + var stp = step + alt; + Game.Renderer.LineRenderer.DrawLine(stp + new float2(-1, -1), stp + new float2(-1, 1), c, c); + Game.Renderer.LineRenderer.DrawLine(stp + new float2(-1, 1), stp + new float2(1, 1), c, c); + Game.Renderer.LineRenderer.DrawLine(stp + new float2(1, 1), stp + new float2(1, -1), c, c); + Game.Renderer.LineRenderer.DrawLine(stp + new float2(1, -1), stp + new float2(-1, -1), c, c); + Game.Renderer.LineRenderer.DrawLine(start, stp, c, c); + start = stp; + } + } + } + + } } diff --git a/OpenRA.Mods.RA/Effects/LaserZap.cs b/OpenRA.Mods.RA/Effects/LaserZap.cs index d07d90ce1d..6fc7234665 100755 --- a/OpenRA.Mods.RA/Effects/LaserZap.cs +++ b/OpenRA.Mods.RA/Effects/LaserZap.cs @@ -66,7 +66,7 @@ namespace OpenRA.Mods.RA.Effects float2 norm = new float2(-unit.Y, unit.X); for (int i = -radius; i < radius; i++) - Game.world.WorldRenderer.DrawLine(args.src + i * norm, args.dest + i * norm, rc, rc); + Game.Renderer.LineRenderer.DrawLine(args.src + i * norm, args.dest + i * norm, rc, rc); yield break; } diff --git a/OpenRA.Mods.RA/Minelayer.cs b/OpenRA.Mods.RA/Minelayer.cs index 97b7887500..b718957106 100644 --- a/OpenRA.Mods.RA/Minelayer.cs +++ b/OpenRA.Mods.RA/Minelayer.cs @@ -135,6 +135,9 @@ namespace OpenRA.Mods.RA public void Render(Actor self) { + if (self.Owner != self.World.LocalPlayer) + return; + if (minefield != null) Game.world.WorldRenderer.DrawLocus(Color.Cyan, minefield); } diff --git a/OpenRA.Mods.RA/Orders/SetChronoTankDestination.cs b/OpenRA.Mods.RA/Orders/SetChronoTankDestination.cs index ac493b7b3a..365d9675fe 100644 --- a/OpenRA.Mods.RA/Orders/SetChronoTankDestination.cs +++ b/OpenRA.Mods.RA/Orders/SetChronoTankDestination.cs @@ -38,7 +38,7 @@ namespace OpenRA.Mods.RA.Orders public void Tick( World world ) { } public void Render( World world ) { - world.WorldRenderer.DrawSelectionBox(self, Color.White, true); + world.WorldRenderer.DrawSelectionBox(self, Color.White); } public string GetCursor(World world, int2 xy, MouseInput mi) diff --git a/OpenRA.Mods.RA/RenderDetectionCircle.cs b/OpenRA.Mods.RA/RenderDetectionCircle.cs index 7f42eac1c1..d08c3de885 100644 --- a/OpenRA.Mods.RA/RenderDetectionCircle.cs +++ b/OpenRA.Mods.RA/RenderDetectionCircle.cs @@ -18,6 +18,9 @@ namespace OpenRA.Mods.RA { public void Render(Actor self) { + if (self.Owner != self.World.LocalPlayer) + return; + self.World.WorldRenderer.DrawRangeCircle( Color.FromArgb(128, Color.LimeGreen), self.CenterLocation, self.Info.Traits.Get().Range); diff --git a/OpenRA.Mods.RA/RenderRangeCircle.cs b/OpenRA.Mods.RA/RenderRangeCircle.cs index 3c17c652d0..c8dcc5a31f 100644 --- a/OpenRA.Mods.RA/RenderRangeCircle.cs +++ b/OpenRA.Mods.RA/RenderRangeCircle.cs @@ -18,6 +18,9 @@ namespace OpenRA.Mods.RA { public void Render(Actor self) { + if (self.Owner != self.World.LocalPlayer) + return; + self.World.WorldRenderer.DrawRangeCircle( Color.FromArgb(128, Color.Yellow), self.CenterLocation, (int)self.GetPrimaryWeapon().Range); diff --git a/OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs b/OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs index 723e83256c..04518a6dd4 100755 --- a/OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs +++ b/OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs @@ -135,7 +135,7 @@ namespace OpenRA.Mods.RA public void Render(World world) { - world.WorldRenderer.DrawSelectionBox(self, Color.Red, true); + world.WorldRenderer.DrawSelectionBox(self, Color.Red); } public string GetCursor(World world, int2 xy, MouseInput mi)