diff --git a/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj b/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj index dc5d5df41d..8efa9f7037 100644 --- a/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj +++ b/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj @@ -76,6 +76,7 @@ + diff --git a/OpenRA.Mods.Cnc/Widgets/CncLobbyLogic.cs b/OpenRA.Mods.Cnc/Widgets/CncLobbyLogic.cs index 42f06cbde1..1f66642ab9 100755 --- a/OpenRA.Mods.Cnc/Widgets/CncLobbyLogic.cs +++ b/OpenRA.Mods.Cnc/Widgets/CncLobbyLogic.cs @@ -136,7 +136,21 @@ namespace OpenRA.Mods.Cnc.Widgets CountryNames.Add("random", "Random"); var mapButton = lobby.GetWidget("CHANGEMAP_BUTTON"); - mapButton.OnClick = () => Widget.OpenWindow( "MAP_CHOOSER", new Dictionary{ { "orderManager", orderManager }, { "mapName", MapUid } } ); + mapButton.OnClick = () => + { + var onSelect = new Action(m => + { + orderManager.IssueOrder(Order.Command("map " + m.Uid)); + Widget.CloseWindow(); + }); + + Widget.OpenWindow( "MAPCHOOSER_PANEL", new Dictionary + { + { "initialMap", Map }, + { "onExit", new Action(() => Widget.CloseWindow()) }, + { "onSelect", onSelect } + }); + }; mapButton.IsVisible = () => mapButton.Visible && Game.IsHost; var disconnectButton = lobby.GetWidget("DISCONNECT_BUTTON"); diff --git a/OpenRA.Mods.Cnc/Widgets/CncMapChooserLogic.cs b/OpenRA.Mods.Cnc/Widgets/CncMapChooserLogic.cs new file mode 100644 index 0000000000..4a861e4601 --- /dev/null +++ b/OpenRA.Mods.Cnc/Widgets/CncMapChooserLogic.cs @@ -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 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("MAP_PREVIEW").Map = () => Map; + panel.GetWidget("CURMAP_TITLE").GetText = () => Map.Title; + panel.GetWidget("CURMAP_AUTHOR").GetText = () => Map.Author; + panel.GetWidget("CURMAP_DESC").GetText = () => Map.Description; + panel.GetWidget("CURMAP_DESC_LABEL").IsVisible = () => Map.Description != null; + panel.GetWidget("CURMAP_SIZE").GetText = () => "{0}x{1}".F(Map.Bounds.Width, Map.Bounds.Height); + panel.GetWidget("CURMAP_THEATER").GetText = () => Rules.TileSets[Map.Tileset].Name; + panel.GetWidget("CURMAP_PLAYERS").GetText = () => Map.PlayerCount.ToString(); + + panel.GetWidget("BUTTON_OK").OnClick = () => onSelect(Map); + panel.GetWidget("BUTTON_CANCEL").OnClick = onExit; + + panel.GetWidget("BUTTON_INSTALL").IsDisabled = () => true; + panel.GetWidget("BUTTON_INSTALL").OnClick = () => InstallMap(); + + scrollpanel = panel.GetWidget("MAP_LIST"); + itemTemplate = scrollpanel.GetWidget("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("TITLE").GetText = () => map.Title; + template.GetWidget("PLAYERS").GetText = () => "{0}".F(map.PlayerCount); + template.GetWidget("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(); + } + } +} diff --git a/OpenRA.Mods.Cnc/Widgets/CncServerCreationLogic.cs b/OpenRA.Mods.Cnc/Widgets/CncServerCreationLogic.cs index 3408e96351..30ec8fbc1d 100644 --- a/OpenRA.Mods.Cnc/Widgets/CncServerCreationLogic.cs +++ b/OpenRA.Mods.Cnc/Widgets/CncServerCreationLogic.cs @@ -12,6 +12,7 @@ using System.Linq; using System.Net; using OpenRA.Widgets; using System; +using System.Collections.Generic; namespace OpenRA.Mods.Cnc.Widgets { @@ -20,6 +21,7 @@ namespace OpenRA.Mods.Cnc.Widgets Widget panel; Action onCreate; Map map; + bool advertiseOnline; [ObjectCreator.UseCtor] public CncServerCreationLogic([ObjectCreator.Param] Widget widget, [ObjectCreator.Param] Action onExit, @@ -31,8 +33,16 @@ namespace OpenRA.Mods.Cnc.Widgets var settings = Game.Settings; panel.GetWidget("BACK_BUTTON").OnClick = onExit; panel.GetWidget("CREATE_BUTTON").OnClick = CreateAndJoin; - - //panel.GetWidget("MAP_BUTTON").IsDisabled = () => true; + + panel.GetWidget("MAP_BUTTON").OnClick = () => + { + Widget.OpenWindow( "MAPCHOOSER_PANEL", new Dictionary + { + { "initialMap", map }, + { "onExit", new Action(() => Widget.CloseWindow()) }, + { "onSelect", new Action(m => { map = m; Widget.CloseWindow(); }) } + }); + }; map = Game.modData.AvailableMaps.FirstOrDefault(m => m.Value.Selectable).Value; panel.GetWidget("MAP_PREVIEW").Map = () => map; @@ -41,20 +51,21 @@ namespace OpenRA.Mods.Cnc.Widgets panel.GetWidget("SERVER_NAME").Text = settings.Server.Name ?? ""; panel.GetWidget("LISTEN_PORT").Text = settings.Server.ListenPort.ToString(); panel.GetWidget("EXTERNAL_PORT").Text = settings.Server.ExternalPort.ToString(); - panel.GetWidget("CHECKBOX_ONLINE").Bind(settings.Server, "AdvertiseOnline"); - panel.GetWidget("CHECKBOX_ONLINE").OnChange += _ => settings.Save(); + + var advertiseCheckbox = panel.GetWidget("ADVERTISE_CHECKBOX"); + advertiseCheckbox.IsChecked = () => advertiseOnline; + advertiseCheckbox.OnClick = () => advertiseOnline ^= true; } void CreateAndJoin() { - var map = Game.modData.AvailableMaps.FirstOrDefault(m => m.Value.Selectable).Key; - - Game.Settings.Server.Name = panel.GetWidget("GAME_TITLE").Text; + Game.Settings.Server.Name = panel.GetWidget("SERVER_NAME").Text; Game.Settings.Server.ListenPort = int.Parse(panel.GetWidget("LISTEN_PORT").Text); Game.Settings.Server.ExternalPort = int.Parse(panel.GetWidget("EXTERNAL_PORT").Text); + Game.Settings.Server.AdvertiseOnline = advertiseOnline; Game.Settings.Save(); - Game.CreateAndJoinServer(Game.Settings, map); + Game.CreateAndJoinServer(Game.Settings, map.Uid); Widget.CloseWindow(); onCreate(); } diff --git a/mods/cnc/chrome/createserver.yaml b/mods/cnc/chrome/createserver.yaml index c945a5e992..847b57f53b 100644 --- a/mods/cnc/chrome/createserver.yaml +++ b/mods/cnc/chrome/createserver.yaml @@ -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: Id:CREATESERVER_PANEL Delegate:CncServerCreationLogic @@ -98,11 +101,11 @@ Container@CREATESERVER_PANEL: MaxLength:5 Height:25 Text:1234 - Checkbox@CHECKBOX_ONLINE: - Id:CHECKBOX_ONLINE + CncCheckbox@ADVERTISE_CHECKBOX: + Id:ADVERTISE_CHECKBOX X:110 Y:155 - Width:275 + Width:150 Height:20 Text:Advertise Online Label@PORT_FORWARDING: diff --git a/mods/cnc/chrome/mapchooser.yaml b/mods/cnc/chrome/mapchooser.yaml index 30524e233c..1c4b97c340 100644 --- a/mods/cnc/chrome/mapchooser.yaml +++ b/mods/cnc/chrome/mapchooser.yaml @@ -1,6 +1,6 @@ -Container@MAP_CHOOSER: - Id:MAP_CHOOSER - Delegate:MapChooserDelegate +Container@MAPCHOOSER_PANEL: + Id:MAPCHOOSER_PANEL + Delegate:CncMapChooserLogic X:(WINDOW_RIGHT - WIDTH)/2 Y:(WINDOW_BOTTOM - 500)/2 Width:740 @@ -26,7 +26,7 @@ Container@MAP_CHOOSER: Background:panel-gray Children: MapPreview@MAP_PREVIEW: - Id:MAPCHOOSER_MAP_PREVIEW + Id:MAP_PREVIEW X:1 Y:1 Width:192