Merge pull request #7564 from Mailaender/common-widgets
Moved the whole widget code to OpenRA.Mods.Common
This commit is contained in:
@@ -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" />
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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(); };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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() : "");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 },
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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];
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user