diff --git a/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj b/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj index 61f99472d9..5d88daefe5 100644 --- a/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj +++ b/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj @@ -73,6 +73,7 @@ + diff --git a/OpenRA.Mods.Cnc/Widgets/CncLobbyLogic.cs b/OpenRA.Mods.Cnc/Widgets/CncLobbyLogic.cs new file mode 100755 index 0000000000..abeaff5e40 --- /dev/null +++ b/OpenRA.Mods.Cnc/Widgets/CncLobbyLogic.cs @@ -0,0 +1,480 @@ +#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.FileFormats; +using OpenRA.Network; +using OpenRA.Traits; +using OpenRA.Widgets; +using OpenRA.Graphics; + +namespace OpenRA.Mods.Cnc.Widgets +{ + public class CncLobbyLogic : IWidgetDelegate + { + Widget LocalPlayerTemplate, RemotePlayerTemplate, EmptySlotTemplate, EmptySlotTemplateHost; + ScrollPanelWidget Players; + Dictionary CountryNames; + string MapUid; + Map Map; + + public static ColorRamp CurrentColorPreview; + + readonly OrderManager orderManager; + readonly WorldRenderer worldRenderer; + [ObjectCreator.UseCtor] + internal CncLobbyLogic([ObjectCreator.Param( "widget" )] Widget lobby, + [ObjectCreator.Param] OrderManager orderManager, + [ObjectCreator.Param] WorldRenderer worldRenderer) + { + this.orderManager = orderManager; + this.worldRenderer = worldRenderer; + + Game.LobbyInfoChanged += UpdateCurrentMap; + UpdateCurrentMap(); + + CurrentColorPreview = Game.Settings.Player.ColorRamp; + + Players = lobby.GetWidget("PLAYERS"); + LocalPlayerTemplate = Players.GetWidget("TEMPLATE_LOCAL"); + RemotePlayerTemplate = Players.GetWidget("TEMPLATE_REMOTE"); + EmptySlotTemplate = Players.GetWidget("TEMPLATE_EMPTY"); + EmptySlotTemplateHost = Players.GetWidget("TEMPLATE_EMPTY_HOST"); + + var mapPreview = lobby.GetWidget("MAP_PREVIEW"); + mapPreview.Map = () => Map; + mapPreview.OnMouseDown = mi => + { + var map = mapPreview.Map(); + if (map == null || mi.Button != MouseButton.Left + || orderManager.LocalClient.State == Session.ClientState.Ready) + return false; + + var p = map.SpawnPoints + .Select((sp, i) => Pair.New(mapPreview.ConvertToPreview(map, sp), i)) + .Where(a => (a.First - mi.Location).LengthSquared < 64) + .Select(a => a.Second + 1) + .FirstOrDefault(); + + var owned = orderManager.LobbyInfo.Clients.Any(c => c.SpawnPoint == p); + if (p == 0 || !owned) + orderManager.IssueOrder(Order.Command("spawn {0}".F(p))); + + return true; + }; + + mapPreview.SpawnColors = () => + { + var spawns = Map.SpawnPoints; + var sc = new Dictionary(); + + for (int i = 1; i <= spawns.Count(); i++) + { + var client = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.SpawnPoint == i); + if (client == null) + continue; + sc.Add(spawns.ElementAt(i - 1), client.ColorRamp.GetColor(0)); + } + return sc; + }; + + CountryNames = Rules.Info["world"].Traits.WithInterface().ToDictionary(a => a.Race, a => a.Name); + CountryNames.Add("random", "Random"); + + var mapButton = lobby.GetWidget("CHANGEMAP_BUTTON"); + mapButton.OnMouseUp = mi => + { + Widget.OpenWindow( "MAP_CHOOSER", new Dictionary { { "orderManager", orderManager }, { "mapName", MapUid } } ); + return true; + }; + + mapButton.IsVisible = () => mapButton.Visible && Game.IsHost; + + var disconnectButton = lobby.GetWidget("DISCONNECT_BUTTON"); + disconnectButton.OnMouseUp = mi => + { + Game.Disconnect(); + Widget.CloseWindow(); + Widget.LoadWidget("MENU_BACKGROUND"); + return true; + }; + + var lockTeamsCheckbox = lobby.GetWidget("LOCKTEAMS_CHECKBOX"); + lockTeamsCheckbox.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.LockTeams; + lockTeamsCheckbox.OnChange += _ => + { + if (Game.IsHost) + orderManager.IssueOrder(Order.Command( + "lockteams {0}".F(!orderManager.LobbyInfo.GlobalSettings.LockTeams))); + }; + + var allowCheats = lobby.GetWidget("ALLOWCHEATS_CHECKBOX"); + allowCheats.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats; + allowCheats.OnChange += _ => + { + if (Game.IsHost) + orderManager.IssueOrder(Order.Command( + "allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats))); + }; + + var startGameButton = lobby.GetWidget("START_GAME_BUTTON"); + startGameButton.OnMouseUp = mi => + { + mapButton.Visible = false; + disconnectButton.Visible = false; + lockTeamsCheckbox.Visible = false; + orderManager.IssueOrder(Order.Command("startgame")); + return true; + }; + + // Todo: Only show if the map requirements are met for player slots + startGameButton.IsVisible = () => Game.IsHost; + Game.LobbyInfoChanged += UpdatePlayerList; + + Game.AddChatLine += lobby.GetWidget("CHAT_DISPLAY").AddLine; + + bool teamChat = false; + var chatLabel = lobby.GetWidget("LABEL_CHATTYPE"); + var chatTextField = lobby.GetWidget("CHAT_TEXTFIELD"); + chatTextField.OnEnterKey = () => + { + if (chatTextField.Text.Length == 0) + return true; + + var order = (teamChat) ? Order.TeamChat(chatTextField.Text) : Order.Chat(chatTextField.Text); + orderManager.IssueOrder(order); + chatTextField.Text = ""; + return true; + }; + + chatTextField.OnTabKey = () => + { + teamChat ^= true; + chatLabel.Text = (teamChat) ? "Team:" : "Chat:"; + return true; + }; + } + + void UpdatePlayerColor(float hf, float sf, float lf, float r) + { + var ramp = new ColorRamp((byte) (hf*255), (byte) (sf*255), (byte) (lf*255), (byte)(r*255)); + Game.Settings.Player.ColorRamp = ramp; + Game.Settings.Save(); + orderManager.IssueOrder(Order.Command("color {0}".F(ramp))); + } + + void UpdateColorPreview(float hf, float sf, float lf, float r) + { + CurrentColorPreview = new ColorRamp((byte)(hf * 255), (byte)(sf * 255), (byte)(lf * 255), (byte)(r * 255)); + } + + void UpdateCurrentMap() + { + 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("TITLE"); + title.Text = orderManager.LobbyInfo.GlobalSettings.ServerName; + } + + Session.Client GetClientInSlot(Session.Slot slot) + { + return orderManager.LobbyInfo.ClientInSlot( slot ); + } + + bool ShowSlotDropDown(Session.Slot slot, ButtonWidget name, bool showBotOptions) + { + var dropDownOptions = new List> + { + new Pair( "Open", + () => orderManager.IssueOrder( Order.Command( "slot_open " + slot.Index ) )), + new Pair( "Closed", + () => orderManager.IssueOrder( Order.Command( "slot_close " + slot.Index ) )), + }; + + if (showBotOptions) + { + var bots = Rules.Info["player"].Traits.WithInterface().Select(t => t.Name); + bots.Do(bot => + dropDownOptions.Add(new Pair("Bot: {0}".F(bot), + () => orderManager.IssueOrder(Order.Command("slot_bot {0} {1}".F(slot.Index, bot)))))); + } + + DropDownButtonWidget.ShowDropDown( name, + dropDownOptions, + (ac, w) => new LabelWidget + { + Bounds = new Rectangle(0, 0, w, 24), + Text = " {0}".F(ac.First), + OnMouseUp = mi => { ac.Second(); return true; }, + }); + return true; + } + + bool ShowRaceDropDown(Session.Slot s, ButtonWidget race) + { + if (Map.Players[s.MapPlayer].LockRace) + return false; + + var dropDownOptions = new List>(); + foreach (var c in CountryNames) + { + var cc = c; + dropDownOptions.Add(new Pair( cc.Key, + () => orderManager.IssueOrder( Order.Command("race "+cc.Key) )) ); + }; + + DropDownButtonWidget.ShowDropDown( race, + dropDownOptions, + (ac, w) => + { + var ret = new LabelWidget + { + Bounds = new Rectangle(0, 0, w, 24), + Text = " {0}".F(CountryNames[ac.First]), + OnMouseUp = mi => { ac.Second(); return true; }, + }; + + ret.AddChild(new ImageWidget + { + Bounds = new Rectangle(5, 5, 40, 15), + GetImageName = () => ac.First, + GetImageCollection = () => "flags", + }); + return ret; + }); + return true; + } + + bool ShowTeamDropDown(ButtonWidget team) + { + var dropDownOptions = new List>(); + for (int i = 0; i <= Map.PlayerCount; i++) + { + var ii = i; + dropDownOptions.Add(new Pair( ii == 0 ? "-" : ii.ToString(), + () => orderManager.IssueOrder( Order.Command("team "+ii) )) ); + }; + + DropDownButtonWidget.ShowDropDown( team, + dropDownOptions, + (ac, w) => new LabelWidget + { + Bounds = new Rectangle(0, 0, w, 24), + Text = " {0}".F(ac.First), + OnMouseUp = mi => { ac.Second(); return true; }, + }); + return true; + } + + bool ShowColorDropDown(Session.Slot s, ButtonWidget color) + { + if (Map.Players[s.MapPlayer].LockColor) + return false; + + var colorChooser = Game.modData.WidgetLoader.LoadWidget( new Dictionary() { {"worldRenderer", worldRenderer} }, null, "COLOR_CHOOSER" ); + var hueSlider = colorChooser.GetWidget("HUE_SLIDER"); + hueSlider.SetOffset(orderManager.LocalClient.ColorRamp.H / 255f); + + var satSlider = colorChooser.GetWidget("SAT_SLIDER"); + satSlider.SetOffset(orderManager.LocalClient.ColorRamp.S / 255f); + + var lumSlider = colorChooser.GetWidget("LUM_SLIDER"); + lumSlider.SetOffset(orderManager.LocalClient.ColorRamp.L / 255f); + + var rangeSlider = colorChooser.GetWidget("RANGE_SLIDER"); + rangeSlider.SetOffset(orderManager.LocalClient.ColorRamp.R / 255f); + + hueSlider.OnChange += _ => UpdateColorPreview(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset()); + satSlider.OnChange += _ => UpdateColorPreview(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset()); + lumSlider.OnChange += _ => UpdateColorPreview(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset()); + rangeSlider.OnChange += _ => UpdateColorPreview(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset()); + UpdateColorPreview(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset()); + + DropDownButtonWidget.ShowDropPanel(color, colorChooser, new List() {colorChooser.GetWidget("BUTTON_OK")}, () => { + UpdateColorPreview(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset()); + UpdatePlayerColor(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset()); + return true; + }); + return true; + } + + void UpdatePlayerList() + { + // This causes problems for people who are in the process of editing their names (the widgets vanish from beneath them) + // Todo: handle this nicer + Players.RemoveChildren(); + + foreach (var slot in orderManager.LobbyInfo.Slots) + { + var s = slot; + var c = GetClientInSlot(s); + Widget template; + + if (c == null) + { + if (Game.IsHost) + { + if (slot.Spectator) + { + template = EmptySlotTemplateHost.Clone(); + var name = template.GetWidget("NAME"); + name.GetText = () => s.Closed ? "Closed" : "Open"; + name.OnMouseDown = _ => ShowSlotDropDown(s, name, false); + var btn = template.GetWidget("JOIN"); + btn.GetText = () => "Spectate in this slot"; + } + else + { + template = EmptySlotTemplateHost.Clone(); + var name = template.GetWidget("NAME"); + name.GetText = () => s.Closed ? "Closed" : (s.Bot == null) ? "Open" : s.Bot; + name.OnMouseDown = _ => ShowSlotDropDown(s, name, Map.Players[ s.MapPlayer ].AllowBots); + } + } + else + { + template = EmptySlotTemplate.Clone(); + var name = template.GetWidget("NAME"); + name.GetText = () => s.Closed ? "Closed" : (s.Bot == null) ? "Open" : s.Bot; + + if (slot.Spectator) + { + var btn = template.GetWidget("JOIN"); + btn.GetText = () => "Spectate in this slot"; + } + } + + var join = template.GetWidget("JOIN"); + if (join != null) + { + join.OnMouseUp = _ => { orderManager.IssueOrder(Order.Command("slot " + s.Index)); return true; }; + join.IsVisible = () => !s.Closed && s.Bot == null && orderManager.LocalClient.State != Session.ClientState.Ready; + } + + var bot = template.GetWidget("BOT"); + if (bot != null) + bot.IsVisible = () => s.Bot != null; + } + else if (c.Index == orderManager.LocalClient.Index && c.State != Session.ClientState.Ready) + { + template = LocalPlayerTemplate.Clone(); + var name = template.GetWidget("NAME"); + name.Text = c.Name; + name.OnEnterKey = () => + { + name.Text = name.Text.Trim(); + if (name.Text.Length == 0) + name.Text = c.Name; + + name.LoseFocus(); + if (name.Text == c.Name) + return true; + + orderManager.IssueOrder(Order.Command("name " + name.Text)); + Game.Settings.Player.Name = name.Text; + Game.Settings.Save(); + return true; + }; + name.OnLoseFocus = () => name.OnEnterKey(); + + var color = template.GetWidget("COLOR"); + color.OnMouseUp = _ => ShowColorDropDown(s, color); + + var colorBlock = color.GetWidget("COLORBLOCK"); + colorBlock.GetColor = () => c.ColorRamp.GetColor(0); + + var faction = template.GetWidget("FACTION"); + faction.OnMouseDown = _ => ShowRaceDropDown(s, faction); + + var factionname = faction.GetWidget("FACTIONNAME"); + factionname.GetText = () => CountryNames[c.Country]; + var factionflag = faction.GetWidget("FACTIONFLAG"); + factionflag.GetImageName = () => c.Country; + factionflag.GetImageCollection = () => "flags"; + + var team = template.GetWidget("TEAM"); + team.OnMouseDown = _ => ShowTeamDropDown(team); + team.GetText = () => (c.Team == 0) ? "-" : c.Team.ToString(); + + var status = template.GetWidget("STATUS"); + status.IsChecked = () => c.State == Session.ClientState.Ready; + status.OnChange += CycleReady; + + var spectator = template.GetWidget("SPECTATOR"); + + Session.Slot slot1 = slot; + color.IsVisible = () => !slot1.Spectator; + colorBlock.IsVisible = () => !slot1.Spectator; + faction.IsVisible = () => !slot1.Spectator; + factionname.IsVisible = () => !slot1.Spectator; + factionflag.IsVisible = () => !slot1.Spectator; + team.IsVisible = () => !slot1.Spectator; + spectator.IsVisible = () => slot1.Spectator || slot1.Bot != null; + } + else + { + template = RemotePlayerTemplate.Clone(); + template.GetWidget("NAME").GetText = () => c.Name; + var color = template.GetWidget("COLOR"); + color.GetColor = () => c.ColorRamp.GetColor(0); + + var faction = template.GetWidget("FACTION"); + var factionname = faction.GetWidget("FACTIONNAME"); + factionname.GetText = () => CountryNames[c.Country]; + var factionflag = faction.GetWidget("FACTIONFLAG"); + factionflag.GetImageName = () => c.Country; + factionflag.GetImageCollection = () => "flags"; + + var team = template.GetWidget("TEAM"); + team.GetText = () => (c.Team == 0) ? "-" : c.Team.ToString(); + + var status = template.GetWidget("STATUS"); + status.IsChecked = () => c.State == Session.ClientState.Ready; + if (c.Index == orderManager.LocalClient.Index) + status.OnChange += CycleReady; + + var spectator = template.GetWidget("SPECTATOR"); + + Session.Slot slot1 = slot; + color.IsVisible = () => !slot1.Spectator; + faction.IsVisible = () => !slot1.Spectator; + factionname.IsVisible = () => !slot1.Spectator; + factionflag.IsVisible = () => !slot1.Spectator; + team.IsVisible = () => !slot1.Spectator; + spectator.IsVisible = () => slot1.Spectator || slot1.Bot != null; + + var kickButton = template.GetWidget("KICK"); + kickButton.IsVisible = () => Game.IsHost && c.Index != orderManager.LocalClient.Index; + kickButton.OnMouseUp = mi => + { + orderManager.IssueOrder(Order.Command("kick " + c.Slot)); + return true; + }; + } + + template.Id = "SLOT_{0}".F(s.Index); + template.IsVisible = () => true; + Players.AddChild(template); + } + } + + bool SpawnPointAvailable(int index) { return (index == 0) || orderManager.LobbyInfo.Clients.All(c => c.SpawnPoint != index); } + + void CycleReady(bool ready) + { + orderManager.IssueOrder(Order.Command("ready")); + } + } +} diff --git a/mods/cnc/chrome/lobby.yaml b/mods/cnc/chrome/lobby.yaml new file mode 100644 index 0000000000..d16b9034ac --- /dev/null +++ b/mods/cnc/chrome/lobby.yaml @@ -0,0 +1,430 @@ +Container@SERVER_LOBBY: + Id:SERVER_LOBBY + Delegate:CncLobbyLogic + X:(WINDOW_RIGHT - WIDTH)/2 + Y:(WINDOW_BOTTOM - 500)/2 + Width:740 + Height:535 + Children: + Label@TITLE: + Id:TITLE + Width:740 + Y:0-25 + Font:BigBold + Contrast:true + Align:Center + Background@bg: + Width:740 + Height:500 + Background:panel-black + Children: + Background@MAP_BG: + X:PARENT_RIGHT-15-WIDTH + Y:30 + Width:194 + Height:194 + Background:panel-darkred + Children: + MapPreview@MAP_PREVIEW: + Id:MAP_PREVIEW + X:1 + Y:1 + Width:192 + Height:192 + Checkbox@LOCKTEAMS_CHECKBOX: + Id:LOCKTEAMS_CHECKBOX + X:PARENT_RIGHT-209 + Y:230 + Width:80 + Height:20 + Text: Lock Teams + Checkbox@ALLOWCHEATS_CHECKBOX: + Id:ALLOWCHEATS_CHECKBOX + X:PARENT_RIGHT-209 + Y:255 + Width:80 + Height:20 + Text: Allow Cheats + ScrollPanel@PLAYERS: + Id:PLAYERS + X:15 + Y:30 + Width:504 + ItemSpacing:5 + Height:245 + Children: + Container@TEMPLATE_LOCAL: + Id:TEMPLATE_LOCAL + X:5 + Y:0 + Width:475 + Height:25 + Visible:false + Children: + TextField@NAME: + Id:NAME + Text:Name + Width:150 + Height:25 + X:0 + Y:0 + MaxLength:16 + DropDownButton@COLOR: + Id:COLOR + Width:80 + Height:25 + X:160 + Y:0 + Children: + ColorBlock@COLORBLOCK: + Id:COLORBLOCK + X:5 + Y:6 + Width:PARENT_RIGHT-35 + Height:PARENT_BOTTOM-12 + DropDownButton@FACTION: + Id:FACTION + Width:130 + Height:25 + X:250 + Y:0 + Children: + Image@FACTIONFLAG: + Id:FACTIONFLAG + Width:30 + Height:15 + X:5 + Y:5 + Label@FACTIONNAME: + Id:FACTIONNAME + Text:Faction + Width:60 + Height:25 + X:40 + Y:0 + DropDownButton@TEAM: + Id:TEAM + Text:Team + Width:48 + Height:25 + X:390 + Y:0 + Checkbox@STATUS: + Id:STATUS + X:448 + Y:2 + Width:20 + Height:20 + Label@SPECTATOR: + Id:SPECTATOR + Text:Spectator + Width:278 + Height:25 + X:160 + Y:0 + Align:Center + Bold:True + Container@TEMPLATE_REMOTE: + Id:TEMPLATE_REMOTE + X:5 + Y:0 + Width:475 + Height:25 + Visible:false + Children: + Label@NAME: + Id:NAME + Text:Name + Width:145 + Height:25 + X:5 + Y:0-1 + Button@KICK: + Id:KICK + Text:X + Width:25 + Height:23 + X:125 + Y:2 + Bold:Yes + ColorBlock@COLOR: + Id:COLOR + X:165 + Y:6 + Width:45 + Height:13 + Label@FACTION: + Id:FACTION + Width:130 + Height:25 + X:250 + Y:0 + Children: + Image@FACTIONFLAG: + Id:FACTIONFLAG + Width:30 + Height:15 + X:5 + Y:5 + Label@FACTIONNAME: + Id:FACTIONNAME + Text:Faction + Width:60 + Height:25 + X:40 + Y:0 + Label@TEAM: + Id:TEAM + Text:Team + Width:23 + Height:25 + Align:Center + X:390 + Y:0 + Checkbox@STATUS: + Id:STATUS + X:448 + Y:2 + Width:20 + Height:20 + Label@SPECTATOR: + Id:SPECTATOR + Text:Spectator + Width:278 + Height:25 + X:160 + Y:0 + Align:Center + Bold:True + Container@TEMPLATE_EMPTY: + Id:TEMPLATE_EMPTY + X:5 + Y:0 + Width:475 + Height:25 + Visible:false + Children: + Label@NAME: + Id:NAME + Text:Name + Width:145 + Height:25 + X:5 + Y:0-1 + Button@JOIN: + Id:JOIN + Text:Play in this slot + Width:278 + Height:25 + X:160 + Y:0 + Label@BOT: + Id:BOT + Text:Bot + Width:278 + Height:25 + X:160 + Y:0 + Align:Center + Bold:True + Container@TEMPLATE_EMPTY_HOST: + Id:TEMPLATE_EMPTY_HOST + X:5 + Y:0 + Width:400 + Height:25 + Visible:false + Children: + DropDownButton@NAME: + Id:NAME + Text:Name + Width:150 + Height:25 + X:0 + Y:0 + Button@JOIN: + Id:JOIN + Text:Play in this slot + Width:278 + Height:25 + X:160 + Y:0 + Label@BOT: + Id:BOT + Text:Bot + Width:278 + Height:25 + X:160 + Y:0 + Align:Center + Bold:True + Container@LABEL_CONTAINER: + X:25 + Y:5 + Children: + Label@LABEL_LOBBY_NAME: + Id:LABEL_LOBBY_NAME + Width:150 + Height:25 + X:0 + Y:0 + Text:Name + Align:Center + Bold:True + Label@LABEL_LOBBY_COLOR: + Id:LABEL_LOBBY_COLOR + Width:80 + Height:25 + X:160 + Y:0 + Text:Color + Align:Center + Bold:True + Label@LABEL_LOBBY_FACTION: + Id:LABEL_LOBBY_FACTION + Width:130 + Height:25 + X:250 + Y:0 + Text:Faction + Align:Center + Bold:True + Label@LABEL_LOBBY_TEAM: + Id:LABEL_LOBBY_TEAM + Width:48 + Height:25 + X:390 + Y:0 + Text:Team + Align:Center + Bold:True + Label@LABEL_LOBBY_STATUS: + Id:LABEL_LOBBY_STATUS + X:448 + Y:0 + Width:20 + Height:25 + Text:Ready + Align:Left + Bold:True + ChatDisplay@CHAT_DISPLAY: + Id:CHAT_DISPLAY + X:15 + Y:285 + Width:PARENT_RIGHT - 30 + Height:PARENT_BOTTOM - 55 - 275 + Notification: beepy2.aud + TextField@CHAT_TEXTFIELD: + Id:CHAT_TEXTFIELD + X:15 + Y:PARENT_BOTTOM - 15 - HEIGHT + LeftMargin:50 + Width:PARENT_RIGHT - 30 + Height:25 + Children: + Label@LABEL_CHATTYPE: + Id:LABEL_CHATTYPE + Y:0-1 + Width:45 + Height:25 + Align:Right + Text:Chat: + CncMenuButton@START_GAME_BUTTON: + Id:START_GAME_BUTTON + X:0 + Y:499 + Width:140 + Height:35 + Text:Start Game + CncMenuButton@CHANGEMAP_BUTTON: + Id:CHANGEMAP_BUTTON + X:150 + Y:499 + Width:140 + Height:35 + Text:Change Map + CncMenuButton@DISCONNECT_BUTTON: + Id:DISCONNECT_BUTTON + X:600 + Y:499 + Width:140 + Height:35 + Text:Leave Game +Background@COLOR_CHOOSER: + Id:COLOR_CHOOSER + Background:dialog2 + Width:310 + Height:120 + Children: + Button@BUTTON_OK: + Id:BUTTON_OK + X:210 + Y:85 + Width:90 + Height:25 + Text:Ok + Bold:True + ShpImage@FACT: + Id:FACT + X:220 + Y:10 + Image:fact + Palette:colorpicker + Label@HUE_LABEL: + X:0 + Y:5 + Width:40 + Height:20 + Align: Right + Text: Hue: + Slider@HUE: + Id:HUE_SLIDER + X:43 + Y:10 + Width:160 + Height:20 + Ticks:5 + Label@SAT_LABEL: + X:0 + Y:30 + Width:40 + Height:20 + Align: Right + Text: Sat: + Slider@SAT: + Id:SAT_SLIDER + X:43 + Y:35 + Width:160 + Height:20 + Ticks:5 + Label@LUM_LABEL: + X:0 + Y:55 + Width:40 + Height:20 + Align: Right + Text: Lum: + Slider@LUM: + Id:LUM_SLIDER + X:43 + Y:60 + Width:160 + Height:20 + Ticks:5 + Range:0.2,1 + Label@RANGE_LABEL: + X:0 + Y:80 + Width:40 + Height:20 + Align: Right + Text: Ran: + Slider@RANGE: + Id:RANGE_SLIDER + X:43 + Y:85 + Width:160 + Height:20 + Ticks:5 + Range:0,0.25 diff --git a/mods/cnc/chrome/unused/mapchooser.yaml b/mods/cnc/chrome/unused/mapchooser.yaml new file mode 100644 index 0000000000..bcdac87c23 --- /dev/null +++ b/mods/cnc/chrome/unused/mapchooser.yaml @@ -0,0 +1,214 @@ +Background@MAP_CHOOSER: + Id:MAP_CHOOSER + X:(WINDOW_RIGHT - WIDTH)/2 + Y:(WINDOW_BOTTOM - HEIGHT)/2 + Delegate:MapChooserDelegate + Width:800 + Height:600 + Children: + Label@MAPCHOOSER_TITLE: + X:0 + Y:17 + Align:Center + Width:800 + Height:20 + Text:Choose Map + Bold:True + ScrollPanel@MAP_LIST: + Id:MAP_LIST + X:20 + Y:67 + Width:504 + Height:474 + Children: + Container@MAP_TEMPLATE: + Id:MAP_TEMPLATE + Width:PARENT_RIGHT-28 + Height:25 + X:2 + Y:0 + Visible:false + Children: + Label@TITLE: + X:10 + Id:TITLE + Width:PARENT_RIGHT-100 + Height:25 + Label@PLAYERS: + Id:PLAYERS + X:PARENT_RIGHT-150 + Width:30 + Height:25 + Label@TYPE: + Id:TYPE + Width:90 + X:PARENT_RIGHT-100 + Align:Right + Height:25 + Container@MAP_LABELS: + Width:494 + Height:25 + X:25 + Y:40 + Children: + Label@TITLE: + Width:125 + Height:25 + X:0 + Y:0 + Text:Title + Align:Center + Bold:True + Label@PLAYERS: + Text:Players + Bold:true + Width:50 + X:304 + Height:25 + Label@TYPE: + Text:Type + Bold:true + Width:50 + X:420 + Height:25 + Background@MAPCHOOSER_MAP_BG: + X:PARENT_RIGHT-268 + Y:50 + Width:252 + Height:252 + Background:dialog3 + Children: + MapPreview@MAPCHOOSER_MAP_PREVIEW: + Id:MAPCHOOSER_MAP_PREVIEW + X:4 + Y:4 + Width:244 + Height:244 + Container@MAP_LABEL_CONTAINER: + Width:70 + Height:200 + X:PARENT_RIGHT - 255 + Y:311 + Children: + Label@CURMAP_TITLE_LABEL: + Id:CURMAP_TITLE_LABEL + X:0 + Y:0 + Align:Right + Width:70 + Height:20 + Text:Title: + Bold:True + Label@CURMAP_TITLE: + Id:CURMAP_TITLE + X:75 + Y:0 + Align:Left + Width:70 + Height:20 + Label@CURMAP_AUTHOR_LABEL: + Id:CURMAP_AUTHOR_LABEL + X:0 + Y:20 + Align:Right + Width:70 + Height:20 + Text:Author: + Bold:True + Label@CURMAP_AUTHOR: + Id:CURMAP_AUTHOR + X:75 + Y:20 + Align:Left + Width:175 + Height:20 + WordWrap:True + Label@CURMAP_SIZE_LABEL: + Id:CURMAP_SIZE_LABEL + X:0 + Y:40 + Align:Right + Width:70 + Height:20 + Text:Size: + Bold:True + Label@CURMAP_SIZE: + Id:CURMAP_SIZE + X:75 + Y:40 + Align:Left + Width:70 + Height:20 + Label@CURMAP_THEATER_LABEL: + Id:CURMAP_THEATER_LABEL + X:0 + Y:60 + Align:Right + Width:70 + Height:20 + Text:Theater: + Bold:True + Label@CURMAP_THEATER: + Id:CURMAP_THEATER + X:75 + Y:60 + Align:Left + Width:70 + Height:20 + Label@CURMAP_PLAYERS_LABEL: + Id:CURMAP_PLAYERS_LABEL + X:0 + Y:80 + Align:Right + Width:70 + Height:20 + Text:Players: + Bold:True + Label@CURMAP_PLAYERS: + Id:CURMAP_PLAYERS + X:75 + Y:80 + Align:Left + Width:70 + Height:20 + Label@CURMAP_DESC_LABEL: + Id:CURMAP_DESC_LABEL + X:0 + Y:100 + Align:Right + Width:70 + Height:20 + Text:Desc: + Bold:True + Label@CURMAP_DESC: + Id:CURMAP_DESC + X:75 + Y:100 + Align:Left + Width:170 + Height:20 + WordWrap:True + Button@BUTTON_OK: + Id:BUTTON_OK + X:PARENT_RIGHT - 295 + Y:PARENT_BOTTOM - 49 + Width:120 + Height:25 + Text:Ok + Bold:True + Button@BUTTON_CANCEL: + Id:BUTTON_CANCEL + X:PARENT_RIGHT-154 + Y:PARENT_BOTTOM-49 + Width:120 + Height:25 + Text:Cancel + Bold:True + Button@BUTTON_INSTALL: + Id:BUTTON_INSTALL + X:20 + Y:PARENT_BOTTOM-49 + Width:120 + Height:25 + Text:Install Map + Bold:True \ No newline at end of file diff --git a/mods/cnc/mod.yaml b/mods/cnc/mod.yaml index 2480782b5b..66fcab430a 100644 --- a/mods/cnc/mod.yaml +++ b/mods/cnc/mod.yaml @@ -63,6 +63,7 @@ ChromeLayout: mods/cnc/chrome/mainmenu.yaml mods/cnc/chrome/serverbrowser.yaml mods/cnc/chrome/directconnect.yaml + mods/cnc/chrome/lobby.yaml Weapons: mods/cnc/weapons.yaml diff --git a/mods/cnc/uibits/panel.png b/mods/cnc/uibits/panel.png new file mode 100644 index 0000000000..4fd615cd05 Binary files /dev/null and b/mods/cnc/uibits/panel.png differ