Start moving towards saner RA widget logic. This switches players to observer mode after they have finished playing in RA/D2k and removes some legacy code.

This commit is contained in:
Scott_NZ
2013-04-21 18:34:48 +12:00
parent 7ec4bcad0e
commit ca80ac2d1f
35 changed files with 951 additions and 1290 deletions

View File

@@ -10,40 +10,9 @@
using OpenRA.Traits;
using OpenRA.Widgets;
using System.Collections.Generic;
namespace OpenRA.Mods.RA
{
// Legacy crap
public class OpenWidgetAtGameStartInfo : ITraitInfo
{
public readonly string Widget = "INGAME_ROOT";
public readonly string ObserverWidget = null;
public object Create(ActorInitializer init) { return new OpenWidgetAtGameStart(this); }
}
public class OpenWidgetAtGameStart: IWorldLoaded
{
readonly OpenWidgetAtGameStartInfo Info;
public OpenWidgetAtGameStart(OpenWidgetAtGameStartInfo Info)
{
this.Info = Info;
}
public void WorldLoaded(World world)
{
// Remove all open widgets
Ui.ResetAll();
if (world.LocalPlayer != null)
Game.OpenWindow(world, Info.Widget);
else if (Info.ObserverWidget != null)
Game.OpenWindow(world, Info.ObserverWidget);
}
}
// New version
public class LoadWidgetAtGameStartInfo : ITraitInfo
{
public readonly string Widget = null;

View File

@@ -267,7 +267,7 @@
<Compile Include="Move\PathSearch.cs" />
<Compile Include="NukePaletteEffect.cs" />
<Compile Include="NullLoadScreen.cs" />
<Compile Include="OpenWidgetAtGameStart.cs" />
<Compile Include="LoadWidgetAtGameStart.cs" />
<Compile Include="Orders\DeployOrderTargeter.cs" />
<Compile Include="Orders\EnterBuildingOrderTargeter.cs" />
<Compile Include="Orders\PlaceBuildingOrderGenerator.cs" />
@@ -370,6 +370,8 @@
<Compile Include="Valued.cs" />
<Compile Include="WaterPaletteRotation.cs" />
<Compile Include="Widgets\BuildPaletteWidget.cs" />
<Compile Include="Widgets\LogicTickerWidget.cs" />
<Compile Include="Widgets\Logic\IngameMenuLogic.cs" />
<Compile Include="Widgets\Logic\ModBrowserLogic.cs" />
<Compile Include="Widgets\Logic\ColorPickerLogic.cs" />
<Compile Include="Widgets\Logic\ConnectionLogic.cs" />
@@ -378,7 +380,6 @@
<Compile Include="Widgets\Logic\DownloadPackagesLogic.cs" />
<Compile Include="Widgets\Logic\IngameChatLogic.cs" />
<Compile Include="Widgets\Logic\IngameChromeLogic.cs" />
<Compile Include="Widgets\Logic\IngameObserverChromeLogic.cs" />
<Compile Include="Widgets\Logic\LobbyLogic.cs" />
<Compile Include="Widgets\Logic\LobbyUtils.cs" />
<Compile Include="Widgets\Logic\MainMenuButtonsLogic.cs" />

View File

@@ -87,11 +87,7 @@ namespace OpenRA.Mods.RA
Ui.OpenWindow(Info["InstallerMenuWidget"], args);
}
else
{
Game.LoadShellMap();
Ui.ResetAll();
Ui.OpenWindow("MAINMENU_BG");
}
}
}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2013 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,
@@ -19,99 +19,92 @@ namespace OpenRA.Mods.RA.Widgets.Logic
public class IngameChromeLogic
{
Widget gameRoot;
Widget playerRoot;
World world;
[ObjectCreator.UseCtor]
public IngameChromeLogic(World world)
{
var r = Ui.Root;
gameRoot = r.Get("INGAME_ROOT");
var optionsBG = gameRoot.Get("INGAME_OPTIONS_BG");
this.world = world;
gameRoot = Ui.Root.Get("INGAME_ROOT");
playerRoot = gameRoot.Get("PLAYER_ROOT");
// TODO: RA's broken UI wiring makes it unreasonably difficult to
// cache and restore the previous pause state, so opening/closing
// the menu in a paused singleplayer game will un-pause the game.
r.Get<ButtonWidget>("INGAME_OPTIONS_BUTTON").OnClick = () =>
InitRootWidgets();
if (world.LocalPlayer == null)
InitObserverWidgets();
else
InitPlayerWidgets();
}
void InitRootWidgets()
{
Widget optionsBG = null;
optionsBG = Game.LoadWidget(world, "INGAME_OPTIONS_BG", Ui.Root, new WidgetArgs
{
optionsBG.Visible = !optionsBG.Visible;
{ "onExit", () =>
{
if (world.LobbyInfo.IsSinglePlayer)
world.IssueOrder(Order.PauseGame(false));
optionsBG.Visible = false;
}
}
});
gameRoot.Get<ButtonWidget>("INGAME_OPTIONS_BUTTON").OnClick = () =>
{
optionsBG.Visible ^= true;
if (world.LobbyInfo.IsSinglePlayer)
world.IssueOrder(Order.PauseGame(true));
world.IssueOrder(Order.PauseGame(optionsBG.Visible));
};
var cheatsButton = gameRoot.Get<ButtonWidget>("CHEATS_BUTTON");
cheatsButton.OnClick = () =>
Game.LoadWidget(world, "CHAT_PANEL", gameRoot, new WidgetArgs());
}
void InitObserverWidgets()
{
var observerWidgets = Game.LoadWidget(world, "OBSERVER_WIDGETS", playerRoot, new WidgetArgs());
Game.LoadWidget(world, "OBSERVER_STATS", observerWidgets, new WidgetArgs());
observerWidgets.Get<ButtonWidget>("INGAME_STATS_BUTTON").OnClick = () => gameRoot.Get("OBSERVER_STATS").Visible ^= true;
}
void InitPlayerWidgets()
{
var playerWidgets = Game.LoadWidget(world, "PLAYER_WIDGETS", playerRoot, new WidgetArgs());
Widget cheats = null;
cheats = Game.LoadWidget(world, "CHEATS_PANEL", playerWidgets, new WidgetArgs
{
Game.OpenWindow("CHEATS_PANEL", new WidgetArgs() {{"onExit", () => {} }});
};
cheatsButton.IsVisible = () => world.LocalPlayer != null && world.LobbyInfo.GlobalSettings.AllowCheats;
{ "onExit", () => cheats.Visible = false }
});
var cheatsButton = playerWidgets.Get<ButtonWidget>("CHEATS_BUTTON");
cheatsButton.OnClick = () => cheats.Visible ^= true;
cheatsButton.IsVisible = () => world.LobbyInfo.GlobalSettings.AllowCheats;
var iop = world.WorldActor.TraitsImplementing<IObjectivesPanel>().FirstOrDefault();
if (iop != null && iop.ObjectivesPanel != null)
{
var objectivesButton = gameRoot.Get<ButtonWidget>("OBJECTIVES_BUTTON");
var objectivesWidget = Game.LoadWidget(world, iop.ObjectivesPanel, Ui.Root, new WidgetArgs());
objectivesWidget.Visible = false;
objectivesButton.OnClick += () => objectivesWidget.Visible = !objectivesWidget.Visible;
objectivesButton.IsVisible = () => world.LocalPlayer != null;
var objectivesButton = playerWidgets.Get<ButtonWidget>("OBJECTIVES_BUTTON");
var objectivesWidget = Game.LoadWidget(world, iop.ObjectivesPanel, playerWidgets, new WidgetArgs());
objectivesButton.Visible = true;
objectivesButton.OnClick += () => objectivesWidget.Visible ^= true;
}
var moneybin = gameRoot.Get("INGAME_MONEY_BIN");
moneybin.Get<OrderButtonWidget>("SELL").GetKey = _ => Game.Settings.Keys.SellKey;
moneybin.Get<OrderButtonWidget>("POWER_DOWN").GetKey = _ => Game.Settings.Keys.PowerDownKey;
moneybin.Get<OrderButtonWidget>("REPAIR").GetKey = _ => Game.Settings.Keys.RepairKey;
var moneyBin = playerWidgets.Get("INGAME_MONEY_BIN");
moneyBin.Get<OrderButtonWidget>("SELL").GetKey = _ => Game.Settings.Keys.SellKey;
moneyBin.Get<OrderButtonWidget>("POWER_DOWN").GetKey = _ => Game.Settings.Keys.PowerDownKey;
moneyBin.Get<OrderButtonWidget>("REPAIR").GetKey = _ => Game.Settings.Keys.RepairKey;
var chatPanel = Game.LoadWidget(world, "CHAT_PANEL", Ui.Root, new WidgetArgs());
gameRoot.AddChild(chatPanel);
optionsBG.Get<ButtonWidget>("DISCONNECT").OnClick = () => LeaveGame(optionsBG, world);
optionsBG.Get<ButtonWidget>("SETTINGS").OnClick = () => Ui.OpenWindow("SETTINGS_MENU");
optionsBG.Get<ButtonWidget>("MUSIC").OnClick = () => Ui.OpenWindow("MUSIC_MENU");
optionsBG.Get<ButtonWidget>("RESUME").OnClick = () =>
var winLossWatcher = playerWidgets.Get<LogicTickerWidget>("WIN_LOSS_WATCHER");
winLossWatcher.OnTick = () =>
{
optionsBG.Visible = false;
if (world.LobbyInfo.IsSinglePlayer)
world.IssueOrder(Order.PauseGame(false));
if (world.LocalPlayer.WinState != WinState.Undefined)
Game.RunAfterTick(() =>
{
playerRoot.RemoveChildren();
InitObserverWidgets();
});
};
optionsBG.Get<ButtonWidget>("SURRENDER").OnClick = () =>
{
optionsBG.Visible = false;
world.IssueOrder(new Order("Surrender", world.LocalPlayer.PlayerActor, false));
};
optionsBG.Get("SURRENDER").IsVisible = () => (world.LocalPlayer != null && world.LocalPlayer.WinState == WinState.Undefined);
var postgameBG = gameRoot.Get("POSTGAME_BG");
var postgameText = postgameBG.Get<LabelWidget>("TEXT");
var postGameObserve = postgameBG.Get<ButtonWidget>("POSTGAME_OBSERVE");
var postgameQuit = postgameBG.Get<ButtonWidget>("POSTGAME_QUIT");
postgameQuit.OnClick = () => LeaveGame(postgameQuit, world);
postGameObserve.OnClick = () => postgameQuit.Visible = false;
postGameObserve.IsVisible = () => world.LocalPlayer.WinState != WinState.Won;
postgameBG.IsVisible = () =>
{
return postgameQuit.Visible && world.LocalPlayer != null && world.LocalPlayer.WinState != WinState.Undefined;
};
postgameText.GetText = () =>
{
var state = world.LocalPlayer.WinState;
return state == WinState.Undefined ? "" :
(state == WinState.Lost ? "YOU ARE DEFEATED" : "YOU ARE VICTORIOUS");
};
}
void LeaveGame(Widget pane, World world)
{
Sound.PlayNotification(null, "Speech", "Leave", world.LocalPlayer.Country.Race);
pane.Visible = false;
Game.Disconnect();
Game.LoadShellMap();
Ui.CloseWindow();
Ui.OpenWindow("MAINMENU_BG");
}
}
}

View File

@@ -0,0 +1,46 @@
#region Copyright & License Information
/*
* Copyright 2007-2013 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
{
class IngameMenuLogic
{
[ObjectCreator.UseCtor]
public IngameMenuLogic(Widget widget, World world, Action onExit)
{
widget.Get<ButtonWidget>("DISCONNECT").OnClick = () =>
{
onExit();
LeaveGame(widget, world, onExit);
};
widget.Get<ButtonWidget>("SETTINGS").OnClick = () => Ui.OpenWindow("SETTINGS_MENU");
widget.Get<ButtonWidget>("MUSIC").OnClick = () => Ui.OpenWindow("MUSIC_MENU");
widget.Get<ButtonWidget>("RESUME").OnClick = () => onExit();
widget.Get<ButtonWidget>("SURRENDER").OnClick = () =>
{
world.IssueOrder(new Order("Surrender", world.LocalPlayer.PlayerActor, false));
onExit();
};
widget.Get("SURRENDER").IsVisible = () => world.LocalPlayer != null && world.LocalPlayer.WinState == WinState.Undefined;
}
void LeaveGame(Widget widget, World world, Action onExit)
{
Sound.PlayNotification(null, "Speech", "Leave", world.LocalPlayer.Country.Race);
Game.Disconnect();
Ui.CloseWindow();
Game.LoadShellMap();
}
}
}

View File

@@ -1,67 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 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;
using OpenRA.Network;
using System;
using System.Drawing;
using System.Linq;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class IngameObserverChromeLogic
{
Widget gameRoot;
// WTF duplication
[ObjectCreator.UseCtor]
public IngameObserverChromeLogic(World world)
{
var r = Ui.Root;
gameRoot = r.Get("OBSERVER_ROOT");
var optionsBG = gameRoot.Get("INGAME_OPTIONS_BG");
r.Get<ButtonWidget>("INGAME_OPTIONS_BUTTON").OnClick = () =>
{
optionsBG.Visible = !optionsBG.Visible;
if (world.LobbyInfo.IsSinglePlayer)
world.IssueOrder(Order.PauseGame(true));
};
optionsBG.Get<ButtonWidget>("DISCONNECT").OnClick = () =>
{
optionsBG.Visible = false;
Game.Disconnect();
Game.LoadShellMap();
Ui.CloseWindow();
Ui.OpenWindow("MAINMENU_BG");
};
optionsBG.Get<ButtonWidget>("SETTINGS").OnClick = () => Ui.OpenWindow("SETTINGS_MENU");
optionsBG.Get<ButtonWidget>("MUSIC").OnClick = () => Ui.OpenWindow("MUSIC_MENU");
optionsBG.Get<ButtonWidget>("RESUME").OnClick = () =>
{
optionsBG.Visible = false;
if (world.LobbyInfo.IsSinglePlayer)
world.IssueOrder(Order.PauseGame(false));
};
optionsBG.Get<ButtonWidget>("SURRENDER").IsVisible = () => false;
Ui.Root.Get<ButtonWidget>("INGAME_STATS_BUTTON").OnClick = () => gameRoot.Get("OBSERVER_STATS").Visible ^= true;
if (!world.IsShellmap)
{
var chatPanel = Game.LoadWidget(world, "CHAT_PANEL", Ui.Root, new WidgetArgs());
gameRoot.AddChild(chatPanel);
}
}
}
}

View File

@@ -0,0 +1,21 @@
#region Copyright & License Information
/*
* Copyright 2007-2013 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
{
public class LogicTickerWidget : Widget
{
public Action OnTick = () => { };
public override void Tick() { OnTick(); }
}
}