diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj index 6b97904528..307397f5a3 100755 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -205,6 +205,7 @@ + diff --git a/OpenRA.Game/Traits/Selectable.cs b/OpenRA.Game/Traits/Selectable.cs index cb8cd7a071..5d6aefc53c 100644 --- a/OpenRA.Game/Traits/Selectable.cs +++ b/OpenRA.Game/Traits/Selectable.cs @@ -23,10 +23,6 @@ namespace OpenRA.Traits public class Selectable : IPostRenderSelection { - // depends on the order of pips in TraitsInterfaces.cs! - static readonly string[] pipStrings = { "pip-empty", "pip-green", "pip-yellow", "pip-red", "pip-gray", "pip-blue" }; - static readonly string[] tagStrings = { "", "tag-fake", "tag-primary" }; - public void RenderAfterWorld (WorldRenderer wr, Actor self) { var bounds = self.Bounds.Value; @@ -37,11 +33,8 @@ namespace OpenRA.Traits wr.DrawSelectionBox(self, Color.White); DrawHealthBar(self, xy, Xy); - DrawControlGroup(wr, self, xy); - DrawPips(wr, self, xY); - DrawTags(wr, self, new float2(.5f * (bounds.Left + bounds.Right), bounds.Top)); - DrawUnitPath(self); DrawExtraBars(self, xy, Xy); + DrawUnitPath(self); } public void DrawRollover(WorldRenderer wr, Actor self) @@ -138,83 +131,6 @@ namespace OpenRA.Traits } } - void DrawControlGroup(WorldRenderer wr, Actor self, float2 basePosition) - { - var group = self.World.Selection.GetControlGroupForActor(self); - if (group == null) return; - - var pipImages = new Animation("pips"); - pipImages.PlayFetchIndex("groups", () => (int)group); - pipImages.Tick(); - pipImages.Image.DrawAt(wr, basePosition + new float2(-8, 1), "chrome"); - } - - void DrawPips(WorldRenderer wr, Actor self, float2 basePosition) - { - if (self.Owner != self.World.LocalPlayer) return; - - var pipSources = self.TraitsImplementing(); - if (pipSources.Count() == 0) - return; - - var pipImages = new Animation("pips"); - pipImages.PlayRepeating(pipStrings[0]); - - var pipSize = pipImages.Image.size; - var pipxyBase = basePosition + new float2(1, -pipSize.Y); - var pipxyOffset = new float2(0, 0); // Correct for offset due to multiple columns/rows - - foreach (var pips in pipSources) - { - var thisRow = pips.GetPips(self); - if (thisRow == null) - continue; - - var width = self.Bounds.Value.Width; - - foreach (var pip in thisRow) - { - if (pipxyOffset.X + pipSize.X >= width) - { - pipxyOffset.X = 0; - pipxyOffset.Y -= pipSize.Y; - } - pipImages.PlayRepeating(pipStrings[(int)pip]); - pipImages.Image.DrawAt(wr, pipxyBase + pipxyOffset, "chrome"); - pipxyOffset += new float2(pipSize.X, 0); - } - - // Increment row - pipxyOffset.X = 0; - pipxyOffset.Y -= pipSize.Y + 1; - } - } - - void DrawTags(WorldRenderer wr, 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.TraitsImplementing()) - { - foreach (var tag in tags.GetTags()) - { - if (tag == TagType.None) - continue; - - var tagImages = new Animation("pips"); - tagImages.PlayRepeating(tagStrings[(int)tag]); - tagImages.Image.DrawAt(wr, tagxyBase + tagxyOffset, "chrome"); - - // Increment row - tagxyOffset.Y += 8; - } - } - } - void DrawUnitPath(Actor self) { if (self.World.LocalPlayer == null ||!self.World.LocalPlayer.PlayerActor.Trait().PathDebug) return; diff --git a/OpenRA.Game/Traits/SelectionDecorations.cs b/OpenRA.Game/Traits/SelectionDecorations.cs new file mode 100644 index 0000000000..8b58d75b15 --- /dev/null +++ b/OpenRA.Game/Traits/SelectionDecorations.cs @@ -0,0 +1,116 @@ +#region Copyright & License Information +/* + * Copyright 2007-2011 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, + * see COPYING. + */ +#endregion + +using System.Drawing; +using System.Linq; +using OpenRA.Graphics; + +namespace OpenRA.Traits +{ + public class SelectionDecorationsInfo : TraitInfo {} + + public class SelectionDecorations : IPostRenderSelection + { + // depends on the order of pips in TraitsInterfaces.cs! + static readonly string[] pipStrings = { "pip-empty", "pip-green", "pip-yellow", "pip-red", "pip-gray", "pip-blue" }; + static readonly string[] tagStrings = { "", "tag-fake", "tag-primary" }; + + public void RenderAfterWorld (WorldRenderer wr, Actor self) + { + var bounds = self.Bounds.Value; + + var xy = new float2(bounds.Left, bounds.Top); + var xY = new float2(bounds.Left, bounds.Bottom); + + DrawControlGroup(wr, self, xy); + DrawPips(wr, self, xY); + DrawTags(wr, self, new float2(.5f * (bounds.Left + bounds.Right), bounds.Top)); + } + + void DrawControlGroup(WorldRenderer wr, Actor self, float2 basePosition) + { + var group = self.World.Selection.GetControlGroupForActor(self); + if (group == null) return; + + var pipImages = new Animation("pips"); + pipImages.PlayFetchIndex("groups", () => (int)group); + pipImages.Tick(); + pipImages.Image.DrawAt(wr, basePosition + new float2(-8, 1), "chrome"); + } + + void DrawPips(WorldRenderer wr, Actor self, float2 basePosition) + { + if (self.Owner != self.World.LocalPlayer) return; + + var pipSources = self.TraitsImplementing(); + if (pipSources.Count() == 0) + return; + + var pipImages = new Animation("pips"); + pipImages.PlayRepeating(pipStrings[0]); + + var pipSize = pipImages.Image.size; + var pipxyBase = basePosition + new float2(1, -pipSize.Y); + var pipxyOffset = new float2(0, 0); // Correct for offset due to multiple columns/rows + + foreach (var pips in pipSources) + { + var thisRow = pips.GetPips(self); + if (thisRow == null) + continue; + + var width = self.Bounds.Value.Width; + + foreach (var pip in thisRow) + { + if (pipxyOffset.X + pipSize.X >= width) + { + pipxyOffset.X = 0; + pipxyOffset.Y -= pipSize.Y; + } + pipImages.PlayRepeating(pipStrings[(int)pip]); + pipImages.Image.DrawAt(wr, pipxyBase + pipxyOffset, "chrome"); + pipxyOffset += new float2(pipSize.X, 0); + } + + // Increment row + pipxyOffset.X = 0; + pipxyOffset.Y -= pipSize.Y + 1; + } + } + + void DrawTags(WorldRenderer wr, 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.TraitsImplementing()) + { + foreach (var tag in tags.GetTags()) + { + if (tag == TagType.None) + continue; + + var tagImages = new Animation("pips"); + tagImages.PlayRepeating(tagStrings[(int)tag]); + tagImages.Image.DrawAt(wr, tagxyBase + tagxyOffset, "chrome"); + + // Increment row + tagxyOffset.Y += 8; + } + } + } + + } +} + diff --git a/mods/cnc/rules/defaults.yaml b/mods/cnc/rules/defaults.yaml index 590a3a35b4..604ef76559 100644 --- a/mods/cnc/rules/defaults.yaml +++ b/mods/cnc/rules/defaults.yaml @@ -10,6 +10,7 @@ BlueTiberium: 40 Beach: 40 ROT: 5 + SelectionDecorations: Selectable: Voice: VehicleVoice TargetableUnit: @@ -43,6 +44,7 @@ BlueTiberium: 70 Beach: 70 ROT: 5 + SelectionDecorations: Selectable: Voice: VehicleVoice TargetableUnit: @@ -69,6 +71,7 @@ UseLocation: yes TargetableUnit: TargetTypes: Air + SelectionDecorations: Selectable: Voice: VehicleVoice Helicopter: @@ -106,6 +109,7 @@ BlueTiberium: 70 PathingCost: 1000 Beach: 80 + SelectionDecorations: Selectable: Voice: GenericVoice TargetableUnit: @@ -135,6 +139,7 @@ -TakeCover: -RenderInfantryProne: AppearsOnRadar: + SelectionDecorations: Selectable: Voice: CivilianMaleVoice Bounds: 12,17,0,-9 @@ -162,6 +167,7 @@ ^Plane: AppearsOnRadar: UseLocation: yes + SelectionDecorations: Selectable: Voice: GenericVoice TargetableUnit: @@ -179,6 +185,7 @@ Crushes: crate TerrainSpeeds: Water: 100 + SelectionDecorations: Selectable: Voice: GenericVoice TargetableUnit: @@ -193,6 +200,7 @@ ^Building: AppearsOnRadar: + SelectionDecorations: Selectable: Priority: 3 TargetableBuilding: @@ -304,6 +312,7 @@ CrushSound: sandbag2.aud LineBuild: Range: 8 + SelectionDecorations: Selectable: Priority: 1 RenderBuildingWall: diff --git a/mods/ra/rules/defaults.yaml b/mods/ra/rules/defaults.yaml index 76459dea20..41b032f932 100644 --- a/mods/ra/rules/defaults.yaml +++ b/mods/ra/rules/defaults.yaml @@ -9,6 +9,7 @@ Ore: 70 Beach: 40 ROT: 5 + SelectionDecorations: Selectable: Voice: VehicleVoice TargetableUnit: @@ -43,6 +44,7 @@ Ore: 70 Beach: 70 ROT: 5 + SelectionDecorations: Selectable: Voice: VehicleVoice TargetableUnit: @@ -83,6 +85,7 @@ Road: 100 Ore: 80 Beach: 80 + SelectionDecorations: Selectable: Voice: GenericVoice TargetableUnit: @@ -115,6 +118,7 @@ Crushes: crate TerrainSpeeds: Water: 100 + SelectionDecorations: Selectable: Voice: ShipVoice TargetableUnit: @@ -138,6 +142,7 @@ ^Plane: AppearsOnRadar: UseLocation: yes + SelectionDecorations: Selectable: Voice: GenericVoice TargetableAircraft: @@ -169,6 +174,7 @@ ^Building: AppearsOnRadar: + SelectionDecorations: Selectable: Priority: 3 TargetableBuilding: @@ -216,6 +222,7 @@ CrushClasses: wall LineBuild: Range: 8 + SelectionDecorations: Selectable: Priority: 1 TargetableBuilding: