move some more (gameplay related) widgets into mods/

This commit is contained in:
Bob
2010-07-30 20:23:16 +12:00
parent b4c84a11f2
commit ede160f1b6
18 changed files with 45 additions and 39 deletions

View File

@@ -201,6 +201,12 @@
<Compile Include="Wall.cs" />
<Compile Include="WaterPaletteRotation.cs" />
<Compile Include="Widgets\BuildPaletteWidget.cs" />
<Compile Include="Widgets\Delegates\IngameChromeDelegate.cs" />
<Compile Include="Widgets\MoneyBinWidget.cs" />
<Compile Include="Widgets\OrderButtonWidget.cs" />
<Compile Include="Widgets\PowerBinWidget.cs" />
<Compile Include="Widgets\RadarBinWidget.cs" />
<Compile Include="Widgets\SpecialPowerBinWidget.cs" />
<Compile Include="WithMuzzleFlash.cs" />
<Compile Include="WithShadow.cs" />
<Compile Include="NukePaletteEffect.cs" />

View File

@@ -6,14 +6,12 @@
* as published by the Free Software Foundation. For more information,
* see LICENSE.
*/
#endregion
#endregion
using System.Drawing;
using OpenRA.Traits;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using OpenRA.FileFormats;
namespace OpenRA.Traits
namespace OpenRA.Mods.RA
{
public class RadarColorFromTerrainInfo : ITraitInfo
{
@@ -33,6 +31,6 @@ namespace OpenRA.Traits
public Color RadarColorOverride(Actor self)
{
return c;
}
}
}
}

View File

@@ -16,8 +16,9 @@ using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Orders;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Widgets
namespace OpenRA.Mods.RA.Widgets
{
class BuildPaletteWidget : Widget
{

View File

@@ -0,0 +1,80 @@
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Delegates
{
public class IngameChromeDelegate : IWidgetDelegate
{
public IngameChromeDelegate()
{
var r = Widget.RootWidget;
var gameRoot = r.GetWidget("INGAME_ROOT");
var optionsBG = gameRoot.GetWidget("INGAME_OPTIONS_BG");
Game.OnGameStart += () => r.OpenWindow("INGAME_ROOT");
Game.OnGameStart += () => gameRoot.GetWidget<RadarBinWidget>("INGAME_RADAR_BIN").SetWorld(Game.world);
r.GetWidget("INGAME_OPTIONS_BUTTON").OnMouseUp = mi => {
optionsBG.Visible = !optionsBG.Visible;
return true;
};
optionsBG.GetWidget("BUTTON_DISCONNECT").OnMouseUp = mi => {
optionsBG.Visible = false;
Game.Disconnect();
return true;
};
optionsBG.GetWidget("BUTTON_SETTINGS").OnMouseUp = mi => {
r.OpenWindow("SETTINGS_MENU");
return true;
};
optionsBG.GetWidget("BUTTON_RESUME").OnMouseUp = mi =>
{
optionsBG.Visible = false;
return true;
};
optionsBG.GetWidget("BUTTON_SURRENDER").OnMouseUp = mi =>
{
Game.IssueOrder(new Order("Surrender", Game.world.LocalPlayer.PlayerActor));
return true;
};
optionsBG.GetWidget("BUTTON_QUIT").OnMouseUp = mi => {
Game.Exit();
return true;
};
Game.AddChatLine += gameRoot.GetWidget<ChatDisplayWidget>("CHAT_DISPLAY").AddLine;
var postgameBG = gameRoot.GetWidget("POSTGAME_BG");
var postgameText = postgameBG.GetWidget<LabelWidget>("TEXT");
postgameBG.IsVisible = () =>
{
return Game.world.LocalPlayer.WinState != WinState.Undefined;
};
postgameText.GetText = () =>
{
var state = Game.world.LocalPlayer.WinState;
return (state == WinState.Undefined)? "" :
((state == WinState.Lost)? "YOU ARE DEFEATED" : "YOU ARE VICTORIOUS");
};
}
bool AreMutualAllies(Player a, Player b) { return a.Stances[b] == Stance.Ally && b.Stances[a] == Stance.Ally; }
}
}

View File

@@ -1,4 +1,3 @@
#region Copyright & License Information
/*
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
@@ -7,10 +6,10 @@
* as published by the Free Software Foundation. For more information,
* see LICENSE.
*/
#endregion
#endregion
using OpenRA.Mods.RA.Orders;
using OpenRA.Widgets;
using OpenRA.Mods.RA.Orders;
namespace OpenRA.Mods.RA.Widgets.Delegates
{

View File

@@ -0,0 +1,91 @@
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets
{
class MoneyBinWidget : Widget
{
const int chromeButtonGap = 2;
public bool SplitOreAndCash = false;
/* legacy crap!!! */
List<Pair<Rectangle, Action<MouseInput>>> buttons = new List<Pair<Rectangle, Action<MouseInput>>>();
void AddButton(Rectangle r, Action<MouseInput> b) { buttons.Add(Pair.New(r, b)); }
public MoneyBinWidget() : base() { }
protected MoneyBinWidget(Widget other) : base(other) { }
public override Widget Clone() { return new MoneyBinWidget(this); }
public override void DrawInner(World world)
{
var playerResources = world.LocalPlayer.PlayerActor.traits.Get<PlayerResources>();
var digitCollection = "digits-" + world.LocalPlayer.Country.Race;
var chromeCollection = "chrome-" + world.LocalPlayer.Country.Race;
Game.Renderer.RgbaSpriteRenderer.DrawSprite(
ChromeProvider.GetImage(chromeCollection, "moneybin"),
new float2(Bounds.Left, 0), "chrome");
// Cash
var cashDigits = (SplitOreAndCash ? playerResources.DisplayCash
: (playerResources.DisplayCash + playerResources.DisplayOre)).ToString();
var x = Bounds.Right - 65;
foreach (var d in cashDigits.Reverse())
{
Game.Renderer.RgbaSpriteRenderer.DrawSprite(
ChromeProvider.GetImage(digitCollection, (d - '0').ToString()),
new float2(x, 6), "chrome");
x -= 14;
}
if (SplitOreAndCash)
{
x -= 14;
// Ore
var oreDigits = playerResources.DisplayOre.ToString();
foreach (var d in oreDigits.Reverse())
{
Game.Renderer.RgbaSpriteRenderer.DrawSprite(
ChromeProvider.GetImage( digitCollection, (d - '0').ToString()),
new float2(x, 6), "chrome");
x -= 14;
}
}
}
public override bool HandleInputInner(MouseInput mi)
{
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;
}
}
}

View File

@@ -0,0 +1,68 @@
using System;
using System.Drawing;
using OpenRA.Graphics;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets
{
public class OrderButtonWidget : ButtonWidget
{
public Func<bool> Enabled = () => true;
public Func<bool> Pressed = () => false;
public string Image, Description, LongDesc = "";
public Func<string> GetImage, GetDescription, GetLongDesc;
public OrderButtonWidget()
{
GetImage = () => Enabled() ? Pressed() ? "pressed" : "normal" : "disabled";
GetDescription = () => Description;
GetLongDesc = () => LongDesc;
}
public override void DrawInner (World world)
{
var image = ChromeProvider.GetImage(Image + "-button", GetImage());
var rect = new Rectangle(RenderBounds.X, RenderBounds.Y, (int)image.size.X, (int)image.size.Y);
if (rect.Contains(Viewport.LastMousePos.ToPoint()))
{
rect = rect.InflateBy(3, 3, 3, 3);
var pos = new int2(rect.Left, rect.Top);
var m = pos + new int2(rect.Width, rect.Height);
var br = pos + new int2(rect.Width, rect.Height + 20);
var u = Game.Renderer.RegularFont.Measure(GetLongDesc().Replace("\\n", "\n"));
br.X -= u.X;
br.Y += u.Y;
br += new int2(-15, 25);
var border = WidgetUtils.GetBorderSizes("dialog4");
WidgetUtils.DrawPanelPartial("dialog4", rect
.InflateBy(0, 0, 0, border[1]),
PanelSides.Top | PanelSides.Left | PanelSides.Right);
WidgetUtils.DrawPanelPartial("dialog4", new Rectangle(br.X, m.Y, pos.X - br.X, br.Y - m.Y)
.InflateBy(0, 0, border[3], 0),
PanelSides.Top | PanelSides.Left | PanelSides.Bottom);
WidgetUtils.DrawPanelPartial("dialog4", new Rectangle(pos.X, m.Y, m.X - pos.X, br.Y - m.Y)
.InflateBy(border[2], border[0], 0, 0),
PanelSides.Right | PanelSides.Bottom);
pos.X = br.X + 8;
pos.Y = m.Y + 8;
Game.Renderer.BoldFont.DrawText(GetDescription(), pos, Color.White);
pos += new int2(0, 20);
Game.Renderer.RegularFont.DrawText(GetLongDesc().Replace("\\n", "\n"), pos, Color.White);
}
Game.Renderer.RgbaSpriteRenderer.DrawSprite(image, new int2(RenderBounds.X, RenderBounds.Y), "chrome");
}
}
}

View File

@@ -0,0 +1,86 @@
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System;
using System.Drawing;
using OpenRA.Graphics;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets
{
public class PowerBinWidget : Widget
{
// Power bar
static float2 powerOrigin = new float2(42, 205); // Relative to radarOrigin
static Size powerSize = new Size(138, 5);
float? lastPowerProvidedPos;
float? lastPowerDrainedPos;
string powerCollection;
public override void DrawInner(World world)
{
powerCollection = "power-" + world.LocalPlayer.Country.Race;
var resources = world.LocalPlayer.PlayerActor.traits.Get<PlayerResources>();
// Nothing to draw
if (resources.PowerProvided == 0
&& resources.PowerDrained == 0)
return;
// Draw bar horizontally
var barStart = powerOrigin + RadarBinWidget.radarOrigin;
var barEnd = barStart + new float2(powerSize.Width, 0);
float powerScaleBy = 100;
var maxPower = Math.Max(resources.PowerProvided, resources.PowerDrained);
while (maxPower >= powerScaleBy) powerScaleBy *= 2;
// Current power supply
var powerLevelTemp = barStart.X + (barEnd.X - barStart.X) * (resources.PowerProvided / powerScaleBy);
lastPowerProvidedPos = float2.Lerp(lastPowerProvidedPos.GetValueOrDefault(powerLevelTemp), powerLevelTemp, .3f);
float2 powerLevel = new float2(lastPowerProvidedPos.Value, barStart.Y);
var color = Color.LimeGreen;
if (resources.GetPowerState() == PowerState.Low)
color = Color.Orange;
if (resources.GetPowerState() == PowerState.Critical)
color = Color.Red;
var colorDark = Graphics.Util.Lerp(0.25f, color, Color.Black);
for (int i = 0; i < powerSize.Height; i++)
{
color = (i - 1 < powerSize.Height / 2) ? color : colorDark;
float2 leftOffset = new float2(0, i);
float2 rightOffset = new float2(0, i);
// Indent corners
if ((i == 0 || i == powerSize.Height - 1) && powerLevel.X - barStart.X > 1)
{
leftOffset.X += 1;
rightOffset.X -= 1;
}
Game.Renderer.LineRenderer.DrawLine(Game.viewport.Location + barStart + leftOffset, Game.viewport.Location + powerLevel + rightOffset, color, color);
}
// Draw on top of the sprite
Game.Renderer.RgbaSpriteRenderer.Flush();
Game.Renderer.LineRenderer.Flush();
// Power usage indicator
var indicator = ChromeProvider.GetImage( powerCollection, "power-indicator");
var powerDrainedTemp = barStart.X + (barEnd.X - barStart.X) * (resources.PowerDrained / powerScaleBy);
lastPowerDrainedPos = float2.Lerp(lastPowerDrainedPos.GetValueOrDefault(powerDrainedTemp), powerDrainedTemp, .3f);
float2 powerDrainLevel = new float2(lastPowerDrainedPos.Value - indicator.size.X / 2, barStart.Y - 1);
Game.Renderer.RgbaSpriteRenderer.DrawSprite(indicator, powerDrainLevel, "chrome");
Game.Renderer.RgbaSpriteRenderer.Flush();
}
}
}

View File

@@ -0,0 +1,234 @@
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System;
using System.Drawing;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets
{
public class RadarBinWidget : Widget
{
static float2 radarOpenOrigin = new float2(Game.viewport.Width - 215, 29);
static float2 radarClosedOrigin = new float2(Game.viewport.Width - 215, -166);
public static float2 radarOrigin = radarClosedOrigin;
float radarMinimapHeight;
const int radarSlideAnimationLength = 15;
const int radarActivateAnimationLength = 5;
int radarAnimationFrame = 0;
bool radarAnimating = false;
bool hasRadar = false;
string radarCollection;
World world;
float previewScale = 0;
RectangleF mapRect = Rectangle.Empty;
int2 previewOrigin;
Sprite terrainSprite;
Sprite customTerrainSprite;
Sprite actorSprite;
Sprite shroudSprite;
public void SetWorld(World world)
{
this.world = world;
var size = Math.Max(world.Map.Width, world.Map.Height);
previewScale = Math.Min(192f / world.Map.Width, 192f / world.Map.Height);
previewOrigin = new int2(9 + (int)(radarOpenOrigin.X + previewScale * (size - world.Map.Width)/2), (int)(radarOpenOrigin.Y + previewScale * (size - world.Map.Height)/2));
mapRect = new RectangleF(previewOrigin.X, previewOrigin.Y, (int)(world.Map.Width * previewScale), (int)(world.Map.Height * previewScale));
// Only needs to be done once
var terrainBitmap = Minimap.TerrainBitmap(world.Map);
var r = new Rectangle( 0, 0, world.Map.Width, world.Map.Height );
var s = new Size( terrainBitmap.Width, terrainBitmap.Height );
terrainSprite = new Sprite(new Sheet(s), r, TextureChannel.Alpha);
terrainSprite.sheet.Texture.SetData(terrainBitmap);
// Data is set in Tick()
customTerrainSprite = new Sprite(new Sheet(s), r, TextureChannel.Alpha);
actorSprite = new Sprite(new Sheet(s), r, TextureChannel.Alpha);
shroudSprite = new Sprite(new Sheet(s), r, TextureChannel.Alpha);
}
public override string GetCursor(int2 pos)
{
if (world == null || !hasRadar)
return null;
var loc = MinimapPixelToCell(pos);
var mi = new MouseInput
{
Location = loc,
Button = MouseButton.Right,
Modifiers = Game.GetModifierKeys()
};
var cursor = Game.world.OrderGenerator.GetCursor( world, loc, mi );
if (cursor == null)
return "default";
return SequenceProvider.HasCursorSequence(cursor+"-minimap") ? cursor+"-minimap" : cursor;
}
public override bool HandleInputInner(MouseInput mi)
{
if (!hasRadar || radarAnimating) return false; // we're not set up for this.
if (!mapRect.Contains(mi.Location.ToPointF()))
return false;
var loc = MinimapPixelToCell(mi.Location);
if ((mi.Event == MouseInputEvent.Down || mi.Event == MouseInputEvent.Move) && mi.Button == MouseButton.Left)
Game.viewport.Center(loc);
if (mi.Event == MouseInputEvent.Down && mi.Button == MouseButton.Right)
{
// fake a mousedown/mouseup here
var fakemi = new MouseInput
{
Event = MouseInputEvent.Down,
Button = MouseButton.Right,
Modifiers = mi.Modifiers,
Location = (loc * Game.CellSize - Game.viewport.Location).ToInt2()
};
Widget.HandleInput(Game.world, fakemi);
fakemi.Event = MouseInputEvent.Up;
Widget.HandleInput(Game.world, fakemi);
}
return true;
}
public override Rectangle EventBounds
{
get { return new Rectangle((int)mapRect.X, (int)mapRect.Y, (int)mapRect.Width, (int)mapRect.Height);}
}
public override void DrawInner(World world)
{
radarCollection = "radar-" + world.LocalPlayer.Country.Race;
Game.Renderer.RgbaSpriteRenderer.DrawSprite(ChromeProvider.GetImage(radarCollection, "left"), radarOrigin, "chrome");
Game.Renderer.RgbaSpriteRenderer.DrawSprite(ChromeProvider.GetImage(radarCollection, "right"), radarOrigin + new float2(201, 0), "chrome");
Game.Renderer.RgbaSpriteRenderer.DrawSprite(ChromeProvider.GetImage(radarCollection, "bottom"), radarOrigin + new float2(0, 192), "chrome");
Game.Renderer.RgbaSpriteRenderer.DrawSprite(ChromeProvider.GetImage(radarCollection, "bg"), radarOrigin + new float2(9, 0), "chrome");
// Don't draw the radar if the tray is moving
if (radarAnimationFrame >= radarSlideAnimationLength)
{
var o = new float2(mapRect.Location.X, mapRect.Location.Y + world.Map.Height * previewScale * (1 - radarMinimapHeight)/2);
var s = new float2(mapRect.Size.Width, mapRect.Size.Height*radarMinimapHeight);
Game.Renderer.RgbaSpriteRenderer.DrawSprite(terrainSprite, o, "chrome", s);
Game.Renderer.RgbaSpriteRenderer.DrawSprite(customTerrainSprite, o, "chrome", s);
Game.Renderer.RgbaSpriteRenderer.DrawSprite(actorSprite, o, "chrome", s);
Game.Renderer.RgbaSpriteRenderer.DrawSprite(shroudSprite, o, "chrome", s);
Game.Renderer.RgbaSpriteRenderer.Flush();
// Draw viewport rect
if (radarAnimationFrame == radarSlideAnimationLength + radarActivateAnimationLength)
{
var tl = CellToMinimapPixel(new int2((int)(Game.viewport.Location.X/Game.CellSize), (int)(Game.viewport.Location.Y/Game.CellSize)));
var br = CellToMinimapPixel(new int2((int)((Game.viewport.Location.X + Game.viewport.Width)/Game.CellSize), (int)((Game.viewport.Location.Y + Game.viewport.Height)/Game.CellSize)));
var tr = new int2(br.X, tl.Y);
var bl = new int2(tl.X, br.Y);
Game.Renderer.LineRenderer.Flush();
Game.Renderer.Device.EnableScissor((int)mapRect.Left, (int)mapRect.Top, (int)mapRect.Width, (int)mapRect.Height);
Game.Renderer.LineRenderer.DrawLine(Game.viewport.Location + tl, Game.viewport.Location + tr, Color.White, Color.White);
Game.Renderer.LineRenderer.DrawLine(Game.viewport.Location + tr, Game.viewport.Location + br, Color.White, Color.White);
Game.Renderer.LineRenderer.DrawLine(Game.viewport.Location + br, Game.viewport.Location + bl, Color.White, Color.White);
Game.Renderer.LineRenderer.DrawLine(Game.viewport.Location + bl, Game.viewport.Location + tl, Color.White, Color.White);
Game.Renderer.LineRenderer.Flush();
Game.Renderer.Device.DisableScissor();
}
}
}
int updateTicks = 0;
public override void Tick(World w)
{
var hasRadarNew = world.Queries.OwnedBy[world.LocalPlayer]
.WithTrait<ProvidesRadar>()
.Any(a => a.Trait.IsActive);
if (hasRadarNew != hasRadar)
radarAnimating = true;
hasRadar = hasRadarNew;
// Build the radar image
if (hasRadar)
{
--updateTicks;
if (updateTicks <= 0)
{
updateTicks = 12;
customTerrainSprite.sheet.Texture.SetData(Minimap.CustomTerrainBitmap(world));
}
if (updateTicks == 8)
actorSprite.sheet.Texture.SetData(Minimap.ActorsBitmap(world));
if (updateTicks == 4)
shroudSprite.sheet.Texture.SetData(Minimap.ShroudBitmap(world));
}
if (!radarAnimating)
return;
// Increment frame
if (hasRadar)
radarAnimationFrame++;
else
radarAnimationFrame--;
// Calculate radar bin position
if (radarAnimationFrame <= radarSlideAnimationLength)
radarOrigin = float2.Lerp(radarClosedOrigin, radarOpenOrigin, radarAnimationFrame * 1.0f / radarSlideAnimationLength);
var eva = Rules.Info["world"].Traits.Get<EvaAlertsInfo>();
// Play radar-on sound at the start of the activate anim (open)
if (radarAnimationFrame == radarSlideAnimationLength && hasRadar)
Sound.Play(eva.RadarUp);
// Play radar-on sound at the start of the activate anim (close)
if (radarAnimationFrame == radarSlideAnimationLength + radarActivateAnimationLength - 1 && !hasRadar)
Sound.Play(eva.RadarDown);
// Minimap height
if (radarAnimationFrame >= radarSlideAnimationLength)
radarMinimapHeight = float2.Lerp(0, 1, (radarAnimationFrame - radarSlideAnimationLength) * 1.0f / radarActivateAnimationLength);
// Animation is complete
if (radarAnimationFrame == (hasRadar ? radarSlideAnimationLength + radarActivateAnimationLength : 0))
radarAnimating = false;
}
int2 CellToMinimapPixel(int2 p)
{
return new int2((int)(mapRect.X +previewScale*(p.X - world.Map.TopLeft.X)), (int)(mapRect.Y + previewScale*(p.Y - world.Map.TopLeft.Y)));
}
int2 MinimapPixelToCell(int2 p)
{
return new int2(world.Map.TopLeft.X + (int)((p.X - mapRect.X)/previewScale), world.Map.TopLeft.Y + (int)((p.Y - mapRect.Y)/previewScale));
}
}
}

View File

@@ -0,0 +1,158 @@
#region Copyright & License Information
/*
* Copyright 2007-2010 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 LICENSE.
*/
#endregion
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets
{
class SpecialPowerBinWidget : Widget
{
static Dictionary<string, Sprite> spsprites;
Animation ready;
Animation clock;
readonly List<Pair<Rectangle, Action<MouseInput>>> buttons = new List<Pair<Rectangle,Action<MouseInput>>>();
public SpecialPowerBinWidget() : base() { }
public override void Initialize()
{
base.Initialize();
if (spsprites == null)
spsprites = Rules.Info.Values.SelectMany( u => u.Traits.WithInterface<SupportPowerInfo>() )
.ToDictionary(
u => u.Image,
u => SpriteSheetBuilder.LoadAllSprites(u.Image)[0]);
ready = new Animation("pips");
ready.PlayRepeating("ready");
clock = new Animation("clock");
}
public override Rectangle EventBounds
{
get { return buttons.Any() ? buttons.Select(b => b.First).Aggregate(Rectangle.Union) : Bounds; }
}
public override bool HandleInputInner(MouseInput mi)
{
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 DrawInner(World world)
{
buttons.Clear();
var powers = world.LocalPlayer.PlayerActor.traits.WithInterface<SupportPower>();
var numPowers = powers.Count(p => p.IsAvailable);
if (numPowers == 0) return;
var rectBounds = RenderBounds;
WidgetUtils.DrawRGBA(WidgetUtils.GetChromeImage(world, "specialbin-top"),new float2(rectBounds.X,rectBounds.Y));
for (var i = 1; i < numPowers; i++)
WidgetUtils.DrawRGBA(WidgetUtils.GetChromeImage(world,"specialbin-middle"), new float2(rectBounds.X, rectBounds.Y + i * 51));
WidgetUtils.DrawRGBA(WidgetUtils.GetChromeImage(world,"specialbin-bottom"), new float2(rectBounds.X, rectBounds.Y + numPowers * 51));
Game.Renderer.RgbaSpriteRenderer.Flush();
// Hack Hack Hack
rectBounds.Width = 69;
rectBounds.Height = 10 + numPowers * 51 + 21;
var y = rectBounds.Y + 10;
foreach (var sp in powers)
{
var image = spsprites[sp.Info.Image];
if (sp.IsAvailable)
{
var drawPos = new float2(rectBounds.X + 5, y);
var rect = new Rectangle(rectBounds.X + 5, y, 64, 48);
if (rect.Contains(Viewport.LastMousePos.ToPoint()))
{
var pos = drawPos.ToInt2();
var tl = new int2(pos.X-3,pos.Y-3);
var m = new int2(pos.X+64+3,pos.Y+48+3);
var br = tl + new int2(64+3+20,60);
if (sp.Info.LongDesc != null)
br += Game.Renderer.RegularFont.Measure(sp.Info.LongDesc.Replace("\\n", "\n"));
else
br += new int2(300,0);
var border = WidgetUtils.GetBorderSizes("dialog4");
WidgetUtils.DrawPanelPartial("dialog4", Rectangle.FromLTRB(tl.X, tl.Y, m.X + border[3], m.Y),
PanelSides.Left | PanelSides.Top | PanelSides.Bottom);
WidgetUtils.DrawPanelPartial("dialog4", Rectangle.FromLTRB(m.X - border[2], tl.Y, br.X, m.Y + border[1]),
PanelSides.Top | PanelSides.Right);
WidgetUtils.DrawPanelPartial("dialog4", Rectangle.FromLTRB(m.X, m.Y - border[1], br.X, br.Y),
PanelSides.Left | PanelSides.Right | PanelSides.Bottom);
pos += new int2(77, 5);
Game.Renderer.BoldFont.DrawText(sp.Info.Description, pos, Color.White);
pos += new int2(0,20);
Game.Renderer.BoldFont.DrawText(WorldUtils.FormatTime(sp.RemainingTime).ToString(), pos, Color.White);
Game.Renderer.BoldFont.DrawText("/ {0}".F(WorldUtils.FormatTime(sp.TotalTime)), pos + new int2(45,0), Color.White);
if (sp.Info.LongDesc != null)
{
pos += new int2(0, 20);
Game.Renderer.RegularFont.DrawText(sp.Info.LongDesc.Replace("\\n", "\n"), pos, Color.White);
}
}
WidgetUtils.DrawSHP(image, drawPos);
clock.PlayFetchIndex("idle",
() => (sp.TotalTime - sp.RemainingTime)
* (clock.CurrentSequence.Length - 1) / sp.TotalTime);
clock.Tick();
WidgetUtils.DrawSHP(clock.Image, drawPos);
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)));
y += 51;
}
}
Game.Renderer.WorldSpriteRenderer.Flush();
}
Action<MouseInput> HandleSupportPower(SupportPower sp)
{
return mi => { if (mi.Button == MouseButton.Left) sp.Activate(); };
}
}
}

View File

@@ -9,9 +9,10 @@
#endregion
using System.Linq;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Traits
namespace OpenRA.Mods.RA.Widgets
{
class ChoosePaletteOnSelectInfo : TraitInfo<ChoosePaletteOnSelect> { }