diff --git a/OpenRA.Game/Chrome.cs b/OpenRA.Game/Chrome.cs index 654a06b348..dd4a9c1a1d 100644 --- a/OpenRA.Game/Chrome.cs +++ b/OpenRA.Game/Chrome.cs @@ -37,16 +37,13 @@ namespace OpenRA public readonly Renderer renderer; public readonly SpriteRenderer rgbaRenderer; public readonly LineRenderer lineRenderer; - readonly SpriteRenderer shpRenderer; + public readonly SpriteRenderer shpRenderer; string chromeCollection; string radarCollection; string paletteCollection; string digitCollection; - // Special power bin - readonly Dictionary spsprites; - // Build Palette tabs string currentTab = "Building"; bool paletteOpen = false; @@ -100,11 +97,6 @@ namespace OpenRA u => u.Name, u => SpriteSheetBuilder.LoadAllSprites(u.Traits.Get().Icon ?? (u.Name + "icon"))[0]); - spsprites = Rules.Info.Values.SelectMany( u => u.Traits.WithInterface() ) - .ToDictionary( - u => u.Image, - u => SpriteSheetBuilder.LoadAllSprites(u.Image)[0]); - var groups = Rules.Categories(); tabImageNames = groups.Select( @@ -190,7 +182,6 @@ namespace OpenRA DrawButtons( world ); int paletteHeight = DrawBuildPalette(world, currentTab); - DrawSupportPowers( world ); DrawBuildTabs(world, paletteHeight); DrawChat(); } @@ -400,7 +391,7 @@ namespace OpenRA } public void DrawWidgets(World world) { rootWidget.Draw(); shpRenderer.Flush(); rgbaRenderer.Flush(); } - + public void DrawLobby() { buttons.Clear(); @@ -1004,7 +995,7 @@ namespace OpenRA } } - int2 lastMousePos; + public int2 lastMousePos; public bool HandleInput(World world, MouseInput mi) { if (selectedWidget != null) @@ -1096,102 +1087,6 @@ namespace OpenRA return Rules.Info[ a.ToLowerInvariant() ].Traits.Get().Description; } - void DrawSupportPowers( World world ) - { - var powers = world.LocalPlayer.PlayerActor.traits.WithInterface(); - var numPowers = powers.Count(p => p.IsAvailable); - - if (numPowers == 0) return; - - rgbaRenderer.DrawSprite(ChromeProvider.GetImage(renderer, chromeCollection, "specialbin-top"), new float2(0, 14), "chrome"); - for (var i = 1; i < numPowers; i++) - rgbaRenderer.DrawSprite(ChromeProvider.GetImage(renderer, chromeCollection, "specialbin-middle"), new float2(0, 14 + i * 51), "chrome"); - rgbaRenderer.DrawSprite(ChromeProvider.GetImage(renderer, chromeCollection, "specialbin-bottom"), new float2(0, 14 + numPowers * 51), "chrome"); - - rgbaRenderer.Flush(); - - var y = 24; - - SupportPower tooltipItem = null; - int2 tooltipPos = int2.Zero; - - foreach (var sp in powers) - { - var image = spsprites[sp.Info.Image]; - if (sp.IsAvailable) - { - var drawPos = new float2(5, y); - shpRenderer.DrawSprite(image, drawPos, "chrome"); - - clock.PlayFetchIndex("idle", - () => (sp.TotalTime - sp.RemainingTime) - * (clock.CurrentSequence.Length - 1) / sp.TotalTime); - clock.Tick(); - - shpRenderer.DrawSprite(clock.Image, drawPos, "chrome"); - - var rect = new Rectangle(5, y, 64, 48); - if (sp.IsReady) - { - ready.Play("ready"); - shpRenderer.DrawSprite(ready.Image, - drawPos + new float2((64 - ready.Image.size.X) / 2, 2), - "chrome"); - } - - AddButton(rect, HandleSupportPower(sp)); - - if (rect.Contains(lastMousePos.ToPoint())) - { - tooltipItem = sp; - tooltipPos = drawPos.ToInt2() + new int2(72, 0); - } - - y += 51; - } - } - - shpRenderer.Flush(); - - if (tooltipItem != null) - DrawSupportPowerTooltip(world, tooltipItem, tooltipPos); - } - - Action HandleSupportPower(SupportPower sp) - { - return b => { if (b) sp.Activate(); }; - } - - string FormatTime(int ticks) - { - var seconds = ticks / 25; - var minutes = seconds / 60; - - return "{0:D2}:{1:D2}".F(minutes, seconds % 60); - } - - void DrawSupportPowerTooltip(World world, SupportPower sp, int2 pos) - { - var tooltipSprite = ChromeProvider.GetImage(renderer, chromeCollection, "tooltip-bg"); - rgbaRenderer.DrawSprite(tooltipSprite, pos, "chrome"); - rgbaRenderer.Flush(); - - pos += new int2(5, 5); - - renderer.BoldFont.DrawText(rgbaRenderer, sp.Info.Description, pos, Color.White); - - var timer = "Charge Time: {0}".F(FormatTime(sp.RemainingTime)); - DrawRightAligned(timer, pos + new int2((int)tooltipSprite.size.X - 10, 0), Color.White); - - if (sp.Info.LongDesc != null) - { - pos += new int2(0, 25); - renderer.RegularFont.DrawText(rgbaRenderer, sp.Info.LongDesc.Replace("\\n", "\n"), pos, Color.White); - } - - rgbaRenderer.Flush(); - } - public void SetCurrentTab(string produces) { if (!paletteOpen) diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj index 46ec2f7900..abd048acd7 100755 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -295,6 +295,7 @@ + diff --git a/OpenRA.Game/Widgets/BackgroundWidget.cs b/OpenRA.Game/Widgets/BackgroundWidget.cs index b45b94e29d..860fe52ff6 100644 --- a/OpenRA.Game/Widgets/BackgroundWidget.cs +++ b/OpenRA.Game/Widgets/BackgroundWidget.cs @@ -22,16 +22,16 @@ namespace OpenRA.Widgets { class BackgroundWidget : Widget { - public override void Draw() + public override void Draw(World world) { if (!Visible) { - base.Draw(); + base.Draw(world); return; } WidgetUtils.DrawPanel("dialog", Bounds, null); - base.Draw(); + base.Draw(world); } } } \ No newline at end of file diff --git a/OpenRA.Game/Widgets/ButtonWidget.cs b/OpenRA.Game/Widgets/ButtonWidget.cs index a82e8e4a05..5c729e992f 100644 --- a/OpenRA.Game/Widgets/ButtonWidget.cs +++ b/OpenRA.Game/Widgets/ButtonWidget.cs @@ -61,11 +61,11 @@ namespace OpenRA.Widgets return false; } - public override void Draw() + public override void Draw(World world) { if (!Visible) { - base.Draw(); + base.Draw(world); return; } @@ -76,7 +76,7 @@ namespace OpenRA.Widgets - new int2(Game.chrome.renderer.BoldFont.Measure(Text).X / 2, Game.chrome.renderer.BoldFont.Measure(Text).Y / 2) + stateOffset, Color.White)); - base.Draw(); + base.Draw(world); } } } \ No newline at end of file diff --git a/OpenRA.Game/Widgets/CheckboxWidget.cs b/OpenRA.Game/Widgets/CheckboxWidget.cs index 35ebfd4e5d..9ce32df0aa 100644 --- a/OpenRA.Game/Widgets/CheckboxWidget.cs +++ b/OpenRA.Game/Widgets/CheckboxWidget.cs @@ -28,11 +28,11 @@ namespace OpenRA.Widgets public string Text = ""; public Func Checked = () => {return false;}; - public override void Draw() + public override void Draw(World world) { if (!Visible) { - base.Draw(); + base.Draw(world); return; } @@ -58,7 +58,7 @@ namespace OpenRA.Widgets Game.chrome.rgbaRenderer.Flush(); - base.Draw(); + base.Draw(world); } } } \ No newline at end of file diff --git a/OpenRA.Game/Widgets/LabelWidget.cs b/OpenRA.Game/Widgets/LabelWidget.cs index 10ed5bc9db..41472d3084 100644 --- a/OpenRA.Game/Widgets/LabelWidget.cs +++ b/OpenRA.Game/Widgets/LabelWidget.cs @@ -27,11 +27,11 @@ namespace OpenRA.Widgets public string Text = ""; public string Align = "Left"; - public override void Draw() + public override void Draw(World world) { if (!Visible) { - base.Draw(); + base.Draw(world); return; } @@ -48,7 +48,7 @@ namespace OpenRA.Widgets Game.chrome.renderer.BoldFont.DrawText(Game.chrome.rgbaRenderer, Text, position, Color.White); Game.chrome.rgbaRenderer.Flush(); Game.chrome.renderer.Device.DisableScissor(); - base.Draw(); + base.Draw(world); } } } \ No newline at end of file diff --git a/OpenRA.Game/Widgets/SpecialPowerBinWidget.cs b/OpenRA.Game/Widgets/SpecialPowerBinWidget.cs new file mode 100644 index 0000000000..b7f71a06bb --- /dev/null +++ b/OpenRA.Game/Widgets/SpecialPowerBinWidget.cs @@ -0,0 +1,178 @@ +#region Copyright & License Information +/* + * Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford. + * This file is part of OpenRA. + * + * OpenRA is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenRA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenRA. If not, see . + */ +#endregion + +using System.Drawing; +using System.Collections.Generic; +using System.Linq; +using OpenRA; +using OpenRA.Traits; +using OpenRA.Graphics; +using OpenRA.FileFormats; +using System; +namespace OpenRA.Widgets +{ + class SpecialPowerBinWidget : Widget + { + static Dictionary spsprites; + Animation ready; + Animation clock; + readonly List>> buttons = new List>>(); + string chromeCollection; + + public override void Initialize() + { + base.Initialize(); + + if (spsprites == null) + spsprites = Rules.Info.Values.SelectMany( u => u.Traits.WithInterface() ) + .ToDictionary( + u => u.Image, + u => SpriteSheetBuilder.LoadAllSprites(u.Image)[0]); + + ready = new Animation("pips"); + ready.PlayRepeating("ready"); + clock = new Animation("clock"); + } + + public override bool HandleInput(MouseInput mi) + { + // Are we able to handle this event? + if (!Visible || !GetEventBounds().Contains(mi.Location.X,mi.Location.Y)) + return base.HandleInput(mi); + + if (base.HandleInput(mi)) + return true; + + if (mi.Event == MouseInputEvent.Down) + { + var action = buttons.Where(a => a.First.Contains(mi.Location.ToPoint())) + .Select(a => a.Second).FirstOrDefault(); + if (action == null) + return false; + + action(mi); + return true; + } + + return false; + } + + public override void Draw(World world) + { + if (!Visible) + { + base.Draw(world); + return; + } + buttons.Clear(); + + var powers = world.LocalPlayer.PlayerActor.traits.WithInterface(); + var numPowers = powers.Count(p => p.IsAvailable); + if (numPowers == 0) return; + + SupportPower tooltipItem = null; + int2 tooltipPos = int2.Zero; + + WidgetUtils.DrawRGBA(WidgetUtils.GetChromeImage(world, "specialbin-top"),new float2(Bounds.X,Bounds.Y)); + for (var i = 1; i < numPowers; i++) + WidgetUtils.DrawRGBA(WidgetUtils.GetChromeImage(world,"specialbin-middle"), new float2(Bounds.X, Bounds.Y + i * 51)); + WidgetUtils.DrawRGBA(WidgetUtils.GetChromeImage(world,"specialbin-bottom"), new float2(Bounds.X, Bounds.Y + numPowers * 51)); + Game.chrome.rgbaRenderer.Flush(); + + // Hack Hack Hack + Bounds.Width = 69; + Bounds.Height = 10 + numPowers * 51 + 21; + + var y = Bounds.Y + 10; + foreach (var sp in powers) + { + var image = spsprites[sp.Info.Image]; + if (sp.IsAvailable) + { + var drawPos = new float2(Bounds.X + 5, y); + WidgetUtils.DrawSHP(image, drawPos); + + clock.PlayFetchIndex("idle", + () => (sp.TotalTime - sp.RemainingTime) + * (clock.CurrentSequence.Length - 1) / sp.TotalTime); + clock.Tick(); + + WidgetUtils.DrawSHP(clock.Image, drawPos); + + var rect = new Rectangle(Bounds.X + 5, y, 64, 48); + if (sp.IsReady) + { + ready.Play("ready"); + WidgetUtils.DrawSHP(ready.Image, drawPos + new float2((64 - ready.Image.size.X) / 2, 2)); + } + + buttons.Add(Pair.New(rect,HandleSupportPower(sp))); + + if (rect.Contains(Game.chrome.lastMousePos.ToPoint())) + { + tooltipItem = sp; + tooltipPos = drawPos.ToInt2() + new int2(72, 0); + } + + y += 51; + } + } + Game.chrome.shpRenderer.Flush(); + + if (tooltipItem != null) + DrawSupportPowerTooltip(world, tooltipItem, tooltipPos); + + base.Draw(world); + } + + Action HandleSupportPower(SupportPower sp) + { + return mi => { if (mi.Button == MouseButton.Left) sp.Activate(); }; + } + + string FormatTime(int ticks) + { + var seconds = ticks / 25; + var minutes = seconds / 60; + + return "{0:D2}:{1:D2}".F(minutes, seconds % 60); + } + + void DrawSupportPowerTooltip(World world, SupportPower sp, int2 pos) + { + var tooltipBounds = new Rectangle(pos.X,pos.Y,400,100); + WidgetUtils.DrawPanel("dialog", tooltipBounds, null); + + pos += new int2(5, 5); + Game.chrome.renderer.BoldFont.DrawText(Game.chrome.rgbaRenderer, sp.Info.Description, pos, Color.White); + + var timer = "Charge Time: {0}".F(FormatTime(sp.RemainingTime)); + Game.chrome.renderer.BoldFont.DrawText(Game.chrome.rgbaRenderer, timer, pos + new int2((int)tooltipBounds.Width - Game.chrome.renderer.BoldFont.Measure(timer).X - 10, 0), Color.White); + + if (sp.Info.LongDesc != null) + { + pos += new int2(0, 25); + Game.chrome.renderer.RegularFont.DrawText(Game.chrome.rgbaRenderer, sp.Info.LongDesc.Replace("\\n", "\n"), pos, Color.White); + } + + Game.chrome.rgbaRenderer.Flush(); + } + } +} \ No newline at end of file diff --git a/OpenRA.Game/Widgets/Widget.cs b/OpenRA.Game/Widgets/Widget.cs index 84025f06f8..ec68afc8d2 100644 --- a/OpenRA.Game/Widgets/Widget.cs +++ b/OpenRA.Game/Widgets/Widget.cs @@ -69,6 +69,7 @@ namespace OpenRA.Widgets width, height); + foreach (var child in Children) child.Initialize(); } @@ -91,6 +92,7 @@ namespace OpenRA.Widgets public Func OnMouseDown = mi => {return false;}; public Func OnMouseUp = mi => {return false;}; public Func OnMouseMove = mi => {return false;}; + public virtual bool HandleInput(MouseInput mi) { @@ -117,11 +119,11 @@ namespace OpenRA.Widgets return false; } - public virtual void Draw() + public virtual void Draw(World world) { if (Visible) foreach (var child in Children) - child.Draw(); + child.Draw(world); } public void AddChild(Widget child) diff --git a/OpenRA.Game/Widgets/WidgetUtils.cs b/OpenRA.Game/Widgets/WidgetUtils.cs index 6a10fb4d9a..0e68c01fa5 100644 --- a/OpenRA.Game/Widgets/WidgetUtils.cs +++ b/OpenRA.Game/Widgets/WidgetUtils.cs @@ -1,4 +1,4 @@ -#region Copyright & License Information +#region Copyright & License Information /* * Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford. * This file is part of OpenRA. @@ -28,6 +28,21 @@ namespace OpenRA.Widgets { static class WidgetUtils { + public static Sprite GetChromeImage(World world, string name) + { + return ChromeProvider.GetImage(Game.chrome.renderer, "chrome-" + world.LocalPlayer.Country.Race, name); + } + + public static void DrawRGBA(Sprite s, float2 pos) + { + Game.chrome.rgbaRenderer.DrawSprite(s,pos,"chrome"); + } + + public static void DrawSHP(Sprite s, float2 pos) + { + Game.chrome.shpRenderer.DrawSprite(s,pos,"chrome"); + } + public static void DrawPanel(string collection, Rectangle Bounds, Action a) { var r = Game.chrome.renderer; diff --git a/mods/cnc/menus.yaml b/mods/cnc/menus.yaml index 3328de4a2c..163f9a86c6 100644 --- a/mods/cnc/menus.yaml +++ b/mods/cnc/menus.yaml @@ -256,4 +256,61 @@ Container: Width:160 Height:25 Text:Abort - Delegate:ConnectionDialogsDelegate \ No newline at end of file + Delegate:ConnectionDialogsDelegate + Container@INGAME_ROOT: + Id:INGAME_ROOT + Visible:false + Children: + SpecialPowerBin@INGAME_POWERS_BIN: + Id:INGAME_POWERS_BIN + X:0 + Y:25 + Delegate:IngameChromeDelegate + Button@INGAME_OPTIONS_BUTTON: + Id:INGAME_OPTIONS_BUTTON + X:0 + Y:0 + Width:160 + Height:25 + Text:Options + Delegate:IngameChromeDelegate + Background@INGAME_OPTIONS_BG: + Id:INGAME_OPTIONS_BG + X:(WINDOW_RIGHT - WIDTH)/2 + Y:(WINDOW_BOTTOM - HEIGHT)/2 + Width:300 + Height:220 + Visible:false + Children: + Label@LABEL_TITLE: + Id:LABEL_TITLE + X:(PARENT_RIGHT - WIDTH)/2 + Y:20 + Width:250 + Height:25 + Text:Options + Align:Center + Button@BUTTON_SETTINGS: + Id:BUTTON_SETTINGS + X:(PARENT_RIGHT - WIDTH)/2 + Y:80 + Width:160 + Height:25 + Text:Settings + Delegate:IngameChromeDelegate + Button@BUTTON_DISCONNECT: + Id:BUTTON_DISCONNECT + X:(PARENT_RIGHT - WIDTH)/2 + Y:120 + Width:160 + Height:25 + Text:Disconnect + Delegate:IngameChromeDelegate + Button@BUTTON_QUIT: + Id:BUTTON_QUIT + X:(PARENT_RIGHT - WIDTH)/2 + Y:160 + Width:160 + Height:25 + Text:Quit + Delegate:IngameChromeDelegate \ No newline at end of file diff --git a/mods/ra/menus.yaml b/mods/ra/menus.yaml index 8e7778d2b1..163f9a86c6 100644 --- a/mods/ra/menus.yaml +++ b/mods/ra/menus.yaml @@ -261,6 +261,11 @@ Container: Id:INGAME_ROOT Visible:false Children: + SpecialPowerBin@INGAME_POWERS_BIN: + Id:INGAME_POWERS_BIN + X:0 + Y:25 + Delegate:IngameChromeDelegate Button@INGAME_OPTIONS_BUTTON: Id:INGAME_OPTIONS_BUTTON X:0