Split the last TD UI logic into reuseable chunks.

This commit is contained in:
Paul Chote
2014-07-13 12:07:07 +12:00
parent ef00411931
commit e7ae615ac9
14 changed files with 313 additions and 138 deletions

View File

@@ -77,7 +77,6 @@
<Compile Include="SpawnViceroid.cs" />
<Compile Include="TiberiumRefinery.cs" />
<Compile Include="Widgets\Logic\CncConquestObjectivesLogic.cs" />
<Compile Include="Widgets\Logic\CncIngameChromeLogic.cs" />
<Compile Include="Widgets\Logic\CncIngameMenuLogic.cs" />
<Compile Include="Widgets\Logic\CncMainMenuLogic.cs" />
<Compile Include="Widgets\Logic\SupportPowerTooltipLogic.cs" />

View File

@@ -1,133 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System.Drawing;
using System.Linq;
using OpenRA.Mods.RA;
using OpenRA.Mods.RA.Buildings;
using OpenRA.Mods.RA.Widgets;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.Cnc.Widgets.Logic
{
public class CncIngameChromeLogic
{
readonly Widget ingameRoot;
readonly World world;
[ObjectCreator.UseCtor]
public CncIngameChromeLogic(Widget widget, World world)
{
this.world = world;
ingameRoot = widget.Get("INGAME_ROOT");
var playerRoot = ingameRoot.Get("PLAYER_ROOT");
// Observer
if (world.LocalPlayer == null)
InitObserverWidgets(world, playerRoot);
else
InitPlayerWidgets(world, playerRoot);
Game.LoadWidget(world, "CHAT_PANEL", ingameRoot, new WidgetArgs());
}
public void OptionsClicked()
{
var cachedPause = world.PredictedPaused;
ingameRoot.IsVisible = () => false;
if (world.LobbyInfo.IsSinglePlayer)
world.SetPauseState(true);
Game.LoadWidget(world, "INGAME_MENU", Ui.Root, new WidgetArgs()
{
{ "onExit", () =>
{
ingameRoot.IsVisible = () => true;
if (world.LobbyInfo.IsSinglePlayer)
world.SetPauseState(cachedPause);
}
}
});
}
public void InitObserverWidgets(World world, Widget playerRoot)
{
var observerWidgets = Game.LoadWidget(world, "OBSERVER_WIDGETS", playerRoot, new WidgetArgs());
observerWidgets.Get<ButtonWidget>("OPTIONS_BUTTON").OnClick = OptionsClicked;
}
public void InitPlayerWidgets(World world, Widget playerRoot)
{
// Real player
var playerWidgets = Game.LoadWidget(world, "PLAYER_WIDGETS", playerRoot, new WidgetArgs());
playerWidgets.IsVisible = () => true;
var sidebarRoot = playerWidgets.Get("SIDEBAR_BACKGROUND");
var powerManager = world.LocalPlayer.PlayerActor.Trait<PowerManager>();
var playerResources = world.LocalPlayer.PlayerActor.Trait<PlayerResources>();
sidebarRoot.Get<LabelWidget>("CASH").GetText = () =>
"${0}".F(playerResources.DisplayCash + playerResources.DisplayResources);
playerWidgets.Get<ButtonWidget>("OPTIONS_BUTTON").OnClick = OptionsClicked;
var radarEnabled = false;
var cachedRadarEnabled = false;
sidebarRoot.Get<RadarWidget>("RADAR_MINIMAP").IsEnabled = () => radarEnabled;
var sidebarTicker = playerWidgets.Get<LogicTickerWidget>("SIDEBAR_TICKER");
sidebarTicker.OnTick = () =>
{
// Update radar bin
radarEnabled = world.ActorsWithTrait<ProvidesRadar>()
.Any(a => a.Actor.Owner == world.LocalPlayer && a.Trait.IsActive);
if (radarEnabled != cachedRadarEnabled)
Sound.PlayNotification(world.Map.Rules, null, "Sounds", radarEnabled ? "RadarUp" : "RadarDown", null);
cachedRadarEnabled = radarEnabled;
// Switch to observer mode after win/loss
if (world.LocalPlayer.WinState != WinState.Undefined)
Game.RunAfterTick(() =>
{
playerRoot.RemoveChildren();
InitObserverWidgets(world, playerRoot);
});
};
var siloBar = playerWidgets.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;
};
var powerBar = playerWidgets.Get<ResourceBarWidget>("POWERBAR");
powerBar.GetProvided = () => powerManager.PowerProvided;
powerBar.GetUsed = () => powerManager.PowerDrained;
powerBar.TooltipFormat = "Power Usage: {0}/{1}";
powerBar.GetBarColor = () =>
{
if (powerManager.PowerState == PowerState.Critical)
return Color.Red;
if (powerManager.PowerState == PowerState.Low)
return Color.Orange;
return Color.LimeGreen;
};
}
}
}

View File

@@ -535,6 +535,13 @@
<Compile Include="Widgets\ProductionTabsWidget.cs" />
<Compile Include="Widgets\ProductionTypeButtonWidget.cs" />
<Compile Include="Widgets\Logic\ProductionTooltipLogic.cs" />
<Compile Include="Widgets\Logic\Ingame\IngameRadarDisplayLogic.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\LoadIngamePlayerOrObserverUILogic.cs" />
<Compile Include="Widgets\MenuButtonWidget.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\OpenRA.Game\OpenRA.Game.csproj">
@@ -579,4 +586,7 @@ cd "$(SolutionDir)thirdparty/"
copy "FuzzyLogicLibrary.dll" "$(SolutionDir)"
cd "$(SolutionDir)"</PostBuildEvent>
</PropertyGroup>
<ItemGroup>
<Folder Include="Widgets\Logic\Ingame\" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,28 @@
#region Copyright & License Information
/*
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.Cnc.Widgets.Logic
{
public class IngameCashCounterLogic
{
[ObjectCreator.UseCtor]
public IngameCashCounterLogic(Widget widget, World world)
{
var playerResources = world.LocalPlayer.PlayerActor.Trait<PlayerResources>();
var cash = widget.Get<LabelWidget>("CASH");
var label = cash.Text;
cash.GetText = () => label.F(playerResources.DisplayCash + playerResources.DisplayResources);
}
}
}

View File

@@ -0,0 +1,38 @@
#region Copyright & License Information
/*
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System.Drawing;
using OpenRA.Mods.RA.Buildings;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class IngamePowerBarLogic
{
[ObjectCreator.UseCtor]
public IngamePowerBarLogic(Widget widget, World world)
{
var powerManager = world.LocalPlayer.PlayerActor.Trait<PowerManager>();
var powerBar = widget.Get<ResourceBarWidget>("POWERBAR");
powerBar.GetProvided = () => powerManager.PowerProvided;
powerBar.GetUsed = () => powerManager.PowerDrained;
powerBar.TooltipFormat = "Power Usage: {0}/{1}";
powerBar.GetBarColor = () =>
{
if (powerManager.PowerState == PowerState.Critical)
return Color.Red;
if (powerManager.PowerState == PowerState.Low)
return Color.Orange;
return Color.LimeGreen;
};
}
}
}

View File

@@ -0,0 +1,27 @@
#region Copyright & License Information
/*
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using OpenRA.Mods.RA.Buildings;
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<LabelWidget>("POWER");
power.GetText = () => powerManager.PowerProvided == 1000000 ? "inf" : powerManager.ExcessPower.ToString();
}
}
}

View File

@@ -0,0 +1,38 @@
#region Copyright & License Information
/*
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System.Linq;
using OpenRA.Mods.RA.Widgets;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class IngameRadarDisplayLogic
{
[ObjectCreator.UseCtor]
public IngameRadarDisplayLogic(Widget widget, World world)
{
var radarEnabled = false;
var cachedRadarEnabled = false;
widget.Get<RadarWidget>("RADAR_MINIMAP").IsEnabled = () => radarEnabled;
var ticker = widget.Get<LogicTickerWidget>("RADAR_TICKER");
ticker.OnTick = () =>
{
radarEnabled = world.ActorsWithTrait<ProvidesRadar>()
.Any(a => a.Actor.Owner == world.LocalPlayer && a.Trait.IsActive);
if (radarEnabled != cachedRadarEnabled)
Sound.PlayNotification(world.Map.Rules, null, "Sounds", radarEnabled ? "RadarUp" : "RadarDown", null);
cachedRadarEnabled = radarEnabled;
};
}
}
}

View File

@@ -0,0 +1,40 @@
#region Copyright & License Information
/*
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System.Drawing;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class IngameSiloBarLogic
{
[ObjectCreator.UseCtor]
public IngameSiloBarLogic(Widget widget, World world)
{
var playerResources = world.LocalPlayer.PlayerActor.Trait<PlayerResources>();
var siloBar = widget.Get<ResourceBarWidget>("SILOBAR");
siloBar.GetProvided = () => playerResources.ResourceCapacity;
siloBar.GetUsed = () => playerResources.Resources;
siloBar.TooltipFormat = "Silo Usage: {0}/{1}";
siloBar.GetBarColor = () =>
{
if (playerResources.Resources == playerResources.ResourceCapacity)
return Color.Red;
if (playerResources.Resources >= 0.8 * playerResources.ResourceCapacity)
return Color.Orange;
return Color.LimeGreen;
};
}
}
}

View File

@@ -0,0 +1,31 @@
#region Copyright & License Information
/*
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class LoadIngamePlayerOrObserverUILogic
{
[ObjectCreator.UseCtor]
public LoadIngamePlayerOrObserverUILogic(Widget widget, World world)
{
var ingameRoot = widget.Get("INGAME_ROOT");
var playerRoot = ingameRoot.Get("PLAYER_ROOT");
if (world.LocalPlayer == null)
Game.LoadWidget(world, "OBSERVER_WIDGETS", playerRoot, new WidgetArgs());
else
Game.LoadWidget(world, "PLAYER_WIDGETS", playerRoot, new WidgetArgs());
Game.LoadWidget(world, "CHAT_PANEL", ingameRoot, new WidgetArgs());
}
}
}

View File

@@ -42,6 +42,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
Widget optionsBG = null;
optionsBG = Game.LoadWidget(world, "INGAME_OPTIONS_BG", Ui.Root, new WidgetArgs
{
{ "transient", false },
{ "onExit", () =>
{
optionsBG.Visible = false;
@@ -52,6 +53,8 @@ namespace OpenRA.Mods.RA.Widgets.Logic
}
});
optionsBG.Visible = false;
gameRoot.Get<ButtonWidget>("INGAME_OPTIONS_BUTTON").OnClick = () =>
{
optionsBG.Visible ^= true;

View File

@@ -17,7 +17,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
class IngameMenuLogic
{
[ObjectCreator.UseCtor]
public IngameMenuLogic(Widget widget, World world, Action onExit, WorldRenderer worldRenderer)
public IngameMenuLogic(Widget widget, World world, Action onExit, WorldRenderer worldRenderer, bool transient)
{
var resumeDisabled = false;
var mpe = world.WorldActor.TraitOrDefault<MenuPaletteEffect>();
@@ -71,8 +71,17 @@ namespace OpenRA.Mods.RA.Widgets.Logic
};
var resumeButton = widget.Get<ButtonWidget>("RESUME");
resumeButton.OnClick = () => onExit();
resumeButton.IsDisabled = () => resumeDisabled;
resumeButton.OnClick = () =>
{
if (transient)
{
Ui.CloseWindow();
Ui.Root.RemoveChild(widget);
}
onExit();
};
widget.Get<ButtonWidget>("SURRENDER").OnClick = () =>
{

View File

@@ -15,9 +15,17 @@ namespace OpenRA.Mods.RA.Widgets.Logic
{
public class OrderButtonsChromeLogic
{
readonly World world;
readonly Widget ingameRoot;
bool disableSystemButtons;
[ObjectCreator.UseCtor]
public OrderButtonsChromeLogic(Widget widget, World world)
{
this.world = world;
ingameRoot = Ui.Root.Get("INGAME_ROOT");
// Order Buttons
var sell = widget.GetOrNull<ButtonWidget>("SELL_BUTTON");
if (sell != null)
{
@@ -45,6 +53,43 @@ namespace OpenRA.Mods.RA.Widgets.Logic
power.GetKey = _ => Game.Settings.Keys.PowerDownKey;
BindOrderButton<PowerDownOrderGenerator>(world, power, "power");
}
// System buttons
var options = widget.GetOrNull<MenuButtonWidget>("OPTIONS_BUTTON");
if (options != null)
{
options.IsDisabled = () => disableSystemButtons;
options.OnClick = () => OpenMenuPanel(options);
}
}
void OpenMenuPanel(MenuButtonWidget button)
{
disableSystemButtons = true;
var cachedPause = world.PredictedPaused;
if (button.HideIngameUI)
ingameRoot.IsVisible = () => false;
if (button.Pause && world.LobbyInfo.IsSinglePlayer)
world.SetPauseState(true);
Game.LoadWidget(world, button.MenuContainer, Ui.Root, new WidgetArgs()
{
{ "transient", true },
{ "onExit", () =>
{
if (button.HideIngameUI)
ingameRoot.IsVisible = () => true;
if (button.Pause && world.LobbyInfo.IsSinglePlayer)
world.SetPauseState(cachedPause);
disableSystemButtons = false;
}
}
});
}
static void BindOrderButton<T>(World world, ButtonWidget w, string icon)

View File

@@ -0,0 +1,33 @@
#region Copyright & License Information
/*
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets
{
public class MenuButtonWidget : ButtonWidget
{
public readonly string MenuContainer = "INGAME_MENU";
public readonly bool Pause = true;
public readonly bool HideIngameUI = true;
[ObjectCreator.UseCtor]
public MenuButtonWidget(Ruleset modRules)
: base(modRules) { }
protected MenuButtonWidget(MenuButtonWidget other)
: base(other)
{
MenuContainer = other.MenuContainer;
Pause = other.Pause;
HideIngameUI = other.HideIngameUI;
}
}
}

View File

@@ -1,5 +1,5 @@
Container@INGAME_ROOT:
Logic: CncIngameChromeLogic
Logic: LoadIngamePlayerOrObserverUILogic
Children:
LogicTicker@DISCONNECT_WATCHER:
Logic: DisconnectWatcherLogic
@@ -196,7 +196,7 @@ Container@PLAYER_WIDGETS:
Height: 240
Background: panel-black
Children:
Button@OPTIONS_BUTTON:
MenuButton@OPTIONS_BUTTON:
Key: escape
X: 22
Y: 0-24
@@ -258,12 +258,16 @@ Container@PLAYER_WIDGETS:
Background: panel-gray
Children:
Radar@RADAR_MINIMAP:
Logic: IngameRadarDisplayLogic
X: 1
Y: 1
Width: PARENT_RIGHT-2
Height: PARENT_BOTTOM-2
WorldInteractionController: INTERACTION_CONTROLLER
Children:
LogicTicker@RADAR_TICKER:
Background@POWERBAR_PANEL:
Logic: IngamePowerBarLogic
X: 4
Y: 5
Width: 10
@@ -279,6 +283,7 @@ Container@PLAYER_WIDGETS:
TooltipTemplate: SIMPLE_TOOLTIP
IndicatorImage: indicator-left
Background@SILOBAR_PANEL:
Logic: IngameSiloBarLogic
X: 180
Y: 5
Width: 10
@@ -294,11 +299,13 @@ Container@PLAYER_WIDGETS:
TooltipTemplate: SIMPLE_TOOLTIP
IndicatorImage: indicator-right
Label@CASH:
Logic: IngameCashCounterLogic
Y: 170
Width: PARENT_RIGHT
Height: 25
Align: Center
Font: Bold
Text: ${0}
Container@PRODUCTION_TYPES:
X: 12
Y: 197