move widget code to commons

This commit is contained in:
Matthias Mailänder
2015-02-28 13:29:39 +01:00
parent cee3d6cf9e
commit ff6dbde8d7
38 changed files with 80 additions and 98 deletions

View File

@@ -99,50 +99,17 @@
<Compile Include="Traits\LeavesHusk.cs" />
<Compile Include="Traits\TargetableSubmarine.cs" />
<Compile Include="Traits\TransformOnPassenger.cs" />
<Compile Include="Widgets\Logic\MissionBrowserLogic.cs" />
<Compile Include="Widgets\Logic\Ingame\DiplomacyLogic.cs" />
<Compile Include="Widgets\Logic\Ingame\GameInfoLogic.cs" />
<Compile Include="Widgets\Logic\Ingame\GameInfoBriefingLogic.cs" />
<Compile Include="Widgets\Logic\Ingame\GameInfoObjectivesLogic.cs" />
<Compile Include="Widgets\Logic\Ingame\GameInfoStatsLogic.cs" />
<Compile Include="Widgets\Logic\IngameMenuLogic.cs" />
<Compile Include="Widgets\Logic\Ingame\LeaveMapLogic.cs" />
<Compile Include="Widgets\Logic\DownloadPackagesLogic.cs" />
<Compile Include="Widgets\Logic\MusicPlayerLogic.cs" />
<Compile Include="Widgets\Logic\ObserverStatsLogic.cs" />
<Compile Include="Widgets\Logic\OrderButtonsChromeLogic.cs" />
<Compile Include="Widgets\Logic\PerfDebugLogic.cs" />
<Compile Include="Widgets\ObserverProductionIconsWidget.cs" />
<Compile Include="Widgets\WorldCommandWidget.cs" />
<Compile Include="Traits\Render\RenderShroudCircle.cs" />
<Compile Include="Traits\Infiltration\InfiltrateForCash.cs" />
<Compile Include="Traits\Infiltration\InfiltrateForExploration.cs" />
<Compile Include="Traits\Infiltration\InfiltrateForPowerOutage.cs" />
<Compile Include="Traits\Infiltration\InfiltrateForSupportPower.cs" />
<Compile Include="Traits\Infiltration\Infiltrates.cs" />
<Compile Include="Widgets\Logic\ObserverShroudSelectorLogic.cs" />
<Compile Include="Widgets\Logic\SpawnSelectorTooltipLogic.cs" />
<Compile Include="Widgets\Logic\CreditsLogic.cs" />
<Compile Include="Widgets\Logic\SimpleTooltipLogic.cs" />
<Compile Include="Widgets\Logic\WorldTooltipLogic.cs" />
<Compile Include="Widgets\Logic\InstallLogic.cs" />
<Compile Include="CombatDebugOverlay.cs" />
<Compile Include="Widgets\Logic\GameTimerLogic.cs" />
<Compile Include="Widgets\Logic\ReplayControlBarLogic.cs" />
<Compile Include="Traits\Attack\AttackGarrisoned.cs" />
<Compile Include="Widgets\Logic\ControlGroupLogic.cs" />
<Compile Include="Scripting\Properties\ChronosphereProperties.cs" />
<Compile Include="Widgets\Logic\InstallFromCDLogic.cs" />
<Compile Include="Widgets\Logic\InstallMusicLogic.cs" />
<Compile Include="Traits\Buildings\ClonesProducedUnits.cs" />
<Compile Include="Traits\Cloneable.cs" />
<Compile Include="Widgets\Logic\Ingame\IngameCashCounterLogic.cs" />
<Compile Include="Widgets\Logic\Ingame\IngamePowerCounterLogic.cs" />
<Compile Include="Widgets\Logic\Ingame\IngamePowerBarLogic.cs" />
<Compile Include="Widgets\Logic\Ingame\IngameSiloBarLogic.cs" />
<Compile Include="Widgets\Logic\Ingame\AddRaceSuffixLogic.cs" />
<Compile Include="Widgets\Logic\ClassicProductionLogic.cs" />
<Compile Include="Widgets\Logic\DebugMenuLogic.cs" />
<Compile Include="Scripting\Properties\HarvesterProperties.cs" />
<Compile Include="Scripting\Properties\TransportProperties.cs" />
<Compile Include="Traits\InvulnerabilityUpgrade.cs" />

View File

@@ -1,196 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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.Linq;
using OpenRA.Mods.Common.Traits;
using OpenRA.Mods.Common.Widgets;
using OpenRA.Mods.RA.Widgets;
using OpenRA.Network;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class ClassicProductionLogic
{
readonly ProductionPaletteWidget palette;
readonly World world;
void SetupProductionGroupButton(OrderManager orderManager, ProductionTypeButtonWidget button)
{
if (button == null)
return;
// Classic production queues are initialized at game start, and then never change.
var queues = world.LocalPlayer.PlayerActor.TraitsImplementing<ProductionQueue>()
.Where(q => q.Info.Type == button.ProductionGroup)
.ToArray();
Action<bool> selectTab = reverse =>
{
palette.CurrentQueue = queues.FirstOrDefault(q => q.Enabled);
// When a tab is selected, scroll to the top because the current row position may be invalid for the new tab
palette.ScrollToTop();
};
Func<ButtonWidget, Hotkey> getKey = _ => Hotkey.Invalid;
if (!string.IsNullOrEmpty(button.HotkeyName))
{
var ks = Game.Settings.Keys;
var field = ks.GetType().GetField(button.HotkeyName);
if (field != null)
getKey = _ => (Hotkey)field.GetValue(ks);
}
button.IsDisabled = () => !queues.Any(q => q.BuildableItems().Any());
button.OnMouseUp = mi => selectTab(mi.Modifiers.HasModifier(Modifiers.Shift));
button.OnKeyPress = e => selectTab(e.Modifiers.HasModifier(Modifiers.Shift));
button.OnClick = () => selectTab(false);
button.IsHighlighted = () => queues.Contains(palette.CurrentQueue);
button.GetKey = getKey;
var chromeName = button.ProductionGroup.ToLowerInvariant();
var icon = button.Get<ImageWidget>("ICON");
icon.GetImageName = () => button.IsDisabled() ? chromeName + "-disabled" :
queues.Any(q => q.CurrentDone) ? chromeName + "-alert" : chromeName;
}
[ObjectCreator.UseCtor]
public ClassicProductionLogic(Widget widget, OrderManager orderManager, World world)
{
this.world = world;
palette = widget.Get<ProductionPaletteWidget>("PRODUCTION_PALETTE");
var background = widget.GetOrNull("PALETTE_BACKGROUND");
var foreground = widget.GetOrNull("PALETTE_FOREGROUND");
if (background != null || foreground != null)
{
Widget backgroundTemplate = null;
Widget backgroundBottom = null;
Widget foregroundTemplate = null;
if (background != null)
{
backgroundTemplate = background.Get("ROW_TEMPLATE");
backgroundBottom = background.GetOrNull("BOTTOM_CAP");
}
if (foreground != null)
foregroundTemplate = foreground.Get("ROW_TEMPLATE");
Action<int, int> updateBackground = (_, icons) =>
{
var rows = Math.Max(palette.MinimumRows, (icons + palette.Columns - 1) / palette.Columns);
rows = Math.Min(rows, palette.MaximumRows);
if (background != null)
{
background.RemoveChildren();
var rowHeight = backgroundTemplate.Bounds.Height;
for (var i = 0; i < rows; i++)
{
var row = backgroundTemplate.Clone();
row.Bounds.Y = i * rowHeight;
background.AddChild(row);
}
if (backgroundBottom == null)
return;
backgroundBottom.Bounds.Y = rows * rowHeight;
background.AddChild(backgroundBottom);
}
if (foreground != null)
{
foreground.RemoveChildren();
var rowHeight = foregroundTemplate.Bounds.Height;
for (var i = 0; i < rows; i++)
{
var row = foregroundTemplate.Clone();
row.Bounds.Y = i * rowHeight;
foreground.AddChild(row);
}
}
};
palette.OnIconCountChanged += updateBackground;
// Set the initial palette state
updateBackground(0, 0);
}
var typesContainer = widget.Get("PRODUCTION_TYPES");
foreach (var i in typesContainer.Children)
SetupProductionGroupButton(orderManager, i as ProductionTypeButtonWidget);
var ticker = widget.Get<LogicTickerWidget>("PRODUCTION_TICKER");
ticker.OnTick = () =>
{
if (palette.CurrentQueue == null || palette.DisplayedIconCount == 0)
{
// Select the first active tab
foreach (var b in typesContainer.Children)
{
var button = b as ProductionTypeButtonWidget;
if (button == null || button.IsDisabled())
continue;
button.OnClick();
break;
}
}
};
// Hook up scroll up and down buttons on the palette
var scrollDown = widget.GetOrNull<ButtonWidget>("SCROLL_DOWN_BUTTON");
if (scrollDown != null)
{
scrollDown.OnClick = palette.ScrollDown;
scrollDown.IsVisible = () => palette.TotalIconCount > (palette.MaxIconRowOffset * palette.Columns);
scrollDown.IsDisabled = () => !palette.CanScrollDown;
}
var scrollUp = widget.GetOrNull<ButtonWidget>("SCROLL_UP_BUTTON");
if (scrollUp != null)
{
scrollUp.OnClick = palette.ScrollUp;
scrollUp.IsVisible = () => palette.TotalIconCount > (palette.MaxIconRowOffset * palette.Columns);
scrollUp.IsDisabled = () => !palette.CanScrollUp;
}
SetMaximumVisibleRows(palette);
}
static void SetMaximumVisibleRows(ProductionPaletteWidget productionPalette)
{
var screenHeight = Game.Renderer.Resolution.Height;
// Get height of currently displayed icons
var containerWidget = Ui.Root.GetOrNull<ContainerWidget>("SIDEBAR_PRODUCTION");
if (containerWidget == null)
return;
var sidebarProductionHeight = containerWidget.Bounds.Y;
// Check if icon heights exceed y resolution
var maxItemsHeight = screenHeight - sidebarProductionHeight;
var maxIconRowOffest = (maxItemsHeight / productionPalette.IconSize.Y) - 1;
productionPalette.MaxIconRowOffset = Math.Min(maxIconRowOffest, productionPalette.MaximumRows);
}
}
}

View File

@@ -1,36 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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 OpenRA.Graphics;
using OpenRA.Mods.Common.Widgets;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class ControlGroupLogic
{
[ObjectCreator.UseCtor]
public ControlGroupLogic(Widget widget, World world, WorldRenderer worldRenderer)
{
var keyhandler = widget.Get<LogicKeyListenerWidget>("CONTROLGROUP_KEYHANDLER");
keyhandler.OnKeyPress = e =>
{
if (e.Key >= Keycode.NUMBER_0 && e.Key <= Keycode.NUMBER_9)
{
var group = (int)e.Key - (int)Keycode.NUMBER_0;
world.Selection.DoControlGroup(world, worldRenderer, group, e.Modifiers, e.MultiTapCount);
return true;
}
return false;
};
}
}
}

View File

@@ -1,46 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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 OpenRA.FileSystem;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class CreditsLogic
{
[ObjectCreator.UseCtor]
public CreditsLogic(Widget widget, Action onExit)
{
var panel = widget.Get("CREDITS_PANEL");
panel.Get<ButtonWidget>("BACK_BUTTON").OnClick = () =>
{
Ui.CloseWindow();
onExit();
};
var scrollPanel = panel.Get<ScrollPanelWidget>("CREDITS_DISPLAY");
var template = scrollPanel.Get<LabelWidget>("CREDITS_TEMPLATE");
scrollPanel.RemoveChildren();
var lines = GlobalFileSystem.Open("AUTHORS").ReadAllLines();
foreach (var l in lines)
{
// Improve the formatting
var line = l.Replace("\t", " ").Replace("*", "\u2022");
var label = template.Clone() as LabelWidget;
label.GetText = () => line;
scrollPanel.AddChild(label);
}
}
}
}

View File

@@ -1,131 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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 OpenRA.Mods.Common.Traits;
using OpenRA.Mods.RA.Traits;
using OpenRA.Support;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class DebugMenuLogic
{
[ObjectCreator.UseCtor]
public DebugMenuLogic(Widget widget, World world)
{
var devTrait = world.LocalPlayer.PlayerActor.Trait<DeveloperMode>();
var shroudCheckbox = widget.GetOrNull<CheckboxWidget>("DISABLE_SHROUD");
if (shroudCheckbox != null)
{
shroudCheckbox.IsChecked = () => devTrait.DisableShroud;
shroudCheckbox.OnClick = () => Order(world, "DevShroudDisable");
}
var pathCheckbox = widget.GetOrNull<CheckboxWidget>("SHOW_UNIT_PATHS");
if (pathCheckbox != null)
{
pathCheckbox.IsChecked = () => devTrait.PathDebug;
pathCheckbox.OnClick = () => Order(world, "DevPathDebug");
}
var cashButton = widget.GetOrNull<ButtonWidget>("GIVE_CASH");
if (cashButton != null)
cashButton.OnClick = () =>
world.IssueOrder(new Order("DevGiveCash", world.LocalPlayer.PlayerActor, false));
var growResourcesButton = widget.GetOrNull<ButtonWidget>("GROW_RESOURCES");
if (growResourcesButton != null)
growResourcesButton.OnClick = () =>
world.IssueOrder(new Order("DevGrowResources", world.LocalPlayer.PlayerActor, false));
var fastBuildCheckbox = widget.GetOrNull<CheckboxWidget>("INSTANT_BUILD");
if (fastBuildCheckbox != null)
{
fastBuildCheckbox.IsChecked = () => devTrait.FastBuild;
fastBuildCheckbox.OnClick = () => Order(world, "DevFastBuild");
}
var fastChargeCheckbox = widget.GetOrNull<CheckboxWidget>("INSTANT_CHARGE");
if (fastChargeCheckbox != null)
{
fastChargeCheckbox.IsChecked = () => devTrait.FastCharge;
fastChargeCheckbox.OnClick = () => Order(world, "DevFastCharge");
}
var showCombatCheckbox = widget.GetOrNull<CheckboxWidget>("SHOW_COMBATOVERLAY");
if (showCombatCheckbox != null)
{
showCombatCheckbox.IsChecked = () => devTrait.ShowCombatGeometry;
showCombatCheckbox.OnClick = () => devTrait.ShowCombatGeometry ^= true;
}
var showGeometryCheckbox = widget.GetOrNull<CheckboxWidget>("SHOW_GEOMETRY");
if (showGeometryCheckbox != null)
{
showGeometryCheckbox.IsChecked = () => devTrait.ShowDebugGeometry;
showGeometryCheckbox.OnClick = () => devTrait.ShowDebugGeometry ^= true;
}
var showTerrainGeometryCheckbox = widget.GetOrNull<CheckboxWidget>("SHOW_TERRAIN_OVERLAY");
if (showTerrainGeometryCheckbox != null)
{
showTerrainGeometryCheckbox.IsChecked = () => devTrait.ShowTerrainGeometry;
showTerrainGeometryCheckbox.OnClick = () => devTrait.ShowTerrainGeometry ^= true;
}
var allTechCheckbox = widget.GetOrNull<CheckboxWidget>("ENABLE_TECH");
if (allTechCheckbox != null)
{
allTechCheckbox.IsChecked = () => devTrait.AllTech;
allTechCheckbox.OnClick = () => Order(world, "DevEnableTech");
}
var powerCheckbox = widget.GetOrNull<CheckboxWidget>("UNLIMITED_POWER");
if (powerCheckbox != null)
{
powerCheckbox.IsChecked = () => devTrait.UnlimitedPower;
powerCheckbox.OnClick = () => Order(world, "DevUnlimitedPower");
}
var buildAnywhereCheckbox = widget.GetOrNull<CheckboxWidget>("BUILD_ANYWHERE");
if (buildAnywhereCheckbox != null)
{
buildAnywhereCheckbox.IsChecked = () => devTrait.BuildAnywhere;
buildAnywhereCheckbox.OnClick = () => Order(world, "DevBuildAnywhere");
}
var explorationButton = widget.GetOrNull<ButtonWidget>("GIVE_EXPLORATION");
if (explorationButton != null)
explorationButton.OnClick = () =>
world.IssueOrder(new Order("DevGiveExploration", world.LocalPlayer.PlayerActor, false));
var noexplorationButton = widget.GetOrNull<ButtonWidget>("RESET_EXPLORATION");
if (noexplorationButton != null)
noexplorationButton.OnClick = () =>
world.IssueOrder(new Order("DevResetExploration", world.LocalPlayer.PlayerActor, false));
var dbgOverlay = world.WorldActor.TraitOrDefault<PathfinderDebugOverlay>();
var showAstarCostCheckbox = widget.GetOrNull<CheckboxWidget>("SHOW_ASTAR");
if (showAstarCostCheckbox != null)
{
showAstarCostCheckbox.IsChecked = () => dbgOverlay != null ? dbgOverlay.Visible : false;
showAstarCostCheckbox.OnClick = () => { if (dbgOverlay != null) dbgOverlay.Visible ^= true; };
}
}
public void Order(World world, string order)
{
world.IssueOrder(new Order(order, world.LocalPlayer.PlayerActor, false));
}
}
}

View File

@@ -1,160 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using OpenRA.Support;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class DownloadPackagesLogic
{
readonly Widget panel;
readonly string mirrorListUrl;
readonly ProgressBarWidget progressBar;
readonly LabelWidget statusLabel;
readonly Action afterInstall;
string mirror;
static readonly string[] SizeSuffixes = { "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
[ObjectCreator.UseCtor]
public DownloadPackagesLogic(Widget widget, Action afterInstall, string mirrorListUrl)
{
this.mirrorListUrl = mirrorListUrl;
this.afterInstall = afterInstall;
panel = widget.Get("INSTALL_DOWNLOAD_PANEL");
progressBar = panel.Get<ProgressBarWidget>("PROGRESS_BAR");
statusLabel = panel.Get<LabelWidget>("STATUS_LABEL");
ShowDownloadDialog();
}
void ShowDownloadDialog()
{
statusLabel.GetText = () => "Fetching list of mirrors...";
progressBar.Indeterminate = true;
var retryButton = panel.Get<ButtonWidget>("RETRY_BUTTON");
retryButton.IsVisible = () => false;
var cancelButton = panel.Get<ButtonWidget>("CANCEL_BUTTON");
var mirrorsFile = Platform.ResolvePath("^", "Content", Game.ModData.Manifest.Mod.Id, "mirrors.txt");
var file = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
var dest = Platform.ResolvePath("^", "Content", Game.ModData.Manifest.Mod.Id);
Action<DownloadProgressChangedEventArgs> onDownloadProgress = i =>
{
var dataReceived = 0.0f;
var dataTotal = 0.0f;
var mag = 0;
var dataSuffix = "";
if (i.TotalBytesToReceive < 0)
{
dataTotal = float.NaN;
dataReceived = i.BytesReceived;
dataSuffix = SizeSuffixes[0];
}
else
{
mag = (int)Math.Log(i.TotalBytesToReceive, 1024);
dataTotal = i.TotalBytesToReceive / (float)(1L << (mag * 10));
dataReceived = i.BytesReceived / (float)(1L << (mag * 10));
dataSuffix = SizeSuffixes[mag];
}
progressBar.Indeterminate = false;
progressBar.Percentage = i.ProgressPercentage;
statusLabel.GetText = () => "Downloading from {4} {1:0.00}/{2:0.00} {3} ({0}%)".F(i.ProgressPercentage,
dataReceived, dataTotal, dataSuffix,
mirror != null ? new Uri(mirror).Host : "unknown host");
};
Action<string> onExtractProgress = s => Game.RunAfterTick(() => statusLabel.GetText = () => s);
Action<string> onError = s => Game.RunAfterTick(() =>
{
statusLabel.GetText = () => "Error: " + s;
retryButton.IsVisible = () => true;
});
Action<AsyncCompletedEventArgs, bool> onDownloadComplete = (i, cancelled) =>
{
if (i.Error != null)
{
onError(Download.FormatErrorMessage(i.Error));
return;
}
else if (cancelled)
{
onError("Download cancelled");
return;
}
// Automatically extract
statusLabel.GetText = () => "Extracting...";
progressBar.Indeterminate = true;
if (InstallUtils.ExtractZip(file, dest, onExtractProgress, onError))
{
Game.RunAfterTick(() =>
{
Ui.CloseWindow();
afterInstall();
});
}
};
Action<AsyncCompletedEventArgs, bool> onFetchMirrorsComplete = (i, cancelled) =>
{
progressBar.Indeterminate = true;
if (i.Error != null)
{
onError(Download.FormatErrorMessage(i.Error));
return;
}
else if (cancelled)
{
onError("Download cancelled");
return;
}
var mirrorList = new List<string>();
using (var r = new StreamReader(mirrorsFile))
{
string line;
while ((line = r.ReadLine()) != null)
if (!string.IsNullOrEmpty(line))
mirrorList.Add(line);
}
mirror = mirrorList.Random(new MersenneTwister());
// Save the package to a temp file
var dl = new Download(mirror, file, onDownloadProgress, onDownloadComplete);
cancelButton.OnClick = () => { dl.Cancel(); Ui.CloseWindow(); };
retryButton.OnClick = () => { dl.Cancel(); ShowDownloadDialog(); };
};
// Get the list of mirrors
var updateMirrors = new Download(mirrorListUrl, mirrorsFile, onDownloadProgress, onFetchMirrorsComplete);
cancelButton.OnClick = () => { updateMirrors.Cancel(); Ui.CloseWindow(); };
retryButton.OnClick = () => { updateMirrors.Cancel(); ShowDownloadDialog(); };
}
}
}

View File

@@ -1,69 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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 OpenRA.Network;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class GameTimerLogic
{
[ObjectCreator.UseCtor]
public GameTimerLogic(Widget widget, OrderManager orderManager, World world)
{
var timer = widget.GetOrNull<LabelWidget>("GAME_TIMER");
var status = widget.GetOrNull<LabelWidget>("GAME_TIMER_STATUS");
var startTick = Ui.LastTickTime;
Func<bool> shouldShowStatus = () => (world.Paused || world.Timestep != Game.Timestep)
&& (Ui.LastTickTime - startTick) / 1000 % 2 == 0;
Func<string> statusText = () =>
{
if (world.Paused || world.Timestep == 0)
return "Paused";
if (world.Timestep == 1)
return "Max Speed";
return "{0}% Speed".F(Game.Timestep * 100 / world.Timestep);
};
if (timer != null)
{
timer.GetText = () =>
{
if (status == null && shouldShowStatus())
return statusText();
return WidgetUtils.FormatTime(world.WorldTick);
};
}
if (status != null)
{
// Blink the status line
status.IsVisible = shouldShowStatus;
status.GetText = statusText;
}
var percentage = widget.GetOrNull<LabelWidget>("GAME_TIMER_PERCENTAGE");
if (percentage != null)
{
var connection = orderManager.Connection as ReplayConnection;
if (connection != null && connection.TickCount != 0)
percentage.GetText = () => "({0}%)".F(orderManager.NetFrameNumber * 100 / connection.TickCount);
else
timer.Bounds.Width += percentage.Bounds.Width;
}
}
}
}

View File

@@ -1,34 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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 OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class AddRaceSuffixLogic
{
[ObjectCreator.UseCtor]
public AddRaceSuffixLogic(Widget widget, World world)
{
string race;
if (!ChromeMetrics.TryGet("RaceSuffix-" + world.LocalPlayer.Country.Race, out race))
race = world.LocalPlayer.Country.Race;
var suffix = "-" + race;
if (widget is ButtonWidget)
((ButtonWidget)widget).Background += suffix;
else if (widget is ImageWidget)
((ImageWidget)widget).ImageCollection += suffix;
else
throw new InvalidOperationException("AddRaceSuffixLogic only supports ButtonWidget and ImageWidget");
}
}
}

View File

@@ -1,109 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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.Linq;
using OpenRA.Mods.Common.Widgets.Logic;
using OpenRA.Network;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class DiplomacyLogic
{
readonly World world;
ScrollPanelWidget diplomacyPanel;
[ObjectCreator.UseCtor]
public DiplomacyLogic(Widget widget, Action onExit, World world)
{
this.world = world;
diplomacyPanel = widget.Get<ScrollPanelWidget>("DIPLOMACY_PANEL");
LayoutPlayers();
var close = widget.GetOrNull<ButtonWidget>("CLOSE");
if (close != null)
close.OnClick = () =>
{
Ui.CloseWindow();
Ui.Root.RemoveChild(widget);
onExit();
};
}
void LayoutPlayers()
{
var teamTemplate = diplomacyPanel.Get<ScrollItemWidget>("TEAM_TEMPLATE");
var players = world.Players.Where(p => p != world.LocalPlayer && !p.NonCombatant);
var teams = players.GroupBy(p => (world.LobbyInfo.ClientWithIndex(p.ClientIndex) ?? new Session.Client()).Team).OrderBy(g => g.Key);
foreach (var t in teams)
{
var team = t;
var tt = ScrollItemWidget.Setup(teamTemplate, () => false, () => { });
tt.IgnoreMouseOver = true;
tt.Get<LabelWidget>("TEAM").GetText = () => team.Key == 0 ? "No Team" : "Team " + team.Key;
diplomacyPanel.AddChild(tt);
foreach (var p in team)
{
var player = p;
diplomacyPanel.AddChild(DiplomaticStatus(player));
}
}
}
ScrollItemWidget DiplomaticStatus(Player player)
{
var playerTemplate = diplomacyPanel.Get<ScrollItemWidget>("PLAYER_TEMPLATE");
var pt = ScrollItemWidget.Setup(playerTemplate, () => false, () => { });
pt.IgnoreMouseOver = true;
LobbyUtils.AddPlayerFlagAndName(pt, player);
pt.Get<LabelWidget>("THEIR_STANCE").GetText = () => player.Stances[world.LocalPlayer].ToString();
var myStance = pt.Get<DropDownButtonWidget>("MY_STANCE");
myStance.GetText = () => world.LocalPlayer.Stances[player].ToString();
myStance.IsDisabled = () => !world.LobbyInfo.GlobalSettings.FragileAlliances;
myStance.OnMouseDown = mi => ShowDropDown(player, myStance);
return pt;
}
void ShowDropDown(Player p, DropDownButtonWidget dropdown)
{
var stances = Enum<Stance>.GetValues();
Func<Stance, ScrollItemWidget, ScrollItemWidget> setupItem = (s, template) =>
{
var item = ScrollItemWidget.Setup(template,
() => s == world.LocalPlayer.Stances[p],
() => SetStance(dropdown, p, s));
item.Get<LabelWidget>("LABEL").GetText = () => s.ToString();
return item;
};
dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 150, stances, setupItem);
}
void SetStance(ButtonWidget bw, Player p, Stance ss)
{
if (!p.World.LobbyInfo.GlobalSettings.FragileAlliances)
return; // stance changes are banned
world.IssueOrder(new Order("SetStance", world.LocalPlayer.PlayerActor, false)
{
ExtraData = (uint)ss,
TargetString = p.InternalName,
});
bw.Text = ss.ToString();
}
}
}

View File

@@ -1,38 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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.Linq;
using OpenRA.Mods.RA;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
class GameInfoBriefingLogic
{
[ObjectCreator.UseCtor]
public GameInfoBriefingLogic(Widget widget, World world)
{
var previewWidget = widget.Get<MapPreviewWidget>("MAP_PREVIEW");
previewWidget.Preview = () => Game.ModData.MapCache[world.Map.Uid];
var mapDescriptionPanel = widget.Get<ScrollPanelWidget>("MAP_DESCRIPTION_PANEL");
var mapDescription = widget.Get<LabelWidget>("MAP_DESCRIPTION");
var mapFont = Game.Renderer.Fonts[mapDescription.Font];
var text = world.Map.Description != null ? world.Map.Description.Replace("\\n", "\n") : "";
text = WidgetUtils.WrapText(text, mapDescription.Bounds.Width, mapFont);
mapDescription.Text = text;
mapDescription.Bounds.Height = mapFont.Measure(text).Y;
mapDescriptionPanel.ScrollToTop();
mapDescriptionPanel.Layout.AdjustChildren();
}
}
}

View File

@@ -1,109 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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.Linq;
using OpenRA.Mods.RA;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public enum IngameInfoPanel { AutoSelect, Map, Objectives, Debug }
class GameInfoLogic
{
[ObjectCreator.UseCtor]
public GameInfoLogic(Widget widget, World world, IngameInfoPanel activePanel)
{
var lp = world.LocalPlayer;
var numTabs = 0;
widget.IsVisible = () => activePanel != IngameInfoPanel.AutoSelect;
// Objectives/Stats tab
var iop = world.WorldActor.TraitsImplementing<IObjectivesPanel>().FirstOrDefault();
if (lp != null && iop != null && iop.PanelName != null)
{
numTabs++;
var objectivesTabButton = widget.Get<ButtonWidget>(string.Concat("BUTTON", numTabs.ToString()));
objectivesTabButton.GetText = () => "Objectives";
objectivesTabButton.IsVisible = () => lp != null && numTabs > 1;
objectivesTabButton.OnClick = () => activePanel = IngameInfoPanel.Objectives;
objectivesTabButton.IsHighlighted = () => activePanel == IngameInfoPanel.Objectives;
var objectivesPanel = widget.Get<ContainerWidget>("OBJECTIVES_PANEL");
objectivesPanel.IsVisible = () => activePanel == IngameInfoPanel.Objectives;
Game.LoadWidget(world, iop.PanelName, objectivesPanel, new WidgetArgs());
if (activePanel == IngameInfoPanel.AutoSelect)
activePanel = IngameInfoPanel.Objectives;
}
// Briefing tab
if (world.Map.CustomPreview != null)
{
numTabs++;
var mapTabButton = widget.Get<ButtonWidget>(string.Concat("BUTTON", numTabs.ToString()));
mapTabButton.Text = "Briefing";
mapTabButton.IsVisible = () => numTabs > 1;
mapTabButton.OnClick = () => activePanel = IngameInfoPanel.Map;
mapTabButton.IsHighlighted = () => activePanel == IngameInfoPanel.Map;
var mapPanel = widget.Get<ContainerWidget>("MAP_PANEL");
mapPanel.IsVisible = () => activePanel == IngameInfoPanel.Map;
Game.LoadWidget(world, "MAP_PANEL", mapPanel, new WidgetArgs());
if (activePanel == IngameInfoPanel.AutoSelect)
activePanel = IngameInfoPanel.Map;
}
// Debug/Cheats tab
if (lp != null && world.LobbyInfo.GlobalSettings.AllowCheats)
{
numTabs++;
var debugTabButton = widget.Get<ButtonWidget>(string.Concat("BUTTON", numTabs.ToString()));
debugTabButton.Text = "Debug";
debugTabButton.IsVisible = () => lp != null && world.LobbyInfo.GlobalSettings.AllowCheats && numTabs > 1;
debugTabButton.OnClick = () => activePanel = IngameInfoPanel.Debug;
debugTabButton.IsHighlighted = () => activePanel == IngameInfoPanel.Debug;
var debugPanelContainer = widget.Get<ContainerWidget>("DEBUG_PANEL");
debugPanelContainer.IsVisible = () => activePanel == IngameInfoPanel.Debug;
Game.LoadWidget(world, "DEBUG_PANEL", debugPanelContainer, new WidgetArgs());
if (activePanel == IngameInfoPanel.AutoSelect)
activePanel = IngameInfoPanel.Debug;
}
// Handle empty space when tabs aren't displayed
var titleText = widget.Get<LabelWidget>("TITLE");
var titleTextNoTabs = widget.GetOrNull<LabelWidget>("TITLE_NO_TABS");
titleText.IsVisible = () => numTabs > 1 || (numTabs == 1 && titleTextNoTabs == null);
titleText.GetText = () => string.Concat(world.Map.Type, ": ", world.Map.Title);
if (titleTextNoTabs != null)
{
titleTextNoTabs.IsVisible = () => numTabs == 1;
titleTextNoTabs.GetText = () => string.Concat(world.Map.Type, ": ", world.Map.Title);
}
var bg = widget.Get<BackgroundWidget>("BACKGROUND");
var bgNoTabs = widget.GetOrNull<BackgroundWidget>("BACKGROUND_NO_TABS");
bg.IsVisible = () => numTabs > 1 || (numTabs == 1 && bgNoTabs == null);
if (bgNoTabs != null)
bgNoTabs.IsVisible = () => numTabs == 1;
}
}
}

View File

@@ -1,73 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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.Drawing;
using System.Linq;
using OpenRA.Mods.Common.Traits;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
class GameInfoObjectivesLogic
{
ContainerWidget template;
[ObjectCreator.UseCtor]
public GameInfoObjectivesLogic(Widget widget, World world)
{
var lp = world.LocalPlayer;
var missionStatus = widget.Get<LabelWidget>("MISSION_STATUS");
missionStatus.GetText = () => lp.WinState == WinState.Undefined ? "In progress" :
lp.WinState == WinState.Won ? "Accomplished" : "Failed";
missionStatus.GetColor = () => lp.WinState == WinState.Undefined ? Color.White :
lp.WinState == WinState.Won ? Color.LimeGreen : Color.Red;
var mo = lp.PlayerActor.TraitOrDefault<MissionObjectives>();
if (mo == null)
return;
var objectivesPanel = widget.Get<ScrollPanelWidget>("OBJECTIVES_PANEL");
template = objectivesPanel.Get<ContainerWidget>("OBJECTIVE_TEMPLATE");
PopulateObjectivesList(mo, objectivesPanel, template);
Action<Player> redrawObjectives = player =>
{
if (player == lp)
PopulateObjectivesList(mo, objectivesPanel, template);
};
mo.ObjectiveAdded += redrawObjectives;
}
void PopulateObjectivesList(MissionObjectives mo, ScrollPanelWidget parent, ContainerWidget template)
{
parent.RemoveChildren();
foreach (var o in mo.Objectives.OrderBy(o => o.Type))
{
var objective = o; // Work around the loop closure issue in older versions of C#
var widget = template.Clone();
var label = widget.Get<LabelWidget>("OBJECTIVE_TYPE");
label.GetText = () => objective.Type == ObjectiveType.Primary ? "Primary" : "Secondary";
var checkbox = widget.Get<CheckboxWidget>("OBJECTIVE_STATUS");
checkbox.IsChecked = () => objective.State != ObjectiveState.Incomplete;
checkbox.GetCheckType = () => objective.State == ObjectiveState.Completed ? "checked" : "crossed";
checkbox.GetText = () => objective.Description;
parent.AddChild(widget);
}
}
}
}

View File

@@ -1,75 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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.Mods.Common.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
class GameInfoStatsLogic
{
[ObjectCreator.UseCtor]
public GameInfoStatsLogic(Widget widget, World world)
{
var lp = world.LocalPlayer;
var checkbox = widget.Get<CheckboxWidget>("STATS_CHECKBOX");
checkbox.IsChecked = () => lp.WinState != WinState.Undefined;
checkbox.GetCheckType = () => lp.WinState == WinState.Won ?
"checked" : "crossed";
var statusLabel = widget.Get<LabelWidget>("STATS_STATUS");
statusLabel.GetText = () => lp.WinState == WinState.Won ? "Accomplished" :
lp.WinState == WinState.Lost ? "Failed" : "In progress";
statusLabel.GetColor = () => lp.WinState == WinState.Won ? Color.LimeGreen :
lp.WinState == WinState.Lost ? Color.Red : Color.White;
var playerPanel = widget.Get<ScrollPanelWidget>("PLAYER_LIST");
var playerTemplate = playerPanel.Get("PLAYER_TEMPLATE");
playerPanel.RemoveChildren();
foreach (var p in world.Players.Where(a => !a.NonCombatant))
{
var pp = p;
var client = world.LobbyInfo.ClientWithIndex(pp.ClientIndex);
var item = playerTemplate.Clone();
var nameLabel = item.Get<LabelWidget>("NAME");
nameLabel.GetText = () =>
{
if (client != null && client.State == Network.Session.ClientState.Disconnected)
return pp.PlayerName + " (Gone)";
return pp.PlayerName + (pp.WinState == WinState.Undefined ? "" : " (" + pp.WinState + ")");
};
nameLabel.GetColor = () => pp.Color.RGB;
var flag = item.Get<ImageWidget>("FACTIONFLAG");
flag.GetImageName = () => pp.Country.Race;
flag.GetImageCollection = () => "flags";
item.Get<LabelWidget>("FACTION").GetText = () => pp.Country.Name;
var team = item.Get<LabelWidget>("TEAM");
var teamNumber = (client == null) ? 0 : client.Team;
team.GetText = () => (teamNumber == 0) ? "-" : teamNumber.ToString();
playerPanel.AddChild(item);
var stats = pp.PlayerActor.TraitOrDefault<PlayerStatistics>();
if (stats == null)
break;
var totalKills = stats.UnitsKilled + stats.BuildingsKilled;
var totalDeaths = stats.UnitsDead + stats.BuildingsDead;
item.Get<LabelWidget>("KILLS").GetText = () => totalKills.ToString();
item.Get<LabelWidget>("DEATHS").GetText = () => totalDeaths.ToString();
}
}
}
}

View File

@@ -1,30 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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 OpenRA.Mods.Common.Widgets;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class IngameCashCounterLogic
{
[ObjectCreator.UseCtor]
public IngameCashCounterLogic(Widget widget, World world)
{
var playerResources = world.LocalPlayer.PlayerActor.Trait<PlayerResources>();
var cash = widget.Get<LabelWithTooltipWidget>("CASH");
var label = cash.Text;
cash.GetText = () => label.F(playerResources.DisplayCash + playerResources.DisplayResources);
cash.GetTooltipText = () => "Silo Usage: {0}/{1}".F(playerResources.Resources, playerResources.ResourceCapacity);
}
}
}

View File

@@ -1,39 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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 OpenRA.Mods.Common.Traits;
using OpenRA.Mods.Common.Widgets;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class IngamePowerBarLogic
{
[ObjectCreator.UseCtor]
public IngamePowerBarLogic(Widget widget, World world)
{
var powerManager = world.LocalPlayer.PlayerActor.Trait<PowerManager>();
var powerBar = widget.Get<ResourceBarWidget>("POWERBAR");
powerBar.GetProvided = () => powerManager.PowerProvided;
powerBar.GetUsed = () => powerManager.PowerDrained;
powerBar.TooltipFormat = "Power Usage: {0}/{1}";
powerBar.GetBarColor = () =>
{
if (powerManager.PowerState == PowerState.Critical)
return Color.Red;
if (powerManager.PowerState == PowerState.Low)
return Color.Orange;
return Color.LimeGreen;
};
}
}
}

View File

@@ -1,33 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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 OpenRA.Mods.Common.Traits;
using OpenRA.Mods.Common.Widgets;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class IngamePowerCounterLogic
{
[ObjectCreator.UseCtor]
public IngamePowerCounterLogic(Widget widget, World world)
{
var powerManager = world.LocalPlayer.PlayerActor.Trait<PowerManager>();
var power = widget.Get<LabelWithTooltipWidget>("POWER");
var powerIcon = widget.Get<ImageWidget>("POWER_ICON");
powerIcon.GetImageName = () => powerManager.ExcessPower < 0 ? "power-critical" : "power-normal";
power.GetColor = () => powerManager.ExcessPower < 0 ? Color.Red : Color.White;
power.GetText = () => powerManager.PowerProvided == 1000000 ? "inf" : powerManager.ExcessPower.ToString();
power.GetTooltipText = () => "Power Usage: " + powerManager.PowerDrained.ToString() + (powerManager.PowerProvided != 1000000 ? "/" + powerManager.PowerProvided.ToString() : "");
}
}
}

View File

@@ -1,41 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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 OpenRA.Mods.Common.Widgets;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class IngameSiloBarLogic
{
[ObjectCreator.UseCtor]
public IngameSiloBarLogic(Widget widget, World world)
{
var playerResources = world.LocalPlayer.PlayerActor.Trait<PlayerResources>();
var siloBar = widget.Get<ResourceBarWidget>("SILOBAR");
siloBar.GetProvided = () => playerResources.ResourceCapacity;
siloBar.GetUsed = () => playerResources.Resources;
siloBar.TooltipFormat = "Silo Usage: {0}/{1}";
siloBar.GetBarColor = () =>
{
if (playerResources.Resources == playerResources.ResourceCapacity)
return Color.Red;
if (playerResources.Resources >= 0.8 * playerResources.ResourceCapacity)
return Color.Orange;
return Color.LimeGreen;
};
}
}
}

View File

@@ -1,156 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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.Drawing;
using System.Linq;
using OpenRA.Mods.Common.Scripting;
using OpenRA.Mods.Common.Traits;
using OpenRA.Network;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets
{
class LeaveMapLogic
{
enum Tab { Objectives, Chat }
Tab currentTab;
OrderManager orderManager;
bool newChatMessage;
[ObjectCreator.UseCtor]
public LeaveMapLogic(Widget widget, World world, OrderManager orderManager)
{
this.orderManager = orderManager;
var mpe = world.WorldActor.TraitOrDefault<MenuPaletteEffect>();
if (mpe != null)
mpe.Fade(mpe.Info.MenuEffect);
widget.Get<LabelWidget>("VERSION_LABEL").Text = Game.ModData.Manifest.Mod.Version;
var showStats = false;
var scriptContext = world.WorldActor.TraitOrDefault<LuaScript>();
var iop = world.WorldActor.TraitsImplementing<IObjectivesPanel>().FirstOrDefault();
var isMultiplayer = !world.LobbyInfo.IsSinglePlayer && !world.IsReplay;
var hasError = scriptContext != null && scriptContext.FatalErrorOccurred;
var hasObjectives = hasError || (iop != null && iop.PanelName != null && world.LocalPlayer != null);
var showTabs = hasObjectives && isMultiplayer;
currentTab = hasObjectives ? Tab.Objectives : Tab.Chat;
var panelName = hasObjectives || isMultiplayer ? "LEAVE_MAP_FULL" : "LEAVE_MAP_SIMPLE";
var dialog = widget.Get<ContainerWidget>(panelName);
dialog.IsVisible = () => !showStats;
widget.IsVisible = () => Ui.CurrentWindow() == null;
if (hasObjectives || isMultiplayer)
{
var titleText = dialog.Get<LabelWidget>("GAME_ENDED_LABEL");
var titleTextNoTabs = dialog.GetOrNull<LabelWidget>("GAME_ENDED_LABEL_NO_TABS");
titleText.IsVisible = () => showTabs || (!showTabs && titleTextNoTabs == null);
if (titleTextNoTabs != null)
titleTextNoTabs.IsVisible = () => !showTabs;
var bg = dialog.Get<BackgroundWidget>("LEAVE_MAP_BG");
var bgNoTabs = dialog.GetOrNull<BackgroundWidget>("LEAVE_MAP_BG_NO_TABS");
bg.IsVisible = () => showTabs || (!showTabs && bgNoTabs == null);
if (bgNoTabs != null)
bgNoTabs.IsVisible = () => !showTabs;
var objButton = dialog.Get<ButtonWidget>("OBJECTIVES_BUTTON");
objButton.IsVisible = () => showTabs;
objButton.OnClick = () => currentTab = Tab.Objectives;
objButton.IsHighlighted = () => currentTab == Tab.Objectives;
var chatButton = dialog.Get<ButtonWidget>("CHAT_BUTTON");
chatButton.IsVisible = () => showTabs;
chatButton.OnClick = () =>
{
currentTab = Tab.Chat;
newChatMessage = false;
};
chatButton.IsHighlighted = () => currentTab == Tab.Chat || (newChatMessage && Game.LocalTick % 50 < 25);
Game.BeforeGameStart += UnregisterChatNotification;
orderManager.AddChatLine += NotifyNewChatMessage;
}
var statsButton = dialog.Get<ButtonWidget>("STATS_BUTTON");
statsButton.IsVisible = () => !world.Map.Visibility.HasFlag(MapVisibility.MissionSelector) || world.IsReplay;
statsButton.OnClick = () =>
{
showStats = true;
Game.LoadWidget(world, "INGAME_OBSERVERSTATS_BG", Ui.Root, new WidgetArgs()
{
{ "onExit", () => showStats = false }
});
};
var leaveButton = dialog.Get<ButtonWidget>("LEAVE_BUTTON");
leaveButton.OnClick = () =>
{
leaveButton.Disabled = true;
Sound.PlayNotification(world.Map.Rules, null, "Speech", "Leave",
world.LocalPlayer == null ? null : world.LocalPlayer.Country.Race);
var exitDelay = 1200;
if (mpe != null)
{
Game.RunAfterDelay(exitDelay, () => mpe.Fade(MenuPaletteEffect.EffectType.Black));
exitDelay += 40 * mpe.Info.FadeLength;
}
Game.RunAfterDelay(exitDelay, () =>
{
Game.Disconnect();
Ui.ResetAll();
Game.LoadShellMap();
});
};
if (hasObjectives)
{
var panel = hasError ? "SCRIPT_ERROR_PANEL" : iop.PanelName;
var objectivesContainer = dialog.Get<ContainerWidget>("OBJECTIVES_PANEL");
Game.LoadWidget(world, panel, objectivesContainer, new WidgetArgs());
objectivesContainer.IsVisible = () => currentTab == Tab.Objectives;
string video = null;
if (world.LocalPlayer.WinState != WinState.Undefined)
video = world.LocalPlayer.WinState == WinState.Won ? world.Map.Videos.GameWon : world.Map.Videos.GameLost;
if (!string.IsNullOrEmpty(video))
Media.PlayFMVFullscreen(world, video, () => { });
}
if (isMultiplayer)
{
var chatContainer = dialog.Get<ContainerWidget>("DIALOG_CHAT_PANEL");
chatContainer.IsVisible = () => currentTab == Tab.Chat;
}
}
void NotifyNewChatMessage(Color c, string s1, string s2)
{
if (currentTab != Tab.Chat)
newChatMessage = true;
}
void UnregisterChatNotification()
{
orderManager.AddChatLine -= NotifyNewChatMessage;
Game.BeforeGameStart -= UnregisterChatNotification;
}
}
}

View File

@@ -1,126 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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 OpenRA.Graphics;
using OpenRA.Mods.Common.Traits;
using OpenRA.Mods.Common.Widgets;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class IngameMenuLogic
{
Widget menu;
[ObjectCreator.UseCtor]
public IngameMenuLogic(Widget widget, World world, Action onExit, WorldRenderer worldRenderer, IngameInfoPanel activePanel)
{
var resumeDisabled = false;
menu = widget.Get("INGAME_MENU");
var mpe = world.WorldActor.TraitOrDefault<MenuPaletteEffect>();
if (mpe != null)
mpe.Fade(mpe.Info.MenuEffect);
menu.Get<LabelWidget>("VERSION_LABEL").Text = Game.ModData.Manifest.Mod.Version;
var hideMenu = false;
menu.Get("MENU_BUTTONS").IsVisible = () => !hideMenu;
// TODO: Create a mechanism to do things like this cleaner. Also needed for scripted missions
Action onQuit = () =>
{
Sound.PlayNotification(world.Map.Rules, null, "Speech", "Leave", world.LocalPlayer == null ? null : world.LocalPlayer.Country.Race);
resumeDisabled = true;
var exitDelay = 1200;
if (mpe != null)
{
Game.RunAfterDelay(exitDelay, () => mpe.Fade(MenuPaletteEffect.EffectType.Black));
exitDelay += 40 * mpe.Info.FadeLength;
}
Game.RunAfterDelay(exitDelay, () =>
{
Game.Disconnect();
Ui.ResetAll();
Game.LoadShellMap();
});
};
Action closeMenu = () =>
{
Ui.CloseWindow();
if (mpe != null)
mpe.Fade(MenuPaletteEffect.EffectType.None);
onExit();
};
Action showMenu = () => hideMenu = false;
menu.Get<ButtonWidget>("ABORT_MISSION").OnClick = () =>
{
hideMenu = true;
ConfirmationDialogs.PromptConfirmAction("Abort Mission", "Leave this game and return to the menu?", onQuit, showMenu);
};
Action onSurrender = () =>
{
world.IssueOrder(new Order("Surrender", world.LocalPlayer.PlayerActor, false));
closeMenu();
};
var surrenderButton = menu.Get<ButtonWidget>("SURRENDER");
surrenderButton.IsDisabled = () => (world.LocalPlayer == null || world.LocalPlayer.WinState != WinState.Undefined);
surrenderButton.OnClick = () =>
{
hideMenu = true;
ConfirmationDialogs.PromptConfirmAction("Surrender", "Are you sure you want to surrender?", onSurrender, showMenu);
};
surrenderButton.IsDisabled = () => world.LocalPlayer == null || world.LocalPlayer.WinState != WinState.Undefined;
menu.Get<ButtonWidget>("MUSIC").OnClick = () =>
{
hideMenu = true;
Ui.OpenWindow("MUSIC_PANEL", new WidgetArgs()
{
{ "onExit", () => hideMenu = false },
{ "world", world }
});
};
var settingsButton = widget.Get<ButtonWidget>("SETTINGS");
settingsButton.OnClick = () =>
{
hideMenu = true;
Ui.OpenWindow("SETTINGS_PANEL", new WidgetArgs()
{
{ "world", world },
{ "worldRenderer", worldRenderer },
{ "onExit", () => hideMenu = false },
});
};
var resumeButton = menu.Get<ButtonWidget>("RESUME");
resumeButton.IsDisabled = () => resumeDisabled;
resumeButton.OnClick = closeMenu;
var panelRoot = widget.GetOrNull("PANEL_ROOT");
if (panelRoot != null)
{
var gameInfoPanel = Game.LoadWidget(world, "GAME_INFO_PANEL", panelRoot, new WidgetArgs()
{
{ "activePanel", activePanel }
});
gameInfoPanel.IsVisible = () => !hideMenu;
}
}
}
}

View File

@@ -1,133 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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.IO;
using System.Linq;
using System.Threading;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class InstallFromCDLogic
{
Widget panel;
ProgressBarWidget progressBar;
LabelWidget statusLabel;
Action continueLoading;
ButtonWidget retryButton, backButton;
Widget installingContainer, insertDiskContainer;
[ObjectCreator.UseCtor]
public InstallFromCDLogic(Widget widget, Action continueLoading)
{
this.continueLoading = continueLoading;
panel = widget.Get("INSTALL_FROMCD_PANEL");
progressBar = panel.Get<ProgressBarWidget>("PROGRESS_BAR");
statusLabel = panel.Get<LabelWidget>("STATUS_LABEL");
backButton = panel.Get<ButtonWidget>("BACK_BUTTON");
backButton.OnClick = Ui.CloseWindow;
retryButton = panel.Get<ButtonWidget>("RETRY_BUTTON");
retryButton.OnClick = CheckForDisk;
installingContainer = panel.Get("INSTALLING");
insertDiskContainer = panel.Get("INSERT_DISK");
CheckForDisk();
}
bool IsValidDisk(string diskRoot)
{
return Game.ModData.Manifest.ContentInstaller.DiskTestFiles.All(f => File.Exists(Path.Combine(diskRoot, f)));
}
void CheckForDisk()
{
var path = InstallUtils.GetMountedDisk(IsValidDisk);
if (path != null)
Install(path);
else
{
insertDiskContainer.IsVisible = () => true;
installingContainer.IsVisible = () => false;
}
}
void Install(string source)
{
backButton.IsDisabled = () => true;
retryButton.IsDisabled = () => true;
insertDiskContainer.IsVisible = () => false;
installingContainer.IsVisible = () => true;
var dest = Platform.ResolvePath("^", "Content", Game.ModData.Manifest.Mod.Id);
var copyFiles = Game.ModData.Manifest.ContentInstaller.CopyFilesFromCD;
var packageToExtract = Game.ModData.Manifest.ContentInstaller.PackageToExtractFromCD.Split(':');
var extractPackage = packageToExtract.First();
var annotation = packageToExtract.Length > 1 ? packageToExtract.Last() : null;
var extractFiles = Game.ModData.Manifest.ContentInstaller.ExtractFilesFromCD;
var installCounter = 0;
var installTotal = copyFiles.Length + extractFiles.Length;
var onProgress = (Action<string>)(s => Game.RunAfterTick(() =>
{
progressBar.Percentage = installCounter * 100 / installTotal;
installCounter++;
statusLabel.GetText = () => s;
}));
var onError = (Action<string>)(s => Game.RunAfterTick(() =>
{
statusLabel.GetText = () => "Error: " + s;
backButton.IsDisabled = () => false;
retryButton.IsDisabled = () => false;
}));
new Thread(() =>
{
try
{
if (!InstallUtils.CopyFiles(source, copyFiles, dest, onProgress, onError))
{
onError("Copying files from CD failed.");
return;
}
if (!string.IsNullOrEmpty(extractPackage))
{
if (!InstallUtils.ExtractFromPackage(source, extractPackage, annotation, extractFiles, dest, onProgress, onError))
{
onError("Extracting files from CD failed.");
return;
}
}
Game.RunAfterTick(() =>
{
statusLabel.GetText = () => "Game assets have been extracted.";
Ui.CloseWindow();
continueLoading();
});
}
catch (Exception e)
{
onError("Installation failed.\n{0}".F(e.Message));
Log.Write("debug", e.ToString());
return;
}
}) { IsBackground = true }.Start();
}
}
}

View File

@@ -1,44 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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 OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class InstallLogic : Widget
{
[ObjectCreator.UseCtor]
public InstallLogic(Widget widget, Action continueLoading)
{
var mirrorListUrl = Game.ModData.Manifest.ContentInstaller.PackageMirrorList;
var panel = widget.Get("INSTALL_PANEL");
var widgetArgs = new WidgetArgs()
{
{ "afterInstall", () => { Ui.CloseWindow(); continueLoading(); } },
{ "continueLoading", continueLoading },
{ "mirrorListUrl", mirrorListUrl },
};
panel.Get<ButtonWidget>("DOWNLOAD_BUTTON").OnClick = () =>
Ui.OpenWindow("INSTALL_DOWNLOAD_PANEL", widgetArgs);
panel.Get<ButtonWidget>("INSTALL_BUTTON").OnClick = () =>
Ui.OpenWindow("INSTALL_FROMCD_PANEL", widgetArgs);
panel.Get<ButtonWidget>("BACK_BUTTON").OnClick = () =>
{
Game.Settings.Game.PreviousMod = Game.ModData.Manifest.Mod.Id;
Game.InitializeMod("modchooser", null);
};
}
}
}

View File

@@ -1,57 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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.IO;
using System.Linq;
using OpenRA.FileSystem;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class InstallMusicLogic
{
[ObjectCreator.UseCtor]
public InstallMusicLogic(Widget widget)
{
var installMusicContainer = widget.Get("INSTALL_MUSIC_PANEL");
var cancelButton = installMusicContainer.GetOrNull<ButtonWidget>("CANCEL_BUTTON");
if (cancelButton != null)
cancelButton.OnClick = () => Game.InitializeMod(Game.Settings.Game.Mod, null);
var copyFromDiscButton = installMusicContainer.GetOrNull<ButtonWidget>("COPY_FROM_CD_BUTTON");
if (copyFromDiscButton != null)
{
copyFromDiscButton.OnClick = () =>
{
Ui.OpenWindow("INSTALL_FROMCD_PANEL", new WidgetArgs() {
{ "continueLoading", () => Game.InitializeMod(Game.Settings.Game.Mod, null) },
});
};
}
var downloadButton = installMusicContainer.GetOrNull<ButtonWidget>("DOWNLOAD_BUTTON");
if (downloadButton != null)
{
var mirrorListUrl = Game.ModData.Manifest.ContentInstaller.MusicPackageMirrorList;
downloadButton.IsVisible = () => !string.IsNullOrEmpty(mirrorListUrl);
downloadButton.OnClick = () =>
{
Ui.OpenWindow("INSTALL_DOWNLOAD_PANEL", new WidgetArgs() {
{ "afterInstall", () => Game.InitializeMod(Game.Settings.Game.Mod, null) },
{ "mirrorListUrl", mirrorListUrl },
});
};
}
}
}
}

View File

@@ -1,300 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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.IO;
using System.Linq;
using System.Net;
using System.Threading;
using OpenRA.FileSystem;
using OpenRA.Graphics;
using OpenRA.Network;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class MissionBrowserLogic
{
enum PlayingVideo { None, Info, Briefing, GameStart }
readonly Action onStart;
readonly ScrollPanelWidget descriptionPanel;
readonly LabelWidget description;
readonly SpriteFont descriptionFont;
readonly DropDownButtonWidget difficultyButton;
readonly ButtonWidget startBriefingVideoButton;
readonly ButtonWidget stopBriefingVideoButton;
readonly ButtonWidget startInfoVideoButton;
readonly ButtonWidget stopInfoVideoButton;
readonly VqaPlayerWidget videoPlayer;
readonly BackgroundWidget fullscreenVideoPlayer;
readonly ScrollPanelWidget missionList;
readonly ScrollItemWidget headerTemplate;
readonly ScrollItemWidget template;
MapPreview selectedMapPreview;
PlayingVideo playingVideo;
string difficulty;
[ObjectCreator.UseCtor]
public MissionBrowserLogic(Widget widget, World world, Action onStart, Action onExit)
{
this.onStart = onStart;
missionList = widget.Get<ScrollPanelWidget>("MISSION_LIST");
headerTemplate = widget.Get<ScrollItemWidget>("HEADER");
template = widget.Get<ScrollItemWidget>("TEMPLATE");
var title = widget.GetOrNull<LabelWidget>("MISSIONBROWSER_TITLE");
if (title != null)
title.GetText = () => playingVideo != PlayingVideo.None ? selectedMapPreview.Title : title.Text;
widget.Get("MISSION_INFO").IsVisible = () => selectedMapPreview != null;
var previewWidget = widget.Get<MapPreviewWidget>("MISSION_PREVIEW");
previewWidget.Preview = () => selectedMapPreview;
previewWidget.IsVisible = () => playingVideo == PlayingVideo.None;
videoPlayer = widget.Get<VqaPlayerWidget>("MISSION_VIDEO");
widget.Get("MISSION_BIN").IsVisible = () => playingVideo != PlayingVideo.None;
fullscreenVideoPlayer = Ui.LoadWidget<BackgroundWidget>("FULLSCREEN_PLAYER", Ui.Root, new WidgetArgs { { "world", world } });
descriptionPanel = widget.Get<ScrollPanelWidget>("MISSION_DESCRIPTION_PANEL");
description = descriptionPanel.Get<LabelWidget>("MISSION_DESCRIPTION");
descriptionFont = Game.Renderer.Fonts[description.Font];
difficultyButton = widget.Get<DropDownButtonWidget>("DIFFICULTY_DROPDOWNBUTTON");
startBriefingVideoButton = widget.Get<ButtonWidget>("START_BRIEFING_VIDEO_BUTTON");
stopBriefingVideoButton = widget.Get<ButtonWidget>("STOP_BRIEFING_VIDEO_BUTTON");
stopBriefingVideoButton.IsVisible = () => playingVideo == PlayingVideo.Briefing;
stopBriefingVideoButton.OnClick = () => StopVideo(videoPlayer);
startInfoVideoButton = widget.Get<ButtonWidget>("START_INFO_VIDEO_BUTTON");
stopInfoVideoButton = widget.Get<ButtonWidget>("STOP_INFO_VIDEO_BUTTON");
stopInfoVideoButton.IsVisible = () => playingVideo == PlayingVideo.Info;
stopInfoVideoButton.OnClick = () => StopVideo(videoPlayer);
var allMaps = new List<Map>();
missionList.RemoveChildren();
// Add a group for each campaign
if (Game.ModData.Manifest.Missions.Any())
{
var yaml = Game.ModData.Manifest.Missions.Select(MiniYaml.FromFile).Aggregate(MiniYaml.MergeLiberal);
foreach (var kv in yaml)
{
var missionMapPaths = kv.Value.Nodes.Select(n => Path.GetFullPath(n.Key));
var maps = Game.ModData.MapCache
.Where(p => p.Status == MapStatus.Available && missionMapPaths.Contains(Path.GetFullPath(p.Map.Path)))
.Select(p => p.Map);
CreateMissionGroup(kv.Key, maps);
allMaps.AddRange(maps);
}
}
// Add an additional group for loose missions
var looseMissions = Game.ModData.MapCache
.Where(p => p.Status == MapStatus.Available && p.Map.Visibility.HasFlag(MapVisibility.MissionSelector) && !allMaps.Contains(p.Map))
.Select(p => p.Map);
if (looseMissions.Any())
{
CreateMissionGroup("Missions", looseMissions);
allMaps.AddRange(looseMissions);
}
if (allMaps.Any())
SelectMap(allMaps.First());
var startButton = widget.Get<ButtonWidget>("STARTGAME_BUTTON");
startButton.OnClick = StartMissionClicked;
startButton.IsDisabled = () => selectedMapPreview == null || selectedMapPreview.RuleStatus != MapRuleStatus.Cached;
widget.Get<ButtonWidget>("BACK_BUTTON").OnClick = () =>
{
StopVideo(videoPlayer);
Game.Disconnect();
Ui.CloseWindow();
onExit();
};
}
void CreateMissionGroup(string title, IEnumerable<Map> maps)
{
var header = ScrollItemWidget.Setup(headerTemplate, () => true, () => { });
header.Get<LabelWidget>("LABEL").GetText = () => title;
missionList.AddChild(header);
foreach (var m in maps)
{
var map = m;
var item = ScrollItemWidget.Setup(template,
() => selectedMapPreview != null && selectedMapPreview.Uid == map.Uid,
() => SelectMap(map),
StartMissionClicked);
item.Get<LabelWidget>("TITLE").GetText = () => map.Title;
missionList.AddChild(item);
}
}
void SelectMap(Map map)
{
selectedMapPreview = Game.ModData.MapCache[map.Uid];
// Cache the rules on a background thread to avoid jank
new Thread(selectedMapPreview.CacheRules).Start();
var briefingVideo = selectedMapPreview.Map.Videos.Briefing;
var briefingVideoVisible = briefingVideo != null;
var briefingVideoDisabled = !(briefingVideoVisible && GlobalFileSystem.Exists(briefingVideo));
var infoVideo = selectedMapPreview.Map.Videos.BackgroundInfo;
var infoVideoVisible = infoVideo != null;
var infoVideoDisabled = !(infoVideoVisible && GlobalFileSystem.Exists(infoVideo));
startBriefingVideoButton.IsVisible = () => briefingVideoVisible && playingVideo != PlayingVideo.Briefing;
startBriefingVideoButton.IsDisabled = () => briefingVideoDisabled || playingVideo != PlayingVideo.None;
startBriefingVideoButton.OnClick = () => PlayVideo(videoPlayer, briefingVideo, PlayingVideo.Briefing, () => StopVideo(videoPlayer));
startInfoVideoButton.IsVisible = () => infoVideoVisible && playingVideo != PlayingVideo.Info;
startInfoVideoButton.IsDisabled = () => infoVideoDisabled || playingVideo != PlayingVideo.None;
startInfoVideoButton.OnClick = () => PlayVideo(videoPlayer, infoVideo, PlayingVideo.Info, () => StopVideo(videoPlayer));
var text = map.Description != null ? map.Description.Replace("\\n", "\n") : "";
text = WidgetUtils.WrapText(text, description.Bounds.Width, descriptionFont);
description.Text = text;
description.Bounds.Height = descriptionFont.Measure(text).Y;
descriptionPanel.ScrollToTop();
descriptionPanel.Layout.AdjustChildren();
difficultyButton.IsVisible = () => map.Options.Difficulties.Any();
if (!map.Options.Difficulties.Any())
return;
difficulty = map.Options.Difficulties.First();
difficultyButton.OnMouseDown = _ =>
{
var options = map.Options.Difficulties.Select(d => new DropDownOption
{
Title = d,
IsSelected = () => difficulty == d,
OnClick = () => difficulty = d
});
Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
{
var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
return item;
};
difficultyButton.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
};
}
float cachedSoundVolume;
float cachedMusicVolume;
void MuteSounds()
{
cachedSoundVolume = Sound.SoundVolume;
cachedMusicVolume = Sound.MusicVolume;
Sound.SoundVolume = Sound.MusicVolume = 0;
}
void UnMuteSounds()
{
if (cachedSoundVolume > 0)
Sound.SoundVolume = cachedSoundVolume;
if (cachedMusicVolume > 0)
Sound.MusicVolume = cachedMusicVolume;
}
void PlayVideo(VqaPlayerWidget player, string video, PlayingVideo pv, Action onComplete)
{
StopVideo(player);
playingVideo = pv;
player.Load(video);
// video playback runs asynchronously
player.PlayThen(onComplete);
// Mute other distracting sounds
MuteSounds();
}
void StopVideo(VqaPlayerWidget player)
{
if (playingVideo == PlayingVideo.None)
return;
UnMuteSounds();
player.Stop();
playingVideo = PlayingVideo.None;
}
void StartMissionClicked()
{
StopVideo(videoPlayer);
if (selectedMapPreview.RuleStatus != MapRuleStatus.Cached)
return;
var gameStartVideo = selectedMapPreview.Map.Videos.GameStart;
if (gameStartVideo != null && GlobalFileSystem.Exists(gameStartVideo))
{
var fsPlayer = fullscreenVideoPlayer.Get<VqaPlayerWidget>("PLAYER");
fullscreenVideoPlayer.Visible = true;
PlayVideo(fsPlayer, gameStartVideo, PlayingVideo.GameStart, () =>
{
StopVideo(fsPlayer);
StartMission();
});
}
else
StartMission();
}
void StartMission()
{
OrderManager om = null;
Action lobbyReady = null;
lobbyReady = () =>
{
om.IssueOrder(Order.Command("difficulty {0}".F(difficulty)));
Game.LobbyInfoChanged -= lobbyReady;
onStart();
om.IssueOrder(Order.Command("state {0}".F(Session.ClientState.Ready)));
};
Game.LobbyInfoChanged += lobbyReady;
om = Game.JoinServer(IPAddress.Loopback.ToString(), Game.CreateLocalServer(selectedMapPreview.Uid), "", false);
}
class DropDownOption
{
public string Title;
public Func<bool> IsSelected;
public Action OnClick;
}
}
}

View File

@@ -1,183 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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.Linq;
using OpenRA.GameRules;
using OpenRA.Mods.Common.Widgets;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class MusicPlayerLogic
{
readonly Ruleset modRules;
bool installed;
MusicInfo currentSong = null;
MusicInfo[] music;
MusicInfo[] random;
ScrollPanelWidget musicList;
ScrollItemWidget itemTemplate;
[ObjectCreator.UseCtor]
public MusicPlayerLogic(Widget widget, Ruleset modRules, World world, Action onExit)
{
this.modRules = modRules;
var panel = widget.Get("MUSIC_PANEL");
musicList = panel.Get<ScrollPanelWidget>("MUSIC_LIST");
itemTemplate = musicList.Get<ScrollItemWidget>("MUSIC_TEMPLATE");
BuildMusicTable();
Func<bool> noMusic = () => !installed;
panel.Get("NO_MUSIC_LABEL").IsVisible = noMusic;
var playButton = panel.Get<ButtonWidget>("BUTTON_PLAY");
playButton.OnClick = Play;
playButton.IsDisabled = noMusic;
playButton.IsVisible = () => !Sound.MusicPlaying;
var pauseButton = panel.Get<ButtonWidget>("BUTTON_PAUSE");
pauseButton.OnClick = Sound.PauseMusic;
pauseButton.IsDisabled = noMusic;
pauseButton.IsVisible = () => Sound.MusicPlaying;
var stopButton = panel.Get<ButtonWidget>("BUTTON_STOP");
stopButton.OnClick = Sound.StopMusic;
stopButton.IsDisabled = noMusic;
var nextButton = panel.Get<ButtonWidget>("BUTTON_NEXT");
nextButton.OnClick = () => { currentSong = GetNextSong(); Play(); };
nextButton.IsDisabled = noMusic;
var prevButton = panel.Get<ButtonWidget>("BUTTON_PREV");
prevButton.OnClick = () => { currentSong = GetPrevSong(); Play(); };
prevButton.IsDisabled = noMusic;
var shuffleCheckbox = panel.Get<CheckboxWidget>("SHUFFLE");
shuffleCheckbox.IsChecked = () => Game.Settings.Sound.Shuffle;
shuffleCheckbox.OnClick = () => Game.Settings.Sound.Shuffle ^= true;
var repeatCheckbox = panel.Get<CheckboxWidget>("REPEAT");
repeatCheckbox.IsChecked = () => Game.Settings.Sound.Repeat;
repeatCheckbox.OnClick = () => Game.Settings.Sound.Repeat ^= true;
panel.Get<LabelWidget>("TIME_LABEL").GetText = () => (currentSong == null) ? "" :
"{0:D2}:{1:D2} / {2:D2}:{3:D2}".F((int)Sound.MusicSeekPosition / 60, (int)Sound.MusicSeekPosition % 60,
currentSong.Length / 60, currentSong.Length % 60);
var musicSlider = panel.Get<SliderWidget>("MUSIC_SLIDER");
musicSlider.OnChange += x => Sound.MusicVolume = x;
musicSlider.Value = Sound.MusicVolume;
var installButton = widget.GetOrNull<ButtonWidget>("INSTALL_BUTTON");
if (installButton != null)
{
installButton.IsDisabled = () => world == null || world.Type != WorldType.Shellmap;
var args = new string[] { "Install.Music=true" };
installButton.OnClick = () =>
{
Game.ModData.LoadScreen.Display(); // HACK: prevent a flicker when transitioning to the installation dialog
Game.InitializeMod(Game.Settings.Game.Mod, new Arguments(args));
};
var installData = Game.ModData.Manifest.ContentInstaller;
installButton.IsVisible = () => modRules.InstalledMusic.ToArray().Length <= installData.ShippedSoundtracks;
}
var songWatcher = widget.GetOrNull<LogicTickerWidget>("SONG_WATCHER");
if (songWatcher != null)
{
songWatcher.OnTick = () =>
{
if (Sound.CurrentMusic == null || currentSong == Sound.CurrentMusic)
return;
currentSong = Sound.CurrentMusic;
};
}
panel.Get<ButtonWidget>("BACK_BUTTON").OnClick = () => { Game.Settings.Save(); Ui.CloseWindow(); onExit(); };
}
public void BuildMusicTable()
{
music = modRules.InstalledMusic.Select(a => a.Value).ToArray();
random = music.Shuffle(Game.CosmeticRandom).ToArray();
currentSong = Sound.CurrentMusic;
if (currentSong == null && music.Any())
currentSong = Game.Settings.Sound.Shuffle ? random.First() : music.First();
musicList.RemoveChildren();
foreach (var s in music)
{
var song = s;
if (currentSong == null)
currentSong = song;
// TODO: We leak the currentSong MusicInfo across map load, so compare the Filename instead.
var item = ScrollItemWidget.Setup(song.Filename, itemTemplate, () => currentSong.Filename == song.Filename, () => { currentSong = song; Play(); }, () => { });
item.Get<LabelWidget>("TITLE").GetText = () => song.Title;
item.Get<LabelWidget>("LENGTH").GetText = () => SongLengthLabel(song);
musicList.AddChild(item);
}
if (currentSong != null)
musicList.ScrollToItem(currentSong.Filename);
installed = modRules.InstalledMusic.Any();
}
void Play()
{
if (currentSong == null)
return;
musicList.ScrollToItem(currentSong.Filename);
Sound.PlayMusicThen(currentSong, () =>
{
if (!Game.Settings.Sound.Repeat)
currentSong = GetNextSong();
Play();
});
}
static string SongLengthLabel(MusicInfo song)
{
return "{0:D1}:{1:D2}".F(song.Length / 60, song.Length % 60);
}
MusicInfo GetNextSong()
{
if (!music.Any())
return null;
var songs = Game.Settings.Sound.Shuffle ? random : music;
return songs.SkipWhile(m => m != currentSong)
.Skip(1).FirstOrDefault() ?? songs.FirstOrDefault();
}
MusicInfo GetPrevSong()
{
if (!music.Any())
return null;
var songs = Game.Settings.Sound.Shuffle ? random : music;
return songs.Reverse().SkipWhile(m => m != currentSong)
.Skip(1).FirstOrDefault() ?? songs.Reverse().FirstOrDefault();
}
}
}

View File

@@ -1,169 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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.Mods.Common.Widgets;
using OpenRA.Network;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class ObserverShroudSelectorLogic
{
CameraOption selected;
CameraOption combined, disableShroud;
IOrderedEnumerable<IGrouping<int, CameraOption>> teams;
class CameraOption
{
public readonly Player Player;
public readonly string Label;
public readonly Color Color;
public readonly string Race;
public readonly Func<bool> IsSelected;
public readonly Action OnClick;
public CameraOption(ObserverShroudSelectorLogic logic, Player p)
{
Player = p;
Label = p.PlayerName;
Color = p.Color.RGB;
Race = p.Country.Race;
IsSelected = () => p.World.RenderPlayer == p;
OnClick = () => { p.World.RenderPlayer = p; logic.selected = this; p.World.Selection.Clear(); };
}
public CameraOption(ObserverShroudSelectorLogic logic, World w, string label, Player p)
{
Player = p;
Label = label;
Color = Color.White;
Race = null;
IsSelected = () => w.RenderPlayer == p;
OnClick = () => { w.RenderPlayer = p; logic.selected = this; };
}
}
[ObjectCreator.UseCtor]
public ObserverShroudSelectorLogic(Widget widget, World world)
{
var groups = new Dictionary<string, IEnumerable<CameraOption>>();
teams = world.Players.Where(p => !p.NonCombatant)
.Select(p => new CameraOption(this, p))
.GroupBy(p => (world.LobbyInfo.ClientWithIndex(p.Player.ClientIndex) ?? new Session.Client()).Team)
.OrderBy(g => g.Key);
var noTeams = teams.Count() == 1;
foreach (var t in teams)
{
var label = noTeams ? "Players" : t.Key == 0 ? "No Team" : "Team {0}".F(t.Key);
groups.Add(label, t);
}
combined = new CameraOption(this, world, "All Players", world.Players.First(p => p.InternalName == "Everyone"));
disableShroud = new CameraOption(this, world, "Disable Shroud", null);
groups.Add("Other", new List<CameraOption>() { combined, disableShroud });
var shroudSelector = widget.Get<DropDownButtonWidget>("SHROUD_SELECTOR");
shroudSelector.OnMouseDown = _ =>
{
Func<CameraOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
{
var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
var showFlag = option.Race != null;
var label = item.Get<LabelWidget>("LABEL");
label.IsVisible = () => showFlag;
label.GetText = () => option.Label;
label.GetColor = () => option.Color;
var flag = item.Get<ImageWidget>("FLAG");
flag.IsVisible = () => showFlag;
flag.GetImageCollection = () => "flags";
flag.GetImageName = () => option.Race;
var labelAlt = item.Get<LabelWidget>("NOFLAG_LABEL");
labelAlt.IsVisible = () => !showFlag;
labelAlt.GetText = () => option.Label;
labelAlt.GetColor = () => option.Color;
return item;
};
shroudSelector.ShowDropDown("SPECTATOR_DROPDOWN_TEMPLATE", 400, groups, setupItem);
};
var shroudLabel = shroudSelector.Get<LabelWidget>("LABEL");
shroudLabel.IsVisible = () => selected.Race != null;
shroudLabel.GetText = () => selected.Label;
shroudLabel.GetColor = () => selected.Color;
var shroudFlag = shroudSelector.Get<ImageWidget>("FLAG");
shroudFlag.IsVisible = () => selected.Race != null;
shroudFlag.GetImageCollection = () => "flags";
shroudFlag.GetImageName = () => selected.Race;
var shroudLabelAlt = shroudSelector.Get<LabelWidget>("NOFLAG_LABEL");
shroudLabelAlt.IsVisible = () => selected.Race == null;
shroudLabelAlt.GetText = () => selected.Label;
shroudLabelAlt.GetColor = () => selected.Color;
var keyhandler = shroudSelector.Get<LogicKeyListenerWidget>("SHROUD_KEYHANDLER");
keyhandler.OnKeyPress = HandleKeyPress;
selected = disableShroud;
}
public bool HandleKeyPress(KeyInput e)
{
if (e.Event == KeyInputEvent.Down)
{
var h = Hotkey.FromKeyInput(e);
if (h == Game.Settings.Keys.ObserverCombinedView)
{
selected = combined;
selected.OnClick();
return true;
}
if (h == Game.Settings.Keys.ObserverWorldView)
{
selected = disableShroud;
selected.OnClick();
return true;
}
if (e.Key >= Keycode.NUMBER_0 && e.Key <= Keycode.NUMBER_9)
{
var key = (int)e.Key - (int)Keycode.NUMBER_0;
var team = teams.Where(t => t.Key == key).SelectMany(s => s);
if (!team.Any())
return false;
if (e.Modifiers == Modifiers.Shift)
team = team.Reverse();
selected = team.SkipWhile(t => t.Player != selected.Player).Skip(1).FirstOrDefault() ?? team.FirstOrDefault();
selected.OnClick();
return true;
}
}
return false;
}
}
}

View File

@@ -1,321 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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.Graphics;
using OpenRA.Mods.Common.Traits;
using OpenRA.Mods.Common.Widgets;
using OpenRA.Mods.Common.Widgets.Logic;
using OpenRA.Mods.RA.Traits;
using OpenRA.Network;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class ObserverStatsLogic
{
ContainerWidget basicStatsHeaders;
ContainerWidget economyStatsHeaders;
ContainerWidget productionStatsHeaders;
ContainerWidget combatStatsHeaders;
ContainerWidget earnedThisMinuteGraphHeaders;
ScrollPanelWidget playerStatsPanel;
ScrollItemWidget basicPlayerTemplate;
ScrollItemWidget economyPlayerTemplate;
ScrollItemWidget productionPlayerTemplate;
ScrollItemWidget combatPlayerTemplate;
ContainerWidget earnedThisMinuteGraphTemplate;
ScrollItemWidget teamTemplate;
DropDownButtonWidget statsDropDown;
IEnumerable<Player> players;
World world;
WorldRenderer worldRenderer;
[ObjectCreator.UseCtor]
public ObserverStatsLogic(World world, WorldRenderer worldRenderer, Widget widget, Action onExit)
{
this.world = world;
this.worldRenderer = worldRenderer;
players = world.Players.Where(p => !p.NonCombatant);
basicStatsHeaders = widget.Get<ContainerWidget>("BASIC_STATS_HEADERS");
economyStatsHeaders = widget.Get<ContainerWidget>("ECONOMY_STATS_HEADERS");
productionStatsHeaders = widget.Get<ContainerWidget>("PRODUCTION_STATS_HEADERS");
combatStatsHeaders = widget.Get<ContainerWidget>("COMBAT_STATS_HEADERS");
earnedThisMinuteGraphHeaders = widget.Get<ContainerWidget>("EARNED_THIS_MIN_GRAPH_HEADERS");
playerStatsPanel = widget.Get<ScrollPanelWidget>("PLAYER_STATS_PANEL");
playerStatsPanel.Layout = new GridLayout(playerStatsPanel);
basicPlayerTemplate = playerStatsPanel.Get<ScrollItemWidget>("BASIC_PLAYER_TEMPLATE");
economyPlayerTemplate = playerStatsPanel.Get<ScrollItemWidget>("ECONOMY_PLAYER_TEMPLATE");
productionPlayerTemplate = playerStatsPanel.Get<ScrollItemWidget>("PRODUCTION_PLAYER_TEMPLATE");
combatPlayerTemplate = playerStatsPanel.Get<ScrollItemWidget>("COMBAT_PLAYER_TEMPLATE");
earnedThisMinuteGraphTemplate = playerStatsPanel.Get<ContainerWidget>("EARNED_THIS_MIN_GRAPH_TEMPLATE");
teamTemplate = playerStatsPanel.Get<ScrollItemWidget>("TEAM_TEMPLATE");
statsDropDown = widget.Get<DropDownButtonWidget>("STATS_DROPDOWN");
statsDropDown.GetText = () => "Basic";
statsDropDown.OnMouseDown = _ =>
{
var options = new List<StatsDropDownOption>
{
new StatsDropDownOption
{
Title = "Basic",
IsSelected = () => basicStatsHeaders.Visible,
OnClick = () =>
{
ClearStats();
statsDropDown.GetText = () => "Basic";
DisplayStats(BasicStats);
}
},
new StatsDropDownOption
{
Title = "Economy",
IsSelected = () => economyStatsHeaders.Visible,
OnClick = () =>
{
ClearStats();
statsDropDown.GetText = () => "Economy";
DisplayStats(EconomyStats);
}
},
new StatsDropDownOption
{
Title = "Production",
IsSelected = () => productionStatsHeaders.Visible,
OnClick = () =>
{
ClearStats();
statsDropDown.GetText = () => "Production";
DisplayStats(ProductionStats);
}
},
new StatsDropDownOption
{
Title = "Combat",
IsSelected = () => combatStatsHeaders.Visible,
OnClick = () =>
{
ClearStats();
statsDropDown.GetText = () => "Combat";
DisplayStats(CombatStats);
}
},
new StatsDropDownOption
{
Title = "Earnings (graph)",
IsSelected = () => earnedThisMinuteGraphHeaders.Visible,
OnClick = () =>
{
ClearStats();
statsDropDown.GetText = () => "Earnings (graph)";
EarnedThisMinuteGraph();
}
}
};
Func<StatsDropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
{
var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
return item;
};
statsDropDown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 150, options, setupItem);
};
ClearStats();
DisplayStats(BasicStats);
var close = widget.GetOrNull<ButtonWidget>("CLOSE");
if (close != null)
close.OnClick = () =>
{
Ui.CloseWindow();
Ui.Root.RemoveChild(widget);
onExit();
};
}
void ClearStats()
{
playerStatsPanel.Children.Clear();
basicStatsHeaders.Visible = false;
economyStatsHeaders.Visible = false;
productionStatsHeaders.Visible = false;
combatStatsHeaders.Visible = false;
earnedThisMinuteGraphHeaders.Visible = false;
}
void EarnedThisMinuteGraph()
{
earnedThisMinuteGraphHeaders.Visible = true;
var template = earnedThisMinuteGraphTemplate.Clone();
var graph = template.Get<LineGraphWidget>("EARNED_THIS_MIN_GRAPH");
graph.GetSeries = () =>
players.Select(p => new LineGraphSeries(
p.PlayerName,
p.Color.RGB,
(p.PlayerActor.TraitOrDefault<PlayerStatistics>() ?? new PlayerStatistics(p.PlayerActor)).EarnedSamples.Select(s => (float)s)));
playerStatsPanel.AddChild(template);
}
void DisplayStats(Func<Player, ScrollItemWidget> createItem)
{
var teams = players.GroupBy(p => (world.LobbyInfo.ClientWithIndex(p.ClientIndex) ?? new Session.Client()).Team).OrderBy(g => g.Key);
foreach (var t in teams)
{
var team = t;
var tt = ScrollItemWidget.Setup(teamTemplate, () => false, () => { });
tt.IgnoreMouseOver = true;
tt.Get<LabelWidget>("TEAM").GetText = () => team.Key == 0 ? "No Team" : "Team " + team.Key;
playerStatsPanel.AddChild(tt);
foreach (var p in team)
{
var player = p;
playerStatsPanel.AddChild(createItem(player));
}
}
}
ScrollItemWidget CombatStats(Player player)
{
combatStatsHeaders.Visible = true;
var template = SetupPlayerScrollItemWidget(combatPlayerTemplate, player);
LobbyUtils.AddPlayerFlagAndName(template, player);
var stats = player.PlayerActor.TraitOrDefault<PlayerStatistics>();
if (stats == null) return template;
template.Get<LabelWidget>("CONTROL").GetText = () => MapControl(stats.MapControl);
template.Get<LabelWidget>("KILLS_COST").GetText = () => "$" + stats.KillsCost;
template.Get<LabelWidget>("DEATHS_COST").GetText = () => "$" + stats.DeathsCost;
template.Get<LabelWidget>("UNITS_KILLED").GetText = () => stats.UnitsKilled.ToString();
template.Get<LabelWidget>("UNITS_DEAD").GetText = () => stats.UnitsDead.ToString();
template.Get<LabelWidget>("BUILDINGS_KILLED").GetText = () => stats.BuildingsKilled.ToString();
template.Get<LabelWidget>("BUILDINGS_DEAD").GetText = () => stats.BuildingsDead.ToString();
return template;
}
ScrollItemWidget ProductionStats(Player player)
{
productionStatsHeaders.Visible = true;
var template = SetupPlayerScrollItemWidget(productionPlayerTemplate, player);
LobbyUtils.AddPlayerFlagAndName(template, player);
template.Get<ObserverProductionIconsWidget>("PRODUCTION_ICONS").GetPlayer = () => player;
template.Get<ObserverSupportPowerIconsWidget>("SUPPORT_POWER_ICONS").GetPlayer = () => player;
return template;
}
ScrollItemWidget EconomyStats(Player player)
{
economyStatsHeaders.Visible = true;
var template = SetupPlayerScrollItemWidget(economyPlayerTemplate, player);
LobbyUtils.AddPlayerFlagAndName(template, player);
var res = player.PlayerActor.Trait<PlayerResources>();
var stats = player.PlayerActor.TraitOrDefault<PlayerStatistics>();
if (stats == null) return template;
template.Get<LabelWidget>("CASH").GetText = () => "$" + (res.DisplayCash + res.DisplayResources);
template.Get<LabelWidget>("EARNED_MIN").GetText = () => AverageEarnedPerMinute(res.Earned);
template.Get<LabelWidget>("EARNED_THIS_MIN").GetText = () => "$" + stats.EarnedThisMinute;
template.Get<LabelWidget>("EARNED").GetText = () => "$" + res.Earned;
template.Get<LabelWidget>("SPENT").GetText = () => "$" + res.Spent;
var assets = template.Get<LabelWidget>("ASSETS");
assets.GetText = () => "$" + world.Actors
.Where(a => a.Owner == player && !a.IsDead && a.Info.Traits.WithInterface<ValuedInfo>().Any())
.Sum(a => a.Info.Traits.WithInterface<ValuedInfo>().First().Cost);
var harvesters = template.Get<LabelWidget>("HARVESTERS");
harvesters.GetText = () => world.Actors.Count(a => a.Owner == player && !a.IsDead && a.HasTrait<Harvester>()).ToString();
return template;
}
ScrollItemWidget BasicStats(Player player)
{
basicStatsHeaders.Visible = true;
var template = SetupPlayerScrollItemWidget(basicPlayerTemplate, player);
LobbyUtils.AddPlayerFlagAndName(template, player);
var res = player.PlayerActor.Trait<PlayerResources>();
template.Get<LabelWidget>("CASH").GetText = () => "$" + (res.DisplayCash + res.DisplayResources);
template.Get<LabelWidget>("EARNED_MIN").GetText = () => AverageEarnedPerMinute(res.Earned);
var powerRes = player.PlayerActor.Trait<PowerManager>();
var power = template.Get<LabelWidget>("POWER");
power.GetText = () => powerRes.PowerDrained + "/" + powerRes.PowerProvided;
power.GetColor = () => GetPowerColor(powerRes.PowerState);
var stats = player.PlayerActor.TraitOrDefault<PlayerStatistics>();
if (stats == null) return template;
template.Get<LabelWidget>("KILLS").GetText = () => (stats.UnitsKilled + stats.BuildingsKilled).ToString();
template.Get<LabelWidget>("DEATHS").GetText = () => (stats.UnitsDead + stats.BuildingsDead).ToString();
template.Get<LabelWidget>("ACTIONS_MIN").GetText = () => AverageOrdersPerMinute(stats.OrderCount);
return template;
}
ScrollItemWidget SetupPlayerScrollItemWidget(ScrollItemWidget template, Player player)
{
return ScrollItemWidget.Setup(template, () => false, () =>
{
var playerBase = world.Actors.FirstOrDefault(a => !a.IsDead && a.HasTrait<BaseBuilding>() && a.Owner == player);
if (playerBase != null)
worldRenderer.Viewport.Center(playerBase.CenterPosition);
});
}
static string MapControl(double control)
{
return (control * 100).ToString("F1") + "%";
}
string AverageOrdersPerMinute(double orders)
{
return (world.WorldTick == 0 ? 0 : orders / (world.WorldTick / 1500.0)).ToString("F1");
}
string AverageEarnedPerMinute(double earned)
{
return "$" + (world.WorldTick == 0 ? 0 : earned / (world.WorldTick / 1500.0)).ToString("F2");
}
static Color GetPowerColor(PowerState state)
{
if (state == PowerState.Critical) return Color.Red;
if (state == PowerState.Low) return Color.Orange;
return Color.LimeGreen;
}
class StatsDropDownOption
{
public string Title;
public Func<bool> IsSelected;
public Action OnClick;
}
}
}

View File

@@ -1,164 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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.Linq;
using OpenRA.Mods.Common.Orders;
using OpenRA.Mods.Common.Traits;
using OpenRA.Mods.Common.Widgets;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class OrderButtonsChromeLogic
{
readonly World world;
readonly Widget worldRoot;
readonly Widget menuRoot;
bool disableSystemButtons;
Widget currentWidget;
[ObjectCreator.UseCtor]
public OrderButtonsChromeLogic(Widget widget, World world)
{
this.world = world;
var ingameRoot = Ui.Root.Get("INGAME_ROOT");
worldRoot = ingameRoot.Get("WORLD_ROOT");
menuRoot = ingameRoot.Get("MENU_ROOT");
Action removeCurrentWidget = () => menuRoot.RemoveChild(currentWidget);
world.GameOver += removeCurrentWidget;
// Order Buttons
var sell = widget.GetOrNull<ButtonWidget>("SELL_BUTTON");
if (sell != null)
{
sell.GetKey = _ => Game.Settings.Keys.SellKey;
BindOrderButton<SellOrderGenerator>(world, sell, "sell");
}
var repair = widget.GetOrNull<ButtonWidget>("REPAIR_BUTTON");
if (repair != null)
{
repair.GetKey = _ => Game.Settings.Keys.RepairKey;
BindOrderButton<RepairOrderGenerator>(world, repair, "repair");
}
var beacon = widget.GetOrNull<ButtonWidget>("BEACON_BUTTON");
if (beacon != null)
{
beacon.GetKey = _ => Game.Settings.Keys.PlaceBeaconKey;
BindOrderButton<BeaconOrderGenerator>(world, beacon, "beacon");
}
var power = widget.GetOrNull<ButtonWidget>("POWER_BUTTON");
if (power != null)
{
power.GetKey = _ => Game.Settings.Keys.PowerDownKey;
BindOrderButton<PowerDownOrderGenerator>(world, power, "power");
}
// System buttons
var options = widget.GetOrNull<MenuButtonWidget>("OPTIONS_BUTTON");
if (options != null)
{
var blinking = false;
var lp = world.LocalPlayer;
options.IsDisabled = () => disableSystemButtons;
options.OnClick = () =>
{
blinking = false;
OpenMenuPanel(options, new WidgetArgs()
{
{ "activePanel", IngameInfoPanel.AutoSelect }
});
};
options.IsHighlighted = () => blinking && Game.LocalTick % 50 < 25;
if (lp != null)
{
Action<Player> startBlinking = player =>
{
if (player == world.LocalPlayer)
blinking = true;
};
var mo = lp.PlayerActor.TraitOrDefault<MissionObjectives>();
if (mo != null)
mo.ObjectiveAdded += startBlinking;
}
}
var diplomacy = widget.GetOrNull<MenuButtonWidget>("DIPLOMACY_BUTTON");
if (diplomacy != null)
{
diplomacy.Visible = !world.Map.Visibility.HasFlag(MapVisibility.MissionSelector) && world.Players.Any(a => a != world.LocalPlayer && !a.NonCombatant);
diplomacy.IsDisabled = () => disableSystemButtons;
diplomacy.OnClick = () => OpenMenuPanel(diplomacy);
}
var debug = widget.GetOrNull<MenuButtonWidget>("DEBUG_BUTTON");
if (debug != null)
{
debug.IsVisible = () => world.LobbyInfo.GlobalSettings.AllowCheats;
debug.IsDisabled = () => disableSystemButtons;
debug.OnClick = () => OpenMenuPanel(debug, new WidgetArgs()
{
{ "activePanel", IngameInfoPanel.Debug }
});
}
var stats = widget.GetOrNull<MenuButtonWidget>("OBSERVER_STATS_BUTTON");
if (stats != null)
{
stats.IsDisabled = () => disableSystemButtons;
stats.OnClick = () => OpenMenuPanel(stats);
}
}
void OpenMenuPanel(MenuButtonWidget button, WidgetArgs widgetArgs = null)
{
disableSystemButtons = true;
var cachedPause = world.PredictedPaused;
if (button.HideIngameUI)
worldRoot.IsVisible = () => false;
if (button.Pause && world.LobbyInfo.IsSinglePlayer)
world.SetPauseState(true);
widgetArgs = widgetArgs ?? new WidgetArgs();
widgetArgs.Add("onExit", () =>
{
if (button.HideIngameUI)
worldRoot.IsVisible = () => true;
if (button.Pause && world.LobbyInfo.IsSinglePlayer)
world.SetPauseState(cachedPause);
menuRoot.RemoveChild(currentWidget);
disableSystemButtons = false;
});
currentWidget = Game.LoadWidget(world, button.MenuContainer, menuRoot, widgetArgs);
}
static void BindOrderButton<T>(World world, ButtonWidget w, string icon)
where T : IOrderGenerator, new()
{
w.OnClick = () => world.ToggleInputMode<T>();
w.IsHighlighted = () => world.OrderGenerator is T;
w.Get<ImageWidget>("ICON").GetImageName =
() => world.OrderGenerator is T ? icon + "-active" : icon;
}
}
}

View File

@@ -1,33 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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 OpenRA.Support;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class PerfDebugLogic
{
[ObjectCreator.UseCtor]
public PerfDebugLogic(Widget widget)
{
var perfGraph = widget.Get("GRAPH_BG");
perfGraph.IsVisible = () => Game.Settings.Debug.PerfGraph;
var perfText = widget.Get<LabelWidget>("PERF_TEXT");
perfText.IsVisible = () => Game.Settings.Debug.PerfText;
perfText.GetText = () =>
"Tick {0} @ {1:F1} ms\nRender {2} @ {3:F1} ms\nBatches: {4}".F(
Game.LocalTick, PerfHistory.Items["tick_time"].Average(Game.Settings.Debug.Samples),
Game.RenderFrame, PerfHistory.Items["render"].Average(Game.Settings.Debug.Samples),
PerfHistory.Items["batches"].LastValue);
}
}
}

View File

@@ -1,96 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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.Collections.Generic;
using OpenRA.Network;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class ReplayControlBarLogic
{
enum PlaybackSpeed { Regular, Slow, Fast, Maximum }
readonly Dictionary<PlaybackSpeed, int> timesteps = new Dictionary<PlaybackSpeed, int>()
{
{ PlaybackSpeed.Regular, Game.Timestep },
{ PlaybackSpeed.Slow, Game.Timestep * 2 },
{ PlaybackSpeed.Fast, Game.Timestep / 2 },
{ PlaybackSpeed.Maximum, 1 },
};
[ObjectCreator.UseCtor]
public ReplayControlBarLogic(Widget widget, World world, OrderManager orderManager)
{
if (world.IsReplay)
{
var container = widget.Get("REPLAY_PLAYER");
var connection = (ReplayConnection)orderManager.Connection;
var replayNetTicks = connection.TickCount;
var background = widget.Parent.GetOrNull("OBSERVER_CONTROL_BG");
if (background != null)
background.Bounds.Height += container.Bounds.Height;
container.Visible = true;
var speed = PlaybackSpeed.Regular;
var pauseButton = widget.Get<ButtonWidget>("BUTTON_PAUSE");
pauseButton.IsVisible = () => world.Timestep != 0 && orderManager.NetFrameNumber < replayNetTicks;
pauseButton.OnClick = () => world.Timestep = 0;
var playButton = widget.Get<ButtonWidget>("BUTTON_PLAY");
playButton.IsVisible = () => world.Timestep == 0 || orderManager.NetFrameNumber >= replayNetTicks;
playButton.OnClick = () => world.Timestep = timesteps[speed];
playButton.IsDisabled = () => orderManager.NetFrameNumber >= replayNetTicks;
var slowButton = widget.Get<ButtonWidget>("BUTTON_SLOW");
slowButton.IsHighlighted = () => speed == PlaybackSpeed.Slow;
slowButton.IsDisabled = () => orderManager.NetFrameNumber >= replayNetTicks;
slowButton.OnClick = () =>
{
speed = PlaybackSpeed.Slow;
if (world.Timestep != 0)
world.Timestep = timesteps[speed];
};
var normalSpeedButton = widget.Get<ButtonWidget>("BUTTON_REGULAR");
normalSpeedButton.IsHighlighted = () => speed == PlaybackSpeed.Regular;
normalSpeedButton.IsDisabled = () => orderManager.NetFrameNumber >= replayNetTicks;
normalSpeedButton.OnClick = () =>
{
speed = PlaybackSpeed.Regular;
if (world.Timestep != 0)
world.Timestep = timesteps[speed];
};
var fastButton = widget.Get<ButtonWidget>("BUTTON_FAST");
fastButton.IsHighlighted = () => speed == PlaybackSpeed.Fast;
fastButton.IsDisabled = () => orderManager.NetFrameNumber >= replayNetTicks;
fastButton.OnClick = () =>
{
speed = PlaybackSpeed.Fast;
if (world.Timestep != 0)
world.Timestep = timesteps[speed];
};
var maximumButton = widget.Get<ButtonWidget>("BUTTON_MAXIMUM");
maximumButton.IsHighlighted = () => speed == PlaybackSpeed.Maximum;
maximumButton.IsDisabled = () => orderManager.NetFrameNumber >= replayNetTicks;
maximumButton.OnClick = () =>
{
speed = PlaybackSpeed.Maximum;
if (world.Timestep != 0)
world.Timestep = timesteps[speed];
};
}
}
}
}

View File

@@ -1,40 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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 OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class SimpleTooltipLogic
{
[ObjectCreator.UseCtor]
public SimpleTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, Func<string> getText)
{
var label = widget.Get<LabelWidget>("LABEL");
var font = Game.Renderer.Fonts[label.Font];
var cachedWidth = 0;
var labelText = "";
tooltipContainer.BeforeRender = () =>
{
labelText = getText();
var textWidth = font.Measure(labelText).X;
if (textWidth != cachedWidth)
{
label.Bounds.Width = textWidth;
widget.Bounds.Width = 2 * label.Bounds.X + textWidth;
}
};
label.GetText = () => labelText;
}
}
}

View File

@@ -1,81 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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.Linq;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class SpawnSelectorTooltipLogic
{
[ObjectCreator.UseCtor]
public SpawnSelectorTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, MapPreviewWidget preview)
{
widget.IsVisible = () => preview.TooltipSpawnIndex != -1;
var label = widget.Get<LabelWidget>("LABEL");
var flag = widget.Get<ImageWidget>("FLAG");
var team = widget.Get<LabelWidget>("TEAM");
var singleHeight = widget.Get("SINGLE_HEIGHT").Bounds.Height;
var doubleHeight = widget.Get("DOUBLE_HEIGHT").Bounds.Height;
var ownerFont = Game.Renderer.Fonts[label.Font];
var teamFont = Game.Renderer.Fonts[team.Font];
// Width specified in YAML is used as the margin between flag / label and label / border
var labelMargin = widget.Bounds.Width;
var cachedWidth = 0;
var labelText = "";
string playerCountry = null;
var playerTeam = -1;
tooltipContainer.BeforeRender = () =>
{
var occupant = preview.SpawnOccupants().Values.FirstOrDefault(c => c.SpawnPoint == preview.TooltipSpawnIndex);
var teamWidth = 0;
if (occupant == null)
{
labelText = "Available spawn";
playerCountry = null;
playerTeam = 0;
widget.Bounds.Height = singleHeight;
}
else
{
labelText = occupant.PlayerName;
playerCountry = occupant.Country;
playerTeam = occupant.Team;
widget.Bounds.Height = playerTeam > 0 ? doubleHeight : singleHeight;
teamWidth = teamFont.Measure(team.GetText()).X;
}
label.Bounds.X = playerCountry != null ? flag.Bounds.Right + labelMargin : labelMargin;
var textWidth = ownerFont.Measure(labelText).X;
if (textWidth != cachedWidth)
{
label.Bounds.Width = textWidth;
widget.Bounds.Width = 2 * label.Bounds.X + textWidth;
}
widget.Bounds.Width = Math.Max(teamWidth + 2 * labelMargin, label.Bounds.Right + labelMargin);
team.Bounds.Width = widget.Bounds.Width;
};
label.GetText = () => labelText;
flag.IsVisible = () => playerCountry != null;
flag.GetImageCollection = () => "flags";
flag.GetImageName = () => playerCountry;
team.GetText = () => "Team {0}".F(playerTeam);
team.IsVisible = () => playerTeam > 0;
}
}
}

View File

@@ -1,103 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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.Drawing;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class WorldTooltipLogic
{
[ObjectCreator.UseCtor]
public WorldTooltipLogic(Widget widget, World world, TooltipContainerWidget tooltipContainer, ViewportControllerWidget viewport)
{
widget.IsVisible = () => viewport.TooltipType != WorldTooltipType.None;
var label = widget.Get<LabelWidget>("LABEL");
var flag = widget.Get<ImageWidget>("FLAG");
var owner = widget.Get<LabelWidget>("OWNER");
var font = Game.Renderer.Fonts[label.Font];
var ownerFont = Game.Renderer.Fonts[owner.Font];
var cachedWidth = 0;
var labelText = "";
var showOwner = false;
var flagRace = "";
var ownerName = "";
var ownerColor = Color.White;
var singleHeight = widget.Get("SINGLE_HEIGHT").Bounds.Height;
var doubleHeight = widget.Get("DOUBLE_HEIGHT").Bounds.Height;
tooltipContainer.BeforeRender = () =>
{
if (viewport == null || viewport.TooltipType == WorldTooltipType.None)
return;
showOwner = false;
Player o = null;
switch (viewport.TooltipType)
{
case WorldTooltipType.Unexplored:
labelText = "Unexplored Terrain";
break;
case WorldTooltipType.Actor:
{
o = viewport.ActorTooltip.Owner;
showOwner = !o.NonCombatant && viewport.ActorTooltip.TooltipInfo.IsOwnerRowVisible;
var stance = o == null || world.RenderPlayer == null ? Stance.None : o.Stances[world.RenderPlayer];
labelText = viewport.ActorTooltip.TooltipInfo.TooltipForPlayerStance(stance);
break;
}
case WorldTooltipType.FrozenActor:
{
o = viewport.FrozenActorTooltip.TooltipOwner;
showOwner = !o.NonCombatant && viewport.FrozenActorTooltip.TooltipInfo.IsOwnerRowVisible;
var stance = o == null || world.RenderPlayer == null ? Stance.None : o.Stances[world.RenderPlayer];
labelText = viewport.FrozenActorTooltip.TooltipInfo.TooltipForPlayerStance(stance);
break;
}
}
var textWidth = font.Measure(labelText).X;
if (textWidth != cachedWidth)
{
label.Bounds.Width = textWidth;
widget.Bounds.Width = 2 * label.Bounds.X + textWidth;
}
if (showOwner)
{
flagRace = o.Country.Race;
ownerName = o.PlayerName;
ownerColor = o.Color.RGB;
widget.Bounds.Height = doubleHeight;
widget.Bounds.Width = Math.Max(widget.Bounds.Width,
owner.Bounds.X + ownerFont.Measure(ownerName).X + label.Bounds.X);
}
else
widget.Bounds.Height = singleHeight;
};
label.GetText = () => labelText;
flag.IsVisible = () => showOwner;
flag.GetImageCollection = () => "flags";
flag.GetImageName = () => flagRace;
owner.IsVisible = () => showOwner;
owner.GetText = () => ownerName;
owner.GetColor = () => ownerColor;
}
}
}

View File

@@ -1,106 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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.Graphics;
using OpenRA.Mods.Common.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets
{
public class ObserverProductionIconsWidget : Widget
{
public Func<Player> GetPlayer;
readonly World world;
readonly WorldRenderer worldRenderer;
Dictionary<ProductionQueue, Animation> clocks;
public int IconWidth = 32;
public int IconHeight = 24;
public int IconSpacing = 8;
[ObjectCreator.UseCtor]
public ObserverProductionIconsWidget(World world, WorldRenderer worldRenderer)
{
this.world = world;
this.worldRenderer = worldRenderer;
clocks = new Dictionary<ProductionQueue, Animation>();
}
protected ObserverProductionIconsWidget(ObserverProductionIconsWidget other)
: base(other)
{
GetPlayer = other.GetPlayer;
world = other.world;
worldRenderer = other.worldRenderer;
clocks = other.clocks;
}
public override void Draw()
{
var player = GetPlayer();
if (player == null)
return;
var queues = world.ActorsWithTrait<ProductionQueue>()
.Where(a => a.Actor.Owner == player)
.Select((a, i) => new { a.Trait, i });
foreach (var queue in queues)
if (!clocks.ContainsKey(queue.Trait))
clocks.Add(queue.Trait, new Animation(world, "clock"));
var iconSize = new float2(IconWidth, IconHeight);
foreach (var queue in queues)
{
var current = queue.Trait.CurrentItem();
if (current == null)
continue;
var actor = queue.Trait.AllItems().FirstOrDefault(a => a.Name == current.Item);
if (actor == null)
continue;
var icon = new Animation(world, RenderSimple.GetImage(actor));
icon.Play(actor.Traits.Get<TooltipInfo>().Icon);
var location = new float2(RenderBounds.Location) + new float2(queue.i * (IconWidth + IconSpacing), 0);
WidgetUtils.DrawSHPCentered(icon.Image, location + 0.5f * iconSize, worldRenderer, 0.5f);
var clock = clocks[queue.Trait];
clock.PlayFetchIndex("idle",
() => current.TotalTime == 0 ? 0 : ((current.TotalTime - current.RemainingTime)
* (clock.CurrentSequence.Length - 1) / current.TotalTime));
clock.Tick();
WidgetUtils.DrawSHPCentered(clock.Image, location + 0.5f * iconSize, worldRenderer, 0.5f);
var tiny = Game.Renderer.Fonts["Tiny"];
var text = GetOverlayForItem(current);
tiny.DrawTextWithContrast(text,
location + new float2(16, 16) - new float2(tiny.Measure(text).X / 2, 0),
Color.White, Color.Black, 1);
}
}
static string GetOverlayForItem(ProductionItem item)
{
if (item.Paused) return "ON HOLD";
if (item.Done) return "READY";
return WidgetUtils.FormatTime(item.RemainingTimeActual);
}
public override Widget Clone()
{
return new ObserverProductionIconsWidget(this);
}
}
}

View File

@@ -1,251 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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.Drawing;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Mods.Common.Traits;
using OpenRA.Mods.RA.Traits;
using OpenRA.Orders;
using OpenRA.Primitives;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets
{
public class WorldCommandWidget : Widget
{
readonly World world;
readonly WorldRenderer worldRenderer;
readonly RadarPings radarPings;
[ObjectCreator.UseCtor]
public WorldCommandWidget(World world, WorldRenderer worldRenderer)
{
this.world = world;
this.worldRenderer = worldRenderer;
radarPings = world.WorldActor.TraitOrDefault<RadarPings>();
}
public override string GetCursor(int2 pos) { return null; }
public override Rectangle GetEventBounds() { return Rectangle.Empty; }
public override bool HandleKeyPress(KeyInput e)
{
if (world == null || world.LocalPlayer == null)
return false;
return ProcessInput(e);
}
bool ProcessInput(KeyInput e)
{
if (e.Event == KeyInputEvent.Down)
{
var key = Hotkey.FromKeyInput(e);
var ks = Game.Settings.Keys;
if (key == ks.CycleBaseKey)
return CycleBases();
if (key == ks.CycleProductionBuildingsKey)
return CycleProductionBuildings();
if (key == ks.ToLastEventKey)
return ToLastEvent();
if (key == ks.ToSelectionKey)
return ToSelection();
// Put all functions that aren't unit-specific before this line!
if (!world.Selection.Actors.Any())
return false;
if (key == ks.AttackMoveKey)
return PerformAttackMove();
if (key == ks.StopKey)
return PerformStop();
if (key == ks.ScatterKey)
return PerformScatter();
if (key == ks.DeployKey)
return PerformDeploy();
if (key == ks.StanceCycleKey)
return PerformStanceCycle();
if (key == ks.GuardKey)
return PerformGuard();
}
return false;
}
// TODO: take ALL this garbage and route it through the OrderTargeter stuff.
bool PerformAttackMove()
{
var actors = world.Selection.Actors
.Where(a => a.Owner == world.LocalPlayer)
.ToArray();
if (actors.Any())
world.OrderGenerator = new GenericSelectTarget(actors,
"AttackMove", "attackmove", MouseButton.Right);
return true;
}
void PerformKeyboardOrderOnSelection(Func<Actor, Order> f)
{
var orders = world.Selection.Actors
.Where(a => a.Owner == world.LocalPlayer && !a.Destroyed)
.Select(f)
.ToArray();
foreach (var o in orders)
world.IssueOrder(o);
world.PlayVoiceForOrders(orders);
}
bool PerformStop()
{
PerformKeyboardOrderOnSelection(a => new Order("Stop", a, false));
return true;
}
bool PerformScatter()
{
PerformKeyboardOrderOnSelection(a => new Order("Scatter", a, false));
return true;
}
bool PerformDeploy()
{
// HACK: multiple orders here
PerformKeyboardOrderOnSelection(a => new Order("ReturnToBase", a, false));
PerformKeyboardOrderOnSelection(a => new Order("DeployTransform", a, false));
PerformKeyboardOrderOnSelection(a => new Order("Unload", a, false));
PerformKeyboardOrderOnSelection(a => new Order("Detonate", a, false));
return true;
}
bool PerformStanceCycle()
{
var actor = world.Selection.Actors
.Where(a => a.Owner == world.LocalPlayer && !a.Destroyed)
.Select(a => Pair.New(a, a.TraitOrDefault<AutoTarget>()))
.FirstOrDefault(a => a.Second != null);
if (actor.First == null)
return true;
var ati = actor.First.Info.Traits.GetOrDefault<AutoTargetInfo>();
if (ati == null || !ati.EnableStances)
return false;
var stances = Enum<UnitStance>.GetValues();
var nextStance = stances.Concat(stances)
.SkipWhile(s => s != actor.Second.PredictedStance)
.Skip(1)
.First();
PerformKeyboardOrderOnSelection(a =>
{
var at = a.TraitOrDefault<AutoTarget>();
if (at != null)
at.PredictedStance = nextStance;
return new Order("SetUnitStance", a, false) { ExtraData = (uint)nextStance };
});
Game.Debug("Unit stance set to: {0}".F(nextStance));
return true;
}
bool PerformGuard()
{
var actors = world.Selection.Actors
.Where(a => !a.Destroyed && a.Owner == world.LocalPlayer && a.HasTrait<Guard>());
if (actors.Any())
world.OrderGenerator = new GuardOrderGenerator(actors);
return true;
}
bool CycleBases()
{
var bases = world.ActorsWithTrait<BaseBuilding>()
.Where(a => a.Actor.Owner == world.LocalPlayer)
.Select(b => b.Actor)
.ToList();
if (!bases.Any())
return true;
var next = bases
.SkipWhile(b => !world.Selection.Actors.Contains(b))
.Skip(1)
.FirstOrDefault();
if (next == null)
next = bases.First();
world.Selection.Combine(world, new Actor[] { next }, false, true);
return ToSelection();
}
bool CycleProductionBuildings()
{
var facilities = world.ActorsWithTrait<Production>()
.Where(a => a.Actor.Owner == world.LocalPlayer && !a.Actor.HasTrait<BaseBuilding>())
.OrderBy(f => f.Actor.Info.Traits.Get<ProductionInfo>().Produces.First())
.Select(b => b.Actor)
.ToList();
if (!facilities.Any())
return true;
var next = facilities
.SkipWhile(b => !world.Selection.Actors.Contains(b))
.Skip(1)
.FirstOrDefault();
if (next == null)
next = facilities.First();
world.Selection.Combine(world, new Actor[] { next }, false, true);
Sound.PlayNotification(world.Map.Rules, null, "Sounds", "ClickSound", null);
return ToSelection();
}
bool ToLastEvent()
{
if (radarPings == null || radarPings.LastPingPosition == null)
return true;
worldRenderer.Viewport.Center(radarPings.LastPingPosition.Value);
return true;
}
bool ToSelection()
{
worldRenderer.Viewport.Center(world.Selection.Actors);
return true;
}
}
}