diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs
index a536661221..e96b7ed0f2 100755
--- a/OpenRA.Game/Game.cs
+++ b/OpenRA.Game/Game.cs
@@ -344,9 +344,10 @@ namespace OpenRA
{
if (orderManager.world != null)
orderManager.world.traitDict.PrintReport();
+
+ orderManager.Dispose();
CloseServer();
JoinLocal();
- orderManager.Dispose();
}
public static void CloseServer()
diff --git a/OpenRA.Game/Network/Connection.cs b/OpenRA.Game/Network/Connection.cs
index 19718c9e3c..79037791e6 100755
--- a/OpenRA.Game/Network/Connection.cs
+++ b/OpenRA.Game/Network/Connection.cs
@@ -202,7 +202,10 @@ namespace OpenRA.Network
if (socket != null)
socket.Client.Close();
using( new PerfSample( "Thread.Join" ))
- t.Join();
+ {
+ if (!t.Join(1000))
+ return;
+ }
}
~NetworkConnection() { Dispose(); }
diff --git a/OpenRA.Game/Network/ReplayConnection.cs b/OpenRA.Game/Network/ReplayConnection.cs
index efae2bf61b..0942165219 100755
--- a/OpenRA.Game/Network/ReplayConnection.cs
+++ b/OpenRA.Game/Network/ReplayConnection.cs
@@ -109,6 +109,7 @@ namespace OpenRA.Network
return;
writer.Close();
+ inner.Dispose();
disposed = true;
}
diff --git a/OpenRA.Game/Widgets/ScrollItemWidget.cs b/OpenRA.Game/Widgets/ScrollItemWidget.cs
index 6860bc770e..51a4d3dacf 100644
--- a/OpenRA.Game/Widgets/ScrollItemWidget.cs
+++ b/OpenRA.Game/Widgets/ScrollItemWidget.cs
@@ -9,8 +9,6 @@
#endregion
using System;
-using System.Drawing;
-using OpenRA.Graphics;
namespace OpenRA.Widgets
{
diff --git a/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj b/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj
index 2bdb93e10a..4425d1d80e 100644
--- a/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj
+++ b/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj
@@ -1,4 +1,4 @@
-
+
Debug
@@ -75,20 +75,14 @@
-
-
-
-
-
-
@@ -103,7 +97,6 @@
-
diff --git a/OpenRA.Mods.Cnc/Widgets/Logic/CncCheatsLogic.cs b/OpenRA.Mods.Cnc/Widgets/Logic/CncCheatsLogic.cs
index 456acc4f7a..1ace3f9c35 100644
--- a/OpenRA.Mods.Cnc/Widgets/Logic/CncCheatsLogic.cs
+++ b/OpenRA.Mods.Cnc/Widgets/Logic/CncCheatsLogic.cs
@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
- * Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
- * This file is part of OpenRA.
- *
- * OpenRA is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * OpenRA is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with OpenRA. If not, see .
+ * 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
diff --git a/OpenRA.Mods.Cnc/Widgets/Logic/CncDirectConnectLogic.cs b/OpenRA.Mods.Cnc/Widgets/Logic/CncDirectConnectLogic.cs
deleted file mode 100644
index 99f6e09099..0000000000
--- a/OpenRA.Mods.Cnc/Widgets/Logic/CncDirectConnectLogic.cs
+++ /dev/null
@@ -1,43 +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 System;
-using OpenRA.Widgets;
-
-namespace OpenRA.Mods.Cnc.Widgets.Logic
-{
- public class CncDirectConnectLogic
- {
- [ObjectCreator.UseCtor]
- public CncDirectConnectLogic(Widget widget, Action onExit, Action openLobby)
- {
- var panel = widget.GetWidget("DIRECTCONNECT_PANEL");
- var ipField = panel.GetWidget("IP");
- var portField = panel.GetWidget("PORT");
-
- var last = Game.Settings.Player.LastServer.Split(':');
- ipField.Text = last.Length > 1 ? last[0] : "localhost";
- portField.Text = last.Length > 2 ? last[1] : "1234";
-
- panel.GetWidget("JOIN_BUTTON").OnClick = () =>
- {
- var port = Exts.WithDefault(1234, () => int.Parse(portField.Text));
-
- Game.Settings.Player.LastServer = "{0}:{1}".F(ipField.Text, port);
- Game.Settings.Save();
-
- Widget.CloseWindow();
- CncConnectionLogic.Connect(ipField.Text, port, openLobby, onExit);
- };
-
- panel.GetWidget("BACK_BUTTON").OnClick = () => { Widget.CloseWindow(); onExit(); };
- }
- }
-}
diff --git a/OpenRA.Mods.Cnc/Widgets/Logic/CncInstallFromCDLogic.cs b/OpenRA.Mods.Cnc/Widgets/Logic/CncInstallFromCDLogic.cs
index ca65ee42d2..dfe8533ac9 100644
--- a/OpenRA.Mods.Cnc/Widgets/Logic/CncInstallFromCDLogic.cs
+++ b/OpenRA.Mods.Cnc/Widgets/Logic/CncInstallFromCDLogic.cs
@@ -102,7 +102,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
retryButton.IsDisabled = () => false;
}));
- var t = new Thread( _ =>
+ new Thread( _ =>
{
try
{
@@ -122,8 +122,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
{
onError("Installation failed");
}
- }) { IsBackground = true };
- t.Start();
+ }) { IsBackground = true }.Start();
}
}
}
diff --git a/OpenRA.Mods.Cnc/Widgets/Logic/CncLobbyLogic.cs b/OpenRA.Mods.Cnc/Widgets/Logic/CncLobbyLogic.cs
deleted file mode 100644
index 3928706cf5..0000000000
--- a/OpenRA.Mods.Cnc/Widgets/Logic/CncLobbyLogic.cs
+++ /dev/null
@@ -1,446 +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 System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Linq;
-using OpenRA.Mods.RA;
-using OpenRA.Mods.RA.Widgets.Logic;
-using OpenRA.Network;
-using OpenRA.Traits;
-using OpenRA.Widgets;
-
-namespace OpenRA.Mods.Cnc.Widgets.Logic
-{
- public class CncLobbyLogic
- {
- Widget EditablePlayerTemplate, NonEditablePlayerTemplate, EmptySlotTemplate,
- EditableSpectatorTemplate, NonEditableSpectatorTemplate, NewSpectatorTemplate;
- ScrollPanelWidget chatPanel;
- Widget chatTemplate;
-
- ScrollPanelWidget Players;
- Dictionary CountryNames;
- string MapUid;
- Map Map;
-
- ColorPickerPaletteModifier PlayerPalettePreview;
-
- readonly Action OnGameStart;
- readonly Action onExit;
- readonly OrderManager orderManager;
-
- // Listen for connection failures
- void ConnectionStateChanged(OrderManager om)
- {
- if (om.Connection.ConnectionState == ConnectionState.NotConnected)
- {
- // Show connection failed dialog
- CloseWindow();
-
- Action onConnect = () =>
- {
- Game.OpenWindow("SERVER_LOBBY", new WidgetArgs()
- {
- { "onExit", onExit },
- { "onStart", OnGameStart },
- { "addBots", false }
- });
- };
-
- Action onRetry = () =>
- {
- CloseWindow();
- CncConnectionLogic.Connect(om.Host, om.Port, onConnect, onExit);
- };
-
- Widget.OpenWindow("CONNECTIONFAILED_PANEL", new WidgetArgs()
- {
- { "onAbort", onExit },
- { "onRetry", onRetry },
- { "host", om.Host },
- { "port", om.Port }
- });
- }
- }
-
- void CloseWindow()
- {
- Game.LobbyInfoChanged -= UpdateCurrentMap;
- Game.LobbyInfoChanged -= UpdatePlayerList;
- Game.BeforeGameStart -= OnGameStart;
- Game.AddChatLine -= AddChatLine;
- Game.ConnectionStateChanged -= ConnectionStateChanged;
-
- Widget.CloseWindow();
- }
-
- [ObjectCreator.UseCtor]
- internal CncLobbyLogic(Widget widget, World world, OrderManager orderManager,
- Action onExit, Action onStart, bool addBots)
- {
- var lobby = widget;
- this.orderManager = orderManager;
- this.OnGameStart = () => { CloseWindow(); onStart(); };
- this.onExit = onExit;
-
- Game.LobbyInfoChanged += UpdateCurrentMap;
- Game.LobbyInfoChanged += UpdatePlayerList;
- Game.BeforeGameStart += OnGameStart;
- Game.AddChatLine += AddChatLine;
- Game.ConnectionStateChanged += ConnectionStateChanged;
-
- UpdateCurrentMap();
- PlayerPalettePreview = world.WorldActor.Trait();
- PlayerPalettePreview.Ramp = Game.Settings.Player.ColorRamp;
- Players = lobby.GetWidget("PLAYERS");
- EditablePlayerTemplate = Players.GetWidget("TEMPLATE_EDITABLE_PLAYER");
- NonEditablePlayerTemplate = Players.GetWidget("TEMPLATE_NONEDITABLE_PLAYER");
- EmptySlotTemplate = Players.GetWidget("TEMPLATE_EMPTY");
- EditableSpectatorTemplate = Players.GetWidget("TEMPLATE_EDITABLE_SPECTATOR");
- NonEditableSpectatorTemplate = Players.GetWidget("TEMPLATE_NONEDITABLE_SPECTATOR");
- NewSpectatorTemplate = Players.GetWidget("TEMPLATE_NEW_SPECTATOR");
-
- var mapPreview = lobby.GetWidget("MAP_PREVIEW");
- mapPreview.IsVisible = () => Map != null;
- mapPreview.Map = () => Map;
- mapPreview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint( orderManager, mapPreview, Map, mi );
-
- var mapTitle = lobby.GetWidget("MAP_TITLE");
- mapTitle.IsVisible = () => Map != null;
- mapTitle.GetText = () => Map.Title;
-
- mapPreview.SpawnColors = () => LobbyUtils.GetSpawnColors( orderManager, Map );
-
- CountryNames = Rules.Info["world"].Traits.WithInterface()
- .Where(c => c.Selectable)
- .ToDictionary(a => a.Race, a => a.Name);
- CountryNames.Add("random", "Any");
-
- var mapButton = lobby.GetWidget("CHANGEMAP_BUTTON");
- mapButton.OnClick = () =>
- {
- var onSelect = new Action
\ No newline at end of file
diff --git a/OpenRA.Mods.RA/RALoadScreen.cs b/OpenRA.Mods.RA/RALoadScreen.cs
index 55dc98b3f1..ce47436c98 100644
--- a/OpenRA.Mods.RA/RALoadScreen.cs
+++ b/OpenRA.Mods.RA/RALoadScreen.cs
@@ -70,32 +70,6 @@ namespace OpenRA.Mods.RA
public void StartGame()
{
- Game.ConnectionStateChanged += orderManager =>
- {
- Widget.CloseWindow();
- switch (orderManager.Connection.ConnectionState)
- {
- case ConnectionState.PreConnecting:
- Widget.LoadWidget("MAINMENU_BG", Widget.RootWidget, new WidgetArgs());
- break;
- case ConnectionState.Connecting:
- Widget.OpenWindow("CONNECTING_BG",
- new WidgetArgs() { { "host", orderManager.Host }, { "port", orderManager.Port } });
- break;
- case ConnectionState.NotConnected:
- Widget.OpenWindow("CONNECTION_FAILED_BG",
- new WidgetArgs() { { "orderManager", orderManager } });
- break;
- case ConnectionState.Connected:
- var lobby = Game.OpenWindow("SERVER_LOBBY", new WidgetArgs {});
- lobby.GetWidget("CHAT_DISPLAY").ClearChat();
- lobby.GetWidget("CHANGEMAP_BUTTON").Visible = true;
- lobby.GetWidget("ALLOWCHEATS_CHECKBOX").Visible = true;
- lobby.GetWidget("DISCONNECT_BUTTON").Visible = true;
- break;
- }
- };
-
TestAndContinue();
Game.JoinExternalGame();
}
diff --git a/OpenRA.Mods.RA/SupportPowers/SupportPowerManager.cs b/OpenRA.Mods.RA/SupportPowers/SupportPowerManager.cs
index 41db5c0e1e..9cff445cf8 100755
--- a/OpenRA.Mods.RA/SupportPowers/SupportPowerManager.cs
+++ b/OpenRA.Mods.RA/SupportPowers/SupportPowerManager.cs
@@ -10,9 +10,8 @@
using System.Collections.Generic;
using System.Linq;
-using OpenRA.Mods.RA.Buildings;
-using OpenRA.Traits;
using OpenRA.Graphics;
+using OpenRA.Traits;
namespace OpenRA.Mods.RA
{
diff --git a/OpenRA.Mods.RA/Widgets/Logic/ConnectionDialogsLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/ConnectionDialogsLogic.cs
deleted file mode 100644
index c27afca6c2..0000000000
--- a/OpenRA.Mods.RA/Widgets/Logic/ConnectionDialogsLogic.cs
+++ /dev/null
@@ -1,53 +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.Network;
-using OpenRA.Widgets;
-
-namespace OpenRA.Mods.RA.Widgets.Logic
-{
- public class ConnectionDialogsLogic
- {
- [ObjectCreator.UseCtor]
- public ConnectionDialogsLogic(Widget widget, string host, int port)
- {
- widget.GetWidget("CONNECTION_BUTTON_ABORT").OnClick = () => {
- widget.GetWidget("CONNECTION_BUTTON_ABORT").Parent.Visible = false;
- Game.Disconnect();
- Game.LoadShellMap();
- Widget.CloseWindow();
- Widget.OpenWindow("MAINMENU_BG");
- };
-
- widget.GetWidget("CONNECTING_DESC").GetText = () =>
- "Connecting to {0}:{1}...".F(host, port);
- }
- }
-
- public class ConnectionFailedLogic
- {
- [ObjectCreator.UseCtor]
- public ConnectionFailedLogic(Widget widget, OrderManager orderManager)
- {
- widget.GetWidget("CONNECTION_BUTTON_CANCEL").OnClick = () => {
- widget.GetWidget("CONNECTION_BUTTON_CANCEL").Parent.Visible = false;
- Game.Disconnect();
- Game.LoadShellMap();
- Widget.CloseWindow();
- Widget.OpenWindow("MAINMENU_BG");
- };
- widget.GetWidget("CONNECTION_BUTTON_RETRY").OnClick = () =>
- Game.JoinServer(orderManager.Host, orderManager.Port);
-
- widget.GetWidget("CONNECTION_FAILED_DESC").GetText = () => string.IsNullOrEmpty(orderManager.ServerError) ?
- "Could not connect to {0}:{1}".F(orderManager.Host, orderManager.Port) : orderManager.ServerError;
- }
- }
-}
diff --git a/OpenRA.Mods.Cnc/Widgets/Logic/CncConnectionLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/ConnectionLogic.cs
similarity index 83%
rename from OpenRA.Mods.Cnc/Widgets/Logic/CncConnectionLogic.cs
rename to OpenRA.Mods.RA/Widgets/Logic/ConnectionLogic.cs
index b3d550c5d8..a8fd3c786f 100644
--- a/OpenRA.Mods.Cnc/Widgets/Logic/CncConnectionLogic.cs
+++ b/OpenRA.Mods.RA/Widgets/Logic/ConnectionLogic.cs
@@ -12,9 +12,9 @@ using System;
using OpenRA.Network;
using OpenRA.Widgets;
-namespace OpenRA.Mods.Cnc.Widgets.Logic
+namespace OpenRA.Mods.RA.Widgets.Logic
{
- public class CncConnectionLogic
+ public class ConnectionLogic
{
Action onConnect, onRetry, onAbort;
string host;
@@ -48,7 +48,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
}
[ObjectCreator.UseCtor]
- public CncConnectionLogic(Widget widget, string host, int port, Action onConnect, Action onRetry, Action onAbort)
+ public ConnectionLogic(Widget widget, string host, int port, Action onConnect, Action onRetry, Action onAbort)
{
this.host = host;
this.port = port;
@@ -58,7 +58,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
Game.ConnectionStateChanged += ConnectionStateChanged;
- var panel = widget.GetWidget("CONNECTING_PANEL");
+ var panel = widget;
panel.GetWidget("ABORT_BUTTON").OnClick = () => { CloseWindow(); onAbort(); };
widget.GetWidget("CONNECTING_DESC").GetText = () =>
@@ -79,16 +79,17 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
}
}
- public class CncConnectionFailedLogic
+ public class ConnectionFailedLogic
{
[ObjectCreator.UseCtor]
- public CncConnectionFailedLogic(Widget widget, string host, int port, Action onRetry, Action onAbort)
+ public ConnectionFailedLogic(Widget widget, string host, int port, Action onRetry, Action onAbort)
{
- var panel = widget.GetWidget("CONNECTIONFAILED_PANEL");
+ var panel = widget;
panel.GetWidget("ABORT_BUTTON").OnClick = () => { Widget.CloseWindow(); onAbort(); };
panel.GetWidget("RETRY_BUTTON").OnClick = () => { Widget.CloseWindow(); onRetry(); };
widget.GetWidget("CONNECTING_DESC").GetText = () =>
"Could not connect to {0}:{1}".F(host, port);
}
- }}
+ }
+}
\ No newline at end of file
diff --git a/OpenRA.Mods.RA/Widgets/Logic/CreateServerMenuLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/CreateServerMenuLogic.cs
deleted file mode 100644
index fb7c29a8b7..0000000000
--- a/OpenRA.Mods.RA/Widgets/Logic/CreateServerMenuLogic.cs
+++ /dev/null
@@ -1,48 +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 System.Net;
-using OpenRA.GameRules;
-using OpenRA.Widgets;
-
-namespace OpenRA.Mods.RA.Widgets.Logic
-{
- public class CreateServerMenuLogic
- {
- [ObjectCreator.UseCtor]
- public CreateServerMenuLogic(Widget widget)
- {
- var settings = Game.Settings;
- var cs = widget;
-
- cs.GetWidget("BUTTON_CANCEL").OnClick = () => Widget.CloseWindow();
- cs.GetWidget("BUTTON_START").OnClick = () =>
- {
- settings.Server.Name = cs.GetWidget("GAME_TITLE").Text;
- settings.Server.ListenPort = int.Parse(cs.GetWidget("LISTEN_PORT").Text);
- settings.Server.ExternalPort = int.Parse(cs.GetWidget("EXTERNAL_PORT").Text);
- settings.Server.Map = WidgetUtils.ChooseInitialMap(Game.Settings.Server.Map);
- settings.Save();
-
- // Take a copy so that subsequent settings changes don't affect the server
- Game.CreateServer(new ServerSettings(Game.Settings.Server));
- Game.JoinServer(IPAddress.Loopback.ToString(), settings.Server.ListenPort);
- };
-
- cs.GetWidget("GAME_TITLE").Text = settings.Server.Name ?? "";
- cs.GetWidget("LISTEN_PORT").Text = settings.Server.ListenPort.ToString();
- cs.GetWidget("EXTERNAL_PORT").Text = settings.Server.ExternalPort.ToString();
-
- var onlineCheckbox = cs.GetWidget("CHECKBOX_ONLINE");
- onlineCheckbox.IsChecked = () => settings.Server.AdvertiseOnline;
- onlineCheckbox.OnClick = () => { settings.Server.AdvertiseOnline ^= true; settings.Save(); };
- }
- }
-}
diff --git a/OpenRA.Mods.RA/Widgets/Logic/DeveloperModeLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/DeveloperModeLogic.cs
index 2e40e26e06..4411f345c1 100644
--- a/OpenRA.Mods.RA/Widgets/Logic/DeveloperModeLogic.cs
+++ b/OpenRA.Mods.RA/Widgets/Logic/DeveloperModeLogic.cs
@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
- * Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
- * This file is part of OpenRA.
- *
- * OpenRA is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * OpenRA is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with OpenRA. If not, see .
+ * 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
diff --git a/OpenRA.Mods.RA/Widgets/Logic/DirectConnectLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/DirectConnectLogic.cs
index 83fa978d1b..06a7ee3694 100644
--- a/OpenRA.Mods.RA/Widgets/Logic/DirectConnectLogic.cs
+++ b/OpenRA.Mods.RA/Widgets/Logic/DirectConnectLogic.cs
@@ -8,7 +8,7 @@
*/
#endregion
-using System.Linq;
+using System;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
@@ -16,34 +16,28 @@ namespace OpenRA.Mods.RA.Widgets.Logic
public class DirectConnectLogic
{
[ObjectCreator.UseCtor]
- public DirectConnectLogic(Widget widget)
+ public DirectConnectLogic(Widget widget, Action onExit, Action openLobby)
{
- var dc = widget.GetWidget("DIRECTCONNECT_BG");
+ var panel = widget;
+ var ipField = panel.GetWidget("IP");
+ var portField = panel.GetWidget("PORT");
- dc.GetWidget("SERVER_ADDRESS").Text = Game.Settings.Player.LastServer;
+ var last = Game.Settings.Player.LastServer.Split(':');
+ ipField.Text = last.Length > 1 ? last[0] : "localhost";
+ portField.Text = last.Length > 2 ? last[1] : "1234";
- dc.GetWidget("JOIN_BUTTON").OnClick = () =>
+ panel.GetWidget("JOIN_BUTTON").OnClick = () =>
{
- var address = dc.GetWidget("SERVER_ADDRESS").Text;
- var addressParts = address.Split(':');
- if (addressParts.Length < 1 || addressParts.Length > 2)
- return;
+ var port = Exts.WithDefault(1234, () => int.Parse(portField.Text));
- var port = Exts.WithDefault(1234, () => int.Parse(addressParts[1]));
-
- Game.Settings.Player.LastServer = address;
+ Game.Settings.Player.LastServer = "{0}:{1}".F(ipField.Text, port);
Game.Settings.Save();
Widget.CloseWindow();
- Game.JoinServer(addressParts[0], port);
+ ConnectionLogic.Connect(ipField.Text, port, openLobby, onExit);
};
- dc.GetWidget("CANCEL_BUTTON").OnClick = () =>
- {
- Widget.CloseWindow();
- Widget.OpenWindow("MAINMENU_BG");
- };
+ panel.GetWidget("BACK_BUTTON").OnClick = () => { Widget.CloseWindow(); onExit(); };
}
}
}
-
diff --git a/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs
index f0208f930a..56727332df 100644
--- a/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs
+++ b/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs
@@ -20,8 +20,10 @@ namespace OpenRA.Mods.RA.Widgets.Logic
{
public class LobbyLogic
{
- Widget lobby, LocalPlayerTemplate, RemotePlayerTemplate, EmptySlotTemplate, EmptySlotTemplateHost,
- LocalSpectatorTemplate, RemoteSpectatorTemplate, NewSpectatorTemplate;
+ Widget EditablePlayerTemplate, NonEditablePlayerTemplate, EmptySlotTemplate,
+ EditableSpectatorTemplate, NonEditableSpectatorTemplate, NewSpectatorTemplate;
+ ScrollPanelWidget chatPanel;
+ Widget chatTemplate;
ScrollPanelWidget Players;
Dictionary CountryNames;
@@ -30,39 +32,98 @@ namespace OpenRA.Mods.RA.Widgets.Logic
ColorPickerPaletteModifier PlayerPalettePreview;
+ readonly Action OnGameStart;
+ readonly Action onExit;
readonly OrderManager orderManager;
- [ObjectCreator.UseCtor]
- internal LobbyLogic(Widget widget, World world, OrderManager orderManager)
+ // Listen for connection failures
+ void ConnectionStateChanged(OrderManager om)
{
+ if (om.Connection.ConnectionState == ConnectionState.NotConnected)
+ {
+ // Show connection failed dialog
+ CloseWindow();
+
+ Action onConnect = () =>
+ {
+ Game.OpenWindow("SERVER_LOBBY", new WidgetArgs()
+ {
+ { "onExit", onExit },
+ { "onStart", OnGameStart },
+ { "addBots", false }
+ });
+ };
+
+ Action onRetry = () =>
+ {
+ CloseWindow();
+ ConnectionLogic.Connect(om.Host, om.Port, onConnect, onExit);
+ };
+
+ Widget.OpenWindow("CONNECTIONFAILED_PANEL", new WidgetArgs()
+ {
+ { "onAbort", onExit },
+ { "onRetry", onRetry },
+ { "host", om.Host },
+ { "port", om.Port }
+ });
+ }
+ }
+
+ void CloseWindow()
+ {
+ Game.LobbyInfoChanged -= UpdateCurrentMap;
+ Game.LobbyInfoChanged -= UpdatePlayerList;
+ Game.BeforeGameStart -= OnGameStart;
+ Game.AddChatLine -= AddChatLine;
+ Game.ConnectionStateChanged -= ConnectionStateChanged;
+
+ Widget.CloseWindow();
+ }
+
+ [ObjectCreator.UseCtor]
+ internal LobbyLogic(Widget widget, World world, OrderManager orderManager,
+ Action onExit, Action onStart, bool addBots)
+ {
+ var lobby = widget;
this.orderManager = orderManager;
- this.lobby = widget;
- Game.BeforeGameStart += CloseWindow;
+ this.OnGameStart = () => { CloseWindow(); onStart(); };
+ this.onExit = onExit;
+
Game.LobbyInfoChanged += UpdateCurrentMap;
Game.LobbyInfoChanged += UpdatePlayerList;
- UpdateCurrentMap();
+ Game.BeforeGameStart += OnGameStart;
+ Game.AddChatLine += AddChatLine;
+ Game.ConnectionStateChanged += ConnectionStateChanged;
+ UpdateCurrentMap();
PlayerPalettePreview = world.WorldActor.Trait();
PlayerPalettePreview.Ramp = Game.Settings.Player.ColorRamp;
-
Players = lobby.GetWidget("PLAYERS");
- LocalPlayerTemplate = Players.GetWidget("TEMPLATE_LOCAL");
- RemotePlayerTemplate = Players.GetWidget("TEMPLATE_REMOTE");
+ EditablePlayerTemplate = Players.GetWidget("TEMPLATE_EDITABLE_PLAYER");
+ NonEditablePlayerTemplate = Players.GetWidget("TEMPLATE_NONEDITABLE_PLAYER");
EmptySlotTemplate = Players.GetWidget("TEMPLATE_EMPTY");
- EmptySlotTemplateHost = Players.GetWidget("TEMPLATE_EMPTY_HOST");
- LocalSpectatorTemplate = Players.GetWidget("TEMPLATE_LOCAL_SPECTATOR");
- RemoteSpectatorTemplate = Players.GetWidget("TEMPLATE_REMOTE_SPECTATOR");
+ EditableSpectatorTemplate = Players.GetWidget("TEMPLATE_EDITABLE_SPECTATOR");
+ NonEditableSpectatorTemplate = Players.GetWidget("TEMPLATE_NONEDITABLE_SPECTATOR");
NewSpectatorTemplate = Players.GetWidget("TEMPLATE_NEW_SPECTATOR");
- var mapPreview = lobby.GetWidget("LOBBY_MAP_PREVIEW");
+ var mapPreview = lobby.GetWidget("MAP_PREVIEW");
+ mapPreview.IsVisible = () => Map != null;
mapPreview.Map = () => Map;
mapPreview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint( orderManager, mapPreview, Map, mi );
mapPreview.SpawnColors = () => LobbyUtils.GetSpawnColors( orderManager, Map );
+ var mapTitle = lobby.GetWidget("MAP_TITLE");
+ if (mapTitle != null)
+ {
+ mapTitle.IsVisible = () => Map != null;
+ mapTitle.GetText = () => Map.Title;
+ }
+
CountryNames = Rules.Info["world"].Traits.WithInterface()
.Where(c => c.Selectable)
.ToDictionary(a => a.Race, a => a.Name);
- CountryNames.Add("random", "Random");
+ CountryNames.Add("random", "Any");
var mapButton = lobby.GetWidget("CHANGEMAP_BUTTON");
mapButton.OnClick = () =>
@@ -74,48 +135,40 @@ namespace OpenRA.Mods.RA.Widgets.Logic
Game.Settings.Save();
});
- Widget.OpenWindow("MAP_CHOOSER", new WidgetArgs()
+ Widget.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
{
- { "initialMap", MapUid },
+ { "initialMap", Map.Uid },
{ "onExit", () => {} },
{ "onSelect", onSelect }
});
};
-
mapButton.IsVisible = () => mapButton.Visible && Game.IsHost;
var disconnectButton = lobby.GetWidget("DISCONNECT_BUTTON");
- disconnectButton.OnClick = () =>
- {
- CloseWindow();
- Game.Disconnect();
- Game.LoadShellMap();
- Widget.OpenWindow("MAINMENU_BG");
- };
+ disconnectButton.OnClick = () => { CloseWindow(); onExit(); };
+
+ var gameStarting = false;
var allowCheats = lobby.GetWidget("ALLOWCHEATS_CHECKBOX");
allowCheats.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats;
- allowCheats.OnClick = () =>
- {
- if (Game.IsHost)
- orderManager.IssueOrder(Order.Command(
+ allowCheats.IsDisabled = () => !Game.IsHost || gameStarting || orderManager.LocalClient == null
+ || orderManager.LocalClient.IsReady;
+ allowCheats.OnClick = () => orderManager.IssueOrder(Order.Command(
"allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats)));
- };
var startGameButton = lobby.GetWidget("START_GAME_BUTTON");
+ startGameButton.IsVisible = () => Game.IsHost;
+ startGameButton.IsDisabled = () => gameStarting;
startGameButton.OnClick = () =>
{
- mapButton.Visible = false;
- disconnectButton.Visible = false;
+ gameStarting = true;
orderManager.IssueOrder(Order.Command("startgame"));
};
- // Todo: Only show if the map requirements are met for player slots
- startGameButton.IsVisible = () => Game.IsHost;
-
bool teamChat = false;
var chatLabel = lobby.GetWidget("LABEL_CHATTYPE");
var chatTextField = lobby.GetWidget("CHAT_TEXTFIELD");
+
chatTextField.OnEnterKey = () =>
{
if (chatTextField.Text.Length == 0)
@@ -133,36 +186,69 @@ namespace OpenRA.Mods.RA.Widgets.Logic
return true;
};
- Game.AddChatLine += AddChatLine;
- }
+ chatPanel = lobby.GetWidget("CHAT_DISPLAY");
+ chatTemplate = chatPanel.GetWidget("CHAT_TEMPLATE");
+ chatPanel.RemoveChildren();
- public void CloseWindow()
- {
- Game.LobbyInfoChanged -= UpdateCurrentMap;
- Game.LobbyInfoChanged -= UpdatePlayerList;
- Game.AddChatLine -= AddChatLine;
- Game.BeforeGameStart -= CloseWindow;
+ var musicButton = lobby.GetWidget("MUSIC_BUTTON");
+ if (musicButton != null)
+ musicButton.OnClick = () => Widget.OpenWindow("MUSIC_PANEL", new WidgetArgs
+ { { "onExit", () => {} } });
- Widget.CloseWindow();
+ // Add a bot on the first lobbyinfo update
+ if (addBots)
+ Game.LobbyInfoChanged += WidgetUtils.Once(() =>
+ {
+ var slot = orderManager.LobbyInfo.FirstEmptySlot();
+ var bot = Rules.Info["player"].Traits.WithInterface().Select(t => t.Name).FirstOrDefault();
+ if (slot != null && bot != null)
+ orderManager.IssueOrder(Order.Command("slot_bot {0} {1}".F(slot, bot)));
+ });
}
void AddChatLine(Color c, string from, string text)
{
- lobby.GetWidget("CHAT_DISPLAY").AddLine(c, from, text);
+ var template = chatTemplate.Clone();
+ var nameLabel = template.GetWidget("NAME");
+ var timeLabel = template.GetWidget("TIME");
+ var textLabel = template.GetWidget("TEXT");
+
+ var name = from + ":";
+ var font = Game.Renderer.Fonts[nameLabel.Font];
+ var nameSize = font.Measure(from);
+
+ var time = DateTime.Now;
+ timeLabel.GetText = () => "{0:D2}:{1:D2}".F(time.Hour, time.Minute);
+
+ nameLabel.GetColor = () => c;
+ nameLabel.GetText = () => name;
+ nameLabel.Bounds.Width = nameSize.X;
+ textLabel.Bounds.X += nameSize.X;
+ textLabel.Bounds.Width -= nameSize.X;
+
+ // Hack around our hacky wordwrap behavior: need to resize the widget to fit the text
+ text = WidgetUtils.WrapText(text, textLabel.Bounds.Width, font);
+ textLabel.GetText = () => text;
+ var dh = font.Measure(text).Y - textLabel.Bounds.Height;
+ if (dh > 0)
+ {
+ textLabel.Bounds.Height += dh;
+ template.Bounds.Height += dh;
+ }
+
+ chatPanel.AddChild(template);
+ chatPanel.ScrollToBottom();
+ Sound.Play("scold1.aud");
}
void UpdateCurrentMap()
{
- var newMap = orderManager.LobbyInfo.GlobalSettings.Map;
- if (MapUid == newMap) return;
-
- MapUid = newMap;
+ if (MapUid == orderManager.LobbyInfo.GlobalSettings.Map) return;
+ MapUid = orderManager.LobbyInfo.GlobalSettings.Map;
Map = new Map(Game.modData.AvailableMaps[MapUid].Path);
- var title = Widget.RootWidget.GetWidget("LOBBY_TITLE");
- if (title != null)
- title.Text = "OpenRA Multiplayer Lobby - {0} - {1}".F(
- orderManager.LobbyInfo.GlobalSettings.ServerName, Map.Title);
+ var title = Widget.RootWidget.GetWidget("TITLE");
+ title.Text = orderManager.LobbyInfo.GlobalSettings.ServerName;
}
void UpdatePlayerList()
@@ -173,108 +259,119 @@ namespace OpenRA.Mods.RA.Widgets.Logic
foreach (var kv in orderManager.LobbyInfo.Slots)
{
- var s = kv.Value;
- var c = orderManager.LobbyInfo.ClientInSlot(kv.Key);
+ var key = kv.Key;
+ var slot = kv.Value;
+ var client = orderManager.LobbyInfo.ClientInSlot(key);
Widget template;
- if (c == null)
+ // Empty slot
+ if (client == null)
{
+ template = EmptySlotTemplate.Clone();
+ Func getText = () => slot.Closed ? "Closed" : "Open";
+ var ready = orderManager.LocalClient.IsReady;
+
if (Game.IsHost)
{
- template = EmptySlotTemplateHost.Clone();
- var name = template.GetWidget("NAME");
- name.GetText = () => s.Closed ? "Closed" : "Open";
- name.OnMouseDown = _ => LobbyUtils.ShowSlotDropDown(name, s, c, orderManager);
+ var name = template.GetWidget("NAME_HOST");
+ name.IsVisible = () => true;
+ name.IsDisabled = () => ready;
+ name.GetText = getText;
+ name.OnMouseDown = _ => LobbyUtils.ShowSlotDropDown(name, slot, client, orderManager);
}
else
{
- template = EmptySlotTemplate.Clone();
var name = template.GetWidget("NAME");
- name.GetText = () => s.Closed ? "Closed" : "Open";
+ name.IsVisible = () => true;
+ name.GetText = getText;
}
var join = template.GetWidget("JOIN");
- if (join != null)
- {
- join.OnClick = () => orderManager.IssueOrder(Order.Command("slot " + s.PlayerReference));
- join.IsVisible = () => !s.Closed && c == null && !orderManager.LocalClient.IsReady;
- }
+ join.IsVisible = () => !slot.Closed;
+ join.IsDisabled = () => ready;
+ join.OnClick = () => orderManager.IssueOrder(Order.Command("slot " + key));
}
-
- else if ((c.Index == orderManager.LocalClient.Index && !c.IsReady) || (c.Bot != null && Game.IsHost))
+ // Editable player in slot
+ else if ((client.Index == orderManager.LocalClient.Index) ||
+ (client.Bot != null && Game.IsHost))
{
- template = LocalPlayerTemplate.Clone();
+ template = EditablePlayerTemplate.Clone();
+ var botReady = client.Bot != null && Game.IsHost && orderManager.LocalClient.IsReady;
+ var ready = botReady || client.IsReady;
- var botReady = (c.Bot != null && Game.IsHost
- && orderManager.LocalClient.IsReady);
- var ready = botReady || c.IsReady;
-
- if (c.Bot == null)
- {
- LobbyUtils.SetupNameWidget(orderManager, c, template.GetWidget("NAME"));
- }
- else
+ if (client.Bot != null)
{
var name = template.GetWidget("BOT_DROPDOWN");
name.IsVisible = () => true;
name.IsDisabled = () => ready;
- name.GetText = () => c.Name;
- name.OnMouseDown = _ => LobbyUtils.ShowSlotDropDown(name, s, c, orderManager);
- }
+ name.GetText = () => client.Name;
+ name.OnMouseDown = _ => LobbyUtils.ShowSlotDropDown(name, slot, client, orderManager);
+ }
+ else
+ {
+ var name = template.GetWidget("NAME");
+ name.IsVisible = () => true;
+ name.IsDisabled = () => ready;
+ LobbyUtils.SetupNameWidget(orderManager, client, name);
+ }
var color = template.GetWidget("COLOR");
- color.IsDisabled = () => s.LockColor;
- color.OnMouseDown = _ => LobbyUtils.ShowColorDropDown(color, c, orderManager, PlayerPalettePreview);
+ color.IsDisabled = () => slot.LockColor || ready;
+ color.OnMouseDown = _ => LobbyUtils.ShowColorDropDown(color, client, orderManager, PlayerPalettePreview);
var colorBlock = color.GetWidget("COLORBLOCK");
- colorBlock.GetColor = () => c.ColorRamp.GetColor(0);
+ colorBlock.GetColor = () => client.ColorRamp.GetColor(0);
var faction = template.GetWidget("FACTION");
- faction.IsDisabled = () => s.LockRace;
- faction.OnMouseDown = _ => LobbyUtils.ShowRaceDropDown(faction, c, orderManager, CountryNames);
+ faction.IsDisabled = () => slot.LockRace || ready;
+ faction.OnMouseDown = _ => LobbyUtils.ShowRaceDropDown(faction, client, orderManager, CountryNames);
var factionname = faction.GetWidget("FACTIONNAME");
- factionname.GetText = () => CountryNames[c.Country];
+ factionname.GetText = () => CountryNames[client.Country];
var factionflag = faction.GetWidget("FACTIONFLAG");
- factionflag.GetImageName = () => c.Country;
+ factionflag.GetImageName = () => client.Country;
factionflag.GetImageCollection = () => "flags";
var team = template.GetWidget("TEAM");
- team.IsDisabled = () => s.LockTeam;
- team.OnMouseDown = _ => LobbyUtils.ShowTeamDropDown(team, c, orderManager, Map);
- team.GetText = () => (c.Team == 0) ? "-" : c.Team.ToString();
+ team.IsDisabled = () => slot.LockTeam || ready;
+ team.OnMouseDown = _ => LobbyUtils.ShowTeamDropDown(team, client, orderManager, Map);
+ team.GetText = () => (client.Team == 0) ? "-" : client.Team.ToString();
- var status = template.GetWidget("STATUS");
- status.IsChecked = () => c.IsReady;
- status.OnClick = CycleReady;
- status.IsVisible = () => c.Bot == null;
+ if (client.Bot == null)
+ {
+ // local player
+ var status = template.GetWidget("STATUS_CHECKBOX");
+ status.IsChecked = () => ready;
+ status.IsVisible = () => true;
+ status.OnClick += CycleReady;
+ }
+ else // Bot
+ template.GetWidget("STATUS_IMAGE").IsVisible = () => true;
}
else
- {
- template = RemotePlayerTemplate.Clone();
- template.GetWidget("NAME").GetText = () => c.Name;
+ { // Non-editable player in slot
+ template = NonEditablePlayerTemplate.Clone();
+ template.GetWidget("NAME").GetText = () => client.Name;
var color = template.GetWidget("COLOR");
- color.GetColor = () => c.ColorRamp.GetColor(0);
+ color.GetColor = () => client.ColorRamp.GetColor(0);
var faction = template.GetWidget("FACTION");
var factionname = faction.GetWidget("FACTIONNAME");
- factionname.GetText = () => CountryNames[c.Country];
+ factionname.GetText = () => CountryNames[client.Country];
var factionflag = faction.GetWidget("FACTIONFLAG");
- factionflag.GetImageName = () => c.Country;
+ factionflag.GetImageName = () => client.Country;
factionflag.GetImageCollection = () => "flags";
var team = template.GetWidget("TEAM");
- team.GetText = () => (c.Team == 0) ? "-" : c.Team.ToString();
+ team.GetText = () => (client.Team == 0) ? "-" : client.Team.ToString();
- var status = template.GetWidget("STATUS");
- status.IsChecked = () => c.IsReady;
- if (c.Index == orderManager.LocalClient.Index)
- status.OnClick = CycleReady;
- status.IsVisible = () => c.Bot == null;
+ template.GetWidget("STATUS_IMAGE").IsVisible = () =>
+ client.Bot != null || client.IsReady;
var kickButton = template.GetWidget("KICK");
- kickButton.IsVisible = () => Game.IsHost && c.Index != orderManager.LocalClient.Index;
- kickButton.OnClick = () => orderManager.IssueOrder(Order.Command("kick " + c.Index));
+ kickButton.IsVisible = () => Game.IsHost && client.Index != orderManager.LocalClient.Index;
+ kickButton.IsDisabled = () => orderManager.LocalClient.IsReady;
+ kickButton.OnClick = () => orderManager.IssueOrder(Order.Command("kick " + client.Index));
}
template.IsVisible = () => true;
@@ -284,39 +381,42 @@ namespace OpenRA.Mods.RA.Widgets.Logic
// Add spectators
foreach (var client in orderManager.LobbyInfo.Clients.Where(client => client.Slot == null))
{
- var c = client;
Widget template;
+ var c = client;
+ var ready = c.IsReady;
+
// Editable spectator
- if (c.Index == orderManager.LocalClient.Index && !c.IsReady)
+ if (c.Index == orderManager.LocalClient.Index)
{
- template = LocalSpectatorTemplate.Clone();
- LobbyUtils.SetupNameWidget(orderManager, c, template.GetWidget("NAME"));
+ template = EditableSpectatorTemplate.Clone();
+ var name = template.GetWidget("NAME");
+ name.IsDisabled = () => ready;
+ LobbyUtils.SetupNameWidget(orderManager, c, name);
var color = template.GetWidget("COLOR");
+ color.IsDisabled = () => ready;
color.OnMouseDown = _ => LobbyUtils.ShowColorDropDown(color, c, orderManager, PlayerPalettePreview);
var colorBlock = color.GetWidget("COLORBLOCK");
colorBlock.GetColor = () => c.ColorRamp.GetColor(0);
- var status = template.GetWidget("STATUS");
- status.IsChecked = () => c.IsReady;
+ var status = template.GetWidget("STATUS_CHECKBOX");
+ status.IsChecked = () => ready;
status.OnClick += CycleReady;
}
// Non-editable spectator
else
{
- template = RemoteSpectatorTemplate.Clone();
+ template = NonEditableSpectatorTemplate.Clone();
template.GetWidget("NAME").GetText = () => c.Name;
var color = template.GetWidget("COLOR");
color.GetColor = () => c.ColorRamp.GetColor(0);
- var status = template.GetWidget("STATUS");
- status.IsChecked = () => c.IsReady;
- if (c.Index == orderManager.LocalClient.Index)
- status.OnClick += CycleReady;
+ template.GetWidget("STATUS_IMAGE").IsVisible = () => c.Bot != null || c.IsReady;
var kickButton = template.GetWidget("KICK");
kickButton.IsVisible = () => Game.IsHost && c.Index != orderManager.LocalClient.Index;
+ kickButton.IsDisabled = () => orderManager.LocalClient.IsReady;
kickButton.OnClick = () => orderManager.IssueOrder(Order.Command("kick " + c.Index));
}
@@ -325,11 +425,12 @@ namespace OpenRA.Mods.RA.Widgets.Logic
}
// Spectate button
- if (orderManager.LocalClient.Slot != null && !orderManager.LocalClient.IsReady)
+ if (orderManager.LocalClient.Slot != null)
{
var spec = NewSpectatorTemplate.Clone();
var btn = spec.GetWidget("SPECTATE");
btn.OnClick = () => orderManager.IssueOrder(Order.Command("spectate"));
+ btn.IsDisabled = () => orderManager.LocalClient.IsReady;
spec.IsVisible = () => true;
Players.AddChild(spec);
}
diff --git a/OpenRA.Mods.RA/Widgets/Logic/MainMenuButtonsLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/MainMenuButtonsLogic.cs
index 8421648a87..772ca6790e 100644
--- a/OpenRA.Mods.RA/Widgets/Logic/MainMenuButtonsLogic.cs
+++ b/OpenRA.Mods.RA/Widgets/Logic/MainMenuButtonsLogic.cs
@@ -8,58 +8,62 @@
*/
#endregion
-using System;
-using System.Linq;
-using OpenRA.FileFormats;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class MainMenuButtonsLogic
{
+ Widget rootMenu;
+
[ObjectCreator.UseCtor]
public MainMenuButtonsLogic(Widget widget)
{
+ rootMenu = widget;
+
Game.modData.WidgetLoader.LoadWidget( new WidgetArgs(), Widget.RootWidget, "PERF_BG" );
- widget.GetWidget("MAINMENU_BUTTON_JOIN").OnClick = () => Widget.OpenWindow("JOINSERVER_BG");
- widget.GetWidget("MAINMENU_BUTTON_CREATE").OnClick = () => Widget.OpenWindow("CREATESERVER_BG");
+ widget.GetWidget("MAINMENU_BUTTON_JOIN").OnClick = () => OpenGamePanel("JOINSERVER_BG");
+ widget.GetWidget("MAINMENU_BUTTON_CREATE").OnClick = () => OpenGamePanel("CREATESERVER_BG");
+ widget.GetWidget("MAINMENU_BUTTON_DIRECTCONNECT").OnClick = () => OpenGamePanel("DIRECTCONNECT_BG");
widget.GetWidget("MAINMENU_BUTTON_SETTINGS").OnClick = () => Widget.OpenWindow("SETTINGS_MENU");
widget.GetWidget("MAINMENU_BUTTON_MUSIC").OnClick = () => Widget.OpenWindow("MUSIC_MENU");
- widget.GetWidget("MAINMENU_BUTTON_REPLAY_VIEWER").OnClick = () => Widget.OpenWindow("REPLAYBROWSER_BG");
+ widget.GetWidget("MAINMENU_BUTTON_MODS").OnClick = () =>
+ Widget.OpenWindow("MODS_PANEL", new WidgetArgs()
+ {
+ { "onExit", () => {} },
+ { "onSwitch", RemoveShellmapUI }
+ });
+ widget.GetWidget("MAINMENU_BUTTON_REPLAY_VIEWER").OnClick = () =>
+ Widget.OpenWindow("REPLAYBROWSER_BG", new WidgetArgs()
+ {
+ { "onExit", () => {} },
+ { "onStart", RemoveShellmapUI }
+ });
widget.GetWidget("MAINMENU_BUTTON_QUIT").OnClick = () => Game.Exit();
-
- DisplayModSelector();
}
- public static void DisplayModSelector()
+ void RemoveShellmapUI()
{
- var selector = Game.modData.WidgetLoader.LoadWidget( new WidgetArgs(), Widget.RootWidget, "QUICKMODSWITCHER" );
- var switcher = selector.GetWidget("SWITCHER");
- switcher.OnMouseDown = _ => ShowModsDropDown(switcher);
- switcher.GetText = WidgetUtils.ActiveModTitle;
- selector.GetWidget("VERSION").GetText = WidgetUtils.ActiveModVersion;
+ rootMenu.Parent.RemoveChild(rootMenu);
}
- static void LoadMod(string mod)
+ void OpenGamePanel(string id)
{
- var mods = Mod.AllMods[mod].WithPrerequisites();
-
- if (Game.CurrentMods.Keys.SymmetricDifference(mods).Any())
- Game.RunAfterTick(() => Game.InitializeWithMods(mods));
- }
-
- static void ShowModsDropDown(DropDownButtonWidget dropdown)
- {
- Func setupItem = (m, itemTemplate) =>
+ Widget.OpenWindow(id, new WidgetArgs()
{
- var item = ScrollItemWidget.Setup(itemTemplate,
- () => m == Game.CurrentMods.Keys.First(),
- () => LoadMod(m));
- item.GetWidget("LABEL").GetText = () => Mod.AllMods[m].Title;
- return item;
- };
+ { "onExit", () => {} },
+ { "openLobby", () => OpenLobbyPanel() }
+ });
+ }
- dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 150, Mod.AllMods.Keys, setupItem);
+ void OpenLobbyPanel()
+ {
+ Game.OpenWindow("SERVER_LOBBY", new WidgetArgs()
+ {
+ { "onExit", () => { Game.Disconnect(); } },
+ { "onStart", RemoveShellmapUI },
+ { "addBots", false }
+ });
}
}
}
diff --git a/OpenRA.Mods.Cnc/Widgets/Logic/CncModBrowserLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/ModBrowserLogic.cs
similarity index 87%
rename from OpenRA.Mods.Cnc/Widgets/Logic/CncModBrowserLogic.cs
rename to OpenRA.Mods.RA/Widgets/Logic/ModBrowserLogic.cs
index 5e3273ca2d..f6327f3048 100644
--- a/OpenRA.Mods.Cnc/Widgets/Logic/CncModBrowserLogic.cs
+++ b/OpenRA.Mods.RA/Widgets/Logic/ModBrowserLogic.cs
@@ -13,16 +13,16 @@ using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Widgets;
-namespace OpenRA.Mods.Cnc.Widgets.Logic
+namespace OpenRA.Mods.RA.Widgets.Logic
{
- public class CncModBrowserLogic
+ public class ModBrowserLogic
{
Mod currentMod;
[ObjectCreator.UseCtor]
- public CncModBrowserLogic(Widget widget, Action onSwitch, Action onExit)
+ public ModBrowserLogic(Widget widget, Action onSwitch, Action onExit)
{
- var panel = widget.GetWidget("MODS_PANEL");
+ var panel = widget;
var modList = panel.GetWidget("MOD_LIST");
var loadButton = panel.GetWidget("LOAD_BUTTON");
loadButton.OnClick = () => LoadMod(currentMod.Id, onSwitch);
@@ -53,7 +53,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
{
Widget.CloseWindow();
onSwitch();
- Game.InitializeWithMods(mods.ToArray());
+ Game.InitializeWithMods(mods);
});
}
}
diff --git a/OpenRA.Mods.RA/Widgets/Logic/RAInstallLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/RAInstallLogic.cs
index cb2080fb1c..733c2ced3c 100644
--- a/OpenRA.Mods.RA/Widgets/Logic/RAInstallLogic.cs
+++ b/OpenRA.Mods.RA/Widgets/Logic/RAInstallLogic.cs
@@ -33,8 +33,6 @@ namespace OpenRA.Mods.RA.Widgets.Logic
Widget.OpenWindow("INSTALL_FROMCD_PANEL", args);
panel.GetWidget("QUIT_BUTTON").OnClick = Game.Exit;
-
- MainMenuButtonsLogic.DisplayModSelector();
}
}
}
diff --git a/OpenRA.Mods.RA/Widgets/Logic/ReplayBrowserLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/ReplayBrowserLogic.cs
index f279760699..f56d248c6e 100644
--- a/OpenRA.Mods.RA/Widgets/Logic/ReplayBrowserLogic.cs
+++ b/OpenRA.Mods.RA/Widgets/Logic/ReplayBrowserLogic.cs
@@ -18,70 +18,80 @@ namespace OpenRA.Mods.RA.Widgets.Logic
{
public class ReplayBrowserLogic
{
- Widget widget;
+ Widget panel;
[ObjectCreator.UseCtor]
- public ReplayBrowserLogic(Widget widget)
+ public ReplayBrowserLogic(Widget widget, Action onExit, Action onStart)
{
- this.widget = widget;
+ panel = widget;
- widget.GetWidget("CANCEL_BUTTON").OnClick = () => Widget.CloseWindow();
+ panel.GetWidget("CANCEL_BUTTON").OnClick = () => { Widget.CloseWindow(); onExit(); };
- /* find some replays? */
- var rl = widget.GetWidget("REPLAY_LIST");
+ var rl = panel.GetWidget("REPLAY_LIST");
var replayDir = Path.Combine(Platform.SupportDir, "Replays");
- var template = widget.GetWidget("REPLAY_TEMPLATE");
- SelectReplay(null);
+ var template = panel.GetWidget("REPLAY_TEMPLATE");
rl.RemoveChildren();
if (Directory.Exists(replayDir))
- foreach (var replayFile in Directory.GetFiles(replayDir, "*.rep").Reverse())
+ {
+ var files = Directory.GetFiles(replayDir, "*.rep").Reverse();
+ foreach (var replayFile in files)
AddReplay(rl, replayFile, template);
- widget.GetWidget("WATCH_BUTTON").OnClick = () =>
+ SelectReplay(files.FirstOrDefault());
+ }
+
+ var watch = panel.GetWidget("WATCH_BUTTON");
+ watch.IsDisabled = () => currentReplay == null || currentMap == null || currentReplay.Duration == 0;
+ watch.OnClick = () =>
{
if (currentReplay != null)
{
+ Game.JoinReplay(currentReplay.Filename);
Widget.CloseWindow();
- Game.JoinReplay(currentReplay);
+ onStart();
}
};
- widget.GetWidget("REPLAY_INFO").IsVisible = () => currentReplay != null;
+ panel.GetWidget("REPLAY_INFO").IsVisible = () => currentReplay != null;
}
- string currentReplay;
+ Replay currentReplay;
+ Map currentMap;
void SelectReplay(string filename)
{
- currentReplay = filename;
+ if (filename == null)
+ return;
- if (currentReplay != null)
+ try
{
- try
- {
- var summary = new Replay(currentReplay);
- var mapStub = summary.Map();
+ currentReplay = new Replay(filename);
+ currentMap = currentReplay.Map();
- widget.GetWidget("DURATION").GetText =
- () => WidgetUtils.FormatTime(summary.Duration * 3 /* todo: 3:1 ratio isnt always true. */);
- widget.GetWidget("MAP_PREVIEW").Map = () => mapStub;
- widget.GetWidget("MAP_TITLE").GetText =
- () => mapStub != null ? mapStub.Title : "(Unknown Map)";
- }
- catch(Exception e)
- {
- Log.Write("debug", "Exception while parsing replay: {0}", e);
- currentReplay = null;
- }
+ panel.GetWidget("DURATION").GetText =
+ () => WidgetUtils.FormatTime(currentReplay.Duration * 3 /* todo: 3:1 ratio isnt always true. */);
+ panel.GetWidget("MAP_PREVIEW").Map = () => currentMap;
+ panel.GetWidget("MAP_TITLE").GetText =
+ () => currentMap != null ? currentMap.Title : "(Unknown Map)";
+
+ var players = currentReplay.LobbyInfo.Slots
+ .Count(s => currentReplay.LobbyInfo.ClientInSlot(s.Key) != null);
+ panel.GetWidget("PLAYERS").GetText = () => players.ToString();
+ }
+ catch (Exception e)
+ {
+ Log.Write("debug", "Exception while parsing replay: {0}", e);
+ currentReplay = null;
+ currentMap = null;
}
}
void AddReplay(ScrollPanelWidget list, string filename, ScrollItemWidget template)
{
var item = ScrollItemWidget.Setup(template,
- () => currentReplay == filename,
+ () => currentReplay != null && currentReplay.Filename == filename,
() => SelectReplay(filename));
var f = Path.GetFileName(filename);
item.GetWidget("TITLE").GetText = () => f;
diff --git a/OpenRA.Mods.RA/Widgets/Logic/ServerBrowserLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/ServerBrowserLogic.cs
index 2bba35259b..a62bfbce1c 100644
--- a/OpenRA.Mods.RA/Widgets/Logic/ServerBrowserLogic.cs
+++ b/OpenRA.Mods.RA/Widgets/Logic/ServerBrowserLogic.cs
@@ -8,6 +8,7 @@
*/
#endregion
+using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.FileFormats;
@@ -18,65 +19,88 @@ namespace OpenRA.Mods.RA.Widgets.Logic
{
public class ServerBrowserLogic
{
- GameServer currentServer = null;
- ScrollItemWidget ServerTemplate;
+ GameServer currentServer;
+ ScrollItemWidget serverTemplate;
+
+ enum SearchStatus { Fetching, Failed, NoGames, Hidden }
+ SearchStatus searchStatus = SearchStatus.Fetching;
+
+ public string ProgressLabelText()
+ {
+ switch (searchStatus)
+ {
+ case SearchStatus.Fetching: return "Fetching game list...";
+ case SearchStatus.Failed: return "Failed to contact master server.";
+ case SearchStatus.NoGames: return "No games found.";
+ default: return "";
+ }
+ }
[ObjectCreator.UseCtor]
- public ServerBrowserLogic(Widget widget)
+ public ServerBrowserLogic(Widget widget, Action openLobby, Action onExit)
{
- var bg = widget.GetWidget("JOINSERVER_BG");
+ var panel = widget;
+ var sl = panel.GetWidget("SERVER_LIST");
- bg.GetWidget("JOINSERVER_PROGRESS_TITLE").Visible = true;
- bg.GetWidget("JOINSERVER_PROGRESS_TITLE").Text = "Fetching game list...";
-
- ServerList.Query(RefreshServerList);
-
- bg.GetWidget("SERVER_INFO").IsVisible = () => currentServer != null;
- var preview = bg.GetWidget("MAP_PREVIEW");
- preview.Map = () => CurrentMap();
- preview.IsVisible = () => CurrentMap() != null;
-
- bg.GetWidget("SERVER_IP").GetText = () => currentServer.Address;
- bg.GetWidget("SERVER_MODS").GetText = () => GenerateModsLabel(currentServer);
- bg.GetWidget("MAP_TITLE").GetText = () => (CurrentMap() != null) ? CurrentMap().Title : "Unknown";
- bg.GetWidget("MAP_PLAYERS").GetText = () =>
+ // Menu buttons
+ var refreshButton = panel.GetWidget("REFRESH_BUTTON");
+ refreshButton.IsDisabled = () => searchStatus == SearchStatus.Fetching;
+ refreshButton.OnClick = () =>
{
- if (currentServer == null)
- return "";
- string ret = currentServer.Players.ToString();
- if (CurrentMap() != null)
- ret += "/" + CurrentMap().PlayerCount.ToString();
- return ret;
- };
-
- var sl = bg.GetWidget("SERVER_LIST");
- ServerTemplate = sl.GetWidget("SERVER_TEMPLATE");
-
- bg.GetWidget("REFRESH_BUTTON").OnClick = () =>
- {
- bg.GetWidget("JOINSERVER_PROGRESS_TITLE").Visible = true;
- bg.GetWidget("JOINSERVER_PROGRESS_TITLE").Text = "Fetching game list...";
+ searchStatus = SearchStatus.Fetching;
sl.RemoveChildren();
currentServer = null;
-
- ServerList.Query(RefreshServerList);
+ ServerList.Query(games => RefreshServerList(panel, games));
};
- bg.GetWidget("CANCEL_BUTTON").OnClick = () => Widget.CloseWindow();
- bg.GetWidget("DIRECTCONNECT_BUTTON").OnClick = () =>
- {
- Widget.CloseWindow();
- Widget.OpenWindow("DIRECTCONNECT_BG");
- };
-
- bg.GetWidget("JOIN_BUTTON").OnClick = () =>
+ var join = panel.GetWidget("JOIN_BUTTON");
+ join.IsDisabled = () => currentServer == null || !currentServer.CanJoin();
+ join.OnClick = () =>
{
if (currentServer == null)
return;
+ var host = currentServer.Address.Split(':')[0];
+ var port = int.Parse(currentServer.Address.Split(':')[1]);
+
Widget.CloseWindow();
- Game.JoinServer(currentServer.Address.Split(':')[0], int.Parse(currentServer.Address.Split(':')[1]));
+ ConnectionLogic.Connect(host, port, openLobby, onExit);
};
+
+ panel.GetWidget("BACK_BUTTON").OnClick = () => { Widget.CloseWindow(); onExit(); };
+
+ // Server list
+ serverTemplate = sl.GetWidget("SERVER_TEMPLATE");
+
+ // Display the progress label over the server list
+ // The text is only visible when the list is empty
+ var progressText = panel.GetWidget("PROGRESS_LABEL");
+ progressText.IsVisible = () => searchStatus != SearchStatus.Hidden;
+ progressText.GetText = ProgressLabelText;
+
+ // Map preview
+ var preview = panel.GetWidget("MAP_PREVIEW");
+ preview.Map = () => CurrentMap();
+ preview.IsVisible = () => CurrentMap() != null;
+
+ // Server info
+ var infoPanel = panel.GetWidget("SERVER_INFO");
+ infoPanel.IsVisible = () => currentServer != null;
+ infoPanel.GetWidget("SERVER_IP").GetText = () => currentServer.Address;
+ infoPanel.GetWidget("SERVER_MODS").GetText = () => ServerBrowserLogic.GenerateModsLabel(currentServer);
+ infoPanel.GetWidget("MAP_TITLE").GetText = () => (CurrentMap() != null) ? CurrentMap().Title : "Unknown";
+ infoPanel.GetWidget("MAP_PLAYERS").GetText = () => GetPlayersLabel(currentServer);
+
+ ServerList.Query(games => RefreshServerList(panel, games));
+ }
+
+ string GetPlayersLabel(GameServer game)
+ {
+ if (game == null)
+ return "";
+
+ var map = Game.modData.FindMapByUid(game.Map);
+ return map == null ? "{0}".F(currentServer.Players) : "{0} / {1}".F(currentServer.Players, map.PlayerCount);
}
Map CurrentMap()
@@ -97,23 +121,16 @@ namespace OpenRA.Mods.RA.Widgets.Logic
return s.UsefulMods.Select(m => GenerateModLabel(m)).JoinWith("\n");
}
- void RefreshServerList(IEnumerable games)
+ public void RefreshServerList(Widget panel, IEnumerable games)
{
- var r = Widget.RootWidget;
- var bg = r.GetWidget("JOINSERVER_BG");
-
- if (bg == null) // We got a MasterServer reply AFTER the browser is gone, just return to prevent crash - Gecko
- return;
-
- var sl = bg.GetWidget("SERVER_LIST");
+ var sl = panel.GetWidget("SERVER_LIST");
sl.RemoveChildren();
currentServer = null;
if (games == null)
{
- r.GetWidget("JOINSERVER_PROGRESS_TITLE").Visible = true;
- r.GetWidget("JOINSERVER_PROGRESS_TITLE").Text = "Failed to contact master server.";
+ searchStatus = SearchStatus.Failed;
return;
}
@@ -121,22 +138,28 @@ namespace OpenRA.Mods.RA.Widgets.Logic
if (gamesWaiting.Count() == 0)
{
- r.GetWidget("JOINSERVER_PROGRESS_TITLE").Visible = true;
- r.GetWidget("JOINSERVER_PROGRESS_TITLE").Text = "No games found.";
+ searchStatus = SearchStatus.NoGames;
return;
}
- r.GetWidget("JOINSERVER_PROGRESS_TITLE").Visible = false;
-
+ searchStatus = SearchStatus.Hidden;
currentServer = gamesWaiting.FirstOrDefault();
foreach (var loop in gamesWaiting)
{
var game = loop;
- var item = ScrollItemWidget.Setup(ServerTemplate,
- () => currentServer == game,
- () => currentServer = game);
- item.GetWidget("TITLE").GetText = () => "{0} ({1})".F(game.Name, game.Address);
+
+ var item = ScrollItemWidget.Setup(serverTemplate, () => currentServer == game, () => currentServer = game);
+ item.GetWidget("TITLE").GetText = () => game.Name;
+ // TODO: Use game.MapTitle once the server supports it
+ item.GetWidget("MAP").GetText = () =>
+ {
+ var map = Game.modData.FindMapByUid(game.Map);
+ return map == null ? "Unknown" : map.Title;
+ };
+ // TODO: Use game.MaxPlayers once the server supports it
+ item.GetWidget("PLAYERS").GetText = () => GetPlayersLabel(game);
+ item.GetWidget("IP").GetText = () => game.Address;
sl.AddChild(item);
}
}
diff --git a/OpenRA.Mods.Cnc/Widgets/Logic/CncServerCreationLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/ServerCreationLogic.cs
similarity index 72%
rename from OpenRA.Mods.Cnc/Widgets/Logic/CncServerCreationLogic.cs
rename to OpenRA.Mods.RA/Widgets/Logic/ServerCreationLogic.cs
index 7b913392c1..aaa8da3bd3 100644
--- a/OpenRA.Mods.Cnc/Widgets/Logic/CncServerCreationLogic.cs
+++ b/OpenRA.Mods.RA/Widgets/Logic/ServerCreationLogic.cs
@@ -13,9 +13,9 @@ using System.Net;
using OpenRA.GameRules;
using OpenRA.Widgets;
-namespace OpenRA.Mods.Cnc.Widgets.Logic
+namespace OpenRA.Mods.RA.Widgets.Logic
{
- public class CncServerCreationLogic
+ public class ServerCreationLogic
{
Widget panel;
Action onCreate;
@@ -24,9 +24,9 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
bool advertiseOnline;
[ObjectCreator.UseCtor]
- public CncServerCreationLogic(Widget widget, Action onExit, Action openLobby)
+ public ServerCreationLogic(Widget widget, Action onExit, Action openLobby)
{
- panel = widget.GetWidget("CREATESERVER_PANEL");
+ panel = widget;
onCreate = openLobby;
this.onExit = onExit;
@@ -34,20 +34,24 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
panel.GetWidget("BACK_BUTTON").OnClick = () => { Widget.CloseWindow(); onExit(); };
panel.GetWidget("CREATE_BUTTON").OnClick = CreateAndJoin;
- panel.GetWidget("MAP_BUTTON").OnClick = () =>
- {
- Widget.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
- {
- { "initialMap", map.Uid },
- { "onExit", () => {} },
- { "onSelect", (Action