예제 #1
0
        public static void ShowColorDropDown(DropDownButtonWidget color, Session.Client client,
			OrderManager orderManager, ColorPreviewManagerWidget preview)
        {
            Action<ColorRamp> onSelect = c =>
            {
                if (client.Bot == null)
                {
                    Game.Settings.Player.ColorRamp = c;
                    Game.Settings.Save();
                }

                color.RemovePanel();
                orderManager.IssueOrder(Order.Command("color {0} {1}".F(client.Index, c)));
            };

            Action<ColorRamp> onChange = c => preview.Ramp = c;

            var colorChooser = Game.LoadWidget(orderManager.world, "COLOR_CHOOSER", null, new WidgetArgs()
            {
                { "onSelect", onSelect },
                { "onChange", onChange },
                { "initialRamp", client.ColorRamp }
            });

            color.AttachPanel(colorChooser);
        }
예제 #2
0
        public static void ShowColorDropDown(DropDownButtonWidget color, Session.Client client,
                                             OrderManager orderManager, World world, ColorPreviewManagerWidget preview)
        {
            Action onExit = () =>
            {
                if (client.Bot == null)
                {
                    Game.Settings.Player.Color = preview.Color;
                    Game.Settings.Save();
                }

                color.RemovePanel();
                orderManager.IssueOrder(Order.Command("color {0} {1}".F(client.Index, preview.Color)));
            };

            Action <Color> onChange = c => preview.Color = c;

            var colorChooser = Game.LoadWidget(world, "COLOR_CHOOSER", null, new WidgetArgs()
            {
                { "onChange", onChange },
                { "initialColor", client.Color },
                { "initialFaction", client.Faction }
            });

            color.AttachPanel(colorChooser, onExit);
        }
예제 #3
0
        void ShowLightDiffuseColorDropDown(DropDownButtonWidget color, ColorPreviewManagerWidget preview, World world)
        {
            Action onExit = () =>
            {
                Color c = preview.Color;
                lightDiffuseColor[0]            = float.Parse((Convert.ToSingle(c.R) / 255).ToString("0.0"));
                lightDiffuseColor[1]            = float.Parse((Convert.ToSingle(c.G) / 255).ToString("0.0"));
                lightDiffuseColor[2]            = float.Parse((Convert.ToSingle(c.B) / 255).ToString("0.0"));
                lightDiffuseColorBlock.GetColor = () => c;
                lightDiffuseColorValue.GetText  = () => string.Format("{0}, {1}, {2}", lightDiffuseColor[0].ToString(), lightDiffuseColor[1].ToString(), lightDiffuseColor[2].ToString());
            };

            color.RemovePanel();

            Action <Color> onChange = c => preview.Color = c;

            var colorChooser = Game.LoadWidget(world, "COLOR_CHOOSER", null, new WidgetArgs()
            {
                { "onChange", onChange },
                { "initialColor", Color.FromArgb(
                      Convert.ToInt32(lightDiffuseColor[0] * 255),
                      Convert.ToInt32(lightDiffuseColor[1] * 255),
                      Convert.ToInt32(lightDiffuseColor[2] * 255)
                      ) },
                { "initialFaction", null }
            });

            color.AttachPanel(colorChooser, onExit);
        }
예제 #4
0
        public static void ShowColorDropDown(DropDownButtonWidget color, ColorPreviewManagerWidget preview, World world)
        {
            Action onExit = () =>
            {
                Game.Settings.Player.Color = preview.Color;
                Game.Settings.Save();
            };

            color.RemovePanel();

            Action <HSLColor> onChange = c => preview.Color = c;

            var colorChooser = Game.LoadWidget(world, "COLOR_CHOOSER", null, new WidgetArgs()
            {
                { "onChange", onChange },
                { "initialColor", Game.Settings.Player.Color }
            });

            color.AttachPanel(colorChooser, onExit);
        }
예제 #5
0
		public static void ShowColorDropDown(DropDownButtonWidget color, ColorPreviewManagerWidget preview, World world)
		{
			Action onExit = () =>
			{
				Game.Settings.Player.Color = preview.Color;
				Game.Settings.Save();
			};

			color.RemovePanel();

			Action<HSLColor> onChange = c => preview.Color = c;

			var colorChooser = Game.LoadWidget(world, "COLOR_CHOOSER", null, new WidgetArgs()
			{
				{ "onChange", onChange },
				{ "initialColor", Game.Settings.Player.Color }
			});

			color.AttachPanel(colorChooser, onExit);
		}
예제 #6
0
        public static void SetupEditableColorWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager, World world, ColorPreviewManagerWidget colorPreview)
        {
            var color = parent.Get <DropDownButtonWidget>("COLOR");

            color.IsDisabled  = () => (s != null && s.LockColor) || orderManager.LocalClient.IsReady;
            color.OnMouseDown = _ => ShowColorDropDown(color, c, orderManager, world, colorPreview);

            SetupColorWidget(color, s, c);
        }
예제 #7
0
파일: LobbyLogic.cs 프로젝트: Tsher/OpenRA
        internal LobbyLogic(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;

            var name = lobby.GetOrNull<LabelWidget>("SERVER_NAME");
            if (name != null)
                name.GetText = () => orderManager.LobbyInfo.GlobalSettings.ServerName;

            UpdateCurrentMap();
            Players = lobby.Get<ScrollPanelWidget>("PLAYERS");
            EditablePlayerTemplate = Players.Get("TEMPLATE_EDITABLE_PLAYER");
            NonEditablePlayerTemplate = Players.Get("TEMPLATE_NONEDITABLE_PLAYER");
            EmptySlotTemplate = Players.Get("TEMPLATE_EMPTY");
            EditableSpectatorTemplate = Players.Get("TEMPLATE_EDITABLE_SPECTATOR");
            NonEditableSpectatorTemplate = Players.Get("TEMPLATE_NONEDITABLE_SPECTATOR");
            NewSpectatorTemplate = Players.Get("TEMPLATE_NEW_SPECTATOR");
            colorPreview = lobby.Get<ColorPreviewManagerWidget>("COLOR_MANAGER");
            colorPreview.Color = Game.Settings.Player.Color;

            var mapPreview = lobby.Get<MapPreviewWidget>("MAP_PREVIEW");
            mapPreview.IsVisible = () => Map != null;
            mapPreview.Map = () => Map;
            mapPreview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint( orderManager, mapPreview, Map, mi );
            mapPreview.SpawnClients = () => LobbyUtils.GetSpawnClients(orderManager, Map);

            var mapTitle = lobby.GetOrNull<LabelWidget>("MAP_TITLE");
            if (mapTitle != null)
            {
                mapTitle.IsVisible = () => Map != null;
                mapTitle.GetText = () => Map.Title;
            }

            var mapType = lobby.GetOrNull<LabelWidget>("MAP_TYPE");
            if (mapType != null)
            {
                mapType.IsVisible = () => Map != null;
                mapType.GetText = () => Map.Type;
            }

            var mapAuthor = lobby.GetOrNull<LabelWidget>("MAP_AUTHOR");
            if (mapAuthor != null)
            {
                mapAuthor.IsVisible = () => Map != null;
                mapAuthor.GetText = () => "Created by {0}".F(Map.Author);
            }

            CountryNames = Rules.Info["world"].Traits.WithInterface<CountryInfo>()
                .Where(c => c.Selectable)
                .ToDictionary(a => a.Race, a => a.Name);
            CountryNames.Add("random", "Any");

            var gameStarting = false;

            var mapButton = lobby.Get<ButtonWidget>("CHANGEMAP_BUTTON");
            mapButton.OnClick = () =>
            {
                var onSelect = new Action<Map>(m =>
                {
                    orderManager.IssueOrder(Order.Command("map " + m.Uid));
                    Game.Settings.Server.Map = m.Uid;
                    Game.Settings.Save();
                });

                Ui.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
                {
                    { "initialMap", Map.Uid },
                    { "onExit", () => {} },
                    { "onSelect", onSelect }
                });
            };
            mapButton.IsVisible = () => mapButton.Visible && Game.IsHost;

            var assignTeams = lobby.GetOrNull<DropDownButtonWidget>("ASSIGNTEAMS_DROPDOWNBUTTON");
            if (assignTeams != null)
            {
                assignTeams.IsVisible = () => Game.IsHost;
                assignTeams.IsDisabled = () => gameStarting || orderManager.LobbyInfo.Clients.Count(c => c.Slot != null) < 2
                    || orderManager.LocalClient == null || orderManager.LocalClient.IsReady;

                assignTeams.OnMouseDown = _ =>
                {
                    var options = Enumerable.Range(2, orderManager.LobbyInfo.Clients.Count(c => c.Slot != null).Clamp(2, 8) - 1).Select(d => new DropDownOption
                    {
                        Title = "{0} Teams".F(d),
                        IsSelected = () => false,
                        OnClick = () => orderManager.IssueOrder(Order.Command("assignteams {0}".F(d.ToString())))
                    });
                    Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
                        return item;
                    };
                    assignTeams.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }

            var disconnectButton = lobby.Get<ButtonWidget>("DISCONNECT_BUTTON");
            disconnectButton.OnClick = () => { CloseWindow(); onExit(); };

            var allowCheats = lobby.Get<CheckboxWidget>("ALLOWCHEATS_CHECKBOX");
            allowCheats.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats;
            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 crates = lobby.GetOrNull<CheckboxWidget>("CRATES_CHECKBOX");
            if (crates != null)
            {
                crates.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Crates;
                crates.IsDisabled = () => !Game.IsHost || gameStarting || orderManager.LocalClient == null
                    || orderManager.LocalClient.IsReady; // maybe disable the checkbox if a map forcefully removes CrateDrop?
                crates.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "crates {0}".F(!orderManager.LobbyInfo.GlobalSettings.Crates)));
            }

            var fragileAlliance = lobby.GetOrNull<CheckboxWidget>("FRAGILEALLIANCES_CHECKBOX");
            if (fragileAlliance != null)
            {
                fragileAlliance.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.FragileAlliances;
                fragileAlliance.IsDisabled = () => !Game.IsHost || gameStarting
                    || orderManager.LocalClient == null	|| orderManager.LocalClient.IsReady;
                fragileAlliance.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "fragilealliance {0}".F(!orderManager.LobbyInfo.GlobalSettings.FragileAlliances)));
            };

            var difficulty = lobby.GetOrNull<DropDownButtonWidget>("DIFFICULTY_DROPDOWNBUTTON");
            if (difficulty != null)
            {
                difficulty.IsVisible = () => Map != null && Map.Difficulties != null && Map.Difficulties.Any();
                difficulty.IsDisabled = () => !Game.IsHost || gameStarting || orderManager.LocalClient == null || orderManager.LocalClient.IsReady;
                difficulty.GetText = () => orderManager.LobbyInfo.GlobalSettings.Difficulty;
                difficulty.OnMouseDown = _ =>
                {
                    var options = Map.Difficulties.Select(d => new DropDownOption
                    {
                        Title = d,
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.Difficulty == d,
                        OnClick = () => orderManager.IssueOrder(Order.Command("difficulty {0}".F(d)))
                    });
                    Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
                        return item;
                    };
                    difficulty.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }

            var startGameButton = lobby.Get<ButtonWidget>("START_GAME_BUTTON");
            startGameButton.IsVisible = () => Game.IsHost;
            startGameButton.IsDisabled = () => gameStarting
                || orderManager.LobbyInfo.Slots.Any(sl => sl.Value.Required && orderManager.LobbyInfo.ClientInSlot(sl.Key) == null);
            startGameButton.OnClick = () =>
            {
                gameStarting = true;
                orderManager.IssueOrder(Order.Command("startgame"));
            };

            bool teamChat = false;
            var chatLabel = lobby.Get<LabelWidget>("LABEL_CHATTYPE");
            var chatTextField = lobby.Get<TextFieldWidget>("CHAT_TEXTFIELD");

            chatTextField.OnEnterKey = () =>
            {
                if (chatTextField.Text.Length == 0)
                    return true;

                orderManager.IssueOrder(Order.Chat(teamChat, chatTextField.Text));
                chatTextField.Text = "";
                return true;
            };

            chatTextField.OnTabKey = () =>
            {
                teamChat ^= true;
                chatLabel.Text = (teamChat) ? "Team:" : "Chat:";
                return true;
            };

            chatPanel = lobby.Get<ScrollPanelWidget>("CHAT_DISPLAY");
            chatTemplate = chatPanel.Get("CHAT_TEMPLATE");
            chatPanel.RemoveChildren();

            var musicButton = lobby.GetOrNull<ButtonWidget>("MUSIC_BUTTON");
            if (musicButton != null)
                musicButton.OnClick = () => Ui.OpenWindow("MUSIC_PANEL", new WidgetArgs
                    { { "onExit", () => {} } });

            // 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<IBotInfo>().Select(t => t.Name).FirstOrDefault();
                    var botController = orderManager.LobbyInfo.Clients.Where(c => c.IsAdmin).FirstOrDefault();
                    if (slot != null && bot != null)
                        orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot, botController.Index, bot)));
                });
        }
예제 #8
0
        internal LobbyLogic(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;

            var name = lobby.GetOrNull <LabelWidget>("SERVER_NAME");

            if (name != null)
            {
                name.GetText = () => orderManager.LobbyInfo.GlobalSettings.ServerName;
            }

            UpdateCurrentMap();
            Players = lobby.Get <ScrollPanelWidget>("PLAYERS");
            EditablePlayerTemplate       = Players.Get("TEMPLATE_EDITABLE_PLAYER");
            NonEditablePlayerTemplate    = Players.Get("TEMPLATE_NONEDITABLE_PLAYER");
            EmptySlotTemplate            = Players.Get("TEMPLATE_EMPTY");
            EditableSpectatorTemplate    = Players.Get("TEMPLATE_EDITABLE_SPECTATOR");
            NonEditableSpectatorTemplate = Players.Get("TEMPLATE_NONEDITABLE_SPECTATOR");
            NewSpectatorTemplate         = Players.Get("TEMPLATE_NEW_SPECTATOR");
            colorPreview       = lobby.Get <ColorPreviewManagerWidget>("COLOR_MANAGER");
            colorPreview.Color = Game.Settings.Player.Color;

            var mapPreview = lobby.Get <MapPreviewWidget>("MAP_PREVIEW");

            mapPreview.IsVisible    = () => Map != null;
            mapPreview.Map          = () => Map;
            mapPreview.OnMouseDown  = mi => LobbyUtils.SelectSpawnPoint(orderManager, mapPreview, Map, mi);
            mapPreview.SpawnClients = () => LobbyUtils.GetSpawnClients(orderManager, Map);

            var mapTitle = lobby.GetOrNull <LabelWidget>("MAP_TITLE");

            if (mapTitle != null)
            {
                mapTitle.IsVisible = () => Map != null;
                mapTitle.GetText   = () => Map.Title;
            }

            var mapType = lobby.GetOrNull <LabelWidget>("MAP_TYPE");

            if (mapType != null)
            {
                mapType.IsVisible = () => Map != null;
                mapType.GetText   = () => Map.Type;
            }

            var mapAuthor = lobby.GetOrNull <LabelWidget>("MAP_AUTHOR");

            if (mapAuthor != null)
            {
                mapAuthor.IsVisible = () => Map != null;
                mapAuthor.GetText   = () => "Created by {0}".F(Map.Author);
            }

            CountryNames = Rules.Info["world"].Traits.WithInterface <CountryInfo>()
                           .Where(c => c.Selectable)
                           .ToDictionary(a => a.Race, a => a.Name);
            CountryNames.Add("random", "Any");

            var gameStarting = false;

            var mapButton = lobby.Get <ButtonWidget>("CHANGEMAP_BUTTON");

            mapButton.OnClick = () =>
            {
                var onSelect = new Action <Map>(m =>
                {
                    orderManager.IssueOrder(Order.Command("map " + m.Uid));
                    Game.Settings.Server.Map = m.Uid;
                    Game.Settings.Save();
                });

                Ui.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
                {
                    { "initialMap", Map.Uid },
                    { "onExit", () => {} },
                    { "onSelect", onSelect }
                });
            };
            mapButton.IsVisible = () => mapButton.Visible && Game.IsHost;

            var assignTeams = lobby.GetOrNull <DropDownButtonWidget>("ASSIGNTEAMS_DROPDOWNBUTTON");

            if (assignTeams != null)
            {
                assignTeams.IsVisible  = () => Game.IsHost;
                assignTeams.IsDisabled = () => gameStarting || orderManager.LobbyInfo.Clients.Count(c => c.Slot != null) < 2 ||
                                         orderManager.LocalClient == null || orderManager.LocalClient.IsReady;

                assignTeams.OnMouseDown = _ =>
                {
                    var options = Enumerable.Range(2, orderManager.LobbyInfo.Clients.Count(c => c.Slot != null).Clamp(2, 8) - 1).Select(d => new DropDownOption
                    {
                        Title      = "{0} Teams".F(d),
                        IsSelected = () => false,
                        OnClick    = () => orderManager.IssueOrder(Order.Command("assignteams {0}".F(d.ToString())))
                    });
                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };
                    assignTeams.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }

            var disconnectButton = lobby.Get <ButtonWidget>("DISCONNECT_BUTTON");

            disconnectButton.OnClick = () => { CloseWindow(); onExit(); };

            var allowCheats = lobby.Get <CheckboxWidget>("ALLOWCHEATS_CHECKBOX");

            allowCheats.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats;
            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 crates = lobby.GetOrNull <CheckboxWidget>("CRATES_CHECKBOX");

            if (crates != null)
            {
                crates.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.Crates;
                crates.IsDisabled = () => !Game.IsHost || gameStarting || orderManager.LocalClient == null ||
                                    orderManager.LocalClient.IsReady;        // maybe disable the checkbox if a map forcefully removes CrateDrop?
                crates.OnClick = () => orderManager.IssueOrder(Order.Command(
                                                                   "crates {0}".F(!orderManager.LobbyInfo.GlobalSettings.Crates)));
            }

            var fragileAlliance = lobby.GetOrNull <CheckboxWidget>("FRAGILEALLIANCES_CHECKBOX");

            if (fragileAlliance != null)
            {
                fragileAlliance.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.FragileAlliances;
                fragileAlliance.IsDisabled = () => !Game.IsHost || gameStarting ||
                                             orderManager.LocalClient == null || orderManager.LocalClient.IsReady;
                fragileAlliance.OnClick = () => orderManager.IssueOrder(Order.Command(
                                                                            "fragilealliance {0}".F(!orderManager.LobbyInfo.GlobalSettings.FragileAlliances)));
            }
            ;


            var difficulty = lobby.GetOrNull <DropDownButtonWidget>("DIFFICULTY_DROPDOWNBUTTON");

            if (difficulty != null)
            {
                difficulty.IsVisible   = () => Map != null && Map.Difficulties != null && Map.Difficulties.Any();
                difficulty.IsDisabled  = () => !Game.IsHost || gameStarting || orderManager.LocalClient == null || orderManager.LocalClient.IsReady;
                difficulty.GetText     = () => orderManager.LobbyInfo.GlobalSettings.Difficulty;
                difficulty.OnMouseDown = _ =>
                {
                    var options = Map.Difficulties.Select(d => new DropDownOption
                    {
                        Title      = d,
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.Difficulty == d,
                        OnClick    = () => orderManager.IssueOrder(Order.Command("difficulty {0}".F(d)))
                    });
                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };
                    difficulty.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }

            var startGameButton = lobby.Get <ButtonWidget>("START_GAME_BUTTON");

            startGameButton.IsVisible  = () => Game.IsHost;
            startGameButton.IsDisabled = () => gameStarting ||
                                         orderManager.LobbyInfo.Slots.Any(sl => sl.Value.Required && orderManager.LobbyInfo.ClientInSlot(sl.Key) == null);
            startGameButton.OnClick = () =>
            {
                gameStarting = true;
                orderManager.IssueOrder(Order.Command("startgame"));
            };

            bool teamChat      = false;
            var  chatLabel     = lobby.Get <LabelWidget>("LABEL_CHATTYPE");
            var  chatTextField = lobby.Get <TextFieldWidget>("CHAT_TEXTFIELD");

            chatTextField.OnEnterKey = () =>
            {
                if (chatTextField.Text.Length == 0)
                {
                    return(true);
                }

                orderManager.IssueOrder(Order.Chat(teamChat, chatTextField.Text));
                chatTextField.Text = "";
                return(true);
            };

            chatTextField.OnTabKey = () =>
            {
                teamChat      ^= true;
                chatLabel.Text = (teamChat) ? "Team:" : "Chat:";
                return(true);
            };

            chatPanel    = lobby.Get <ScrollPanelWidget>("CHAT_DISPLAY");
            chatTemplate = chatPanel.Get("CHAT_TEMPLATE");
            chatPanel.RemoveChildren();

            var musicButton = lobby.GetOrNull <ButtonWidget>("MUSIC_BUTTON");

            if (musicButton != null)
            {
                musicButton.OnClick = () => Ui.OpenWindow("MUSIC_PANEL", new WidgetArgs
                {
                    { "onExit", () => {} }
                });
            }

            // 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 <IBotInfo>().Select(t => t.Name).FirstOrDefault();
                    var botController = orderManager.LobbyInfo.Clients.Where(c => c.IsAdmin).FirstOrDefault();
                    if (slot != null && bot != null)
                    {
                        orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot, botController.Index, bot)));
                    }
                });
            }
        }
예제 #9
0
        internal LobbyLogic(Widget widget, ModData modData, WorldRenderer worldRenderer, OrderManager orderManager,
			Action onExit, Action onStart, bool skirmishMode)
        {
            Map = MapCache.UnknownMap;
            lobby = widget;
            this.modData = modData;
            this.orderManager = orderManager;
            this.onStart = onStart;
            this.onExit = onExit;
            this.skirmishMode = skirmishMode;

            // TODO: This needs to be reworked to support per-map tech levels, bots, etc.
            this.modRules = modData.DefaultRules;
            shellmapWorld = worldRenderer.World;

            orderManager.AddChatLine += AddChatLine;
            Game.LobbyInfoChanged += UpdateCurrentMap;
            Game.LobbyInfoChanged += UpdatePlayerList;
            Game.BeforeGameStart += OnGameStart;
            Game.ConnectionStateChanged += ConnectionStateChanged;

            var name = lobby.GetOrNull<LabelWidget>("SERVER_NAME");
            if (name != null)
                name.GetText = () => orderManager.LobbyInfo.GlobalSettings.ServerName;

            Ui.LoadWidget("LOBBY_MAP_PREVIEW", lobby.Get("MAP_PREVIEW_ROOT"), new WidgetArgs
            {
                { "orderManager", orderManager },
                { "lobby", this }
            });

            UpdateCurrentMap();

            var playerBin = Ui.LoadWidget("LOBBY_PLAYER_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs());
            playerBin.IsVisible = () => panel == PanelType.Players;

            players = playerBin.Get<ScrollPanelWidget>("LOBBY_PLAYERS");
            editablePlayerTemplate = players.Get("TEMPLATE_EDITABLE_PLAYER");
            nonEditablePlayerTemplate = players.Get("TEMPLATE_NONEDITABLE_PLAYER");
            emptySlotTemplate = players.Get("TEMPLATE_EMPTY");
            editableSpectatorTemplate = players.Get("TEMPLATE_EDITABLE_SPECTATOR");
            nonEditableSpectatorTemplate = players.Get("TEMPLATE_NONEDITABLE_SPECTATOR");
            newSpectatorTemplate = players.Get("TEMPLATE_NEW_SPECTATOR");
            colorPreview = lobby.Get<ColorPreviewManagerWidget>("COLOR_MANAGER");
            colorPreview.Color = Game.Settings.Player.Color;

            foreach (var f in modRules.Actors["world"].TraitInfos<FactionInfo>())
                factions.Add(f.InternalName, new LobbyFaction { Selectable = f.Selectable, Name = f.Name, Side = f.Side, Description = f.Description });

            var gameStarting = false;
            Func<bool> configurationDisabled = () => !Game.IsHost || gameStarting ||
                panel == PanelType.Kick || panel == PanelType.ForceStart ||
                !Map.RulesLoaded || Map.InvalidCustomRules ||
                orderManager.LocalClient == null || orderManager.LocalClient.IsReady;

            var mapButton = lobby.GetOrNull<ButtonWidget>("CHANGEMAP_BUTTON");
            if (mapButton != null)
            {
                mapButton.IsDisabled = () => gameStarting || panel == PanelType.Kick || panel == PanelType.ForceStart ||
                    orderManager.LocalClient == null || orderManager.LocalClient.IsReady;
                mapButton.OnClick = () =>
                {
                    var onSelect = new Action<string>(uid =>
                    {
                        // Don't select the same map again
                        if (uid == Map.Uid)
                            return;

                        orderManager.IssueOrder(Order.Command("map " + uid));
                        Game.Settings.Server.Map = uid;
                        Game.Settings.Save();
                    });

                    Ui.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
                    {
                        { "initialMap", Map.Uid },
                        { "initialTab", MapClassification.System },
                        { "onExit", DoNothing },
                        { "onSelect", Game.IsHost ? onSelect : null },
                        { "filter", MapVisibility.Lobby },
                    });
                };
            }

            var slotsButton = lobby.GetOrNull<DropDownButtonWidget>("SLOTS_DROPDOWNBUTTON");
            if (slotsButton != null)
            {
                slotsButton.IsDisabled = () => configurationDisabled() || panel != PanelType.Players ||
                    (orderManager.LobbyInfo.Slots.Values.All(s => !s.AllowBots) &&
                    orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) == 0);

                slotsButton.OnMouseDown = _ =>
                {
                    var botNames = Map.Rules.Actors["player"].TraitInfos<IBotInfo>().Select(t => t.Name);
                    var options = new Dictionary<string, IEnumerable<DropDownOption>>();

                    var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin);
                    if (orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots))
                    {
                        var botOptions = new List<DropDownOption>()
                        {
                            new DropDownOption()
                            {
                                Title = "Add",
                                IsSelected = () => false,
                                OnClick = () =>
                                {
                                    foreach (var slot in orderManager.LobbyInfo.Slots)
                                    {
                                        var bot = botNames.Random(Game.CosmeticRandom);
                                        var c = orderManager.LobbyInfo.ClientInSlot(slot.Key);
                                        if (slot.Value.AllowBots == true && (c == null || c.Bot != null))
                                            orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot.Key, botController.Index, bot)));
                                    }
                                }
                            }
                        };

                        if (orderManager.LobbyInfo.Clients.Any(c => c.Bot != null))
                        {
                            botOptions.Add(new DropDownOption()
                            {
                                Title = "Remove",
                                IsSelected = () => false,
                                OnClick = () =>
                                {
                                    foreach (var slot in orderManager.LobbyInfo.Slots)
                                    {
                                        var c = orderManager.LobbyInfo.ClientInSlot(slot.Key);
                                        if (c != null && c.Bot != null)
                                            orderManager.IssueOrder(Order.Command("slot_open " + slot.Value.PlayerReference));
                                    }
                                }
                            });
                        }

                        options.Add("Configure Bots", botOptions);
                    }

                    var teamCount = (orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) + 1) / 2;
                    if (teamCount >= 1)
                    {
                        var teamOptions = Enumerable.Range(2, teamCount - 1).Reverse().Select(d => new DropDownOption
                        {
                            Title = "{0} Teams".F(d),
                            IsSelected = () => false,
                            OnClick = () => orderManager.IssueOrder(Order.Command("assignteams {0}".F(d.ToString())))
                        }).ToList();

                        if (orderManager.LobbyInfo.Slots.Any(s => s.Value.AllowBots))
                        {
                            teamOptions.Add(new DropDownOption
                            {
                                Title = "Humans vs Bots",
                                IsSelected = () => false,
                                OnClick = () => orderManager.IssueOrder(Order.Command("assignteams 1"))
                            });
                        }

                        teamOptions.Add(new DropDownOption
                        {
                            Title = "Free for all",
                            IsSelected = () => false,
                            OnClick = () => orderManager.IssueOrder(Order.Command("assignteams 0"))
                        });

                        options.Add("Configure Teams", teamOptions);
                    }

                    Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
                        return item;
                    };
                    slotsButton.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 175, options, setupItem);
                };
            }

            var optionsBin = Ui.LoadWidget("LOBBY_OPTIONS_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs());
            optionsBin.IsVisible = () => panel == PanelType.Options;

            var musicBin = Ui.LoadWidget("LOBBY_MUSIC_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs
            {
                { "onExit", DoNothing },
                { "world", worldRenderer.World }
            });
            musicBin.IsVisible = () => panel == PanelType.Music;

            var optionsTab = lobby.Get<ButtonWidget>("OPTIONS_TAB");
            optionsTab.IsHighlighted = () => panel == PanelType.Options;
            optionsTab.IsDisabled = () => !Map.RulesLoaded || Map.InvalidCustomRules || panel == PanelType.Kick || panel == PanelType.ForceStart;
            optionsTab.OnClick = () => panel = PanelType.Options;

            var playersTab = lobby.Get<ButtonWidget>("PLAYERS_TAB");
            playersTab.IsHighlighted = () => panel == PanelType.Players;
            playersTab.IsDisabled = () => panel == PanelType.Kick || panel == PanelType.ForceStart;
            playersTab.OnClick = () => panel = PanelType.Players;

            var musicTab = lobby.Get<ButtonWidget>("MUSIC_TAB");
            musicTab.IsHighlighted = () => panel == PanelType.Music;
            musicTab.IsDisabled = () => panel == PanelType.Kick || panel == PanelType.ForceStart;
            musicTab.OnClick = () => panel = PanelType.Music;

            // Force start panel
            Action startGame = () =>
            {
                gameStarting = true;
                orderManager.IssueOrder(Order.Command("startgame"));
            };

            var startGameButton = lobby.GetOrNull<ButtonWidget>("START_GAME_BUTTON");
            if (startGameButton != null)
            {
                startGameButton.IsDisabled = () => configurationDisabled() || Map.Status != MapStatus.Available ||
                    orderManager.LobbyInfo.Slots.Any(sl => sl.Value.Required && orderManager.LobbyInfo.ClientInSlot(sl.Key) == null) ||
                    (orderManager.LobbyInfo.GlobalSettings.DisableSingleplayer && orderManager.LobbyInfo.IsSinglePlayer);

                startGameButton.OnClick = () =>
                {
                    // Bots and admins don't count
                    if (orderManager.LobbyInfo.Clients.Any(c => c.Slot != null && !c.IsAdmin && c.Bot == null && !c.IsReady))
                        panel = PanelType.ForceStart;
                    else
                        startGame();
                };
            }

            var forceStartBin = Ui.LoadWidget("FORCE_START_DIALOG", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs());
            forceStartBin.IsVisible = () => panel == PanelType.ForceStart;
            forceStartBin.Get("KICK_WARNING").IsVisible = () => orderManager.LobbyInfo.Clients.Any(c => c.IsInvalid);
            forceStartBin.Get<ButtonWidget>("OK_BUTTON").OnClick = startGame;
            forceStartBin.Get<ButtonWidget>("CANCEL_BUTTON").OnClick = () => panel = PanelType.Players;

            // Options panel
            var allowCheats = optionsBin.GetOrNull<CheckboxWidget>("ALLOWCHEATS_CHECKBOX");
            if (allowCheats != null)
            {
                var cheatsLocked = new CachedTransform<MapPreview, bool>(
                    map => map.Rules.Actors["player"].TraitInfo<DeveloperModeInfo>().Locked);

                allowCheats.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats;
                allowCheats.IsDisabled = () => configurationDisabled() || cheatsLocked.Update(Map);
                allowCheats.OnClick = () => orderManager.IssueOrder(Order.Command(
                        "allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats)));
            }

            var crates = optionsBin.GetOrNull<CheckboxWidget>("CRATES_CHECKBOX");
            if (crates != null)
            {
                var cratesLocked = new CachedTransform<MapPreview, bool>(map =>
                {
                    var crateSpawner = map.Rules.Actors["world"].TraitInfoOrDefault<CrateSpawnerInfo>();
                    return crateSpawner == null || crateSpawner.Locked;
                });

                crates.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Crates;
                crates.IsDisabled = () => configurationDisabled() || cratesLocked.Update(Map);
                crates.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "crates {0}".F(!orderManager.LobbyInfo.GlobalSettings.Crates)));
            }

            var creeps = optionsBin.GetOrNull<CheckboxWidget>("CREEPS_CHECKBOX");
            if (creeps != null)
            {
                var creepsLocked = new CachedTransform<MapPreview, bool>(map =>
                {
                    var mapCreeps = map.Rules.Actors["world"].TraitInfoOrDefault<MapCreepsInfo>();
                    return mapCreeps == null || mapCreeps.Locked;
                });

                creeps.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Creeps;
                creeps.IsDisabled = () => configurationDisabled() || creepsLocked.Update(Map);
                creeps.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "creeps {0}".F(!orderManager.LobbyInfo.GlobalSettings.Creeps)));
            }

            var allybuildradius = optionsBin.GetOrNull<CheckboxWidget>("ALLYBUILDRADIUS_CHECKBOX");
            if (allybuildradius != null)
            {
                var allyBuildRadiusLocked = new CachedTransform<MapPreview, bool>(map =>
                {
                    var mapBuildRadius = map.Rules.Actors["world"].TraitInfoOrDefault<MapBuildRadiusInfo>();
                    return mapBuildRadius == null || mapBuildRadius.AllyBuildRadiusLocked;
                });

                allybuildradius.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius;
                allybuildradius.IsDisabled = () => configurationDisabled() || allyBuildRadiusLocked.Update(Map);
                allybuildradius.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "allybuildradius {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius)));
            }

            var shortGame = optionsBin.GetOrNull<CheckboxWidget>("SHORTGAME_CHECKBOX");
            if (shortGame != null)
            {
                var shortGameLocked = new CachedTransform<MapPreview, bool>(
                    map => map.Rules.Actors["world"].TraitInfo<MapOptionsInfo>().ShortGameLocked);

                shortGame.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.ShortGame;
                shortGame.IsDisabled = () => configurationDisabled() || shortGameLocked.Update(Map);
                shortGame.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "shortgame {0}".F(!orderManager.LobbyInfo.GlobalSettings.ShortGame)));
            }

            var difficulty = optionsBin.GetOrNull<DropDownButtonWidget>("DIFFICULTY_DROPDOWNBUTTON");
            if (difficulty != null)
            {
                var mapOptions = new CachedTransform<MapPreview, MapOptionsInfo>(
                    map => map.Rules.Actors["world"].TraitInfo<MapOptionsInfo>());

                difficulty.IsVisible = () => Map.RulesLoaded && mapOptions.Update(Map).Difficulties.Any();
                difficulty.IsDisabled = () => configurationDisabled() || mapOptions.Update(Map).DifficultyLocked;
                difficulty.GetText = () => orderManager.LobbyInfo.GlobalSettings.Difficulty;
                difficulty.OnMouseDown = _ =>
                {
                    var options = mapOptions.Update(Map).Difficulties.Select(d => new DropDownOption
                    {
                        Title = d,
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.Difficulty == d,
                        OnClick = () => orderManager.IssueOrder(Order.Command("difficulty {0}".F(d)))
                    });
                    Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
                        return item;
                    };
                    difficulty.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };

                optionsBin.Get<LabelWidget>("DIFFICULTY_DESC").IsVisible = difficulty.IsVisible;
            }

            var startingUnits = optionsBin.GetOrNull<DropDownButtonWidget>("STARTINGUNITS_DROPDOWNBUTTON");
            if (startingUnits != null)
            {
                var startUnitsInfos = new CachedTransform<MapPreview, IEnumerable<MPStartUnitsInfo>>(
                    map => map.Rules.Actors["world"].TraitInfos<MPStartUnitsInfo>());

                var startUnitsLocked = new CachedTransform<MapPreview, bool>(map =>
                {
                    var spawnUnitsInfo = map.Rules.Actors["world"].TraitInfoOrDefault<SpawnMPUnitsInfo>();
                    return spawnUnitsInfo == null || spawnUnitsInfo.Locked;
                });

                Func<string, string> className = c =>
                {
                    var selectedClass = startUnitsInfos.Update(Map).Where(s => s.Class == c).Select(u => u.ClassName).FirstOrDefault();
                    return selectedClass != null ? selectedClass : c;
                };

                startingUnits.IsDisabled = () => configurationDisabled() || startUnitsLocked.Update(Map);
                startingUnits.GetText = () => !Map.RulesLoaded || startUnitsLocked.Update(Map) ?
                    "Not Available" : className(orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass);
                startingUnits.OnMouseDown = _ =>
                {
                    var classes = startUnitsInfos.Update(Map).Select(a => a.Class).Distinct();
                    var options = classes.Select(c => new DropDownOption
                    {
                        Title = className(c),
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass == c,
                        OnClick = () => orderManager.IssueOrder(Order.Command("startingunits {0}".F(c)))
                    });

                    Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
                        return item;
                    };

                    startingUnits.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };

                optionsBin.Get<LabelWidget>("STARTINGUNITS_DESC").IsVisible = startingUnits.IsVisible;
            }

            var startingCash = optionsBin.GetOrNull<DropDownButtonWidget>("STARTINGCASH_DROPDOWNBUTTON");
            if (startingCash != null)
            {
                var playerResources = new CachedTransform<MapPreview, PlayerResourcesInfo>(
                    map => map.Rules.Actors["player"].TraitInfo<PlayerResourcesInfo>());

                startingCash.IsDisabled = () => configurationDisabled() || playerResources.Update(Map).DefaultCashLocked;
                startingCash.GetText = () => !Map.RulesLoaded || playerResources.Update(Map).DefaultCashLocked ?
                    "Not Available" : "${0}".F(orderManager.LobbyInfo.GlobalSettings.StartingCash);
                startingCash.OnMouseDown = _ =>
                {
                    var options = playerResources.Update(Map).SelectableCash.Select(c => new DropDownOption
                    {
                        Title = "${0}".F(c),
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.StartingCash == c,
                        OnClick = () => orderManager.IssueOrder(Order.Command("startingcash {0}".F(c)))
                    });

                    Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
                        return item;
                    };

                    startingCash.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }

            var techLevel = optionsBin.GetOrNull<DropDownButtonWidget>("TECHLEVEL_DROPDOWNBUTTON");
            if (techLevel != null)
            {
                var mapOptions = new CachedTransform<MapPreview, MapOptionsInfo>(
                    map => map.Rules.Actors["world"].TraitInfo<MapOptionsInfo>());

                var techLevels = new CachedTransform<MapPreview, List<ProvidesTechPrerequisiteInfo>>(
                    map => map.Rules.Actors["player"].TraitInfos<ProvidesTechPrerequisiteInfo>().ToList());

                techLevel.IsVisible = () => Map.RulesLoaded && techLevels.Update(Map).Any();
                var techLevelDescription = optionsBin.GetOrNull<LabelWidget>("TECHLEVEL_DESC");
                if (techLevelDescription != null)
                    techLevelDescription.IsVisible = techLevel.IsVisible;

                techLevel.IsDisabled = () => configurationDisabled() || mapOptions.Update(Map).TechLevelLocked;
                techLevel.GetText = () => !Map.RulesLoaded || mapOptions.Update(Map).TechLevelLocked ?
                    "Not Available" : "{0}".F(orderManager.LobbyInfo.GlobalSettings.TechLevel);
                techLevel.OnMouseDown = _ =>
                {
                    var options = techLevels.Update(Map).Select(c => new DropDownOption
                    {
                        Title = "{0}".F(c.Name),
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.TechLevel == c.Name,
                        OnClick = () => orderManager.IssueOrder(Order.Command("techlevel {0}".F(c.Name)))
                    });

                    Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
                        return item;
                    };

                    techLevel.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }

            var gameSpeed = optionsBin.GetOrNull<DropDownButtonWidget>("GAMESPEED_DROPDOWNBUTTON");
            if (gameSpeed != null)
            {
                var speeds = modData.Manifest.Get<GameSpeeds>().Speeds;

                gameSpeed.IsDisabled = configurationDisabled;
                gameSpeed.GetText = () =>
                {
                    if (Map.Status != MapStatus.Available)
                        return "Not Available";

                    GameSpeed speed;
                    if (!speeds.TryGetValue(orderManager.LobbyInfo.GlobalSettings.GameSpeedType, out speed))
                        return "Unknown";

                    return speed.Name;
                };

                gameSpeed.OnMouseDown = _ =>
                {
                    var options = speeds.Select(s => new DropDownOption
                    {
                        Title = s.Value.Name,
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.GameSpeedType == s.Key,
                        OnClick = () => orderManager.IssueOrder(Order.Command("gamespeed {0}".F(s.Key)))
                    });

                    Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
                        return item;
                    };

                    gameSpeed.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }

            var exploredMap = optionsBin.GetOrNull<CheckboxWidget>("EXPLORED_MAP_CHECKBOX");
            if (exploredMap != null)
            {
                var exploredMapLocked = new CachedTransform<MapPreview, bool>(
                    map => map.Rules.Actors["player"].TraitInfo<ShroudInfo>().ExploredMapLocked);

                exploredMap.IsChecked = () => !orderManager.LobbyInfo.GlobalSettings.Shroud;
                exploredMap.IsDisabled = () => configurationDisabled() || exploredMapLocked.Update(Map);
                exploredMap.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "shroud {0}".F(!orderManager.LobbyInfo.GlobalSettings.Shroud)));
            }

            var enableFog = optionsBin.GetOrNull<CheckboxWidget>("FOG_CHECKBOX");
            if (enableFog != null)
            {
                var fogLocked = new CachedTransform<MapPreview, bool>(
                    map => map.Rules.Actors["player"].TraitInfo<ShroudInfo>().FogLocked);

                enableFog.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Fog;
                enableFog.IsDisabled = () => configurationDisabled() || fogLocked.Update(Map);
                enableFog.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "fog {0}".F(!orderManager.LobbyInfo.GlobalSettings.Fog)));
            }

            var disconnectButton = lobby.Get<ButtonWidget>("DISCONNECT_BUTTON");
            disconnectButton.OnClick = () => { CloseWindow(); onExit(); };

            if (skirmishMode)
                disconnectButton.Text = "Back";

            var globalChat = Game.LoadWidget(null, "LOBBY_GLOBALCHAT_PANEL", lobby.Get("GLOBALCHAT_ROOT"), new WidgetArgs());
            var globalChatInput = globalChat.Get<TextFieldWidget>("CHAT_TEXTFIELD");

            globalChat.IsVisible = () => chatPanel == ChatPanelType.Global;

            var globalChatTab = lobby.Get<ButtonWidget>("GLOBALCHAT_TAB");
            globalChatTab.IsHighlighted = () => chatPanel == ChatPanelType.Global;
            globalChatTab.OnClick = () =>
            {
                chatPanel = ChatPanelType.Global;
                globalChatInput.TakeKeyboardFocus();
            };

            var globalChatLabel = globalChatTab.Text;
            globalChatTab.GetText = () =>
            {
                if (globalChatUnreadMessages == 0 || chatPanel == ChatPanelType.Global)
                    return globalChatLabel;

                return globalChatLabel + " ({0})".F(globalChatUnreadMessages);
            };

            globalChatLastReadMessages = Game.GlobalChat.History.Count(m => m.Type == ChatMessageType.Message);

            var lobbyChat = lobby.Get("LOBBYCHAT");
            lobbyChat.IsVisible = () => chatPanel == ChatPanelType.Lobby;

            chatLabel = lobby.Get<LabelWidget>("LABEL_CHATTYPE");
            var chatTextField = lobby.Get<TextFieldWidget>("CHAT_TEXTFIELD");
            chatTextField.TakeKeyboardFocus();
            chatTextField.OnEnterKey = () =>
            {
                if (chatTextField.Text.Length == 0)
                    return true;

                // Always scroll to bottom when we've typed something
                lobbyChatPanel.ScrollToBottom();

                orderManager.IssueOrder(Order.Chat(teamChat, chatTextField.Text));
                chatTextField.Text = "";
                return true;
            };

            chatTextField.OnTabKey = () =>
            {
                var previousText = chatTextField.Text;
                chatTextField.Text = tabCompletion.Complete(chatTextField.Text);
                chatTextField.CursorPosition = chatTextField.Text.Length;

                if (chatTextField.Text == previousText)
                    return SwitchTeamChat();
                else
                    return true;
            };

            chatTextField.OnEscKey = () => { chatTextField.Text = ""; return true; };

            var lobbyChatTab = lobby.Get<ButtonWidget>("LOBBYCHAT_TAB");
            lobbyChatTab.IsHighlighted = () => chatPanel == ChatPanelType.Lobby;
            lobbyChatTab.OnClick = () =>
            {
                chatPanel = ChatPanelType.Lobby;
                chatTextField.TakeKeyboardFocus();
            };

            var lobbyChatLabel = lobbyChatTab.Text;
            lobbyChatTab.GetText = () =>
            {
                if (lobbyChatUnreadMessages == 0 || chatPanel == ChatPanelType.Lobby)
                    return lobbyChatLabel;

                return lobbyChatLabel + " ({0})".F(lobbyChatUnreadMessages);
            };

            lobbyChatPanel = lobby.Get<ScrollPanelWidget>("CHAT_DISPLAY");
            chatTemplate = lobbyChatPanel.Get("CHAT_TEMPLATE");
            lobbyChatPanel.RemoveChildren();

            var settingsButton = lobby.GetOrNull<ButtonWidget>("SETTINGS_BUTTON");
            if (settingsButton != null)
            {
                settingsButton.OnClick = () => Ui.OpenWindow("SETTINGS_PANEL", new WidgetArgs
                {
                    { "onExit", DoNothing },
                    { "worldRenderer", worldRenderer }
                });
            }

            // Add a bot on the first lobbyinfo update
            if (skirmishMode)
                addBotOnMapLoad = true;
        }
예제 #10
0
        public static void ShowColorDropDown(DropDownButtonWidget color, Session.Client client,
			OrderManager orderManager, World world, ColorPreviewManagerWidget preview)
        {
            Action onExit = () =>
            {
                if (client.Bot == null)
                {
                    Game.Settings.Player.Color = preview.Color;
                    Game.Settings.Save();
                }

                color.RemovePanel();
                orderManager.IssueOrder(Order.Command("color {0} {1}".F(client.Index, preview.Color)));
            };

            Action<HSLColor> onChange = c => preview.Color = c;

            var colorChooser = Game.LoadWidget(world, "COLOR_CHOOSER", null, new WidgetArgs()
            {
                { "onChange", onChange },
                { "initialColor", client.Color }
            });

            color.AttachPanel(colorChooser, onExit);
        }
예제 #11
0
        internal LobbyLogic(Widget widget, ModData modData, WorldRenderer worldRenderer, OrderManager orderManager,
                            Action onExit, Action onStart, bool skirmishMode)
        {
            map               = MapCache.UnknownMap;
            lobby             = widget;
            this.modData      = modData;
            this.orderManager = orderManager;
            this.onStart      = onStart;
            this.onExit       = onExit;
            this.skirmishMode = skirmishMode;

            // TODO: This needs to be reworked to support per-map tech levels, bots, etc.
            this.modRules = modData.DefaultRules;
            shellmapWorld = worldRenderer.World;

            services = modData.Manifest.Get <WebServices>();

            orderManager.AddChatLine    += AddChatLine;
            Game.LobbyInfoChanged       += UpdateCurrentMap;
            Game.LobbyInfoChanged       += UpdatePlayerList;
            Game.BeforeGameStart        += OnGameStart;
            Game.ConnectionStateChanged += ConnectionStateChanged;

            var name = lobby.GetOrNull <LabelWidget>("SERVER_NAME");

            if (name != null)
            {
                name.GetText = () => orderManager.LobbyInfo.GlobalSettings.ServerName;
            }

            Ui.LoadWidget("MAP_PREVIEW", lobby.Get("MAP_PREVIEW_ROOT"), new WidgetArgs
            {
                { "orderManager", orderManager },
                { "getMap", (Func <MapPreview>)(() => map) },
                { "onMouseDown", (Action <MapPreviewWidget, MapPreview, MouseInput>)((preview, mapPreview, mi) =>
                                                                                     LobbyUtils.SelectSpawnPoint(orderManager, preview, mapPreview, mi)) },
                { "getSpawnOccupants", (Func <MapPreview, Dictionary <CPos, SpawnOccupant> >)(mapPreview => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, mapPreview)) },
                { "showUnoccupiedSpawnpoints", true },
            });

            UpdateCurrentMap();

            var playerBin = Ui.LoadWidget("LOBBY_PLAYER_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs());

            playerBin.IsVisible = () => panel == PanelType.Players;

            players = playerBin.Get <ScrollPanelWidget>("LOBBY_PLAYERS");
            editablePlayerTemplate       = players.Get("TEMPLATE_EDITABLE_PLAYER");
            nonEditablePlayerTemplate    = players.Get("TEMPLATE_NONEDITABLE_PLAYER");
            emptySlotTemplate            = players.Get("TEMPLATE_EMPTY");
            editableSpectatorTemplate    = players.Get("TEMPLATE_EDITABLE_SPECTATOR");
            nonEditableSpectatorTemplate = players.Get("TEMPLATE_NONEDITABLE_SPECTATOR");
            newSpectatorTemplate         = players.Get("TEMPLATE_NEW_SPECTATOR");
            colorPreview       = lobby.Get <ColorPreviewManagerWidget>("COLOR_MANAGER");
            colorPreview.Color = Game.Settings.Player.Color;

            foreach (var f in modRules.Actors["world"].TraitInfos <FactionInfo>())
            {
                factions.Add(f.InternalName, new LobbyFaction {
                    Selectable = f.Selectable, Name = f.Name, Side = f.Side, Description = f.Description
                });
            }

            var         gameStarting          = false;
            Func <bool> configurationDisabled = () => !Game.IsHost || gameStarting ||
                                                panel == PanelType.Kick || panel == PanelType.ForceStart ||
                                                !map.RulesLoaded || map.InvalidCustomRules ||
                                                orderManager.LocalClient == null || orderManager.LocalClient.IsReady;

            var mapButton = lobby.GetOrNull <ButtonWidget>("CHANGEMAP_BUTTON");

            if (mapButton != null)
            {
                mapButton.IsDisabled = () => gameStarting || panel == PanelType.Kick || panel == PanelType.ForceStart ||
                                       orderManager.LocalClient == null || orderManager.LocalClient.IsReady;
                mapButton.OnClick = () =>
                {
                    var onSelect = new Action <string>(uid =>
                    {
                        // Don't select the same map again
                        if (uid == map.Uid)
                        {
                            return;
                        }

                        orderManager.IssueOrder(Order.Command("map " + uid));
                        Game.Settings.Server.Map = uid;
                        Game.Settings.Save();
                    });

                    Ui.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
                    {
                        { "initialMap", map.Uid },
                        { "initialTab", MapClassification.System },
                        { "onExit", DoNothing },
                        { "onSelect", Game.IsHost ? onSelect : null },
                        { "filter", MapVisibility.Lobby },
                    });
                };
            }

            var slotsButton = lobby.GetOrNull <DropDownButtonWidget>("SLOTS_DROPDOWNBUTTON");

            if (slotsButton != null)
            {
                slotsButton.IsDisabled = () => configurationDisabled() || panel != PanelType.Players ||
                                         (orderManager.LobbyInfo.Slots.Values.All(s => !s.AllowBots) &&
                                          orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) == 0);

                slotsButton.OnMouseDown = _ =>
                {
                    var botTypes = map.Rules.Actors["player"].TraitInfos <IBotInfo>().Select(t => t.Type);
                    var options  = new Dictionary <string, IEnumerable <DropDownOption> >();

                    var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin);
                    if (orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots))
                    {
                        var botOptions = new List <DropDownOption>()
                        {
                            new DropDownOption()
                            {
                                Title      = "Add",
                                IsSelected = () => false,
                                OnClick    = () =>
                                {
                                    foreach (var slot in orderManager.LobbyInfo.Slots)
                                    {
                                        var bot = botTypes.Random(Game.CosmeticRandom);
                                        var c   = orderManager.LobbyInfo.ClientInSlot(slot.Key);
                                        if (slot.Value.AllowBots == true && (c == null || c.Bot != null))
                                        {
                                            orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot.Key, botController.Index, bot)));
                                        }
                                    }
                                }
                            }
                        };

                        if (orderManager.LobbyInfo.Clients.Any(c => c.Bot != null))
                        {
                            botOptions.Add(new DropDownOption()
                            {
                                Title      = "Remove",
                                IsSelected = () => false,
                                OnClick    = () =>
                                {
                                    foreach (var slot in orderManager.LobbyInfo.Slots)
                                    {
                                        var c = orderManager.LobbyInfo.ClientInSlot(slot.Key);
                                        if (c != null && c.Bot != null)
                                        {
                                            orderManager.IssueOrder(Order.Command("slot_open " + slot.Value.PlayerReference));
                                        }
                                    }
                                }
                            });
                        }

                        options.Add("Configure Bots", botOptions);
                    }

                    var teamCount = (orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) + 1) / 2;
                    if (teamCount >= 1)
                    {
                        var teamOptions = Enumerable.Range(2, teamCount - 1).Reverse().Select(d => new DropDownOption
                        {
                            Title      = "{0} Teams".F(d),
                            IsSelected = () => false,
                            OnClick    = () => orderManager.IssueOrder(Order.Command("assignteams {0}".F(d.ToString())))
                        }).ToList();

                        if (orderManager.LobbyInfo.Slots.Any(s => s.Value.AllowBots))
                        {
                            teamOptions.Add(new DropDownOption
                            {
                                Title      = "Humans vs Bots",
                                IsSelected = () => false,
                                OnClick    = () => orderManager.IssueOrder(Order.Command("assignteams 1"))
                            });
                        }

                        teamOptions.Add(new DropDownOption
                        {
                            Title      = "Free for all",
                            IsSelected = () => false,
                            OnClick    = () => orderManager.IssueOrder(Order.Command("assignteams 0"))
                        });

                        options.Add("Configure Teams", teamOptions);
                    }

                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };
                    slotsButton.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 175, options, setupItem);
                };
            }

            var optionsBin = Ui.LoadWidget("LOBBY_OPTIONS_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs());

            optionsBin.IsVisible = () => panel == PanelType.Options;

            var musicBin = Ui.LoadWidget("LOBBY_MUSIC_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs
            {
                { "onExit", DoNothing },
                { "world", worldRenderer.World }
            });

            musicBin.IsVisible = () => panel == PanelType.Music;

            var optionsTab = lobby.Get <ButtonWidget>("OPTIONS_TAB");

            optionsTab.IsHighlighted = () => panel == PanelType.Options;
            optionsTab.IsDisabled    = () => !map.RulesLoaded || map.InvalidCustomRules || panel == PanelType.Kick || panel == PanelType.ForceStart;
            optionsTab.OnClick       = () => panel = PanelType.Options;

            var playersTab = lobby.Get <ButtonWidget>("PLAYERS_TAB");

            playersTab.IsHighlighted = () => panel == PanelType.Players;
            playersTab.IsDisabled    = () => panel == PanelType.Kick || panel == PanelType.ForceStart;
            playersTab.OnClick       = () => panel = PanelType.Players;

            var musicTab = lobby.Get <ButtonWidget>("MUSIC_TAB");

            musicTab.IsHighlighted = () => panel == PanelType.Music;
            musicTab.IsDisabled    = () => panel == PanelType.Kick || panel == PanelType.ForceStart;
            musicTab.OnClick       = () => panel = PanelType.Music;

            // Force start panel
            Action startGame = () =>
            {
                gameStarting = true;
                orderManager.IssueOrder(Order.Command("startgame"));
            };

            var startGameButton = lobby.GetOrNull <ButtonWidget>("START_GAME_BUTTON");

            if (startGameButton != null)
            {
                startGameButton.IsDisabled = () => configurationDisabled() || map.Status != MapStatus.Available ||
                                             orderManager.LobbyInfo.Slots.Any(sl => sl.Value.Required && orderManager.LobbyInfo.ClientInSlot(sl.Key) == null) ||
                                             (!orderManager.LobbyInfo.GlobalSettings.EnableSingleplayer && orderManager.LobbyInfo.NonBotPlayers.Count() < 2);

                startGameButton.OnClick = () =>
                {
                    // Bots and admins don't count
                    if (orderManager.LobbyInfo.Clients.Any(c => c.Slot != null && !c.IsAdmin && c.Bot == null && !c.IsReady))
                    {
                        panel = PanelType.ForceStart;
                    }
                    else
                    {
                        startGame();
                    }
                };
            }

            var forceStartBin = Ui.LoadWidget("FORCE_START_DIALOG", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs());

            forceStartBin.IsVisible = () => panel == PanelType.ForceStart;
            forceStartBin.Get("KICK_WARNING").IsVisible               = () => orderManager.LobbyInfo.Clients.Any(c => c.IsInvalid);
            forceStartBin.Get <ButtonWidget>("OK_BUTTON").OnClick     = startGame;
            forceStartBin.Get <ButtonWidget>("CANCEL_BUTTON").OnClick = () => panel = PanelType.Players;

            // Options panel
            var optionCheckboxes = new Dictionary <string, string>()
            {
                { "EXPLORED_MAP_CHECKBOX", "explored" },
                { "CRATES_CHECKBOX", "crates" },
                { "SHORTGAME_CHECKBOX", "shortgame" },
                { "FOG_CHECKBOX", "fog" },
                { "ALLYBUILDRADIUS_CHECKBOX", "allybuild" },
                { "ALLOWCHEATS_CHECKBOX", "cheats" },
                { "CREEPS_CHECKBOX", "creeps" },
            };

            foreach (var kv in optionCheckboxes)
            {
                var checkbox = optionsBin.GetOrNull <CheckboxWidget>(kv.Key);
                if (checkbox != null)
                {
                    var option = new CachedTransform <Session.Global, Session.LobbyOptionState>(
                        gs => gs.LobbyOptions[kv.Value]);

                    var visible = new CachedTransform <Session.Global, bool>(
                        gs => gs.LobbyOptions.ContainsKey(kv.Value));

                    checkbox.IsVisible  = () => visible.Update(orderManager.LobbyInfo.GlobalSettings);
                    checkbox.IsChecked  = () => option.Update(orderManager.LobbyInfo.GlobalSettings).Enabled;
                    checkbox.IsDisabled = () => configurationDisabled() ||
                                          option.Update(orderManager.LobbyInfo.GlobalSettings).Locked;
                    checkbox.OnClick = () => orderManager.IssueOrder(Order.Command(
                                                                         "option {0} {1}".F(kv.Value, !option.Update(orderManager.LobbyInfo.GlobalSettings).Enabled)));
                }
            }

            var optionDropdowns = new Dictionary <string, string>()
            {
                { "TECHLEVEL", "techlevel" },
                { "STARTINGUNITS", "startingunits" },
                { "STARTINGCASH", "startingcash" },
                { "DIFFICULTY", "difficulty" },
                { "GAMESPEED", "gamespeed" }
            };

            var allOptions = new CachedTransform <MapPreview, LobbyOption[]>(
                mapPreview => mapPreview.Rules.Actors["player"].TraitInfos <ILobbyOptions>()
                .Concat(mapPreview.Rules.Actors["world"].TraitInfos <ILobbyOptions>())
                .SelectMany(t => t.LobbyOptions(mapPreview.Rules))
                .ToArray());

            foreach (var kv in optionDropdowns)
            {
                var dropdown = optionsBin.GetOrNull <DropDownButtonWidget>(kv.Key + "_DROPDOWNBUTTON");
                if (dropdown != null)
                {
                    var optionValue = new CachedTransform <Session.Global, Session.LobbyOptionState>(
                        gs => gs.LobbyOptions[kv.Value]);

                    var option = new CachedTransform <MapPreview, LobbyOption>(
                        mapPreview => allOptions.Update(mapPreview).FirstOrDefault(o => o.Id == kv.Value));

                    var getOptionLabel = new CachedTransform <string, string>(id =>
                    {
                        string value;
                        if (id == null || !option.Update(map).Values.TryGetValue(id, out value))
                        {
                            return("Not Available");
                        }

                        return(value);
                    });

                    dropdown.GetText    = () => getOptionLabel.Update(optionValue.Update(orderManager.LobbyInfo.GlobalSettings).Value);
                    dropdown.IsVisible  = () => option.Update(map) != null;
                    dropdown.IsDisabled = () => configurationDisabled() ||
                                          optionValue.Update(orderManager.LobbyInfo.GlobalSettings).Locked;

                    dropdown.OnMouseDown = _ =>
                    {
                        Func <KeyValuePair <string, string>, ScrollItemWidget, ScrollItemWidget> setupItem = (c, template) =>
                        {
                            Func <bool> isSelected = () => optionValue.Update(orderManager.LobbyInfo.GlobalSettings).Value == c.Key;
                            Action      onClick    = () => orderManager.IssueOrder(Order.Command("option {0} {1}".F(kv.Value, c.Key)));

                            var item = ScrollItemWidget.Setup(template, isSelected, onClick);
                            item.Get <LabelWidget>("LABEL").GetText = () => c.Value;
                            return(item);
                        };

                        var options = option.Update(map).Values;
                        dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                    };

                    var label = optionsBin.GetOrNull(kv.Key + "_DESC");
                    if (label != null)
                    {
                        label.IsVisible = () => option.Update(map) != null;
                    }
                }
            }

            var disconnectButton = lobby.Get <ButtonWidget>("DISCONNECT_BUTTON");

            disconnectButton.OnClick = () => { Ui.CloseWindow(); onExit(); };

            if (skirmishMode)
            {
                disconnectButton.Text = "Back";
            }

            var globalChat      = Game.LoadWidget(null, "LOBBY_GLOBALCHAT_PANEL", lobby.Get("GLOBALCHAT_ROOT"), new WidgetArgs());
            var globalChatInput = globalChat.Get <TextFieldWidget>("CHAT_TEXTFIELD");

            globalChat.IsVisible = () => chatPanel == ChatPanelType.Global;

            var globalChatTab = lobby.Get <ButtonWidget>("GLOBALCHAT_TAB");

            globalChatTab.IsHighlighted = () => chatPanel == ChatPanelType.Global;
            globalChatTab.OnClick       = () =>
            {
                chatPanel = ChatPanelType.Global;
                globalChatInput.TakeKeyboardFocus();
            };

            var globalChatLabel = globalChatTab.Text;

            globalChatTab.GetText = () =>
            {
                if (globalChatUnreadMessages == 0 || chatPanel == ChatPanelType.Global)
                {
                    return(globalChatLabel);
                }

                return(globalChatLabel + " ({0})".F(globalChatUnreadMessages));
            };

            globalChatLastReadMessages = Game.GlobalChat.History.Count(m => m.Type == ChatMessageType.Message);

            var lobbyChat = lobby.Get("LOBBYCHAT");

            lobbyChat.IsVisible = () => chatPanel == ChatPanelType.Lobby;

            chatLabel = lobby.Get <LabelWidget>("LABEL_CHATTYPE");
            var chatTextField = lobby.Get <TextFieldWidget>("CHAT_TEXTFIELD");

            chatTextField.MaxLength = UnitOrders.ChatMessageMaxLength;

            chatTextField.TakeKeyboardFocus();
            chatTextField.OnEnterKey = () =>
            {
                if (chatTextField.Text.Length == 0)
                {
                    return(true);
                }

                // Always scroll to bottom when we've typed something
                lobbyChatPanel.ScrollToBottom();

                orderManager.IssueOrder(Order.Chat(teamChat, chatTextField.Text));
                chatTextField.Text = "";
                return(true);
            };

            chatTextField.OnTabKey = () =>
            {
                var previousText = chatTextField.Text;
                chatTextField.Text           = tabCompletion.Complete(chatTextField.Text);
                chatTextField.CursorPosition = chatTextField.Text.Length;

                if (chatTextField.Text == previousText)
                {
                    return(SwitchTeamChat());
                }
                else
                {
                    return(true);
                }
            };

            chatTextField.OnEscKey = () => { chatTextField.Text = ""; return(true); };

            var lobbyChatTab = lobby.Get <ButtonWidget>("LOBBYCHAT_TAB");

            lobbyChatTab.IsHighlighted = () => chatPanel == ChatPanelType.Lobby;
            lobbyChatTab.OnClick       = () =>
            {
                chatPanel = ChatPanelType.Lobby;
                chatTextField.TakeKeyboardFocus();
            };

            var lobbyChatLabel = lobbyChatTab.Text;

            lobbyChatTab.GetText = () =>
            {
                if (lobbyChatUnreadMessages == 0 || chatPanel == ChatPanelType.Lobby)
                {
                    return(lobbyChatLabel);
                }

                return(lobbyChatLabel + " ({0})".F(lobbyChatUnreadMessages));
            };

            lobbyChatPanel = lobby.Get <ScrollPanelWidget>("CHAT_DISPLAY");
            chatTemplate   = lobbyChatPanel.Get("CHAT_TEMPLATE");
            lobbyChatPanel.RemoveChildren();

            var settingsButton = lobby.GetOrNull <ButtonWidget>("SETTINGS_BUTTON");

            if (settingsButton != null)
            {
                settingsButton.OnClick = () => Ui.OpenWindow("SETTINGS_PANEL", new WidgetArgs
                {
                    { "onExit", DoNothing },
                    { "worldRenderer", worldRenderer }
                });
            }

            // Add a bot on the first lobbyinfo update
            if (skirmishMode)
            {
                addBotOnMapLoad = true;
            }
        }
예제 #12
0
        internal LobbyLogic(Widget widget, WorldRenderer worldRenderer, OrderManager orderManager,
                            Action onExit, Action onStart, bool skirmishMode, Ruleset modRules)
        {
            lobby             = widget;
            this.orderManager = orderManager;
            this.onStart      = onStart;
            this.onExit       = onExit;
            this.skirmishMode = skirmishMode;
            this.modRules     = modRules;

            orderManager.AddChatLine    += AddChatLine;
            Game.LobbyInfoChanged       += UpdateCurrentMap;
            Game.LobbyInfoChanged       += UpdatePlayerList;
            Game.BeforeGameStart        += OnGameStart;
            Game.ConnectionStateChanged += ConnectionStateChanged;

            var name = lobby.GetOrNull <LabelWidget>("SERVER_NAME");

            if (name != null)
            {
                name.GetText = () => orderManager.LobbyInfo.GlobalSettings.ServerName;
            }

            Ui.LoadWidget("LOBBY_MAP_PREVIEW", lobby.Get("MAP_PREVIEW_ROOT"), new WidgetArgs
            {
                { "orderManager", orderManager },
                { "lobby", this }
            });

            UpdateCurrentMap();
            players           = Ui.LoadWidget <ScrollPanelWidget>("LOBBY_PLAYER_BIN", lobby.Get("PLAYER_BIN_ROOT"), new WidgetArgs());
            players.IsVisible = () => panel == PanelType.Players;

            var playerBinHeaders = lobby.GetOrNull <ContainerWidget>("LABEL_CONTAINER");

            if (playerBinHeaders != null)
            {
                playerBinHeaders.IsVisible = () => panel == PanelType.Players;
            }

            editablePlayerTemplate       = players.Get("TEMPLATE_EDITABLE_PLAYER");
            nonEditablePlayerTemplate    = players.Get("TEMPLATE_NONEDITABLE_PLAYER");
            emptySlotTemplate            = players.Get("TEMPLATE_EMPTY");
            editableSpectatorTemplate    = players.Get("TEMPLATE_EDITABLE_SPECTATOR");
            nonEditableSpectatorTemplate = players.Get("TEMPLATE_NONEDITABLE_SPECTATOR");
            newSpectatorTemplate         = players.Get("TEMPLATE_NEW_SPECTATOR");
            colorPreview       = lobby.Get <ColorPreviewManagerWidget>("COLOR_MANAGER");
            colorPreview.Color = Game.Settings.Player.Color;

            countryNames = modRules.Actors["world"].Traits.WithInterface <CountryInfo>()
                           .Where(c => c.Selectable)
                           .ToDictionary(a => a.Race, a => a.Name);
            countryNames.Add("random", "Any");

            var         gameStarting          = false;
            Func <bool> configurationDisabled = () => !Game.IsHost || gameStarting ||
                                                panel == PanelType.Kick || panel == PanelType.ForceStart ||
                                                orderManager.LocalClient == null || orderManager.LocalClient.IsReady;

            var mapButton = lobby.GetOrNull <ButtonWidget>("CHANGEMAP_BUTTON");

            if (mapButton != null)
            {
                mapButton.IsDisabled = configurationDisabled;
                mapButton.OnClick    = () =>
                {
                    var onSelect = new Action <string>(uid =>
                    {
                        // Don't select the same map again
                        if (uid == Map.Uid)
                        {
                            return;
                        }

                        orderManager.IssueOrder(Order.Command("map " + uid));
                        Game.Settings.Server.Map = uid;
                        Game.Settings.Save();
                    });

                    Ui.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
                    {
                        { "initialMap", Map.Uid },
                        { "onExit", DoNothing },
                        { "onSelect", onSelect }
                    });
                };
            }

            var slotsButton = lobby.GetOrNull <DropDownButtonWidget>("SLOTS_DROPDOWNBUTTON");

            if (slotsButton != null)
            {
                slotsButton.IsDisabled = () => configurationDisabled() || panel != PanelType.Players ||
                                         Map.RuleStatus != MapRuleStatus.Cached || !orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots || !s.LockTeam);

                var botNames = modRules.Actors["player"].Traits.WithInterface <IBotInfo>().Select(t => t.Name);
                slotsButton.OnMouseDown = _ =>
                {
                    var options = new Dictionary <string, IEnumerable <DropDownOption> >();

                    var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin);
                    if (orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots))
                    {
                        var botOptions = new List <DropDownOption>()
                        {
                            new DropDownOption()
                            {
                                Title      = "Add",
                                IsSelected = () => false,
                                OnClick    = () =>
                                {
                                    foreach (var slot in orderManager.LobbyInfo.Slots)
                                    {
                                        var bot = botNames.Random(Game.CosmeticRandom);
                                        var c   = orderManager.LobbyInfo.ClientInSlot(slot.Key);
                                        if (slot.Value.AllowBots == true && (c == null || c.Bot != null))
                                        {
                                            orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot.Key, botController.Index, bot)));
                                        }
                                    }
                                }
                            }
                        };

                        if (orderManager.LobbyInfo.Clients.Any(c => c.Bot != null))
                        {
                            botOptions.Add(new DropDownOption()
                            {
                                Title      = "Remove",
                                IsSelected = () => false,
                                OnClick    = () =>
                                {
                                    foreach (var slot in orderManager.LobbyInfo.Slots)
                                    {
                                        var c = orderManager.LobbyInfo.ClientInSlot(slot.Key);
                                        if (c != null && c.Bot != null)
                                        {
                                            orderManager.IssueOrder(Order.Command("slot_open " + slot.Value.PlayerReference));
                                        }
                                    }
                                }
                            });
                        }

                        options.Add("Configure Bots", botOptions);
                    }

                    var teamCount = (orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) + 1) / 2;
                    if (teamCount >= 1)
                    {
                        var teamOptions = Enumerable.Range(2, teamCount - 1).Reverse().Select(d => new DropDownOption
                        {
                            Title      = "{0} Teams".F(d),
                            IsSelected = () => false,
                            OnClick    = () => orderManager.IssueOrder(Order.Command("assignteams {0}".F(d.ToString())))
                        }).ToList();

                        if (orderManager.LobbyInfo.Slots.Any(s => s.Value.AllowBots))
                        {
                            teamOptions.Add(new DropDownOption
                            {
                                Title      = "Humans vs Bots",
                                IsSelected = () => false,
                                OnClick    = () => orderManager.IssueOrder(Order.Command("assignteams 1"))
                            });
                        }

                        teamOptions.Add(new DropDownOption
                        {
                            Title      = "Free for all",
                            IsSelected = () => false,
                            OnClick    = () => orderManager.IssueOrder(Order.Command("assignteams 0"))
                        });

                        options.Add("Configure Teams", teamOptions);
                    }

                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };
                    slotsButton.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 175, options, setupItem);
                };
            }

            var optionsBin = Ui.LoadWidget("LOBBY_OPTIONS_BIN", lobby, new WidgetArgs());

            optionsBin.IsVisible = () => panel == PanelType.Options;

            var optionsButton = lobby.Get <ButtonWidget>("OPTIONS_BUTTON");

            optionsButton.IsDisabled = () => Map.RuleStatus != MapRuleStatus.Cached || panel == PanelType.Kick || panel == PanelType.ForceStart;
            optionsButton.GetText    = () => panel == PanelType.Options ? "Players" : "Options";
            optionsButton.OnClick    = () => panel = (panel == PanelType.Options) ? PanelType.Players : PanelType.Options;

            // Force start panel
            Action startGame = () =>
            {
                gameStarting = true;
                orderManager.IssueOrder(Order.Command("startgame"));
            };

            var startGameButton = lobby.GetOrNull <ButtonWidget>("START_GAME_BUTTON");

            if (startGameButton != null)
            {
                startGameButton.IsDisabled = () => configurationDisabled() || Map.RuleStatus != MapRuleStatus.Cached ||
                                             orderManager.LobbyInfo.Slots.Any(sl => sl.Value.Required && orderManager.LobbyInfo.ClientInSlot(sl.Key) == null);
                startGameButton.OnClick = () =>
                {
                    Func <KeyValuePair <string, Session.Slot>, bool> notReady = sl =>
                    {
                        var cl = orderManager.LobbyInfo.ClientInSlot(sl.Key);

                        // Bots and admins don't count
                        return(cl != null && !cl.IsAdmin && cl.Bot == null && !cl.IsReady);
                    };

                    if (orderManager.LobbyInfo.Slots.Any(notReady))
                    {
                        panel = PanelType.ForceStart;
                    }
                    else
                    {
                        startGame();
                    }
                };
            }

            var forceStartBin = Ui.LoadWidget("FORCE_START_DIALOG", lobby, new WidgetArgs());

            forceStartBin.IsVisible = () => panel == PanelType.ForceStart;
            forceStartBin.Get("KICK_WARNING").IsVisible               = () => orderManager.LobbyInfo.Clients.Any(c => c.IsInvalid);
            forceStartBin.Get <ButtonWidget>("OK_BUTTON").OnClick     = startGame;
            forceStartBin.Get <ButtonWidget>("CANCEL_BUTTON").OnClick = () => panel = PanelType.Players;

            // Options panel
            var allowCheats = optionsBin.GetOrNull <CheckboxWidget>("ALLOWCHEATS_CHECKBOX");

            if (allowCheats != null)
            {
                allowCheats.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats;
                allowCheats.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Cheats.HasValue || configurationDisabled();
                allowCheats.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                           "allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats)));
            }

            var crates = optionsBin.GetOrNull <CheckboxWidget>("CRATES_CHECKBOX");

            if (crates != null)
            {
                crates.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.Crates;
                crates.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Crates.HasValue || configurationDisabled();
                crates.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                      "crates {0}".F(!orderManager.LobbyInfo.GlobalSettings.Crates)));
            }

            var allybuildradius = optionsBin.GetOrNull <CheckboxWidget>("ALLYBUILDRADIUS_CHECKBOX");

            if (allybuildradius != null)
            {
                allybuildradius.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius;
                allybuildradius.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.AllyBuildRadius.HasValue || configurationDisabled();
                allybuildradius.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                               "allybuildradius {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius)));
            }

            var fragileAlliance = optionsBin.GetOrNull <CheckboxWidget>("FRAGILEALLIANCES_CHECKBOX");

            if (fragileAlliance != null)
            {
                fragileAlliance.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.FragileAlliances;
                fragileAlliance.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.FragileAlliances.HasValue || configurationDisabled();
                fragileAlliance.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                               "fragilealliance {0}".F(!orderManager.LobbyInfo.GlobalSettings.FragileAlliances)));
            }

            var difficulty = optionsBin.GetOrNull <DropDownButtonWidget>("DIFFICULTY_DROPDOWNBUTTON");

            if (difficulty != null)
            {
                difficulty.IsVisible   = () => Map.Status == MapStatus.Available && Map.Map.Options.Difficulties.Any();
                difficulty.IsDisabled  = () => Map.Status != MapStatus.Available || configurationDisabled();
                difficulty.GetText     = () => orderManager.LobbyInfo.GlobalSettings.Difficulty;
                difficulty.OnMouseDown = _ =>
                {
                    var options = Map.Map.Options.Difficulties.Select(d => new DropDownOption
                    {
                        Title      = d,
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.Difficulty == d,
                        OnClick    = () => orderManager.IssueOrder(Order.Command("difficulty {0}".F(d)))
                    });
                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };
                    difficulty.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };

                optionsBin.Get <LabelWidget>("DIFFICULTY_DESC").IsVisible = difficulty.IsVisible;
            }

            var startingUnits = optionsBin.GetOrNull <DropDownButtonWidget>("STARTINGUNITS_DROPDOWNBUTTON");

            if (startingUnits != null)
            {
                var startUnitsInfo = modRules.Actors["world"].Traits.WithInterface <MPStartUnitsInfo>();
                var classes        = startUnitsInfo.Select(a => a.Class).Distinct();
                Func <string, string> className = c =>
                {
                    var selectedClass = startUnitsInfo.Where(s => s.Class == c).Select(u => u.ClassName).FirstOrDefault();
                    return(selectedClass != null ? selectedClass : c);
                };

                startingUnits.IsDisabled  = () => Map.Status != MapStatus.Available || !Map.Map.Options.ConfigurableStartingUnits || configurationDisabled();
                startingUnits.GetText     = () => Map.Status != MapStatus.Available || !Map.Map.Options.ConfigurableStartingUnits ? "Not Available" : className(orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass);
                startingUnits.OnMouseDown = _ =>
                {
                    var options = classes.Select(c => new DropDownOption
                    {
                        Title      = className(c),
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass == c,
                        OnClick    = () => orderManager.IssueOrder(Order.Command("startingunits {0}".F(c)))
                    });

                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };

                    startingUnits.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };

                optionsBin.Get <LabelWidget>("STARTINGUNITS_DESC").IsVisible = startingUnits.IsVisible;
            }

            var startingCash = optionsBin.GetOrNull <DropDownButtonWidget>("STARTINGCASH_DROPDOWNBUTTON");

            if (startingCash != null)
            {
                startingCash.IsDisabled  = () => Map.Status != MapStatus.Available || Map.Map.Options.StartingCash.HasValue || configurationDisabled();
                startingCash.GetText     = () => Map.Status != MapStatus.Available || Map.Map.Options.StartingCash.HasValue ? "Not Available" : "${0}".F(orderManager.LobbyInfo.GlobalSettings.StartingCash);
                startingCash.OnMouseDown = _ =>
                {
                    var options = modRules.Actors["player"].Traits.Get <PlayerResourcesInfo>().SelectableCash.Select(c => new DropDownOption
                    {
                        Title      = "${0}".F(c),
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.StartingCash == c,
                        OnClick    = () => orderManager.IssueOrder(Order.Command("startingcash {0}".F(c)))
                    });

                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };

                    startingCash.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }

            var techLevel = optionsBin.GetOrNull <DropDownButtonWidget>("TECHLEVEL_DROPDOWNBUTTON");

            if (techLevel != null)
            {
                var techTraits = modRules.Actors["player"].Traits.WithInterface <ProvidesTechPrerequisiteInfo>().ToArray();
                techLevel.IsVisible = () => techTraits.Length > 0;
                optionsBin.GetOrNull <LabelWidget>("TECHLEVEL_DESC").IsVisible = () => techTraits.Length > 0;
                techLevel.IsDisabled  = () => Map.Status != MapStatus.Available || Map.Map.Options.TechLevel != null || configurationDisabled() || techTraits.Length <= 1;
                techLevel.GetText     = () => Map.Status != MapStatus.Available || Map.Map.Options.TechLevel != null ? "Not Available" : "{0}".F(orderManager.LobbyInfo.GlobalSettings.TechLevel);
                techLevel.OnMouseDown = _ =>
                {
                    var options = techTraits.Select(c => new DropDownOption
                    {
                        Title      = "{0}".F(c.Name),
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.TechLevel == c.Name,
                        OnClick    = () => orderManager.IssueOrder(Order.Command("techlevel {0}".F(c.Name)))
                    });

                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };

                    techLevel.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }

            var enableShroud = optionsBin.GetOrNull <CheckboxWidget>("SHROUD_CHECKBOX");

            if (enableShroud != null)
            {
                enableShroud.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.Shroud;
                enableShroud.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Shroud.HasValue || configurationDisabled();
                enableShroud.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                            "shroud {0}".F(!orderManager.LobbyInfo.GlobalSettings.Shroud)));
            }

            var enableFog = optionsBin.GetOrNull <CheckboxWidget>("FOG_CHECKBOX");

            if (enableFog != null)
            {
                enableFog.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.Fog;
                enableFog.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Fog.HasValue || configurationDisabled();
                enableFog.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                         "fog {0}".F(!orderManager.LobbyInfo.GlobalSettings.Fog)));
            }

            var disconnectButton = lobby.Get <ButtonWidget>("DISCONNECT_BUTTON");

            disconnectButton.OnClick = () => { CloseWindow(); onExit(); };

            if (skirmishMode)
            {
                disconnectButton.Text = "Cancel";
            }

            var teamChat      = false;
            var chatLabel     = lobby.Get <LabelWidget>("LABEL_CHATTYPE");
            var chatTextField = lobby.Get <TextFieldWidget>("CHAT_TEXTFIELD");

            chatTextField.TakeKeyboardFocus();

            chatTextField.OnEnterKey = () =>
            {
                if (chatTextField.Text.Length == 0)
                {
                    return(true);
                }

                // Always scroll to bottom when we've typed something
                chatPanel.ScrollToBottom();

                orderManager.IssueOrder(Order.Chat(teamChat, chatTextField.Text));
                chatTextField.Text = "";
                return(true);
            };
            chatTextField.OnAltKey = () =>
            {
                teamChat      ^= true;
                chatLabel.Text = teamChat ? "Team:" : "Chat:";
                return(true);
            };
            chatTextField.OnTabKey = () =>
            {
                chatTextField.Text           = tabCompletion.Complete(chatTextField.Text);
                chatTextField.CursorPosition = chatTextField.Text.Length;
                return(true);
            };

            chatPanel    = lobby.Get <ScrollPanelWidget>("CHAT_DISPLAY");
            chatTemplate = chatPanel.Get("CHAT_TEMPLATE");
            chatPanel.RemoveChildren();

            var musicButton = lobby.GetOrNull <ButtonWidget>("MUSIC_BUTTON");

            if (musicButton != null)
            {
                musicButton.OnClick = () => Ui.OpenWindow("MUSIC_PANEL", new WidgetArgs
                {
                    { "onExit", DoNothing },
                    { "world", orderManager.world }
                });
            }

            var settingsButton = lobby.GetOrNull <ButtonWidget>("SETTINGS_BUTTON");

            if (settingsButton != null)
            {
                settingsButton.OnClick = () => Ui.OpenWindow("SETTINGS_PANEL", new WidgetArgs
                {
                    { "onExit", DoNothing },
                    { "worldRenderer", worldRenderer }
                });
            }

            // Add a bot on the first lobbyinfo update
            if (skirmishMode)
            {
                Game.LobbyInfoChanged += WidgetUtils.Once(() =>
                {
                    var slot          = orderManager.LobbyInfo.FirstEmptyBotSlot();
                    var bot           = modRules.Actors["player"].Traits.WithInterface <IBotInfo>().Select(t => t.Name).FirstOrDefault();
                    var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin);
                    if (slot != null && bot != null)
                    {
                        orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot, botController.Index, bot)));
                    }
                });
            }
        }
예제 #13
0
        public CncSettingsLogic(Widget widget, World world, Action onExit)
        {
            this.world = world;
            var panel = widget.Get("SETTINGS_PANEL");

            // General pane
            var generalButton = panel.Get <ButtonWidget>("GENERAL_BUTTON");

            generalButton.OnClick       = () => Settings = PanelType.General;
            generalButton.IsHighlighted = () => Settings == PanelType.General;

            var generalPane = panel.Get("GENERAL_CONTROLS");

            generalPane.IsVisible = () => Settings == PanelType.General;

            var gameSettings     = Game.Settings.Game;
            var playerSettings   = Game.Settings.Player;
            var debugSettings    = Game.Settings.Debug;
            var graphicsSettings = Game.Settings.Graphics;
            var soundSettings    = Game.Settings.Sound;

            // Player profile
            var nameTextfield = generalPane.Get <TextFieldWidget>("NAME_TEXTFIELD");

            nameTextfield.Text = playerSettings.Name;

            colorPreview       = panel.Get <ColorPreviewManagerWidget>("COLOR_MANAGER");
            colorPreview.Color = playerSettings.Color;

            var colorDropdown = generalPane.Get <DropDownButtonWidget>("COLOR");

            colorDropdown.OnMouseDown = _ => ShowColorPicker(colorDropdown, playerSettings);
            colorDropdown.Get <ColorBlockWidget>("COLORBLOCK").GetColor = () => playerSettings.Color.RGB;

            // Debug
            var perftextCheckbox = generalPane.Get <CheckboxWidget>("PERFTEXT_CHECKBOX");

            perftextCheckbox.IsChecked = () => debugSettings.PerfText;
            perftextCheckbox.OnClick   = () => debugSettings.PerfText ^= true;

            var perfgraphCheckbox = generalPane.Get <CheckboxWidget>("PERFGRAPH_CHECKBOX");

            perfgraphCheckbox.IsChecked = () => debugSettings.PerfGraph;
            perfgraphCheckbox.OnClick   = () => debugSettings.PerfGraph ^= true;

            var checkunsyncedCheckbox = generalPane.Get <CheckboxWidget>("CHECKUNSYNCED_CHECKBOX");

            checkunsyncedCheckbox.IsChecked = () => debugSettings.SanityCheckUnsyncedCode;
            checkunsyncedCheckbox.OnClick   = () => debugSettings.SanityCheckUnsyncedCode ^= true;

            // Video
            var windowModeDropdown = generalPane.Get <DropDownButtonWidget>("MODE_DROPDOWN");

            windowModeDropdown.OnMouseDown = _ => SettingsMenuLogic.ShowWindowModeDropdown(windowModeDropdown, graphicsSettings);
            windowModeDropdown.GetText     = () => graphicsSettings.Mode == WindowMode.Windowed ?
                                             "Windowed" : graphicsSettings.Mode == WindowMode.Fullscreen ? "Fullscreen" : "Pseudo-Fullscreen";

            var pixelDoubleCheckbox = generalPane.Get <CheckboxWidget>("PIXELDOUBLE_CHECKBOX");

            pixelDoubleCheckbox.IsChecked = () => graphicsSettings.PixelDouble;
            pixelDoubleCheckbox.OnClick   = () =>
            {
                graphicsSettings.PixelDouble ^= true;
                Game.viewport.Zoom            = graphicsSettings.PixelDouble ? 2 : 1;
            };

            var showShellmapCheckbox = generalPane.Get <CheckboxWidget>("SHOW_SHELLMAP");

            showShellmapCheckbox.IsChecked = () => gameSettings.ShowShellmap;
            showShellmapCheckbox.OnClick   = () => gameSettings.ShowShellmap ^= true;

            generalPane.Get("WINDOW_RESOLUTION").IsVisible = () => graphicsSettings.Mode == WindowMode.Windowed;
            var windowWidth = generalPane.Get <TextFieldWidget>("WINDOW_WIDTH");

            windowWidth.Text = graphicsSettings.WindowedSize.X.ToString();

            var windowHeight = generalPane.Get <TextFieldWidget>("WINDOW_HEIGHT");

            windowHeight.Text = graphicsSettings.WindowedSize.Y.ToString();

            // Audio
            var soundSlider = generalPane.Get <SliderWidget>("SOUND_SLIDER");

            soundSlider.OnChange += x => { soundSettings.SoundVolume = x; Sound.SoundVolume = x; };
            soundSlider.Value     = soundSettings.SoundVolume;

            var musicSlider = generalPane.Get <SliderWidget>("MUSIC_SLIDER");

            musicSlider.OnChange += x => { soundSettings.MusicVolume = x; Sound.MusicVolume = x; };
            musicSlider.Value     = soundSettings.MusicVolume;

            var shellmapMusicCheckbox = generalPane.Get <CheckboxWidget>("SHELLMAP_MUSIC");

            shellmapMusicCheckbox.IsChecked = () => soundSettings.MapMusic;
            shellmapMusicCheckbox.OnClick   = () => soundSettings.MapMusic ^= true;

            // Input pane
            var inputPane = panel.Get("INPUT_CONTROLS");

            inputPane.IsVisible = () => Settings == PanelType.Input;

            var inputButton = panel.Get <ButtonWidget>("INPUT_BUTTON");

            inputButton.OnClick       = () => Settings = PanelType.Input;
            inputButton.IsHighlighted = () => Settings == PanelType.Input;

            var classicMouseCheckbox = inputPane.Get <CheckboxWidget>("CLASSICORDERS_CHECKBOX");

            classicMouseCheckbox.IsChecked = () => gameSettings.UseClassicMouseStyle;
            classicMouseCheckbox.OnClick   = () => gameSettings.UseClassicMouseStyle ^= true;

            var scrollSlider = inputPane.Get <SliderWidget>("SCROLLSPEED_SLIDER");

            scrollSlider.Value     = gameSettings.ViewportEdgeScrollStep;
            scrollSlider.OnChange += x => gameSettings.ViewportEdgeScrollStep = x;

            var edgescrollCheckbox = inputPane.Get <CheckboxWidget>("EDGESCROLL_CHECKBOX");

            edgescrollCheckbox.IsChecked = () => gameSettings.ViewportEdgeScroll;
            edgescrollCheckbox.OnClick   = () => gameSettings.ViewportEdgeScroll ^= true;

            var mouseScrollDropdown = inputPane.Get <DropDownButtonWidget>("MOUSE_SCROLL");

            mouseScrollDropdown.OnMouseDown = _ => ShowMouseScrollDropdown(mouseScrollDropdown, gameSettings);
            mouseScrollDropdown.GetText     = () => gameSettings.MouseScroll.ToString();

            var teamchatCheckbox = inputPane.Get <CheckboxWidget>("TEAMCHAT_CHECKBOX");

            teamchatCheckbox.IsChecked = () => gameSettings.TeamChatToggle;
            teamchatCheckbox.OnClick   = () => gameSettings.TeamChatToggle ^= true;

            panel.Get <ButtonWidget>("BACK_BUTTON").OnClick = () =>
            {
                playerSettings.Name = nameTextfield.Text;
                int x, y;
                int.TryParse(windowWidth.Text, out x);
                int.TryParse(windowHeight.Text, out y);
                graphicsSettings.WindowedSize = new int2(x, y);
                Game.Settings.Save();
                Ui.CloseWindow();
                onExit();
            };
        }
예제 #14
0
파일: LobbyLogic.cs 프로젝트: pchote/OpenRA
        internal LobbyLogic(Widget widget, ModData modData, WorldRenderer worldRenderer, OrderManager orderManager,
			Action onExit, Action onStart, bool skirmishMode)
        {
            Map = MapCache.UnknownMap;
            lobby = widget;
            this.modData = modData;
            this.orderManager = orderManager;
            this.onStart = onStart;
            this.onExit = onExit;
            this.skirmishMode = skirmishMode;

            // TODO: This needs to be reworked to support per-map tech levels, bots, etc.
            this.modRules = modData.DefaultRules;
            shellmapWorld = worldRenderer.World;

            orderManager.AddChatLine += AddChatLine;
            Game.LobbyInfoChanged += UpdateCurrentMap;
            Game.LobbyInfoChanged += UpdatePlayerList;
            Game.BeforeGameStart += OnGameStart;
            Game.ConnectionStateChanged += ConnectionStateChanged;

            var name = lobby.GetOrNull<LabelWidget>("SERVER_NAME");
            if (name != null)
                name.GetText = () => orderManager.LobbyInfo.GlobalSettings.ServerName;

            Ui.LoadWidget("LOBBY_MAP_PREVIEW", lobby.Get("MAP_PREVIEW_ROOT"), new WidgetArgs
            {
                { "orderManager", orderManager },
                { "lobby", this }
            });

            UpdateCurrentMap();

            var playerBin = Ui.LoadWidget("LOBBY_PLAYER_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs());
            playerBin.IsVisible = () => panel == PanelType.Players;

            players = playerBin.Get<ScrollPanelWidget>("LOBBY_PLAYERS");
            editablePlayerTemplate = players.Get("TEMPLATE_EDITABLE_PLAYER");
            nonEditablePlayerTemplate = players.Get("TEMPLATE_NONEDITABLE_PLAYER");
            emptySlotTemplate = players.Get("TEMPLATE_EMPTY");
            editableSpectatorTemplate = players.Get("TEMPLATE_EDITABLE_SPECTATOR");
            nonEditableSpectatorTemplate = players.Get("TEMPLATE_NONEDITABLE_SPECTATOR");
            newSpectatorTemplate = players.Get("TEMPLATE_NEW_SPECTATOR");
            colorPreview = lobby.Get<ColorPreviewManagerWidget>("COLOR_MANAGER");
            colorPreview.Color = Game.Settings.Player.Color;

            foreach (var f in modRules.Actors["world"].TraitInfos<FactionInfo>())
                factions.Add(f.InternalName, new LobbyFaction { Selectable = f.Selectable, Name = f.Name, Side = f.Side, Description = f.Description });

            var gameStarting = false;
            Func<bool> configurationDisabled = () => !Game.IsHost || gameStarting ||
                panel == PanelType.Kick || panel == PanelType.ForceStart ||
                !Map.RulesLoaded || Map.InvalidCustomRules ||
                orderManager.LocalClient == null || orderManager.LocalClient.IsReady;

            var mapButton = lobby.GetOrNull<ButtonWidget>("CHANGEMAP_BUTTON");
            if (mapButton != null)
            {
                mapButton.IsDisabled = () => gameStarting || panel == PanelType.Kick || panel == PanelType.ForceStart ||
                    orderManager.LocalClient == null || orderManager.LocalClient.IsReady;
                mapButton.OnClick = () =>
                {
                    var onSelect = new Action<string>(uid =>
                    {
                        // Don't select the same map again
                        if (uid == Map.Uid)
                            return;

                        orderManager.IssueOrder(Order.Command("map " + uid));
                        Game.Settings.Server.Map = uid;
                        Game.Settings.Save();
                    });

                    Ui.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
                    {
                        { "initialMap", Map.Uid },
                        { "initialTab", MapClassification.System },
                        { "onExit", DoNothing },
                        { "onSelect", Game.IsHost ? onSelect : null },
                        { "filter", MapVisibility.Lobby },
                    });
                };
            }

            var slotsButton = lobby.GetOrNull<DropDownButtonWidget>("SLOTS_DROPDOWNBUTTON");
            if (slotsButton != null)
            {
                slotsButton.IsDisabled = () => configurationDisabled() || panel != PanelType.Players ||
                    (orderManager.LobbyInfo.Slots.Values.All(s => !s.AllowBots) &&
                    orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) == 0);

                slotsButton.OnMouseDown = _ =>
                {
                    var botNames = Map.Rules.Actors["player"].TraitInfos<IBotInfo>().Select(t => t.Name);
                    var options = new Dictionary<string, IEnumerable<DropDownOption>>();

                    var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin);
                    if (orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots))
                    {
                        var botOptions = new List<DropDownOption>()
                        {
                            new DropDownOption()
                            {
                                Title = "Add",
                                IsSelected = () => false,
                                OnClick = () =>
                                {
                                    foreach (var slot in orderManager.LobbyInfo.Slots)
                                    {
                                        var bot = botNames.Random(Game.CosmeticRandom);
                                        var c = orderManager.LobbyInfo.ClientInSlot(slot.Key);
                                        if (slot.Value.AllowBots == true && (c == null || c.Bot != null))
                                            orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot.Key, botController.Index, bot)));
                                    }
                                }
                            }
                        };

                        if (orderManager.LobbyInfo.Clients.Any(c => c.Bot != null))
                        {
                            botOptions.Add(new DropDownOption()
                            {
                                Title = "Remove",
                                IsSelected = () => false,
                                OnClick = () =>
                                {
                                    foreach (var slot in orderManager.LobbyInfo.Slots)
                                    {
                                        var c = orderManager.LobbyInfo.ClientInSlot(slot.Key);
                                        if (c != null && c.Bot != null)
                                            orderManager.IssueOrder(Order.Command("slot_open " + slot.Value.PlayerReference));
                                    }
                                }
                            });
                        }

                        options.Add("Configure Bots", botOptions);
                    }

                    var teamCount = (orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) + 1) / 2;
                    if (teamCount >= 1)
                    {
                        var teamOptions = Enumerable.Range(2, teamCount - 1).Reverse().Select(d => new DropDownOption
                        {
                            Title = "{0} Teams".F(d),
                            IsSelected = () => false,
                            OnClick = () => orderManager.IssueOrder(Order.Command("assignteams {0}".F(d.ToString())))
                        }).ToList();

                        if (orderManager.LobbyInfo.Slots.Any(s => s.Value.AllowBots))
                        {
                            teamOptions.Add(new DropDownOption
                            {
                                Title = "Humans vs Bots",
                                IsSelected = () => false,
                                OnClick = () => orderManager.IssueOrder(Order.Command("assignteams 1"))
                            });
                        }

                        teamOptions.Add(new DropDownOption
                        {
                            Title = "Free for all",
                            IsSelected = () => false,
                            OnClick = () => orderManager.IssueOrder(Order.Command("assignteams 0"))
                        });

                        options.Add("Configure Teams", teamOptions);
                    }

                    Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
                        return item;
                    };
                    slotsButton.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 175, options, setupItem);
                };
            }

            var optionsBin = Ui.LoadWidget("LOBBY_OPTIONS_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs());
            optionsBin.IsVisible = () => panel == PanelType.Options;

            var musicBin = Ui.LoadWidget("LOBBY_MUSIC_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs
            {
                { "onExit", DoNothing },
                { "world", worldRenderer.World }
            });
            musicBin.IsVisible = () => panel == PanelType.Music;

            var optionsTab = lobby.Get<ButtonWidget>("OPTIONS_TAB");
            optionsTab.IsHighlighted = () => panel == PanelType.Options;
            optionsTab.IsDisabled = () => !Map.RulesLoaded || Map.InvalidCustomRules || panel == PanelType.Kick || panel == PanelType.ForceStart;
            optionsTab.OnClick = () => panel = PanelType.Options;

            var playersTab = lobby.Get<ButtonWidget>("PLAYERS_TAB");
            playersTab.IsHighlighted = () => panel == PanelType.Players;
            playersTab.IsDisabled = () => panel == PanelType.Kick || panel == PanelType.ForceStart;
            playersTab.OnClick = () => panel = PanelType.Players;

            var musicTab = lobby.Get<ButtonWidget>("MUSIC_TAB");
            musicTab.IsHighlighted = () => panel == PanelType.Music;
            musicTab.IsDisabled = () => panel == PanelType.Kick || panel == PanelType.ForceStart;
            musicTab.OnClick = () => panel = PanelType.Music;

            // Force start panel
            Action startGame = () =>
            {
                gameStarting = true;
                orderManager.IssueOrder(Order.Command("startgame"));
            };

            var startGameButton = lobby.GetOrNull<ButtonWidget>("START_GAME_BUTTON");
            if (startGameButton != null)
            {
                startGameButton.IsDisabled = () => configurationDisabled() || Map.Status != MapStatus.Available ||
                    orderManager.LobbyInfo.Slots.Any(sl => sl.Value.Required && orderManager.LobbyInfo.ClientInSlot(sl.Key) == null) ||
                    (!orderManager.LobbyInfo.GlobalSettings.EnableSingleplayer && orderManager.LobbyInfo.IsSinglePlayer);

                startGameButton.OnClick = () =>
                {
                    // Bots and admins don't count
                    if (orderManager.LobbyInfo.Clients.Any(c => c.Slot != null && !c.IsAdmin && c.Bot == null && !c.IsReady))
                        panel = PanelType.ForceStart;
                    else
                        startGame();
                };
            }

            var forceStartBin = Ui.LoadWidget("FORCE_START_DIALOG", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs());
            forceStartBin.IsVisible = () => panel == PanelType.ForceStart;
            forceStartBin.Get("KICK_WARNING").IsVisible = () => orderManager.LobbyInfo.Clients.Any(c => c.IsInvalid);
            forceStartBin.Get<ButtonWidget>("OK_BUTTON").OnClick = startGame;
            forceStartBin.Get<ButtonWidget>("CANCEL_BUTTON").OnClick = () => panel = PanelType.Players;

            // Options panel
            var optionCheckboxes = new Dictionary<string, string>()
            {
                { "EXPLORED_MAP_CHECKBOX", "explored" },
                { "CRATES_CHECKBOX", "crates" },
                { "SHORTGAME_CHECKBOX", "shortgame" },
                { "FOG_CHECKBOX", "fog" },
                { "ALLYBUILDRADIUS_CHECKBOX", "allybuild" },
                { "ALLOWCHEATS_CHECKBOX", "cheats" },
                { "CREEPS_CHECKBOX", "creeps" },
            };

            foreach (var kv in optionCheckboxes)
            {
                var checkbox = optionsBin.GetOrNull<CheckboxWidget>(kv.Key);
                if (checkbox != null)
                {
                    var option = new CachedTransform<Session.Global, Session.LobbyOptionState>(
                        gs => gs.LobbyOptions[kv.Value]);

                    var visible = new CachedTransform<Session.Global, bool>(
                        gs => gs.LobbyOptions.ContainsKey(kv.Value));

                    checkbox.IsVisible = () => visible.Update(orderManager.LobbyInfo.GlobalSettings);
                    checkbox.IsChecked = () => option.Update(orderManager.LobbyInfo.GlobalSettings).Enabled;
                    checkbox.IsDisabled = () => configurationDisabled() ||
                        option.Update(orderManager.LobbyInfo.GlobalSettings).Locked;
                    checkbox.OnClick = () => orderManager.IssueOrder(Order.Command(
                        "option {0} {1}".F(kv.Value, !option.Update(orderManager.LobbyInfo.GlobalSettings).Enabled)));
                }
            }

            var optionDropdowns = new Dictionary<string, string>()
            {
                { "TECHLEVEL", "techlevel" },
                { "STARTINGUNITS", "startingunits" },
                { "STARTINGCASH", "startingcash" },
                { "DIFFICULTY", "difficulty" },
                { "GAMESPEED", "gamespeed" }
            };

            var allOptions = new CachedTransform<MapPreview, LobbyOption[]>(
                map => map.Rules.Actors["player"].TraitInfos<ILobbyOptions>()
                    .Concat(map.Rules.Actors["world"].TraitInfos<ILobbyOptions>())
                    .SelectMany(t => t.LobbyOptions(map.Rules))
                    .ToArray());

            foreach (var kv in optionDropdowns)
            {
                var dropdown = optionsBin.GetOrNull<DropDownButtonWidget>(kv.Key + "_DROPDOWNBUTTON");
                if (dropdown != null)
                {
                    var optionValue = new CachedTransform<Session.Global, Session.LobbyOptionState>(
                        gs => gs.LobbyOptions[kv.Value]);

                    var option = new CachedTransform<MapPreview, LobbyOption>(
                        map => allOptions.Update(map).FirstOrDefault(o => o.Id == kv.Value));

                    var getOptionLabel = new CachedTransform<string, string>(id =>
                    {
                        string value;
                        if (id == null || !option.Update(Map).Values.TryGetValue(id, out value))
                            return "Not Available";

                        return value;
                    });

                    dropdown.GetText = () => getOptionLabel.Update(optionValue.Update(orderManager.LobbyInfo.GlobalSettings).Value);
                    dropdown.IsVisible = () => option.Update(Map) != null;
                    dropdown.IsDisabled = () => configurationDisabled() ||
                        optionValue.Update(orderManager.LobbyInfo.GlobalSettings).Locked;

                    dropdown.OnMouseDown = _ =>
                    {
                        Func<KeyValuePair<string, string>, ScrollItemWidget, ScrollItemWidget> setupItem = (c, template) =>
                        {
                            Func<bool> isSelected = () => optionValue.Update(orderManager.LobbyInfo.GlobalSettings).Value == c.Key;
                            Action onClick = () => orderManager.IssueOrder(Order.Command("option {0} {1}".F(kv.Value, c.Key)));

                            var item = ScrollItemWidget.Setup(template, isSelected, onClick);
                            item.Get<LabelWidget>("LABEL").GetText = () => c.Value;
                            return item;
                        };

                        var options = option.Update(Map).Values;
                        dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                    };

                    var label = optionsBin.GetOrNull(kv.Key + "_DESC");
                    if (label != null)
                        label.IsVisible = () => option.Update(Map) != null;
                }
            }

            var disconnectButton = lobby.Get<ButtonWidget>("DISCONNECT_BUTTON");
            disconnectButton.OnClick = () => { Ui.CloseWindow(); onExit(); };

            if (skirmishMode)
                disconnectButton.Text = "Back";

            var globalChat = Game.LoadWidget(null, "LOBBY_GLOBALCHAT_PANEL", lobby.Get("GLOBALCHAT_ROOT"), new WidgetArgs());
            var globalChatInput = globalChat.Get<TextFieldWidget>("CHAT_TEXTFIELD");

            globalChat.IsVisible = () => chatPanel == ChatPanelType.Global;

            var globalChatTab = lobby.Get<ButtonWidget>("GLOBALCHAT_TAB");
            globalChatTab.IsHighlighted = () => chatPanel == ChatPanelType.Global;
            globalChatTab.OnClick = () =>
            {
                chatPanel = ChatPanelType.Global;
                globalChatInput.TakeKeyboardFocus();
            };

            var globalChatLabel = globalChatTab.Text;
            globalChatTab.GetText = () =>
            {
                if (globalChatUnreadMessages == 0 || chatPanel == ChatPanelType.Global)
                    return globalChatLabel;

                return globalChatLabel + " ({0})".F(globalChatUnreadMessages);
            };

            globalChatLastReadMessages = Game.GlobalChat.History.Count(m => m.Type == ChatMessageType.Message);

            var lobbyChat = lobby.Get("LOBBYCHAT");
            lobbyChat.IsVisible = () => chatPanel == ChatPanelType.Lobby;

            chatLabel = lobby.Get<LabelWidget>("LABEL_CHATTYPE");
            var chatTextField = lobby.Get<TextFieldWidget>("CHAT_TEXTFIELD");
            chatTextField.TakeKeyboardFocus();
            chatTextField.OnEnterKey = () =>
            {
                if (chatTextField.Text.Length == 0)
                    return true;

                // Always scroll to bottom when we've typed something
                lobbyChatPanel.ScrollToBottom();

                orderManager.IssueOrder(Order.Chat(teamChat, chatTextField.Text));
                chatTextField.Text = "";
                return true;
            };

            chatTextField.OnTabKey = () =>
            {
                var previousText = chatTextField.Text;
                chatTextField.Text = tabCompletion.Complete(chatTextField.Text);
                chatTextField.CursorPosition = chatTextField.Text.Length;

                if (chatTextField.Text == previousText)
                    return SwitchTeamChat();
                else
                    return true;
            };

            chatTextField.OnEscKey = () => { chatTextField.Text = ""; return true; };

            var lobbyChatTab = lobby.Get<ButtonWidget>("LOBBYCHAT_TAB");
            lobbyChatTab.IsHighlighted = () => chatPanel == ChatPanelType.Lobby;
            lobbyChatTab.OnClick = () =>
            {
                chatPanel = ChatPanelType.Lobby;
                chatTextField.TakeKeyboardFocus();
            };

            var lobbyChatLabel = lobbyChatTab.Text;
            lobbyChatTab.GetText = () =>
            {
                if (lobbyChatUnreadMessages == 0 || chatPanel == ChatPanelType.Lobby)
                    return lobbyChatLabel;

                return lobbyChatLabel + " ({0})".F(lobbyChatUnreadMessages);
            };

            lobbyChatPanel = lobby.Get<ScrollPanelWidget>("CHAT_DISPLAY");
            chatTemplate = lobbyChatPanel.Get("CHAT_TEMPLATE");
            lobbyChatPanel.RemoveChildren();

            var settingsButton = lobby.GetOrNull<ButtonWidget>("SETTINGS_BUTTON");
            if (settingsButton != null)
            {
                settingsButton.OnClick = () => Ui.OpenWindow("SETTINGS_PANEL", new WidgetArgs
                {
                    { "onExit", DoNothing },
                    { "worldRenderer", worldRenderer }
                });
            }

            // Add a bot on the first lobbyinfo update
            if (skirmishMode)
                addBotOnMapLoad = true;
        }
        internal LobbyLogic(Widget widget, ModData modData, WorldRenderer worldRenderer, OrderManager orderManager,
                            Action onExit, Action onStart, bool skirmishMode)
        {
            map                = MapCache.UnknownMap;
            lobby              = widget;
            this.modData       = modData;
            this.orderManager  = orderManager;
            this.worldRenderer = worldRenderer;
            this.onStart       = onStart;
            this.onExit        = onExit;
            this.skirmishMode  = skirmishMode;

            // TODO: This needs to be reworked to support per-map tech levels, bots, etc.
            this.modRules = modData.DefaultRules;
            shellmapWorld = worldRenderer.World;

            services = modData.Manifest.Get <WebServices>();

            orderManager.AddChatLine    += AddChatLine;
            Game.LobbyInfoChanged       += UpdateCurrentMap;
            Game.LobbyInfoChanged       += UpdatePlayerList;
            Game.BeforeGameStart        += OnGameStart;
            Game.ConnectionStateChanged += ConnectionStateChanged;

            var name = lobby.GetOrNull <LabelWidget>("SERVER_NAME");

            if (name != null)
            {
                name.GetText = () => orderManager.LobbyInfo.GlobalSettings.ServerName;
            }

            var mapContainer = Ui.LoadWidget("MAP_PREVIEW", lobby.Get("MAP_PREVIEW_ROOT"), new WidgetArgs
            {
                { "orderManager", orderManager },
                { "getMap", (Func <MapPreview>)(() => map) },
                { "onMouseDown", (Action <MapPreviewWidget, MapPreview, MouseInput>)((preview, mapPreview, mi) =>
                                                                                     LobbyUtils.SelectSpawnPoint(orderManager, preview, mapPreview, mi)) },
                { "getSpawnOccupants", (Func <MapPreview, Dictionary <CPos, SpawnOccupant> >)(mapPreview => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, mapPreview)) },
                { "showUnoccupiedSpawnpoints", true },
            });

            mapContainer.IsVisible = () => panel != PanelType.Servers;

            UpdateCurrentMap();

            var playerBin = Ui.LoadWidget("LOBBY_PLAYER_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs());

            playerBin.IsVisible = () => panel == PanelType.Players;

            players = playerBin.Get <ScrollPanelWidget>("LOBBY_PLAYERS");
            editablePlayerTemplate       = players.Get("TEMPLATE_EDITABLE_PLAYER");
            nonEditablePlayerTemplate    = players.Get("TEMPLATE_NONEDITABLE_PLAYER");
            emptySlotTemplate            = players.Get("TEMPLATE_EMPTY");
            editableSpectatorTemplate    = players.Get("TEMPLATE_EDITABLE_SPECTATOR");
            nonEditableSpectatorTemplate = players.Get("TEMPLATE_NONEDITABLE_SPECTATOR");
            newSpectatorTemplate         = players.Get("TEMPLATE_NEW_SPECTATOR");
            colorPreview       = lobby.Get <ColorPreviewManagerWidget>("COLOR_MANAGER");
            colorPreview.Color = Game.Settings.Player.Color;

            foreach (var f in modRules.Actors["world"].TraitInfos <FactionInfo>())
            {
                factions.Add(f.InternalName, new LobbyFaction {
                    Selectable = f.Selectable, Name = f.Name, Side = f.Side, Description = f.Description
                });
            }

            var         gameStarting          = false;
            Func <bool> configurationDisabled = () => !Game.IsHost || gameStarting ||
                                                panel == PanelType.Kick || panel == PanelType.ForceStart ||
                                                !map.RulesLoaded || map.InvalidCustomRules ||
                                                orderManager.LocalClient == null || orderManager.LocalClient.IsReady;

            var mapButton = lobby.GetOrNull <ButtonWidget>("CHANGEMAP_BUTTON");

            if (mapButton != null)
            {
                mapButton.IsVisible  = () => panel != PanelType.Servers;
                mapButton.IsDisabled = () => gameStarting || panel == PanelType.Kick || panel == PanelType.ForceStart ||
                                       orderManager.LocalClient == null || orderManager.LocalClient.IsReady;
                mapButton.OnClick = () =>
                {
                    var onSelect = new Action <string>(uid =>
                    {
                        // Don't select the same map again
                        if (uid == map.Uid)
                        {
                            return;
                        }

                        orderManager.IssueOrder(Order.Command("map " + uid));
                        Game.Settings.Server.Map = uid;
                        Game.Settings.Save();
                    });

                    Ui.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
                    {
                        { "initialMap", map.Uid },
                        { "initialTab", MapClassification.System },
                        { "onExit", DoNothing },
                        { "onSelect", Game.IsHost ? onSelect : null },
                        { "filter", MapVisibility.Lobby },
                    });
                };
            }

            var slotsButton = lobby.GetOrNull <DropDownButtonWidget>("SLOTS_DROPDOWNBUTTON");

            if (slotsButton != null)
            {
                slotsButton.IsVisible  = () => panel != PanelType.Servers;
                slotsButton.IsDisabled = () => configurationDisabled() || panel != PanelType.Players ||
                                         (orderManager.LobbyInfo.Slots.Values.All(s => !s.AllowBots) &&
                                          orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) == 0);

                slotsButton.OnMouseDown = _ =>
                {
                    var botTypes = map.Rules.Actors["player"].TraitInfos <IBotInfo>().Select(t => t.Type);
                    var options  = new Dictionary <string, IEnumerable <DropDownOption> >();

                    var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin);
                    if (orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots))
                    {
                        var botOptions = new List <DropDownOption>()
                        {
                            new DropDownOption()
                            {
                                Title      = "Add",
                                IsSelected = () => false,
                                OnClick    = () =>
                                {
                                    foreach (var slot in orderManager.LobbyInfo.Slots)
                                    {
                                        var bot = botTypes.Random(Game.CosmeticRandom);
                                        var c   = orderManager.LobbyInfo.ClientInSlot(slot.Key);
                                        if (slot.Value.AllowBots == true && (c == null || c.Bot != null))
                                        {
                                            orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot.Key, botController.Index, bot)));
                                        }
                                    }
                                }
                            }
                        };

                        if (orderManager.LobbyInfo.Clients.Any(c => c.Bot != null))
                        {
                            botOptions.Add(new DropDownOption()
                            {
                                Title      = "Remove",
                                IsSelected = () => false,
                                OnClick    = () =>
                                {
                                    foreach (var slot in orderManager.LobbyInfo.Slots)
                                    {
                                        var c = orderManager.LobbyInfo.ClientInSlot(slot.Key);
                                        if (c != null && c.Bot != null)
                                        {
                                            orderManager.IssueOrder(Order.Command("slot_open " + slot.Value.PlayerReference));
                                        }
                                    }
                                }
                            });
                        }

                        options.Add("Configure Bots", botOptions);
                    }

                    var teamCount = (orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) + 1) / 2;
                    if (teamCount >= 1)
                    {
                        var teamOptions = Enumerable.Range(2, teamCount - 1).Reverse().Select(d => new DropDownOption
                        {
                            Title      = "{0} Teams".F(d),
                            IsSelected = () => false,
                            OnClick    = () => orderManager.IssueOrder(Order.Command("assignteams {0}".F(d.ToString())))
                        }).ToList();

                        if (orderManager.LobbyInfo.Slots.Any(s => s.Value.AllowBots))
                        {
                            teamOptions.Add(new DropDownOption
                            {
                                Title      = "Humans vs Bots",
                                IsSelected = () => false,
                                OnClick    = () => orderManager.IssueOrder(Order.Command("assignteams 1"))
                            });
                        }

                        teamOptions.Add(new DropDownOption
                        {
                            Title      = "Free for all",
                            IsSelected = () => false,
                            OnClick    = () => orderManager.IssueOrder(Order.Command("assignteams 0"))
                        });

                        options.Add("Configure Teams", teamOptions);
                    }

                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };
                    slotsButton.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 175, options, setupItem);
                };
            }

            var optionsBin = Ui.LoadWidget("LOBBY_OPTIONS_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs()
            {
                { "orderManager", orderManager },
                { "getMap", (Func <MapPreview>)(() => map) },
                { "configurationDisabled", configurationDisabled }
            });

            optionsBin.IsVisible = () => panel == PanelType.Options;

            var musicBin = Ui.LoadWidget("LOBBY_MUSIC_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs
            {
                { "onExit", DoNothing },
                { "world", worldRenderer.World }
            });

            musicBin.IsVisible = () => panel == PanelType.Music;

            ServerListLogic serverListLogic = null;

            if (!skirmishMode)
            {
                Action <GameServer> doNothingWithServer = _ => { };

                var serversBin = Ui.LoadWidget("LOBBY_SERVERS_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs
                {
                    { "onJoin", doNothingWithServer },
                });

                serverListLogic      = serversBin.LogicObjects.Select(l => l as ServerListLogic).FirstOrDefault(l => l != null);
                serversBin.IsVisible = () => panel == PanelType.Servers;
            }

            var tabContainer = skirmishMode ? lobby.Get("SKIRMISH_TABS") : lobby.Get("MULTIPLAYER_TABS");

            tabContainer.IsVisible = () => true;

            var optionsTab = tabContainer.Get <ButtonWidget>("OPTIONS_TAB");

            optionsTab.IsHighlighted = () => panel == PanelType.Options;
            optionsTab.IsDisabled    = OptionsTabDisabled;
            optionsTab.OnClick       = () => panel = PanelType.Options;
            optionsTab.GetText       = () => !map.RulesLoaded ? "Loading..." : optionsTab.Text;

            var playersTab = tabContainer.Get <ButtonWidget>("PLAYERS_TAB");

            playersTab.IsHighlighted = () => panel == PanelType.Players;
            playersTab.IsDisabled    = () => panel == PanelType.Kick || panel == PanelType.ForceStart;
            playersTab.OnClick       = () => panel = PanelType.Players;

            var musicTab = tabContainer.Get <ButtonWidget>("MUSIC_TAB");

            musicTab.IsHighlighted = () => panel == PanelType.Music;
            musicTab.IsDisabled    = () => panel == PanelType.Kick || panel == PanelType.ForceStart;
            musicTab.OnClick       = () => panel = PanelType.Music;

            var serversTab = tabContainer.GetOrNull <ButtonWidget>("SERVERS_TAB");

            if (serversTab != null)
            {
                serversTab.IsHighlighted = () => panel == PanelType.Servers;
                serversTab.IsDisabled    = () => panel == PanelType.Kick || panel == PanelType.ForceStart;
                serversTab.OnClick       = () =>
                {
                    // Refresh the list when switching to the servers tab
                    if (serverListLogic != null && panel != PanelType.Servers)
                    {
                        serverListLogic.RefreshServerList();
                    }

                    panel = PanelType.Servers;
                };
            }

            // Force start panel
            Action startGame = () =>
            {
                gameStarting = true;
                orderManager.IssueOrder(Order.Command("startgame"));
            };

            var startGameButton = lobby.GetOrNull <ButtonWidget>("START_GAME_BUTTON");

            if (startGameButton != null)
            {
                startGameButton.IsDisabled = () => configurationDisabled() || map.Status != MapStatus.Available ||
                                             orderManager.LobbyInfo.Slots.Any(sl => sl.Value.Required && orderManager.LobbyInfo.ClientInSlot(sl.Key) == null) ||
                                             (!orderManager.LobbyInfo.GlobalSettings.EnableSingleplayer && orderManager.LobbyInfo.NonBotPlayers.Count() < 2);

                startGameButton.OnClick = () =>
                {
                    // Bots and admins don't count
                    if (orderManager.LobbyInfo.Clients.Any(c => c.Slot != null && !c.IsAdmin && c.Bot == null && !c.IsReady))
                    {
                        panel = PanelType.ForceStart;
                    }
                    else
                    {
                        startGame();
                    }
                };
            }

            var forceStartBin = Ui.LoadWidget("FORCE_START_DIALOG", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs());

            forceStartBin.IsVisible = () => panel == PanelType.ForceStart;
            forceStartBin.Get("KICK_WARNING").IsVisible               = () => orderManager.LobbyInfo.Clients.Any(c => c.IsInvalid);
            forceStartBin.Get <ButtonWidget>("OK_BUTTON").OnClick     = startGame;
            forceStartBin.Get <ButtonWidget>("CANCEL_BUTTON").OnClick = () => panel = PanelType.Players;

            var disconnectButton = lobby.Get <ButtonWidget>("DISCONNECT_BUTTON");

            disconnectButton.OnClick = () => { Ui.CloseWindow(); onExit(); };

            if (skirmishMode)
            {
                disconnectButton.Text = "Back";
            }

            chatLabel = lobby.Get <LabelWidget>("LABEL_CHATTYPE");
            var chatTextField = lobby.Get <TextFieldWidget>("CHAT_TEXTFIELD");

            chatTextField.MaxLength = UnitOrders.ChatMessageMaxLength;

            chatTextField.TakeKeyboardFocus();
            chatTextField.OnEnterKey = () =>
            {
                if (chatTextField.Text.Length == 0)
                {
                    return(true);
                }

                // Always scroll to bottom when we've typed something
                lobbyChatPanel.ScrollToBottom();

                orderManager.IssueOrder(Order.Chat(teamChat, chatTextField.Text));
                chatTextField.Text = "";
                return(true);
            };

            chatTextField.OnTabKey = () =>
            {
                var previousText = chatTextField.Text;
                chatTextField.Text           = tabCompletion.Complete(chatTextField.Text);
                chatTextField.CursorPosition = chatTextField.Text.Length;

                if (chatTextField.Text == previousText)
                {
                    return(SwitchTeamChat());
                }
                else
                {
                    return(true);
                }
            };

            chatTextField.OnEscKey = () => { chatTextField.Text = ""; return(true); };

            lobbyChatPanel = lobby.Get <ScrollPanelWidget>("CHAT_DISPLAY");
            chatTemplate   = lobbyChatPanel.Get("CHAT_TEMPLATE");
            lobbyChatPanel.RemoveChildren();

            var settingsButton = lobby.GetOrNull <ButtonWidget>("SETTINGS_BUTTON");

            if (settingsButton != null)
            {
                settingsButton.OnClick = () => Ui.OpenWindow("SETTINGS_PANEL", new WidgetArgs
                {
                    { "onExit", DoNothing },
                    { "worldRenderer", worldRenderer }
                });
            }

            // Add a bot on the first lobbyinfo update
            if (skirmishMode)
            {
                addBotOnMapLoad = true;
            }
        }
예제 #16
0
        internal LobbyLogic(Widget widget, WorldRenderer worldRenderer, OrderManager orderManager,
                            Action onExit, Action onStart, bool skirmishMode, Ruleset modRules)
        {
            lobby             = widget;
            this.orderManager = orderManager;
            this.onStart      = onStart;
            this.onExit       = onExit;
            this.skirmishMode = skirmishMode;
            this.modRules     = modRules;
            shellmapWorld     = worldRenderer.World;

            orderManager.AddChatLine    += AddChatLine;
            Game.LobbyInfoChanged       += UpdateCurrentMap;
            Game.LobbyInfoChanged       += UpdatePlayerList;
            Game.BeforeGameStart        += OnGameStart;
            Game.ConnectionStateChanged += ConnectionStateChanged;

            var name = lobby.GetOrNull <LabelWidget>("SERVER_NAME");

            if (name != null)
            {
                name.GetText = () => orderManager.LobbyInfo.GlobalSettings.ServerName;
            }

            Ui.LoadWidget("LOBBY_MAP_PREVIEW", lobby.Get("MAP_PREVIEW_ROOT"), new WidgetArgs
            {
                { "orderManager", orderManager },
                { "lobby", this }
            });

            UpdateCurrentMap();

            var playerBin = Ui.LoadWidget("LOBBY_PLAYER_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs());

            playerBin.IsVisible = () => panel == PanelType.Players;

            players = playerBin.Get <ScrollPanelWidget>("LOBBY_PLAYERS");
            editablePlayerTemplate       = players.Get("TEMPLATE_EDITABLE_PLAYER");
            nonEditablePlayerTemplate    = players.Get("TEMPLATE_NONEDITABLE_PLAYER");
            emptySlotTemplate            = players.Get("TEMPLATE_EMPTY");
            editableSpectatorTemplate    = players.Get("TEMPLATE_EDITABLE_SPECTATOR");
            nonEditableSpectatorTemplate = players.Get("TEMPLATE_NONEDITABLE_SPECTATOR");
            newSpectatorTemplate         = players.Get("TEMPLATE_NEW_SPECTATOR");
            colorPreview       = lobby.Get <ColorPreviewManagerWidget>("COLOR_MANAGER");
            colorPreview.Color = Game.Settings.Player.Color;

            foreach (var f in modRules.Actors["world"].TraitInfos <FactionInfo>())
            {
                factions.Add(f.InternalName, new LobbyFaction {
                    Selectable = f.Selectable, Name = f.Name, Side = f.Side, Description = f.Description
                });
            }

            var         gameStarting          = false;
            Func <bool> configurationDisabled = () => !Game.IsHost || gameStarting ||
                                                panel == PanelType.Kick || panel == PanelType.ForceStart ||
                                                orderManager.LocalClient == null || orderManager.LocalClient.IsReady;

            var mapButton = lobby.GetOrNull <ButtonWidget>("CHANGEMAP_BUTTON");

            if (mapButton != null)
            {
                mapButton.IsDisabled = () => gameStarting || panel == PanelType.Kick || panel == PanelType.ForceStart ||
                                       orderManager.LocalClient == null || orderManager.LocalClient.IsReady;
                mapButton.OnClick = () =>
                {
                    var onSelect = new Action <string>(uid =>
                    {
                        // Don't select the same map again
                        if (uid == Map.Uid)
                        {
                            return;
                        }

                        orderManager.IssueOrder(Order.Command("map " + uid));
                        Game.Settings.Server.Map = uid;
                        Game.Settings.Save();
                    });

                    Ui.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
                    {
                        { "initialMap", Map.Uid },
                        { "initialTab", MapClassification.System },
                        { "onExit", DoNothing },
                        { "onSelect", Game.IsHost ? onSelect : null },
                        { "filter", MapVisibility.Lobby },
                    });
                };
            }

            var slotsButton = lobby.GetOrNull <DropDownButtonWidget>("SLOTS_DROPDOWNBUTTON");

            if (slotsButton != null)
            {
                slotsButton.IsDisabled = () => configurationDisabled() || panel != PanelType.Players ||
                                         Map.RuleStatus != MapRuleStatus.Cached || !orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots || !s.LockTeam);

                var botNames = modRules.Actors["player"].TraitInfos <IBotInfo>().Select(t => t.Name);
                slotsButton.OnMouseDown = _ =>
                {
                    var options = new Dictionary <string, IEnumerable <DropDownOption> >();

                    var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin);
                    if (orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots))
                    {
                        var botOptions = new List <DropDownOption>()
                        {
                            new DropDownOption()
                            {
                                Title      = "Add",
                                IsSelected = () => false,
                                OnClick    = () =>
                                {
                                    foreach (var slot in orderManager.LobbyInfo.Slots)
                                    {
                                        var bot = botNames.Random(Game.CosmeticRandom);
                                        var c   = orderManager.LobbyInfo.ClientInSlot(slot.Key);
                                        if (slot.Value.AllowBots == true && (c == null || c.Bot != null))
                                        {
                                            orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot.Key, botController.Index, bot)));
                                        }
                                    }
                                }
                            }
                        };

                        if (orderManager.LobbyInfo.Clients.Any(c => c.Bot != null))
                        {
                            botOptions.Add(new DropDownOption()
                            {
                                Title      = "Remove",
                                IsSelected = () => false,
                                OnClick    = () =>
                                {
                                    foreach (var slot in orderManager.LobbyInfo.Slots)
                                    {
                                        var c = orderManager.LobbyInfo.ClientInSlot(slot.Key);
                                        if (c != null && c.Bot != null)
                                        {
                                            orderManager.IssueOrder(Order.Command("slot_open " + slot.Value.PlayerReference));
                                        }
                                    }
                                }
                            });
                        }

                        options.Add("Configure Bots", botOptions);
                    }

                    var teamCount = (orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) + 1) / 2;
                    if (teamCount >= 1)
                    {
                        var teamOptions = Enumerable.Range(2, teamCount - 1).Reverse().Select(d => new DropDownOption
                        {
                            Title      = "{0} Teams".F(d),
                            IsSelected = () => false,
                            OnClick    = () => orderManager.IssueOrder(Order.Command("assignteams {0}".F(d.ToString())))
                        }).ToList();

                        if (orderManager.LobbyInfo.Slots.Any(s => s.Value.AllowBots))
                        {
                            teamOptions.Add(new DropDownOption
                            {
                                Title      = "Humans vs Bots",
                                IsSelected = () => false,
                                OnClick    = () => orderManager.IssueOrder(Order.Command("assignteams 1"))
                            });
                        }

                        teamOptions.Add(new DropDownOption
                        {
                            Title      = "Free for all",
                            IsSelected = () => false,
                            OnClick    = () => orderManager.IssueOrder(Order.Command("assignteams 0"))
                        });

                        options.Add("Configure Teams", teamOptions);
                    }

                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };
                    slotsButton.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 175, options, setupItem);
                };
            }

            var optionsBin = Ui.LoadWidget("LOBBY_OPTIONS_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs());

            optionsBin.IsVisible = () => panel == PanelType.Options;

            var musicBin = Ui.LoadWidget("LOBBY_MUSIC_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs
            {
                { "onExit", DoNothing },
                { "world", worldRenderer.World }
            });

            musicBin.IsVisible = () => panel == PanelType.Music;

            var optionsTab = lobby.Get <ButtonWidget>("OPTIONS_TAB");

            optionsTab.IsHighlighted = () => panel == PanelType.Options;
            optionsTab.IsDisabled    = () => Map.RuleStatus != MapRuleStatus.Cached || panel == PanelType.Kick || panel == PanelType.ForceStart;
            optionsTab.OnClick       = () => panel = PanelType.Options;

            var playersTab = lobby.Get <ButtonWidget>("PLAYERS_TAB");

            playersTab.IsHighlighted = () => panel == PanelType.Players;
            playersTab.IsDisabled    = () => panel == PanelType.Kick || panel == PanelType.ForceStart;
            playersTab.OnClick       = () => panel = PanelType.Players;

            var musicTab = lobby.Get <ButtonWidget>("MUSIC_TAB");

            musicTab.IsHighlighted = () => panel == PanelType.Music;
            musicTab.IsDisabled    = () => panel == PanelType.Kick || panel == PanelType.ForceStart;
            musicTab.OnClick       = () => panel = PanelType.Music;

            // Force start panel
            Action startGame = () =>
            {
                gameStarting = true;
                orderManager.IssueOrder(Order.Command("startgame"));
            };

            var startGameButton = lobby.GetOrNull <ButtonWidget>("START_GAME_BUTTON");

            if (startGameButton != null)
            {
                startGameButton.IsDisabled = () => configurationDisabled() || Map.RuleStatus != MapRuleStatus.Cached ||
                                             orderManager.LobbyInfo.Slots.Any(sl => sl.Value.Required && orderManager.LobbyInfo.ClientInSlot(sl.Key) == null);
                startGameButton.OnClick = () =>
                {
                    // Bots and admins don't count
                    if (orderManager.LobbyInfo.Clients.Any(c => c.Slot != null && !c.IsAdmin && c.Bot == null && !c.IsReady))
                    {
                        panel = PanelType.ForceStart;
                    }
                    else
                    {
                        startGame();
                    }
                };
            }

            var forceStartBin = Ui.LoadWidget("FORCE_START_DIALOG", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs());

            forceStartBin.IsVisible = () => panel == PanelType.ForceStart;
            forceStartBin.Get("KICK_WARNING").IsVisible               = () => orderManager.LobbyInfo.Clients.Any(c => c.IsInvalid);
            forceStartBin.Get <ButtonWidget>("OK_BUTTON").OnClick     = startGame;
            forceStartBin.Get <ButtonWidget>("CANCEL_BUTTON").OnClick = () => panel = PanelType.Players;

            // Options panel
            var allowCheats = optionsBin.GetOrNull <CheckboxWidget>("ALLOWCHEATS_CHECKBOX");

            if (allowCheats != null)
            {
                allowCheats.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats;
                allowCheats.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Cheats.HasValue || configurationDisabled();
                allowCheats.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                           "allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats)));
            }

            var crates = optionsBin.GetOrNull <CheckboxWidget>("CRATES_CHECKBOX");

            if (crates != null)
            {
                crates.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.Crates;
                crates.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Crates.HasValue || configurationDisabled();
                crates.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                      "crates {0}".F(!orderManager.LobbyInfo.GlobalSettings.Crates)));
            }

            var creeps = optionsBin.GetOrNull <CheckboxWidget>("CREEPS_CHECKBOX");

            if (creeps != null)
            {
                creeps.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.Creeps;
                creeps.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Creeps.HasValue || configurationDisabled();
                creeps.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                      "creeps {0}".F(!orderManager.LobbyInfo.GlobalSettings.Creeps)));
            }

            var allybuildradius = optionsBin.GetOrNull <CheckboxWidget>("ALLYBUILDRADIUS_CHECKBOX");

            if (allybuildradius != null)
            {
                allybuildradius.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius;
                allybuildradius.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.AllyBuildRadius.HasValue || configurationDisabled();
                allybuildradius.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                               "allybuildradius {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius)));
            }

            var fragileAlliance = optionsBin.GetOrNull <CheckboxWidget>("FRAGILEALLIANCES_CHECKBOX");

            if (fragileAlliance != null)
            {
                fragileAlliance.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.FragileAlliances;
                fragileAlliance.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.FragileAlliances.HasValue || configurationDisabled();
                fragileAlliance.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                               "fragilealliance {0}".F(!orderManager.LobbyInfo.GlobalSettings.FragileAlliances)));
            }

            var shortGame = optionsBin.GetOrNull <CheckboxWidget>("SHORTGAME_CHECKBOX");

            if (shortGame != null)
            {
                shortGame.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.ShortGame;
                shortGame.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.ShortGame.HasValue || configurationDisabled();
                shortGame.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                         "shortgame {0}".F(!orderManager.LobbyInfo.GlobalSettings.ShortGame)));
            }

            var difficulty = optionsBin.GetOrNull <DropDownButtonWidget>("DIFFICULTY_DROPDOWNBUTTON");

            if (difficulty != null)
            {
                difficulty.IsVisible   = () => Map.Status == MapStatus.Available && Map.Map.Options.Difficulties.Any();
                difficulty.IsDisabled  = () => Map.Status != MapStatus.Available || configurationDisabled();
                difficulty.GetText     = () => orderManager.LobbyInfo.GlobalSettings.Difficulty;
                difficulty.OnMouseDown = _ =>
                {
                    var options = Map.Map.Options.Difficulties.Select(d => new DropDownOption
                    {
                        Title      = d,
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.Difficulty == d,
                        OnClick    = () => orderManager.IssueOrder(Order.Command("difficulty {0}".F(d)))
                    });
                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };
                    difficulty.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };

                optionsBin.Get <LabelWidget>("DIFFICULTY_DESC").IsVisible = difficulty.IsVisible;
            }

            var startingUnits = optionsBin.GetOrNull <DropDownButtonWidget>("STARTINGUNITS_DROPDOWNBUTTON");

            if (startingUnits != null)
            {
                var startUnitsInfo = modRules.Actors["world"].TraitInfos <MPStartUnitsInfo>();
                var classes        = startUnitsInfo.Select(a => a.Class).Distinct();
                Func <string, string> className = c =>
                {
                    var selectedClass = startUnitsInfo.Where(s => s.Class == c).Select(u => u.ClassName).FirstOrDefault();
                    return(selectedClass != null ? selectedClass : c);
                };

                startingUnits.IsDisabled = () => Map.Status != MapStatus.Available ||
                                           !Map.Map.Options.ConfigurableStartingUnits || configurationDisabled();
                startingUnits.GetText = () => Map.Status != MapStatus.Available ||
                                        !Map.Map.Options.ConfigurableStartingUnits ? "Not Available" : className(orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass);
                startingUnits.OnMouseDown = _ =>
                {
                    var options = classes.Select(c => new DropDownOption
                    {
                        Title      = className(c),
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass == c,
                        OnClick    = () => orderManager.IssueOrder(Order.Command("startingunits {0}".F(c)))
                    });

                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };

                    startingUnits.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };

                optionsBin.Get <LabelWidget>("STARTINGUNITS_DESC").IsVisible = startingUnits.IsVisible;
            }

            var startingCash = optionsBin.GetOrNull <DropDownButtonWidget>("STARTINGCASH_DROPDOWNBUTTON");

            if (startingCash != null)
            {
                startingCash.IsDisabled = () => Map.Status != MapStatus.Available ||
                                          Map.Map.Options.StartingCash.HasValue || configurationDisabled();
                startingCash.GetText = () => Map.Status != MapStatus.Available ||
                                       Map.Map.Options.StartingCash.HasValue ? "Not Available" : "${0}".F(orderManager.LobbyInfo.GlobalSettings.StartingCash);
                startingCash.OnMouseDown = _ =>
                {
                    var options = modRules.Actors["player"].TraitInfo <PlayerResourcesInfo>().SelectableCash.Select(c => new DropDownOption
                    {
                        Title      = "${0}".F(c),
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.StartingCash == c,
                        OnClick    = () => orderManager.IssueOrder(Order.Command("startingcash {0}".F(c)))
                    });

                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };

                    startingCash.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }

            var techLevel = optionsBin.GetOrNull <DropDownButtonWidget>("TECHLEVEL_DROPDOWNBUTTON");

            if (techLevel != null)
            {
                var techTraits = modRules.Actors["player"].TraitInfos <ProvidesTechPrerequisiteInfo>().ToList();
                techLevel.IsVisible = () => techTraits.Count > 0;

                var techLevelDescription = optionsBin.GetOrNull <LabelWidget>("TECHLEVEL_DESC");
                if (techLevelDescription != null)
                {
                    techLevelDescription.IsVisible = () => techTraits.Count > 0;
                }

                techLevel.IsDisabled = () => Map.Status != MapStatus.Available ||
                                       Map.Map.Options.TechLevel != null || configurationDisabled() || techTraits.Count <= 1;
                techLevel.GetText = () => Map.Status != MapStatus.Available ||
                                    Map.Map.Options.TechLevel != null ? "Not Available" : "{0}".F(orderManager.LobbyInfo.GlobalSettings.TechLevel);
                techLevel.OnMouseDown = _ =>
                {
                    var options = techTraits.Select(c => new DropDownOption
                    {
                        Title      = "{0}".F(c.Name),
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.TechLevel == c.Name,
                        OnClick    = () => orderManager.IssueOrder(Order.Command("techlevel {0}".F(c.Name)))
                    });

                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };

                    techLevel.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }

            var gameSpeed = optionsBin.GetOrNull <DropDownButtonWidget>("GAMESPEED_DROPDOWNBUTTON");

            if (gameSpeed != null)
            {
                var speeds = Game.ModData.Manifest.Get <GameSpeeds>().Speeds;

                gameSpeed.IsDisabled = () => Map.Status != MapStatus.Available || configurationDisabled();
                gameSpeed.GetText    = () =>
                {
                    if (Map.Status != MapStatus.Available)
                    {
                        return("Not Available");
                    }

                    GameSpeed speed;
                    if (!speeds.TryGetValue(orderManager.LobbyInfo.GlobalSettings.GameSpeedType, out speed))
                    {
                        return("Unknown");
                    }

                    return(speed.Name);
                };

                gameSpeed.OnMouseDown = _ =>
                {
                    var options = speeds.Select(s => new DropDownOption
                    {
                        Title      = s.Value.Name,
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.GameSpeedType == s.Key,
                        OnClick    = () => orderManager.IssueOrder(Order.Command("gamespeed {0}".F(s.Key)))
                    });

                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };

                    gameSpeed.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }

            var exploredMap = optionsBin.GetOrNull <CheckboxWidget>("EXPLORED_MAP_CHECKBOX");

            if (exploredMap != null)
            {
                exploredMap.IsChecked  = () => !orderManager.LobbyInfo.GlobalSettings.Shroud;
                exploredMap.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Shroud.HasValue || configurationDisabled();
                exploredMap.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                           "shroud {0}".F(!orderManager.LobbyInfo.GlobalSettings.Shroud)));
            }

            var enableFog = optionsBin.GetOrNull <CheckboxWidget>("FOG_CHECKBOX");

            if (enableFog != null)
            {
                enableFog.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.Fog;
                enableFog.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Fog.HasValue || configurationDisabled();
                enableFog.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                         "fog {0}".F(!orderManager.LobbyInfo.GlobalSettings.Fog)));
            }

            var disconnectButton = lobby.Get <ButtonWidget>("DISCONNECT_BUTTON");

            disconnectButton.OnClick = () => { CloseWindow(); onExit(); };

            if (skirmishMode)
            {
                disconnectButton.Text = "Back";
            }

            var globalChat      = Game.LoadWidget(null, "LOBBY_GLOBALCHAT_PANEL", lobby.Get("GLOBALCHAT_ROOT"), new WidgetArgs());
            var globalChatInput = globalChat.Get <TextFieldWidget>("CHAT_TEXTFIELD");

            globalChat.IsVisible = () => chatPanel == ChatPanelType.Global;

            var globalChatTab = lobby.Get <ButtonWidget>("GLOBALCHAT_TAB");

            globalChatTab.IsHighlighted = () => chatPanel == ChatPanelType.Global;
            globalChatTab.OnClick       = () =>
            {
                chatPanel = ChatPanelType.Global;
                globalChatInput.TakeKeyboardFocus();
            };

            var globalChatLabel = globalChatTab.Text;

            globalChatTab.GetText = () =>
            {
                if (globalChatUnreadMessages == 0 || chatPanel == ChatPanelType.Global)
                {
                    return(globalChatLabel);
                }

                return(globalChatLabel + " ({0})".F(globalChatUnreadMessages));
            };

            globalChatLastReadMessages = Game.GlobalChat.History.Count;

            var lobbyChat = lobby.Get("LOBBYCHAT");

            lobbyChat.IsVisible = () => chatPanel == ChatPanelType.Lobby;

            chatLabel = lobby.Get <LabelWidget>("LABEL_CHATTYPE");
            var chatTextField = lobby.Get <TextFieldWidget>("CHAT_TEXTFIELD");

            chatTextField.TakeKeyboardFocus();
            chatTextField.OnEnterKey = () =>
            {
                if (chatTextField.Text.Length == 0)
                {
                    return(true);
                }

                // Always scroll to bottom when we've typed something
                lobbyChatPanel.ScrollToBottom();

                orderManager.IssueOrder(Order.Chat(teamChat, chatTextField.Text));
                chatTextField.Text = "";
                return(true);
            };

            chatTextField.OnTabKey = () =>
            {
                var previousText = chatTextField.Text;
                chatTextField.Text           = tabCompletion.Complete(chatTextField.Text);
                chatTextField.CursorPosition = chatTextField.Text.Length;

                if (chatTextField.Text == previousText)
                {
                    return(SwitchTeamChat());
                }
                else
                {
                    return(true);
                }
            };

            chatTextField.OnEscKey = () => { chatTextField.Text = ""; return(true); };

            var lobbyChatTab = lobby.Get <ButtonWidget>("LOBBYCHAT_TAB");

            lobbyChatTab.IsHighlighted = () => chatPanel == ChatPanelType.Lobby;
            lobbyChatTab.OnClick       = () =>
            {
                chatPanel = ChatPanelType.Lobby;
                chatTextField.TakeKeyboardFocus();
            };

            var lobbyChatLabel = lobbyChatTab.Text;

            lobbyChatTab.GetText = () =>
            {
                if (lobbyChatUnreadMessages == 0 || chatPanel == ChatPanelType.Lobby)
                {
                    return(lobbyChatLabel);
                }

                return(lobbyChatLabel + " ({0})".F(lobbyChatUnreadMessages));
            };

            lobbyChatPanel = lobby.Get <ScrollPanelWidget>("CHAT_DISPLAY");
            chatTemplate   = lobbyChatPanel.Get("CHAT_TEMPLATE");
            lobbyChatPanel.RemoveChildren();

            var settingsButton = lobby.GetOrNull <ButtonWidget>("SETTINGS_BUTTON");

            if (settingsButton != null)
            {
                settingsButton.OnClick = () => Ui.OpenWindow("SETTINGS_PANEL", new WidgetArgs
                {
                    { "onExit", DoNothing },
                    { "worldRenderer", worldRenderer }
                });
            }

            // Add a bot on the first lobbyinfo update
            if (skirmishMode)
            {
                Game.LobbyInfoChanged += WidgetUtils.Once(() =>
                {
                    var slot          = orderManager.LobbyInfo.FirstEmptyBotSlot();
                    var bot           = modRules.Actors["player"].TraitInfos <IBotInfo>().Select(t => t.Name).FirstOrDefault();
                    var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin);
                    if (slot != null && bot != null)
                    {
                        orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot, botController.Index, bot)));
                    }
                });
            }
        }
예제 #17
0
        public static void SetupEditableColorWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager, World world, ColorPreviewManagerWidget colorPreview)
        {
            var color = parent.Get<DropDownButtonWidget>("COLOR");
            color.IsDisabled = () => (s != null && s.LockColor) || orderManager.LocalClient.IsReady;
            color.OnMouseDown = _ => ShowColorDropDown(color, c, orderManager, world, colorPreview);

            SetupColorWidget(color, s, c);
        }
예제 #18
0
        internal LobbyLogic(Widget widget, WorldRenderer worldRenderer, OrderManager orderManager,
			Action onExit, Action onStart, bool skirmishMode, Ruleset modRules)
        {
            lobby = widget;
            this.orderManager = orderManager;
            this.onStart = onStart;
            this.onExit = onExit;
            this.skirmishMode = skirmishMode;
            this.modRules = modRules;
            shellmapWorld = worldRenderer.World;

            orderManager.AddChatLine += AddChatLine;
            Game.LobbyInfoChanged += UpdateCurrentMap;
            Game.LobbyInfoChanged += UpdatePlayerList;
            Game.BeforeGameStart += OnGameStart;
            Game.ConnectionStateChanged += ConnectionStateChanged;

            var name = lobby.GetOrNull<LabelWidget>("SERVER_NAME");
            if (name != null)
                name.GetText = () => orderManager.LobbyInfo.GlobalSettings.ServerName;

            Ui.LoadWidget("LOBBY_MAP_PREVIEW", lobby.Get("MAP_PREVIEW_ROOT"), new WidgetArgs
            {
                { "orderManager", orderManager },
                { "lobby", this }
            });

            UpdateCurrentMap();
            players = Ui.LoadWidget<ScrollPanelWidget>("LOBBY_PLAYER_BIN", lobby.Get("PLAYER_BIN_ROOT"), new WidgetArgs());
            players.IsVisible = () => panel == PanelType.Players;

            var playerBinHeaders = lobby.GetOrNull<ContainerWidget>("LABEL_CONTAINER");
            if (playerBinHeaders != null)
                playerBinHeaders.IsVisible = () => panel == PanelType.Players;

            editablePlayerTemplate = players.Get("TEMPLATE_EDITABLE_PLAYER");
            nonEditablePlayerTemplate = players.Get("TEMPLATE_NONEDITABLE_PLAYER");
            emptySlotTemplate = players.Get("TEMPLATE_EMPTY");
            editableSpectatorTemplate = players.Get("TEMPLATE_EDITABLE_SPECTATOR");
            nonEditableSpectatorTemplate = players.Get("TEMPLATE_NONEDITABLE_SPECTATOR");
            newSpectatorTemplate = players.Get("TEMPLATE_NEW_SPECTATOR");
            colorPreview = lobby.Get<ColorPreviewManagerWidget>("COLOR_MANAGER");
            colorPreview.Color = Game.Settings.Player.Color;

            foreach (var f in modRules.Actors["world"].Traits.WithInterface<FactionInfo>())
                factions.Add(f.InternalName, new LobbyFaction { Selectable = f.Selectable, Name = f.Name, Side = f.Side, Description = f.Description });

            var gameStarting = false;
            Func<bool> configurationDisabled = () => !Game.IsHost || gameStarting ||
                panel == PanelType.Kick || panel == PanelType.ForceStart ||
                orderManager.LocalClient == null || orderManager.LocalClient.IsReady;

            var mapButton = lobby.GetOrNull<ButtonWidget>("CHANGEMAP_BUTTON");
            if (mapButton != null)
            {
                mapButton.IsDisabled = () => gameStarting || panel == PanelType.Kick || panel == PanelType.ForceStart ||
                    orderManager.LocalClient == null || orderManager.LocalClient.IsReady;
                mapButton.OnClick = () =>
                {
                    var onSelect = new Action<string>(uid =>
                    {
                        // Don't select the same map again
                        if (uid == Map.Uid)
                            return;

                        orderManager.IssueOrder(Order.Command("map " + uid));
                        Game.Settings.Server.Map = uid;
                        Game.Settings.Save();
                    });

                    Ui.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
                    {
                        { "initialMap", Map.Uid },
                        { "initialTab", MapClassification.System },
                        { "onExit", DoNothing },
                        { "onSelect", Game.IsHost ? onSelect : null },
                        { "filter", MapVisibility.Lobby },
                    });
                };
            }

            var slotsButton = lobby.GetOrNull<DropDownButtonWidget>("SLOTS_DROPDOWNBUTTON");
            if (slotsButton != null)
            {
                slotsButton.IsDisabled = () => configurationDisabled() || panel != PanelType.Players ||
                    Map.RuleStatus != MapRuleStatus.Cached || !orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots || !s.LockTeam);

                var botNames = modRules.Actors["player"].Traits.WithInterface<IBotInfo>().Select(t => t.Name);
                slotsButton.OnMouseDown = _ =>
                {
                    var options = new Dictionary<string, IEnumerable<DropDownOption>>();

                    var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin);
                    if (orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots))
                    {
                        var botOptions = new List<DropDownOption>()
                        {
                            new DropDownOption()
                            {
                                Title = "Add",
                                IsSelected = () => false,
                                OnClick = () =>
                                {
                                    foreach (var slot in orderManager.LobbyInfo.Slots)
                                    {
                                        var bot = botNames.Random(Game.CosmeticRandom);
                                        var c = orderManager.LobbyInfo.ClientInSlot(slot.Key);
                                        if (slot.Value.AllowBots == true && (c == null || c.Bot != null))
                                            orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot.Key, botController.Index, bot)));
                                    }
                                }
                            }
                        };

                        if (orderManager.LobbyInfo.Clients.Any(c => c.Bot != null))
                        {
                            botOptions.Add(new DropDownOption()
                            {
                                Title = "Remove",
                                IsSelected = () => false,
                                OnClick = () =>
                                {
                                    foreach (var slot in orderManager.LobbyInfo.Slots)
                                    {
                                        var c = orderManager.LobbyInfo.ClientInSlot(slot.Key);
                                        if (c != null && c.Bot != null)
                                            orderManager.IssueOrder(Order.Command("slot_open " + slot.Value.PlayerReference));
                                    }
                                }
                            });
                        }

                        options.Add("Configure Bots", botOptions);
                    }

                    var teamCount = (orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) + 1) / 2;
                    if (teamCount >= 1)
                    {
                        var teamOptions = Enumerable.Range(2, teamCount - 1).Reverse().Select(d => new DropDownOption
                        {
                            Title = "{0} Teams".F(d),
                            IsSelected = () => false,
                            OnClick = () => orderManager.IssueOrder(Order.Command("assignteams {0}".F(d.ToString())))
                        }).ToList();

                        if (orderManager.LobbyInfo.Slots.Any(s => s.Value.AllowBots))
                        {
                            teamOptions.Add(new DropDownOption
                            {
                                Title = "Humans vs Bots",
                                IsSelected = () => false,
                                OnClick = () => orderManager.IssueOrder(Order.Command("assignteams 1"))
                            });
                        }

                        teamOptions.Add(new DropDownOption
                        {
                            Title = "Free for all",
                            IsSelected = () => false,
                            OnClick = () => orderManager.IssueOrder(Order.Command("assignteams 0"))
                        });

                        options.Add("Configure Teams", teamOptions);
                    }

                    Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
                        return item;
                    };
                    slotsButton.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 175, options, setupItem);
                };
            }

            var optionsBin = Ui.LoadWidget("LOBBY_OPTIONS_BIN", lobby, new WidgetArgs());
            optionsBin.IsVisible = () => panel == PanelType.Options;

            var optionsButton = lobby.Get<ButtonWidget>("OPTIONS_BUTTON");
            optionsButton.IsDisabled = () => Map.RuleStatus != MapRuleStatus.Cached || panel == PanelType.Kick || panel == PanelType.ForceStart;
            optionsButton.GetText = () => panel == PanelType.Options ? "Players" : "Options";
            optionsButton.OnClick = () => panel = (panel == PanelType.Options) ? PanelType.Players : PanelType.Options;

            // Force start panel
            Action startGame = () =>
            {
                gameStarting = true;
                orderManager.IssueOrder(Order.Command("startgame"));
            };

            var startGameButton = lobby.GetOrNull<ButtonWidget>("START_GAME_BUTTON");
            if (startGameButton != null)
            {
                startGameButton.IsDisabled = () => configurationDisabled() || Map.RuleStatus != MapRuleStatus.Cached ||
                    orderManager.LobbyInfo.Slots.Any(sl => sl.Value.Required && orderManager.LobbyInfo.ClientInSlot(sl.Key) == null);
                startGameButton.OnClick = () =>
                {
                    Func<KeyValuePair<string, Session.Slot>, bool> notReady = sl =>
                    {
                        var cl = orderManager.LobbyInfo.ClientInSlot(sl.Key);

                        // Bots and admins don't count
                        return cl != null && !cl.IsAdmin && cl.Bot == null && !cl.IsReady;
                    };

                    if (orderManager.LobbyInfo.Slots.Any(notReady))
                        panel = PanelType.ForceStart;
                    else
                        startGame();
                };
            }

            var forceStartBin = Ui.LoadWidget("FORCE_START_DIALOG", lobby, new WidgetArgs());
            forceStartBin.IsVisible = () => panel == PanelType.ForceStart;
            forceStartBin.Get("KICK_WARNING").IsVisible = () => orderManager.LobbyInfo.Clients.Any(c => c.IsInvalid);
            forceStartBin.Get<ButtonWidget>("OK_BUTTON").OnClick = startGame;
            forceStartBin.Get<ButtonWidget>("CANCEL_BUTTON").OnClick = () => panel = PanelType.Players;

            // Options panel
            var allowCheats = optionsBin.GetOrNull<CheckboxWidget>("ALLOWCHEATS_CHECKBOX");
            if (allowCheats != null)
            {
                allowCheats.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats;
                allowCheats.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Cheats.HasValue || configurationDisabled();
                allowCheats.OnClick = () => orderManager.IssueOrder(Order.Command(
                        "allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats)));
            }

            var crates = optionsBin.GetOrNull<CheckboxWidget>("CRATES_CHECKBOX");
            if (crates != null)
            {
                crates.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Crates;
                crates.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Crates.HasValue || configurationDisabled();
                crates.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "crates {0}".F(!orderManager.LobbyInfo.GlobalSettings.Crates)));
            }

            var creeps = optionsBin.GetOrNull<CheckboxWidget>("CREEPS_CHECKBOX");
            if (creeps != null)
            {
                creeps.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Creeps;
                creeps.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Creeps.HasValue || configurationDisabled();
                creeps.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "creeps {0}".F(!orderManager.LobbyInfo.GlobalSettings.Creeps)));
            }

            var allybuildradius = optionsBin.GetOrNull<CheckboxWidget>("ALLYBUILDRADIUS_CHECKBOX");
            if (allybuildradius != null)
            {
                allybuildradius.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius;
                allybuildradius.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.AllyBuildRadius.HasValue || configurationDisabled();
                allybuildradius.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "allybuildradius {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius)));
            }

            var fragileAlliance = optionsBin.GetOrNull<CheckboxWidget>("FRAGILEALLIANCES_CHECKBOX");
            if (fragileAlliance != null)
            {
                fragileAlliance.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.FragileAlliances;
                fragileAlliance.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.FragileAlliances.HasValue || configurationDisabled();
                fragileAlliance.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "fragilealliance {0}".F(!orderManager.LobbyInfo.GlobalSettings.FragileAlliances)));
            }

            var shortGame = optionsBin.GetOrNull<CheckboxWidget>("SHORTGAME_CHECKBOX");
            if (shortGame != null)
            {
                shortGame.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.ShortGame;
                shortGame.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.ShortGame.HasValue || configurationDisabled();
                shortGame.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "shortgame {0}".F(!orderManager.LobbyInfo.GlobalSettings.ShortGame)));
            }

            var difficulty = optionsBin.GetOrNull<DropDownButtonWidget>("DIFFICULTY_DROPDOWNBUTTON");
            if (difficulty != null)
            {
                difficulty.IsVisible = () => Map.Status == MapStatus.Available && Map.Map.Options.Difficulties.Any();
                difficulty.IsDisabled = () => Map.Status != MapStatus.Available || configurationDisabled();
                difficulty.GetText = () => orderManager.LobbyInfo.GlobalSettings.Difficulty;
                difficulty.OnMouseDown = _ =>
                {
                    var options = Map.Map.Options.Difficulties.Select(d => new DropDownOption
                    {
                        Title = d,
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.Difficulty == d,
                        OnClick = () => orderManager.IssueOrder(Order.Command("difficulty {0}".F(d)))
                    });
                    Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
                        return item;
                    };
                    difficulty.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };

                optionsBin.Get<LabelWidget>("DIFFICULTY_DESC").IsVisible = difficulty.IsVisible;
            }

            var startingUnits = optionsBin.GetOrNull<DropDownButtonWidget>("STARTINGUNITS_DROPDOWNBUTTON");
            if (startingUnits != null)
            {
                var startUnitsInfo = modRules.Actors["world"].Traits.WithInterface<MPStartUnitsInfo>();
                var classes = startUnitsInfo.Select(a => a.Class).Distinct();
                Func<string, string> className = c =>
                {
                    var selectedClass = startUnitsInfo.Where(s => s.Class == c).Select(u => u.ClassName).FirstOrDefault();
                    return selectedClass != null ? selectedClass : c;
                };

                startingUnits.IsDisabled = () => Map.Status != MapStatus.Available ||
                    !Map.Map.Options.ConfigurableStartingUnits || configurationDisabled();
                startingUnits.GetText = () => Map.Status != MapStatus.Available ||
                    !Map.Map.Options.ConfigurableStartingUnits ? "Not Available" : className(orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass);
                startingUnits.OnMouseDown = _ =>
                {
                    var options = classes.Select(c => new DropDownOption
                    {
                        Title = className(c),
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass == c,
                        OnClick = () => orderManager.IssueOrder(Order.Command("startingunits {0}".F(c)))
                    });

                    Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
                        return item;
                    };

                    startingUnits.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };

                optionsBin.Get<LabelWidget>("STARTINGUNITS_DESC").IsVisible = startingUnits.IsVisible;
            }

            var startingCash = optionsBin.GetOrNull<DropDownButtonWidget>("STARTINGCASH_DROPDOWNBUTTON");
            if (startingCash != null)
            {
                startingCash.IsDisabled = () => Map.Status != MapStatus.Available ||
                    Map.Map.Options.StartingCash.HasValue || configurationDisabled();
                startingCash.GetText = () => Map.Status != MapStatus.Available ||
                    Map.Map.Options.StartingCash.HasValue ? "Not Available" : "${0}".F(orderManager.LobbyInfo.GlobalSettings.StartingCash);
                startingCash.OnMouseDown = _ =>
                {
                    var options = modRules.Actors["player"].Traits.Get<PlayerResourcesInfo>().SelectableCash.Select(c => new DropDownOption
                    {
                        Title = "${0}".F(c),
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.StartingCash == c,
                        OnClick = () => orderManager.IssueOrder(Order.Command("startingcash {0}".F(c)))
                    });

                    Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
                        return item;
                    };

                    startingCash.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }

            var techLevel = optionsBin.GetOrNull<DropDownButtonWidget>("TECHLEVEL_DROPDOWNBUTTON");
            if (techLevel != null)
            {
                var techTraits = modRules.Actors["player"].Traits.WithInterface<ProvidesTechPrerequisiteInfo>().ToList();
                techLevel.IsVisible = () => techTraits.Count > 0;

                var techLevelDescription = optionsBin.GetOrNull<LabelWidget>("TECHLEVEL_DESC");
                if (techLevelDescription != null)
                    techLevelDescription.IsVisible = () => techTraits.Count > 0;

                techLevel.IsDisabled = () => Map.Status != MapStatus.Available ||
                    Map.Map.Options.TechLevel != null || configurationDisabled() || techTraits.Count <= 1;
                techLevel.GetText = () => Map.Status != MapStatus.Available ||
                    Map.Map.Options.TechLevel != null ? "Not Available" : "{0}".F(orderManager.LobbyInfo.GlobalSettings.TechLevel);
                techLevel.OnMouseDown = _ =>
                {
                    var options = techTraits.Select(c => new DropDownOption
                    {
                        Title = "{0}".F(c.Name),
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.TechLevel == c.Name,
                        OnClick = () => orderManager.IssueOrder(Order.Command("techlevel {0}".F(c.Name)))
                    });

                    Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
                        return item;
                    };

                    techLevel.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }

            var enableShroud = optionsBin.GetOrNull<CheckboxWidget>("SHROUD_CHECKBOX");
            if (enableShroud != null)
            {
                enableShroud.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Shroud;
                enableShroud.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Shroud.HasValue || configurationDisabled();
                enableShroud.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "shroud {0}".F(!orderManager.LobbyInfo.GlobalSettings.Shroud)));
            }

            var enableFog = optionsBin.GetOrNull<CheckboxWidget>("FOG_CHECKBOX");
            if (enableFog != null)
            {
                enableFog.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Fog;
                enableFog.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Fog.HasValue || configurationDisabled();
                enableFog.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "fog {0}".F(!orderManager.LobbyInfo.GlobalSettings.Fog)));
            }

            var disconnectButton = lobby.Get<ButtonWidget>("DISCONNECT_BUTTON");
            disconnectButton.OnClick = () => { CloseWindow(); onExit(); };

            if (skirmishMode)
                disconnectButton.Text = "Back";

            chatLabel = lobby.Get<LabelWidget>("LABEL_CHATTYPE");
            var chatTextField = lobby.Get<TextFieldWidget>("CHAT_TEXTFIELD");
            chatTextField.TakeKeyboardFocus();
            chatTextField.OnEnterKey = () =>
            {
                if (chatTextField.Text.Length == 0)
                    return true;

                // Always scroll to bottom when we've typed something
                chatPanel.ScrollToBottom();

                orderManager.IssueOrder(Order.Chat(teamChat, chatTextField.Text));
                chatTextField.Text = "";
                return true;
            };

            chatTextField.OnTabKey = () =>
            {
                var previousText = chatTextField.Text;
                chatTextField.Text = tabCompletion.Complete(chatTextField.Text);
                chatTextField.CursorPosition = chatTextField.Text.Length;

                if (chatTextField.Text == previousText)
                    return SwitchTeamChat();
                else
                    return true;
            };

            chatTextField.OnEscKey = () => { chatTextField.Text = ""; return true; };

            chatPanel = lobby.Get<ScrollPanelWidget>("CHAT_DISPLAY");
            chatTemplate = chatPanel.Get("CHAT_TEMPLATE");
            chatPanel.RemoveChildren();

            var musicButton = lobby.GetOrNull<ButtonWidget>("MUSIC_BUTTON");
            if (musicButton != null)
                musicButton.OnClick = () => Ui.OpenWindow("MUSIC_PANEL", new WidgetArgs
                {
                    { "onExit", DoNothing },
                    { "world", worldRenderer.World }
                });

            var settingsButton = lobby.GetOrNull<ButtonWidget>("SETTINGS_BUTTON");
            if (settingsButton != null)
            {
                settingsButton.OnClick = () => Ui.OpenWindow("SETTINGS_PANEL", new WidgetArgs
                {
                    { "onExit", DoNothing },
                    { "worldRenderer", worldRenderer }
                });
            }

            // Add a bot on the first lobbyinfo update
            if (skirmishMode)
            {
                Game.LobbyInfoChanged += WidgetUtils.Once(() =>
                {
                    var slot = orderManager.LobbyInfo.FirstEmptyBotSlot();
                    var bot = modRules.Actors["player"].Traits.WithInterface<IBotInfo>().Select(t => t.Name).FirstOrDefault();
                    var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin);
                    if (slot != null && bot != null)
                        orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot, botController.Index, bot)));
                });
            }
        }
예제 #19
0
        internal LobbyLogic(Widget widget, World world, OrderManager orderManager,
                            Action onExit, Action onStart, bool addBots)
        {
            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;

            var name = lobby.GetOrNull <LabelWidget>("SERVER_NAME");

            if (name != null)
            {
                name.GetText = () => orderManager.LobbyInfo.GlobalSettings.ServerName;
            }

            UpdateCurrentMap();
            Players           = Ui.LoadWidget <ScrollPanelWidget>("LOBBY_PLAYER_BIN", lobby.Get("PLAYER_BIN_ROOT"), new WidgetArgs());
            Players.IsVisible = () => panel == PanelType.Players;

            EditablePlayerTemplate       = Players.Get("TEMPLATE_EDITABLE_PLAYER");
            NonEditablePlayerTemplate    = Players.Get("TEMPLATE_NONEDITABLE_PLAYER");
            EmptySlotTemplate            = Players.Get("TEMPLATE_EMPTY");
            EditableSpectatorTemplate    = Players.Get("TEMPLATE_EDITABLE_SPECTATOR");
            NonEditableSpectatorTemplate = Players.Get("TEMPLATE_NONEDITABLE_SPECTATOR");
            NewSpectatorTemplate         = Players.Get("TEMPLATE_NEW_SPECTATOR");
            colorPreview       = lobby.Get <ColorPreviewManagerWidget>("COLOR_MANAGER");
            colorPreview.Color = Game.Settings.Player.Color;

            var mapPreview = lobby.Get <MapPreviewWidget>("MAP_PREVIEW");

            mapPreview.IsVisible    = () => Map != null;
            mapPreview.Map          = () => Map;
            mapPreview.OnMouseDown  = mi => LobbyUtils.SelectSpawnPoint(orderManager, mapPreview, Map, mi);
            mapPreview.SpawnClients = () => LobbyUtils.GetSpawnClients(orderManager, Map);

            var mapTitle = lobby.GetOrNull <LabelWidget>("MAP_TITLE");

            if (mapTitle != null)
            {
                mapTitle.IsVisible = () => Map != null;
                mapTitle.GetText   = () => Map.Title;
            }

            var mapType = lobby.GetOrNull <LabelWidget>("MAP_TYPE");

            if (mapType != null)
            {
                mapType.IsVisible = () => Map != null;
                mapType.GetText   = () => Map.Type;
            }

            var mapAuthor = lobby.GetOrNull <LabelWidget>("MAP_AUTHOR");

            if (mapAuthor != null)
            {
                mapAuthor.IsVisible = () => Map != null;
                mapAuthor.GetText   = () => "Created by {0}".F(Map.Author);
            }

            CountryNames = Rules.Info["world"].Traits.WithInterface <CountryInfo>()
                           .Where(c => c.Selectable)
                           .ToDictionary(a => a.Race, a => a.Name);
            CountryNames.Add("random", "Any");

            var         gameStarting          = false;
            Func <bool> configurationDisabled = () => !Game.IsHost || gameStarting || panel == PanelType.Kick ||
                                                orderManager.LocalClient == null || orderManager.LocalClient.IsReady;

            var mapButton = lobby.GetOrNull <ButtonWidget>("CHANGEMAP_BUTTON");

            if (mapButton != null)
            {
                mapButton.IsDisabled = configurationDisabled;
                mapButton.OnClick    = () =>
                {
                    var onSelect = new Action <Map>(m =>
                    {
                        orderManager.IssueOrder(Order.Command("map " + m.Uid));
                        Game.Settings.Server.Map = m.Uid;
                        Game.Settings.Save();
                    });

                    Ui.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
                    {
                        { "initialMap", Map.Uid },
                        { "onExit", () => {} },
                        { "onSelect", onSelect }
                    });
                };
            }

            var slotsButton = lobby.GetOrNull <DropDownButtonWidget>("SLOTS_DROPDOWNBUTTON");

            if (slotsButton != null)
            {
                slotsButton.IsDisabled = () => configurationDisabled() || panel != PanelType.Players ||
                                         !orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots || !s.LockTeam);

                var aiModes = Rules.Info["player"].Traits.WithInterface <IBotInfo>().Select(t => t.Name);
                slotsButton.OnMouseDown = _ =>
                {
                    var options = new Dictionary <string, IEnumerable <DropDownOption> >();

                    var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin);
                    if (orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots))
                    {
                        var botOptions = new List <DropDownOption>()
                        {
                            new DropDownOption()
                            {
                                Title      = "Add",
                                IsSelected = () => false,
                                OnClick    = () =>
                                {
                                    foreach (var slot in orderManager.LobbyInfo.Slots)
                                    {
                                        var bot = aiModes.Random(Game.CosmeticRandom);
                                        var c   = orderManager.LobbyInfo.ClientInSlot(slot.Key);
                                        if (slot.Value.AllowBots == true && (c == null || c.Bot != null))
                                        {
                                            orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot.Key, botController.Index, bot)));
                                        }
                                    }
                                }
                            }
                        };

                        if (orderManager.LobbyInfo.Clients.Any(c => c.Bot != null))
                        {
                            botOptions.Add(new DropDownOption()
                            {
                                Title      = "Remove",
                                IsSelected = () => false,
                                OnClick    = () =>
                                {
                                    foreach (var slot in orderManager.LobbyInfo.Slots)
                                    {
                                        var c = orderManager.LobbyInfo.ClientInSlot(slot.Key);
                                        if (c != null && c.Bot != null)
                                        {
                                            orderManager.IssueOrder(Order.Command("slot_open " + slot.Value.PlayerReference));
                                        }
                                    }
                                }
                            });
                        }

                        options.Add("Configure Bots", botOptions);
                    }

                    var teamCount = (orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) + 1) / 2;
                    if (teamCount >= 1)
                    {
                        var teamOptions = Enumerable.Range(2, teamCount - 1).Reverse().Select(d => new DropDownOption
                        {
                            Title      = "{0} Teams".F(d),
                            IsSelected = () => false,
                            OnClick    = () => orderManager.IssueOrder(Order.Command("assignteams {0}".F(d.ToString())))
                        }).ToList();

                        if (orderManager.LobbyInfo.Slots.Any(s => s.Value.AllowBots))
                        {
                            teamOptions.Add(new DropDownOption
                            {
                                Title      = "Humans vs Bots",
                                IsSelected = () => false,
                                OnClick    = () => orderManager.IssueOrder(Order.Command("assignteams 1"))
                            });
                        }

                        teamOptions.Add(new DropDownOption
                        {
                            Title      = "Free for all",
                            IsSelected = () => false,
                            OnClick    = () => orderManager.IssueOrder(Order.Command("assignteams 0"))
                        });

                        options.Add("Configure Teams", teamOptions);
                    }

                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };
                    slotsButton.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 175, options, setupItem);
                };
            }

            var optionsBin = Ui.LoadWidget("LOBBY_OPTIONS_BIN", lobby, new WidgetArgs());

            optionsBin.IsVisible = () => panel == PanelType.Options;

            var optionsButton = lobby.Get <ButtonWidget>("OPTIONS_BUTTON");

            optionsButton.IsDisabled = () => panel == PanelType.Kick;
            optionsButton.GetText    = () => panel == PanelType.Options ? "Players" : "Options";
            optionsButton.OnClick    = () => panel = (panel == PanelType.Options) ? PanelType.Players : PanelType.Options;

            var startGameButton = lobby.GetOrNull <ButtonWidget>("START_GAME_BUTTON");

            if (startGameButton != null)
            {
                startGameButton.IsDisabled = () => configurationDisabled() ||
                                             orderManager.LobbyInfo.Slots.Any(sl => sl.Value.Required && orderManager.LobbyInfo.ClientInSlot(sl.Key) == null);
                startGameButton.OnClick = () =>
                {
                    gameStarting = true;
                    orderManager.IssueOrder(Order.Command("startgame"));
                };
            }

            // Options panel
            var allowCheats = optionsBin.GetOrNull <CheckboxWidget>("ALLOWCHEATS_CHECKBOX");

            if (allowCheats != null)
            {
                allowCheats.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats;
                allowCheats.IsDisabled = () => Map.Options.Cheats.HasValue || configurationDisabled();
                allowCheats.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                           "allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats)));
            }

            var crates = optionsBin.GetOrNull <CheckboxWidget>("CRATES_CHECKBOX");

            if (crates != null)
            {
                crates.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.Crates;
                crates.IsDisabled = () => Map.Options.Crates.HasValue || configurationDisabled();
                crates.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                      "crates {0}".F(!orderManager.LobbyInfo.GlobalSettings.Crates)));
            }

            var allybuildradius = optionsBin.GetOrNull <CheckboxWidget>("ALLYBUILDRADIUS_CHECKBOX");

            if (allybuildradius != null)
            {
                allybuildradius.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius;
                allybuildradius.IsDisabled = () => Map.Options.AllyBuildRadius.HasValue || configurationDisabled();
                allybuildradius.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                               "allybuildradius {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius)));
            }

            var fragileAlliance = optionsBin.GetOrNull <CheckboxWidget>("FRAGILEALLIANCES_CHECKBOX");

            if (fragileAlliance != null)
            {
                fragileAlliance.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.FragileAlliances;
                fragileAlliance.IsDisabled = () => Map.Options.FragileAlliances.HasValue || configurationDisabled();
                fragileAlliance.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                               "fragilealliance {0}".F(!orderManager.LobbyInfo.GlobalSettings.FragileAlliances)));
            }

            var difficulty = optionsBin.GetOrNull <DropDownButtonWidget>("DIFFICULTY_DROPDOWNBUTTON");

            if (difficulty != null)
            {
                difficulty.IsVisible   = () => Map.Options.Difficulties.Any();
                difficulty.IsDisabled  = configurationDisabled;
                difficulty.GetText     = () => orderManager.LobbyInfo.GlobalSettings.Difficulty;
                difficulty.OnMouseDown = _ =>
                {
                    var options = Map.Options.Difficulties.Select(d => new DropDownOption
                    {
                        Title      = d,
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.Difficulty == d,
                        OnClick    = () => orderManager.IssueOrder(Order.Command("difficulty {0}".F(d)))
                    });
                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };
                    difficulty.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };

                optionsBin.Get <LabelWidget>("DIFFICULTY_DESC").IsVisible = difficulty.IsVisible;
            }

            var startingUnits = optionsBin.GetOrNull <DropDownButtonWidget>("STARTINGUNITS_DROPDOWNBUTTON");

            if (startingUnits != null)
            {
                var classNames = new Dictionary <string, string>()
                {
                    { "none", "MCV Only" },
                    { "light", "Light Support" },
                    { "heavy", "Heavy Support" },
                };

                Func <string, string> className = c => classNames.ContainsKey(c) ? classNames[c] : c;
                var classes = Rules.Info["world"].Traits.WithInterface <MPStartUnitsInfo>()
                              .Select(a => a.Class).Distinct();

                startingUnits.IsDisabled  = () => !Map.Options.ConfigurableStartingUnits || configurationDisabled();
                startingUnits.GetText     = () => !Map.Options.ConfigurableStartingUnits ? "Not Available" : className(orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass);
                startingUnits.OnMouseDown = _ =>
                {
                    var options = classes.Select(c => new DropDownOption
                    {
                        Title      = className(c),
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass == c,
                        OnClick    = () => orderManager.IssueOrder(Order.Command("startingunits {0}".F(c)))
                    });

                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };

                    startingUnits.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };

                optionsBin.Get <LabelWidget>("STARTINGUNITS_DESC").IsVisible = startingUnits.IsVisible;
            }

            var startingCash = optionsBin.GetOrNull <DropDownButtonWidget>("STARTINGCASH_DROPDOWNBUTTON");

            if (startingCash != null)
            {
                startingCash.IsDisabled  = () => Map.Options.StartingCash.HasValue || configurationDisabled();
                startingCash.GetText     = () => Map.Options.StartingCash.HasValue ? "Not Available" : "${0}".F(orderManager.LobbyInfo.GlobalSettings.StartingCash);
                startingCash.OnMouseDown = _ =>
                {
                    var options = Rules.Info["player"].Traits.Get <PlayerResourcesInfo>().SelectableCash.Select(c => new DropDownOption
                    {
                        Title      = "${0}".F(c),
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.StartingCash == c,
                        OnClick    = () => orderManager.IssueOrder(Order.Command("startingcash {0}".F(c)))
                    });

                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };

                    startingCash.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }

            var enableShroud = optionsBin.GetOrNull <CheckboxWidget>("SHROUD_CHECKBOX");

            if (enableShroud != null)
            {
                enableShroud.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.Shroud;
                enableShroud.IsDisabled = () => Map.Options.Shroud.HasValue || configurationDisabled();
                enableShroud.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                            "shroud {0}".F(!orderManager.LobbyInfo.GlobalSettings.Shroud)));
            }

            var enableFog = optionsBin.GetOrNull <CheckboxWidget>("FOG_CHECKBOX");

            if (enableFog != null)
            {
                enableFog.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.Fog;
                enableFog.IsDisabled = () => Map.Options.Fog.HasValue || configurationDisabled();
                enableFog.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                         "fog {0}".F(!orderManager.LobbyInfo.GlobalSettings.Fog)));
            }

            var disconnectButton = lobby.Get <ButtonWidget>("DISCONNECT_BUTTON");

            disconnectButton.OnClick = () => { CloseWindow(); onExit(); };

            bool teamChat      = false;
            var  chatLabel     = lobby.Get <LabelWidget>("LABEL_CHATTYPE");
            var  chatTextField = lobby.Get <TextFieldWidget>("CHAT_TEXTFIELD");

            chatTextField.OnEnterKey = () =>
            {
                if (chatTextField.Text.Length == 0)
                {
                    return(true);
                }

                orderManager.IssueOrder(Order.Chat(teamChat, chatTextField.Text));
                chatTextField.Text = "";
                return(true);
            };

            chatTextField.OnTabKey = () =>
            {
                teamChat      ^= true;
                chatLabel.Text = (teamChat) ? "Team:" : "Chat:";
                return(true);
            };

            chatPanel    = lobby.Get <ScrollPanelWidget>("CHAT_DISPLAY");
            chatTemplate = chatPanel.Get("CHAT_TEMPLATE");
            chatPanel.RemoveChildren();

            var musicButton = lobby.GetOrNull <ButtonWidget>("MUSIC_BUTTON");

            if (musicButton != null)
            {
                musicButton.OnClick = () => Ui.OpenWindow("MUSIC_PANEL", new WidgetArgs
                {
                    { "onExit", () => {} }
                });
            }

            // 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 <IBotInfo>().Select(t => t.Name).FirstOrDefault();
                    var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin);
                    if (slot != null && bot != null)
                    {
                        orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot, botController.Index, bot)));
                    }
                });
            }
        }
예제 #20
0
        internal LobbyLogic(Widget widget, World world, OrderManager orderManager,
			Action onExit, Action onStart, bool addBots)
        {
            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;

            var name = lobby.GetOrNull<LabelWidget>("SERVER_NAME");
            if (name != null)
                name.GetText = () => orderManager.LobbyInfo.GlobalSettings.ServerName;

            UpdateCurrentMap();
            Players = Ui.LoadWidget<ScrollPanelWidget>("LOBBY_PLAYER_BIN", lobby.Get("PLAYER_BIN_ROOT"), new WidgetArgs());
            Players.IsVisible = () => panel == PanelType.Players;

            EditablePlayerTemplate = Players.Get("TEMPLATE_EDITABLE_PLAYER");
            NonEditablePlayerTemplate = Players.Get("TEMPLATE_NONEDITABLE_PLAYER");
            EmptySlotTemplate = Players.Get("TEMPLATE_EMPTY");
            EditableSpectatorTemplate = Players.Get("TEMPLATE_EDITABLE_SPECTATOR");
            NonEditableSpectatorTemplate = Players.Get("TEMPLATE_NONEDITABLE_SPECTATOR");
            NewSpectatorTemplate = Players.Get("TEMPLATE_NEW_SPECTATOR");
            colorPreview = lobby.Get<ColorPreviewManagerWidget>("COLOR_MANAGER");
            colorPreview.Color = Game.Settings.Player.Color;

            var mapPreview = lobby.Get<MapPreviewWidget>("MAP_PREVIEW");
            mapPreview.IsVisible = () => Map != null;
            mapPreview.Map = () => Map;
            mapPreview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, mapPreview, Map, mi);
            mapPreview.SpawnClients = () => LobbyUtils.GetSpawnClients(orderManager, Map);

            var mapTitle = lobby.GetOrNull<LabelWidget>("MAP_TITLE");
            if (mapTitle != null)
            {
                mapTitle.IsVisible = () => Map != null;
                mapTitle.GetText = () => Map.Title;
            }

            var mapType = lobby.GetOrNull<LabelWidget>("MAP_TYPE");
            if (mapType != null)
            {
                mapType.IsVisible = () => Map != null;
                mapType.GetText = () => Map.Type;
            }

            var mapAuthor = lobby.GetOrNull<LabelWidget>("MAP_AUTHOR");
            if (mapAuthor != null)
            {
                mapAuthor.IsVisible = () => Map != null;
                mapAuthor.GetText = () => "Created by {0}".F(Map.Author);
            }

            CountryNames = Rules.Info["world"].Traits.WithInterface<CountryInfo>()
                .Where(c => c.Selectable)
                .ToDictionary(a => a.Race, a => a.Name);
            CountryNames.Add("random", "Any");

            var gameStarting = false;
            Func<bool> configurationDisabled = () => !Game.IsHost || gameStarting || panel == PanelType.Kick ||
                orderManager.LocalClient == null || orderManager.LocalClient.IsReady;

            var mapButton = lobby.GetOrNull<ButtonWidget>("CHANGEMAP_BUTTON");
            if (mapButton != null)
            {
                mapButton.IsDisabled = configurationDisabled;
                mapButton.OnClick = () =>
                {
                    var onSelect = new Action<Map>(m =>
                    {
                        orderManager.IssueOrder(Order.Command("map " + m.Uid));
                        Game.Settings.Server.Map = m.Uid;
                        Game.Settings.Save();
                    });

                    Ui.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
                    {
                        { "initialMap", Map.Uid },
                        { "onExit", () => {} },
                        { "onSelect", onSelect }
                    });
                };
            }

            var slotsButton = lobby.GetOrNull<DropDownButtonWidget>("SLOTS_DROPDOWNBUTTON");
            if (slotsButton != null)
            {
                slotsButton.IsDisabled = () => configurationDisabled() || panel != PanelType.Players ||
                    !orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots || !s.LockTeam);

                var aiModes = Rules.Info["player"].Traits.WithInterface<IBotInfo>().Select(t => t.Name);
                slotsButton.OnMouseDown = _ =>
                {
                    var options = new Dictionary<string, IEnumerable<DropDownOption>>();

                    var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin);
                    if (orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots))
                    {
                        var botOptions = new List<DropDownOption>(){ new DropDownOption()
                        {
                            Title = "Add",
                            IsSelected = () => false,
                            OnClick = () =>
                            {
                                foreach (var slot in orderManager.LobbyInfo.Slots)
                                {
                                    var bot = aiModes.Random(Game.CosmeticRandom);
                                    var c = orderManager.LobbyInfo.ClientInSlot(slot.Key);
                                    if (slot.Value.AllowBots == true && (c == null || c.Bot != null))
                                        orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot.Key, botController.Index, bot)));
                                }
                            }
                        }};

                        if (orderManager.LobbyInfo.Clients.Any(c => c.Bot != null))
                        {
                            botOptions.Add(new DropDownOption()
                            {
                                Title = "Remove",
                                IsSelected = () => false,
                                OnClick = () =>
                                {
                                    foreach (var slot in orderManager.LobbyInfo.Slots)
                                    {
                                        var c = orderManager.LobbyInfo.ClientInSlot(slot.Key);
                                        if (c != null && c.Bot != null)
                                            orderManager.IssueOrder(Order.Command("slot_open "+slot.Value.PlayerReference));
                                    }
                                }
                            });
                        }

                        options.Add("Configure Bots", botOptions);
                    }

                    var teamCount = (orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) + 1) / 2;
                    if (teamCount >= 1)
                    {
                        var teamOptions = Enumerable.Range(2, teamCount - 1).Reverse().Select(d => new DropDownOption
                        {
                            Title = "{0} Teams".F(d),
                            IsSelected = () => false,
                            OnClick = () => orderManager.IssueOrder(Order.Command("assignteams {0}".F(d.ToString())))
                        }).ToList();

                        if (orderManager.LobbyInfo.Slots.Any(s => s.Value.AllowBots))
                        {
                            teamOptions.Add(new DropDownOption
                            {
                                Title = "Humans vs Bots",
                                IsSelected = () => false,
                                OnClick = () => orderManager.IssueOrder(Order.Command("assignteams 1"))
                            });
                        }

                        teamOptions.Add(new DropDownOption
                        {
                            Title = "Free for all",
                            IsSelected = () => false,
                            OnClick = () => orderManager.IssueOrder(Order.Command("assignteams 0"))
                        });

                        options.Add("Configure Teams", teamOptions);
                    }

                    Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
                        return item;
                    };
                    slotsButton.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 175, options, setupItem);
                };
            }

            var optionsBin = Ui.LoadWidget("LOBBY_OPTIONS_BIN", lobby, new WidgetArgs());
            optionsBin.IsVisible = () => panel == PanelType.Options;

            var optionsButton = lobby.Get<ButtonWidget>("OPTIONS_BUTTON");
            optionsButton.IsDisabled = () => panel == PanelType.Kick;
            optionsButton.GetText = () => panel == PanelType.Options ? "Players" : "Options";
            optionsButton.OnClick = () => panel = (panel == PanelType.Options) ? PanelType.Players : PanelType.Options;

            var startGameButton = lobby.GetOrNull<ButtonWidget>("START_GAME_BUTTON");
            if (startGameButton != null)
            {
                startGameButton.IsDisabled = () => configurationDisabled() ||
                    orderManager.LobbyInfo.Slots.Any(sl => sl.Value.Required && orderManager.LobbyInfo.ClientInSlot(sl.Key) == null);
                startGameButton.OnClick = () =>
                {
                    gameStarting = true;
                    orderManager.IssueOrder(Order.Command("startgame"));
                };
            }

            // Options panel
            var allowCheats = optionsBin.GetOrNull<CheckboxWidget>("ALLOWCHEATS_CHECKBOX");
            if (allowCheats != null)
            {
                allowCheats.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats;
                allowCheats.IsDisabled = () => Map.Options.Cheats.HasValue || configurationDisabled();
                allowCheats.OnClick = () =>	orderManager.IssueOrder(Order.Command(
                        "allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats)));
            }

            var crates = optionsBin.GetOrNull<CheckboxWidget>("CRATES_CHECKBOX");
            if (crates != null)
            {
                crates.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Crates;
                crates.IsDisabled = () => Map.Options.Crates.HasValue || configurationDisabled();
                crates.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "crates {0}".F(!orderManager.LobbyInfo.GlobalSettings.Crates)));
            }

            var allybuildradius = optionsBin.GetOrNull<CheckboxWidget>("ALLYBUILDRADIUS_CHECKBOX");
            if (allybuildradius != null)
            {
                allybuildradius.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius;
                allybuildradius.IsDisabled = () => Map.Options.AllyBuildRadius.HasValue || configurationDisabled();
                allybuildradius.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "allybuildradius {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius)));
            }

            var fragileAlliance = optionsBin.GetOrNull<CheckboxWidget>("FRAGILEALLIANCES_CHECKBOX");
            if (fragileAlliance != null)
            {
                fragileAlliance.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.FragileAlliances;
                fragileAlliance.IsDisabled = () => Map.Options.FragileAlliances.HasValue || configurationDisabled();
                fragileAlliance.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "fragilealliance {0}".F(!orderManager.LobbyInfo.GlobalSettings.FragileAlliances)));
            }

            var difficulty = optionsBin.GetOrNull<DropDownButtonWidget>("DIFFICULTY_DROPDOWNBUTTON");
            if (difficulty != null)
            {
                difficulty.IsVisible = () => Map.Options.Difficulties.Any();
                difficulty.IsDisabled = configurationDisabled;
                difficulty.GetText = () => orderManager.LobbyInfo.GlobalSettings.Difficulty;
                difficulty.OnMouseDown = _ =>
                {
                    var options = Map.Options.Difficulties.Select(d => new DropDownOption
                    {
                        Title = d,
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.Difficulty == d,
                        OnClick = () => orderManager.IssueOrder(Order.Command("difficulty {0}".F(d)))
                    });
                    Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
                        return item;
                    };
                    difficulty.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };

                optionsBin.Get<LabelWidget>("DIFFICULTY_DESC").IsVisible = difficulty.IsVisible;
            }

            var startingUnits = optionsBin.GetOrNull<DropDownButtonWidget>("STARTINGUNITS_DROPDOWNBUTTON");
            if (startingUnits != null)
            {
                var classNames = new Dictionary<string,string>()
                {
                    {"none", "MCV Only"},
                    {"light", "Light Support"},
                    {"heavy", "Heavy Support"},
                };

                Func<string, string> className = c => classNames.ContainsKey(c) ? classNames[c] : c;
                var classes = Rules.Info["world"].Traits.WithInterface<MPStartUnitsInfo>()
                    .Select(a => a.Class).Distinct();

                startingUnits.IsDisabled =  () => !Map.Options.ConfigurableStartingUnits || configurationDisabled();
                startingUnits.GetText = () => !Map.Options.ConfigurableStartingUnits ? "Not Available" : className(orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass);
                startingUnits.OnMouseDown = _ =>
                {
                    var options = classes.Select(c => new DropDownOption
                    {
                        Title = className(c),
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass == c,
                        OnClick = () => orderManager.IssueOrder(Order.Command("startingunits {0}".F(c)))
                    });

                    Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
                        return item;
                    };

                    startingUnits.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };

                optionsBin.Get<LabelWidget>("STARTINGUNITS_DESC").IsVisible = startingUnits.IsVisible;
            }

            var startingCash = optionsBin.GetOrNull<DropDownButtonWidget>("STARTINGCASH_DROPDOWNBUTTON");
            if (startingCash != null)
            {
                startingCash.IsDisabled = () => Map.Options.StartingCash.HasValue || configurationDisabled();
                startingCash.GetText = () => Map.Options.StartingCash.HasValue ? "Not Available" : "${0}".F(orderManager.LobbyInfo.GlobalSettings.StartingCash);
                startingCash.OnMouseDown = _ =>
                {
                    var options = Rules.Info["player"].Traits.Get<PlayerResourcesInfo>().SelectableCash.Select(c => new DropDownOption
                    {
                        Title = "${0}".F(c),
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.StartingCash == c,
                        OnClick = () => orderManager.IssueOrder(Order.Command("startingcash {0}".F(c)))
                    });

                    Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
                        return item;
                    };

                    startingCash.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }

            var enableShroud = optionsBin.GetOrNull<CheckboxWidget>("SHROUD_CHECKBOX");
            if (enableShroud != null)
            {
                enableShroud.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Shroud;
                enableShroud.IsDisabled = () => Map.Options.Shroud.HasValue || configurationDisabled();
                enableShroud.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "shroud {0}".F(!orderManager.LobbyInfo.GlobalSettings.Shroud)));
            }

            var enableFog = optionsBin.GetOrNull<CheckboxWidget>("FOG_CHECKBOX");
            if (enableFog != null)
            {
                enableFog.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Fog;
                enableFog.IsDisabled = () => Map.Options.Fog.HasValue || configurationDisabled();
                enableFog.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "fog {0}".F(!orderManager.LobbyInfo.GlobalSettings.Fog)));
            }

            var disconnectButton = lobby.Get<ButtonWidget>("DISCONNECT_BUTTON");
            disconnectButton.OnClick = () => { CloseWindow(); onExit(); };

            bool teamChat = false;
            var chatLabel = lobby.Get<LabelWidget>("LABEL_CHATTYPE");
            var chatTextField = lobby.Get<TextFieldWidget>("CHAT_TEXTFIELD");

            chatTextField.OnEnterKey = () =>
            {
                if (chatTextField.Text.Length == 0)
                    return true;

                orderManager.IssueOrder(Order.Chat(teamChat, chatTextField.Text));
                chatTextField.Text = "";
                return true;
            };

            chatTextField.OnTabKey = () =>
            {
                teamChat ^= true;
                chatLabel.Text = (teamChat) ? "Team:" : "Chat:";
                return true;
            };

            chatPanel = lobby.Get<ScrollPanelWidget>("CHAT_DISPLAY");
            chatTemplate = chatPanel.Get("CHAT_TEMPLATE");
            chatPanel.RemoveChildren();

            var musicButton = lobby.GetOrNull<ButtonWidget>("MUSIC_BUTTON");
            if (musicButton != null)
                musicButton.OnClick = () => Ui.OpenWindow("MUSIC_PANEL", new WidgetArgs
                    { { "onExit", () => {} } });

            // 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<IBotInfo>().Select(t => t.Name).FirstOrDefault();
                    var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin);
                    if (slot != null && bot != null)
                        orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot, botController.Index, bot)));
                });
        }