Generalize the map chooser to work anywhere. Hook it up in server creation.

This commit is contained in:
Paul Chote
2011-05-08 13:51:43 +12:00
parent 1c1b89948a
commit 1881a6b713
6 changed files with 151 additions and 16 deletions

View File

@@ -76,6 +76,7 @@
<Compile Include="Widgets\CncLobbyLogic.cs" /> <Compile Include="Widgets\CncLobbyLogic.cs" />
<Compile Include="Widgets\CncReplayBrowserLogic.cs" /> <Compile Include="Widgets\CncReplayBrowserLogic.cs" />
<Compile Include="Widgets\CncServerCreationLogic.cs" /> <Compile Include="Widgets\CncServerCreationLogic.cs" />
<Compile Include="Widgets\CncMapChooserLogic.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj"> <ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">

View File

@@ -136,7 +136,21 @@ namespace OpenRA.Mods.Cnc.Widgets
CountryNames.Add("random", "Random"); CountryNames.Add("random", "Random");
var mapButton = lobby.GetWidget<CncMenuButtonWidget>("CHANGEMAP_BUTTON"); var mapButton = lobby.GetWidget<CncMenuButtonWidget>("CHANGEMAP_BUTTON");
mapButton.OnClick = () => Widget.OpenWindow( "MAP_CHOOSER", new Dictionary<string, object>{ { "orderManager", orderManager }, { "mapName", MapUid } } ); mapButton.OnClick = () =>
{
var onSelect = new Action<Map>(m =>
{
orderManager.IssueOrder(Order.Command("map " + m.Uid));
Widget.CloseWindow();
});
Widget.OpenWindow( "MAPCHOOSER_PANEL", new Dictionary<string, object>
{
{ "initialMap", Map },
{ "onExit", new Action(() => Widget.CloseWindow()) },
{ "onSelect", onSelect }
});
};
mapButton.IsVisible = () => mapButton.Visible && Game.IsHost; mapButton.IsVisible = () => mapButton.Visible && Game.IsHost;
var disconnectButton = lobby.GetWidget<CncMenuButtonWidget>("DISCONNECT_BUTTON"); var disconnectButton = lobby.GetWidget<CncMenuButtonWidget>("DISCONNECT_BUTTON");

View File

@@ -0,0 +1,106 @@
#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.Drawing;
using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Network;
using OpenRA.Widgets;
using System.IO;
using System;
namespace OpenRA.Mods.Cnc.Widgets
{
public class CncMapChooserLogic : IWidgetDelegate
{
Map Map = null;
Widget scrollpanel;
Widget itemTemplate;
[ObjectCreator.UseCtor]
internal CncMapChooserLogic([ObjectCreator.Param] Widget widget,
[ObjectCreator.Param] Map initialMap,
[ObjectCreator.Param] Action onExit,
[ObjectCreator.Param] Action<Map> onSelect)
{
if (initialMap != null)
Map = initialMap;
else
Map = Game.modData.AvailableMaps.FirstOrDefault(m => m.Value.Selectable).Value;
var panel = widget.GetWidget("MAPCHOOSER_PANEL");
panel.GetWidget<MapPreviewWidget>("MAP_PREVIEW").Map = () => Map;
panel.GetWidget<LabelWidget>("CURMAP_TITLE").GetText = () => Map.Title;
panel.GetWidget<LabelWidget>("CURMAP_AUTHOR").GetText = () => Map.Author;
panel.GetWidget<LabelWidget>("CURMAP_DESC").GetText = () => Map.Description;
panel.GetWidget<LabelWidget>("CURMAP_DESC_LABEL").IsVisible = () => Map.Description != null;
panel.GetWidget<LabelWidget>("CURMAP_SIZE").GetText = () => "{0}x{1}".F(Map.Bounds.Width, Map.Bounds.Height);
panel.GetWidget<LabelWidget>("CURMAP_THEATER").GetText = () => Rules.TileSets[Map.Tileset].Name;
panel.GetWidget<LabelWidget>("CURMAP_PLAYERS").GetText = () => Map.PlayerCount.ToString();
panel.GetWidget<CncMenuButtonWidget>("BUTTON_OK").OnClick = () => onSelect(Map);
panel.GetWidget<CncMenuButtonWidget>("BUTTON_CANCEL").OnClick = onExit;
panel.GetWidget<CncMenuButtonWidget>("BUTTON_INSTALL").IsDisabled = () => true;
panel.GetWidget<CncMenuButtonWidget>("BUTTON_INSTALL").OnClick = () => InstallMap();
scrollpanel = panel.GetWidget<ScrollPanelWidget>("MAP_LIST");
itemTemplate = scrollpanel.GetWidget<ContainerWidget>("MAP_TEMPLATE");
EnumerateMaps();
}
void EnumerateMaps()
{
scrollpanel.RemoveChildren();
foreach (var kv in Game.modData.AvailableMaps.OrderBy(kv => kv.Value.Title).OrderBy(kv => kv.Value.PlayerCount))
{
var map = kv.Value;
if (!map.Selectable)
continue;
var template = itemTemplate.Clone() as ContainerWidget;
template.GetBackground = () => ((Map == map) ? "panel-darkred" : null);
template.OnMouseDown = mi => { if (mi.Button != MouseButton.Left) return false; Map = map; return true; };
template.IsVisible = () => true;
template.GetWidget<LabelWidget>("TITLE").GetText = () => map.Title;
template.GetWidget<LabelWidget>("PLAYERS").GetText = () => "{0}".F(map.PlayerCount);
template.GetWidget<LabelWidget>("TYPE").GetText = () => map.Type;
scrollpanel.AddChild(template);
}
}
bool InstallMap()
{
Game.Utilities.PromptFilepathAsync("Select an OpenRA map file", path =>
{
if (!string.IsNullOrEmpty(path))
Game.RunAfterTick(() => InstallMapInner(path));
});
return true;
}
void InstallMapInner(string path)
{
var toPath = new [] { Platform.SupportDir, "maps", Game.modData.Manifest.Mods[0], Path.GetFileName(path) }.Aggregate(Path.Combine);
// Create directory if required
var dir = Path.GetDirectoryName(toPath);
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
// TODO: Attempt to mount the map and verify that
// it is a valid Game.modData.Manifest.Mods[0] map.
File.Copy(path, toPath, true);
Game.modData.ReloadMaps();
EnumerateMaps();
}
}
}

View File

@@ -12,6 +12,7 @@ using System.Linq;
using System.Net; using System.Net;
using OpenRA.Widgets; using OpenRA.Widgets;
using System; using System;
using System.Collections.Generic;
namespace OpenRA.Mods.Cnc.Widgets namespace OpenRA.Mods.Cnc.Widgets
{ {
@@ -20,6 +21,7 @@ namespace OpenRA.Mods.Cnc.Widgets
Widget panel; Widget panel;
Action onCreate; Action onCreate;
Map map; Map map;
bool advertiseOnline;
[ObjectCreator.UseCtor] [ObjectCreator.UseCtor]
public CncServerCreationLogic([ObjectCreator.Param] Widget widget, public CncServerCreationLogic([ObjectCreator.Param] Widget widget,
[ObjectCreator.Param] Action onExit, [ObjectCreator.Param] Action onExit,
@@ -31,8 +33,16 @@ namespace OpenRA.Mods.Cnc.Widgets
var settings = Game.Settings; var settings = Game.Settings;
panel.GetWidget<CncMenuButtonWidget>("BACK_BUTTON").OnClick = onExit; panel.GetWidget<CncMenuButtonWidget>("BACK_BUTTON").OnClick = onExit;
panel.GetWidget<CncMenuButtonWidget>("CREATE_BUTTON").OnClick = CreateAndJoin; panel.GetWidget<CncMenuButtonWidget>("CREATE_BUTTON").OnClick = CreateAndJoin;
//panel.GetWidget<CncMenuButtonWidget>("MAP_BUTTON").IsDisabled = () => true; panel.GetWidget<CncMenuButtonWidget>("MAP_BUTTON").OnClick = () =>
{
Widget.OpenWindow( "MAPCHOOSER_PANEL", new Dictionary<string, object>
{
{ "initialMap", map },
{ "onExit", new Action(() => Widget.CloseWindow()) },
{ "onSelect", new Action<Map>(m => { map = m; Widget.CloseWindow(); }) }
});
};
map = Game.modData.AvailableMaps.FirstOrDefault(m => m.Value.Selectable).Value; map = Game.modData.AvailableMaps.FirstOrDefault(m => m.Value.Selectable).Value;
panel.GetWidget<MapPreviewWidget>("MAP_PREVIEW").Map = () => map; panel.GetWidget<MapPreviewWidget>("MAP_PREVIEW").Map = () => map;
@@ -41,20 +51,21 @@ namespace OpenRA.Mods.Cnc.Widgets
panel.GetWidget<TextFieldWidget>("SERVER_NAME").Text = settings.Server.Name ?? ""; panel.GetWidget<TextFieldWidget>("SERVER_NAME").Text = settings.Server.Name ?? "";
panel.GetWidget<TextFieldWidget>("LISTEN_PORT").Text = settings.Server.ListenPort.ToString(); panel.GetWidget<TextFieldWidget>("LISTEN_PORT").Text = settings.Server.ListenPort.ToString();
panel.GetWidget<TextFieldWidget>("EXTERNAL_PORT").Text = settings.Server.ExternalPort.ToString(); panel.GetWidget<TextFieldWidget>("EXTERNAL_PORT").Text = settings.Server.ExternalPort.ToString();
panel.GetWidget<CheckboxWidget>("CHECKBOX_ONLINE").Bind(settings.Server, "AdvertiseOnline");
panel.GetWidget<CheckboxWidget>("CHECKBOX_ONLINE").OnChange += _ => settings.Save(); var advertiseCheckbox = panel.GetWidget<CncCheckboxWidget>("ADVERTISE_CHECKBOX");
advertiseCheckbox.IsChecked = () => advertiseOnline;
advertiseCheckbox.OnClick = () => advertiseOnline ^= true;
} }
void CreateAndJoin() void CreateAndJoin()
{ {
var map = Game.modData.AvailableMaps.FirstOrDefault(m => m.Value.Selectable).Key; Game.Settings.Server.Name = panel.GetWidget<TextFieldWidget>("SERVER_NAME").Text;
Game.Settings.Server.Name = panel.GetWidget<TextFieldWidget>("GAME_TITLE").Text;
Game.Settings.Server.ListenPort = int.Parse(panel.GetWidget<TextFieldWidget>("LISTEN_PORT").Text); Game.Settings.Server.ListenPort = int.Parse(panel.GetWidget<TextFieldWidget>("LISTEN_PORT").Text);
Game.Settings.Server.ExternalPort = int.Parse(panel.GetWidget<TextFieldWidget>("EXTERNAL_PORT").Text); Game.Settings.Server.ExternalPort = int.Parse(panel.GetWidget<TextFieldWidget>("EXTERNAL_PORT").Text);
Game.Settings.Server.AdvertiseOnline = advertiseOnline;
Game.Settings.Save(); Game.Settings.Save();
Game.CreateAndJoinServer(Game.Settings, map); Game.CreateAndJoinServer(Game.Settings, map.Uid);
Widget.CloseWindow(); Widget.CloseWindow();
onCreate(); onCreate();
} }

View File

@@ -1,3 +1,6 @@
# TODO: Hook up the description field
# TODO: Hook up the password field
# TODO: Have the advertise checkbox en/disable the external port textfield
Container@CREATESERVER_PANEL: Container@CREATESERVER_PANEL:
Id:CREATESERVER_PANEL Id:CREATESERVER_PANEL
Delegate:CncServerCreationLogic Delegate:CncServerCreationLogic
@@ -98,11 +101,11 @@ Container@CREATESERVER_PANEL:
MaxLength:5 MaxLength:5
Height:25 Height:25
Text:1234 Text:1234
Checkbox@CHECKBOX_ONLINE: CncCheckbox@ADVERTISE_CHECKBOX:
Id:CHECKBOX_ONLINE Id:ADVERTISE_CHECKBOX
X:110 X:110
Y:155 Y:155
Width:275 Width:150
Height:20 Height:20
Text:Advertise Online Text:Advertise Online
Label@PORT_FORWARDING: Label@PORT_FORWARDING:

View File

@@ -1,6 +1,6 @@
Container@MAP_CHOOSER: Container@MAPCHOOSER_PANEL:
Id:MAP_CHOOSER Id:MAPCHOOSER_PANEL
Delegate:MapChooserDelegate Delegate:CncMapChooserLogic
X:(WINDOW_RIGHT - WIDTH)/2 X:(WINDOW_RIGHT - WIDTH)/2
Y:(WINDOW_BOTTOM - 500)/2 Y:(WINDOW_BOTTOM - 500)/2
Width:740 Width:740
@@ -26,7 +26,7 @@ Container@MAP_CHOOSER:
Background:panel-gray Background:panel-gray
Children: Children:
MapPreview@MAP_PREVIEW: MapPreview@MAP_PREVIEW:
Id:MAPCHOOSER_MAP_PREVIEW Id:MAP_PREVIEW
X:1 X:1
Y:1 Y:1
Width:192 Width:192