Files
OpenRA/OpenRA.Mods.Cnc/Widgets/ProductionPaletteWidget.cs
deniz1a 1821c52db0 Make "Ready" text alternate between red and white
Make color of "Ready" text alternate between red and white.

Made the code cleaner.

Whitespace correction.

Whitespace correction again.

Change color from red to green and make it moddable

Use enum for ReadyTextStyle

Use enum for cnc

Made variables public and simplified if statements

fix enum

fix enum and )

ReadyText settings in ra yaml

ReadyText settings in cnc yaml

Move values from code to ra yaml

Move values from code to cnc yaml

revert code changes cnc

revert code changes ra

move around a bit in ra yaml

move around a bit in cnc yaml

Add values to d2k yaml
2014-06-10 12:00:57 +03:00

289 lines
8.9 KiB
C#

#region Copyright & License Information
/*
* Copyright 2007-2014 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;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Network;
using OpenRA.Mods.RA;
using OpenRA.Mods.RA.Buildings;
using OpenRA.Mods.RA.Orders;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.Cnc.Widgets
{
public class ProductionIcon
{
public string Name;
public Sprite Sprite;
public float2 Pos;
public List<ProductionItem> Queued;
}
public class ProductionPaletteWidget : Widget
{
public enum ReadyTextStyleOptions { Solid, AlternatingColor, Blinking }
public readonly ReadyTextStyleOptions ReadyTextStyle = ReadyTextStyleOptions.AlternatingColor;
public readonly Color ReadyTextAltColor = Color.LimeGreen;
public readonly int Columns = 3;
public readonly string TabClick = null;
public readonly string DisabledTabClick = null;
public readonly string TooltipContainer;
public readonly string TooltipTemplate = "PRODUCTION_TOOLTIP";
[Translate] public readonly string ReadyText = "";
[Translate] public readonly string HoldText = "";
public string TooltipActor { get; private set; }
public readonly World World;
readonly OrderManager orderManager;
Lazy<TooltipContainerWidget> tooltipContainer;
ProductionQueue currentQueue;
public ProductionQueue CurrentQueue
{
get { return currentQueue; }
set { currentQueue = value; RefreshIcons(); }
}
public override Rectangle EventBounds { get { return eventBounds; } }
Dictionary<Rectangle, ProductionIcon> icons = new Dictionary<Rectangle, ProductionIcon>();
Animation cantBuild, clock;
Rectangle eventBounds = Rectangle.Empty;
readonly WorldRenderer worldRenderer;
SpriteFont overlayFont;
float2 holdOffset, readyOffset, timeOffset, queuedOffset;
[ObjectCreator.UseCtor]
public ProductionPaletteWidget(OrderManager orderManager, World world, WorldRenderer worldRenderer)
{
this.orderManager = orderManager;
this.World = world;
this.worldRenderer = worldRenderer;
tooltipContainer = Exts.Lazy(() =>
Ui.Root.Get<TooltipContainerWidget>(TooltipContainer));
cantBuild = new Animation(world, "clock");
cantBuild.PlayFetchIndex("idle", () => 0);
clock = new Animation(world, "clock");
}
public override void Tick()
{
if (CurrentQueue != null && !CurrentQueue.self.IsInWorld)
CurrentQueue = null;
if (CurrentQueue != null)
RefreshIcons();
}
public override void MouseEntered()
{
if (TooltipContainer != null)
tooltipContainer.Value.SetTooltip(TooltipTemplate,
new WidgetArgs() { { "palette", this } });
}
public override void MouseExited()
{
if (TooltipContainer != null)
tooltipContainer.Value.RemoveTooltip();
}
public override bool HandleMouseInput(MouseInput mi)
{
var icon = icons.Where(i => i.Key.Contains(mi.Location))
.Select(i => i.Value).FirstOrDefault();
if (mi.Event == MouseInputEvent.Move)
TooltipActor = icon != null ? icon.Name : null;
if (icon == null)
return false;
// Eat mouse-up events
if (mi.Event != MouseInputEvent.Down)
return true;
var actor = World.Map.Rules.Actors[icon.Name];
var first = icon.Queued.FirstOrDefault();
if (mi.Button == MouseButton.Left)
{
// Pick up a completed building
if (first != null && first.Done && actor.Traits.Contains<BuildingInfo>())
{
Sound.Play(TabClick);
World.OrderGenerator = new PlaceBuildingOrderGenerator(CurrentQueue.self, icon.Name);
}
else if (first != null && first.Paused)
{
// Resume a paused item
Sound.Play(TabClick);
World.IssueOrder(Order.PauseProduction(CurrentQueue.self, icon.Name, false));
}
else if (CurrentQueue.BuildableItems().Any(a => a.Name == icon.Name))
{
// Queue a new item
Sound.Play(TabClick);
Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", CurrentQueue.Info.QueuedAudio, World.LocalPlayer.Country.Race);
World.IssueOrder(Order.StartProduction(CurrentQueue.self, icon.Name,
Game.GetModifierKeys().HasModifier(Modifiers.Shift) ? 5 : 1));
}
else
Sound.Play(DisabledTabClick);
}
else if (mi.Button == MouseButton.Right)
{
// Hold/Cancel an existing item
if (first != null)
{
Sound.Play(TabClick);
// instant cancel of things we havent started yet and things that are finished
if (first.Paused || first.Done || first.TotalCost == first.RemainingCost)
{
Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", CurrentQueue.Info.CancelledAudio, World.LocalPlayer.Country.Race);
World.IssueOrder(Order.CancelProduction(CurrentQueue.self, icon.Name,
Game.GetModifierKeys().HasModifier(Modifiers.Shift) ? 5 : 1));
}
else
{
Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", CurrentQueue.Info.OnHoldAudio, World.LocalPlayer.Country.Race);
World.IssueOrder(Order.PauseProduction(CurrentQueue.self, icon.Name, true));
}
}
else
Sound.Play(DisabledTabClick);
}
return true;
}
public void RefreshIcons()
{
icons = new Dictionary<Rectangle, ProductionIcon>();
if (CurrentQueue == null)
return;
var allBuildables = CurrentQueue.AllItems().OrderBy(a => a.Traits.Get<BuildableInfo>().BuildPaletteOrder);
var i = 0;
var rb = RenderBounds;
foreach (var item in allBuildables)
{
var x = i % Columns;
var y = i / Columns;
var rect = new Rectangle(rb.X + x * 64 + 1, rb.Y + y * 48 + 1, 64, 48);
var icon = new Animation(World, RenderSimple.GetImage(item));
icon.Play(item.Traits.Get<TooltipInfo>().Icon);
var pi = new ProductionIcon()
{
Name = item.Name,
Sprite = icon.Image,
Pos = new float2(rect.Location),
Queued = CurrentQueue.AllQueued().Where(a => a.Item == item.Name).ToList(),
};
icons.Add(rect, pi);
i++;
}
eventBounds = icons.Keys.Aggregate(Rectangle.Union);
}
public override void Draw()
{
var iconSize = new float2(64, 48);
var iconOffset = 0.5f * iconSize;
overlayFont = Game.Renderer.Fonts["TinyBold"];
timeOffset = iconOffset - overlayFont.Measure(WidgetUtils.FormatTime(0)) / 2;
queuedOffset = new float2(4, 2);
holdOffset = iconOffset - overlayFont.Measure(HoldText) / 2;
readyOffset = iconOffset - overlayFont.Measure(ReadyText) / 2;
if (CurrentQueue == null)
return;
var buildableItems = CurrentQueue.BuildableItems();
// Background
foreach (var rect in icons.Keys)
WidgetUtils.DrawPanel("panel-black", rect.InflateBy(1, 1, 1, 1));
// Icons
foreach (var icon in icons.Values)
{
WidgetUtils.DrawSHPCentered(icon.Sprite, icon.Pos + iconOffset, worldRenderer);
// Build progress
if (icon.Queued.Count > 0)
{
var first = icon.Queued[0];
clock.PlayFetchIndex("idle",
() => (first.TotalTime - first.RemainingTime)
* (clock.CurrentSequence.Length - 1) / first.TotalTime);
clock.Tick();
WidgetUtils.DrawSHPCentered(clock.Image, icon.Pos + iconOffset, worldRenderer);
}
else if (!buildableItems.Any(a => a.Name == icon.Name))
WidgetUtils.DrawSHPCentered(cantBuild.Image, icon.Pos + iconOffset, worldRenderer);
}
// Overlays
foreach (var icon in icons.Values)
{
var total = icon.Queued.Count;
if (total > 0)
{
var first = icon.Queued[0];
var waiting = first != CurrentQueue.CurrentItem() && !first.Done;
if (first.Done)
{
if (ReadyTextStyle == ReadyTextStyleOptions.Solid || orderManager.LocalFrameNumber / 9 % 2 == 0)
overlayFont.DrawTextWithContrast(ReadyText,
icon.Pos + readyOffset,
Color.White, Color.Black, 1);
else if (ReadyTextStyle == ReadyTextStyleOptions.AlternatingColor)
overlayFont.DrawTextWithContrast(ReadyText,
icon.Pos + readyOffset,
ReadyTextAltColor, Color.Black, 1);
}
else if (first.Paused)
overlayFont.DrawTextWithContrast(HoldText,
icon.Pos + holdOffset,
Color.White, Color.Black, 1);
else if (!waiting)
overlayFont.DrawTextWithContrast(WidgetUtils.FormatTime(first.RemainingTimeActual),
icon.Pos + timeOffset,
Color.White, Color.Black, 1);
if (total > 1 || waiting)
overlayFont.DrawTextWithContrast(total.ToString(),
icon.Pos + queuedOffset,
Color.White, Color.Black, 1);
}
}
}
public override string GetCursor(int2 pos)
{
var icon = icons.Where(i => i.Key.Contains(pos))
.Select(i => i.Value).FirstOrDefault();
return icon != null ? base.GetCursor(pos) : null;
}
}
}