Exemple #1
0
        public static void AddPlayerFlagAndName(ScrollItemWidget template, Player player)
        {
            var flag = template.Get<ImageWidget>("FLAG");
            flag.GetImageCollection = () => "flags";
            if (player.World.RenderPlayer != null && player.World.RenderPlayer.Stances[player] != Stance.Ally)
                flag.GetImageName = () => player.DisplayFaction.InternalName;
            else
                flag.GetImageName = () => player.Faction.InternalName;

            var client = player.World.LobbyInfo.ClientWithIndex(player.ClientIndex);
            var playerName = template.Get<LabelWidget>("PLAYER");
            var playerNameFont = Game.Renderer.Fonts[playerName.Font];
            var suffixLength = new CachedTransform<string, int>(s => playerNameFont.Measure(s).X);
            var name = new CachedTransform<Pair<string, int>, string>(c =>
                WidgetUtils.TruncateText(c.First, playerName.Bounds.Width - c.Second, playerNameFont));

            playerName.GetText = () =>
            {
                var suffix = player.WinState == WinState.Undefined ? "" : " (" + player.WinState + ")";
                if (client != null && client.State == Session.ClientState.Disconnected)
                    suffix = " (Gone)";

                var sl = suffixLength.Update(suffix);
                return name.Update(Pair.New(player.PlayerName, sl)) + suffix;
            };

            playerName.GetColor = () => player.Color.RGB;
        }
		public ReplayBrowserLogic(Widget widget, Action onExit, Action onStart)
		{
			panel = widget;

			this.onStart = onStart;

			playerList = panel.Get<ScrollPanelWidget>("PLAYER_LIST");
			playerHeader = playerList.Get<ScrollItemWidget>("HEADER");
			playerTemplate = playerList.Get<ScrollItemWidget>("TEMPLATE");
			playerList.RemoveChildren();

			panel.Get<ButtonWidget>("CANCEL_BUTTON").OnClick = () => { cancelLoadingReplays = true; Ui.CloseWindow(); onExit(); };

			replayList = panel.Get<ScrollPanelWidget>("REPLAY_LIST");
			var template = panel.Get<ScrollItemWidget>("REPLAY_TEMPLATE");

			var mod = Game.ModData.Manifest.Mod;
			var dir = Platform.ResolvePath("^", "Replays", mod.Id, mod.Version);

			if (Directory.Exists(dir))
				ThreadPool.QueueUserWorkItem(_ => LoadReplays(dir, template));

			var watch = panel.Get<ButtonWidget>("WATCH_BUTTON");
			watch.IsDisabled = () => selectedReplay == null || selectedReplay.GameInfo.MapPreview.Status != MapStatus.Available;
			watch.OnClick = () => { WatchReplay(); };

			panel.Get("REPLAY_INFO").IsVisible = () => selectedReplay != null;

			var preview = panel.Get<MapPreviewWidget>("MAP_PREVIEW");
			preview.SpawnOccupants = () => selectedSpawns;
			preview.Preview = () => selectedReplay != null ? selectedReplay.GameInfo.MapPreview : null;

			var titleLabel = panel.GetOrNull<LabelWidget>("MAP_TITLE");
			if (titleLabel != null)
			{
				titleLabel.IsVisible = () => selectedReplay != null;

				var font = Game.Renderer.Fonts[titleLabel.Font];
				var title = new CachedTransform<MapPreview, string>(m => WidgetUtils.TruncateText(m.Title, titleLabel.Bounds.Width, font));
				titleLabel.GetText = () => title.Update(selectedReplay.GameInfo.MapPreview);
			}

			var type = panel.GetOrNull<LabelWidget>("MAP_TYPE");
			if (type != null)
				type.GetText = () => selectedReplay.GameInfo.MapPreview.Type;

			panel.Get<LabelWidget>("DURATION").GetText = () => WidgetUtils.FormatTimeSeconds((int)selectedReplay.GameInfo.Duration.TotalSeconds);

			SetupFilters();
			SetupManagement();
		}
        void ShowProgressbar(string title, Func<string> getMessage)
        {
            visible = Mode.Progress;
            titleLabel.Text = title;
            progressBar.IsIndeterminate = () => true;

            var font = Game.Renderer.Fonts[progressLabel.Font];
            var status = new CachedTransform<string, string>(s => WidgetUtils.TruncateText(s, progressLabel.Bounds.Width, font));
            progressLabel.GetText = () => status.Update(getMessage());

            primaryButton.Bounds.Y += progressContainer.Bounds.Height - panel.Bounds.Height;
            secondaryButton.Bounds.Y += progressContainer.Bounds.Height - panel.Bounds.Height;
            panel.Bounds.Y -= (progressContainer.Bounds.Height - panel.Bounds.Height) / 2;
            panel.Bounds.Height = progressContainer.Bounds.Height;
        }
		public ServerCreationLogic(Widget widget, Action onExit, Action openLobby)
		{
			panel = widget;
			onCreate = openLobby;
			this.onExit = onExit;

			var settings = Game.Settings;
			preview = Game.ModData.MapCache[WidgetUtils.ChooseInitialMap(Game.Settings.Server.Map)];

			panel.Get<ButtonWidget>("CREATE_BUTTON").OnClick = CreateAndJoin;

			var mapButton = panel.GetOrNull<ButtonWidget>("MAP_BUTTON");
			if (mapButton != null)
			{
				panel.Get<ButtonWidget>("MAP_BUTTON").OnClick = () =>
				{
					Ui.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
					{
						{ "initialMap", preview.Uid },
						{ "initialTab", MapClassification.System },
						{ "onExit", () => { } },
						{ "onSelect", (Action<string>)(uid => preview = Game.ModData.MapCache[uid]) },
						{ "filter", MapVisibility.Lobby },
						{ "onStart", () => { } }
					});
				};

				panel.Get<MapPreviewWidget>("MAP_PREVIEW").Preview = () => preview;

				var mapTitle = panel.Get<LabelWidget>("MAP_NAME");
				if (mapTitle != null)
				{
					var font = Game.Renderer.Fonts[mapTitle.Font];
					var title = new CachedTransform<MapPreview, string>(m => WidgetUtils.TruncateText(m.Title, mapTitle.Bounds.Width, font));
					mapTitle.GetText = () => title.Update(preview);
				}
			}

			var serverName = panel.Get<TextFieldWidget>("SERVER_NAME");
			serverName.Text = Settings.SanitizedServerName(settings.Server.Name);
			serverName.OnEnterKey = () => { serverName.YieldKeyboardFocus(); return true; };
			serverName.OnLoseFocus = () =>
			{
				serverName.Text = Settings.SanitizedServerName(serverName.Text);
				settings.Server.Name = serverName.Text;
			};

			panel.Get<TextFieldWidget>("LISTEN_PORT").Text = settings.Server.ListenPort.ToString();

			advertiseOnline = Game.Settings.Server.AdvertiseOnline;

			var externalPort = panel.Get<TextFieldWidget>("EXTERNAL_PORT");
			externalPort.Text = settings.Server.ExternalPort.ToString();
			externalPort.IsDisabled = () => !advertiseOnline;

			var advertiseCheckbox = panel.Get<CheckboxWidget>("ADVERTISE_CHECKBOX");
			advertiseCheckbox.IsChecked = () => advertiseOnline;
			advertiseCheckbox.OnClick = () => advertiseOnline ^= true;

			allowPortForward = Game.Settings.Server.AllowPortForward;
			var checkboxUPnP = panel.Get<CheckboxWidget>("UPNP_CHECKBOX");
			checkboxUPnP.IsChecked = () => allowPortForward;
			checkboxUPnP.OnClick = () => allowPortForward ^= true;
			checkboxUPnP.IsDisabled = () => !Game.Settings.Server.NatDeviceAvailable;

			var passwordField = panel.GetOrNull<PasswordFieldWidget>("PASSWORD");
			if (passwordField != null)
				passwordField.Text = Game.Settings.Server.Password;
		}
Exemple #5
0
        Action InitAudioPanel(Widget panel)
        {
            var ss = Game.Settings.Sound;

            BindCheckboxPref(panel, "CASH_TICKS", ss, "CashTicks");
            BindCheckboxPref(panel, "MUTE_SOUND", ss, "Mute");

            BindSliderPref(panel, "SOUND_VOLUME", ss, "SoundVolume");
            BindSliderPref(panel, "MUSIC_VOLUME", ss, "MusicVolume");
            BindSliderPref(panel, "VIDEO_VOLUME", ss, "VideoVolume");

            var muteCheckbox = panel.Get<CheckboxWidget>("MUTE_SOUND");
            var muteCheckboxOnClick = muteCheckbox.OnClick;
            muteCheckbox.OnClick = () =>
            {
                muteCheckboxOnClick();

                if (ss.Mute)
                    Game.Sound.MuteAudio();
                else
                    Game.Sound.UnmuteAudio();
            };

            if (!ss.Mute)
            {
                panel.Get<SliderWidget>("SOUND_VOLUME").OnChange += x => Game.Sound.SoundVolume = x;
                panel.Get<SliderWidget>("MUSIC_VOLUME").OnChange += x => Game.Sound.MusicVolume = x;
                panel.Get<SliderWidget>("VIDEO_VOLUME").OnChange += x => Game.Sound.VideoVolume = x;
            }

            var devices = Game.Sound.AvailableDevices();
            soundDevice = devices.FirstOrDefault(d => d.Engine == ss.Engine && d.Device == ss.Device) ?? devices.First();

            var audioDeviceDropdown = panel.Get<DropDownButtonWidget>("AUDIO_DEVICE");
            audioDeviceDropdown.OnMouseDown = _ => ShowAudioDeviceDropdown(audioDeviceDropdown, devices);

            var deviceFont = Game.Renderer.Fonts[audioDeviceDropdown.Font];
            var deviceLabel = new CachedTransform<SoundDevice, string>(
                s => WidgetUtils.TruncateText(s.Label, audioDeviceDropdown.UsableWidth, deviceFont));
            audioDeviceDropdown.GetText = () => deviceLabel.Update(soundDevice);

            return () =>
            {
                ss.Device = soundDevice.Device;
                ss.Engine = soundDevice.Engine;
            };
        }
Exemple #6
0
        void LoadBrowserPanel(Widget widget)
        {
            var browserPanel = Game.LoadWidget(null, "MULTIPLAYER_BROWSER_PANEL", widget.Get("TOP_PANELS_ROOT"), new WidgetArgs());
            browserPanel.IsVisible = () => panel == PanelType.Browser;

            serverList = browserPanel.Get<ScrollPanelWidget>("SERVER_LIST");
            headerTemplate = serverList.Get<ScrollItemWidget>("HEADER_TEMPLATE");
            serverTemplate = serverList.Get<ScrollItemWidget>("SERVER_TEMPLATE");

            var join = widget.Get<ButtonWidget>("JOIN_BUTTON");
            join.IsDisabled = () => currentServer == null || !currentServer.IsJoinable;
            join.OnClick = () => Join(currentServer);

            // Display the progress label over the server list
            // The text is only visible when the list is empty
            var progressText = widget.Get<LabelWidget>("PROGRESS_LABEL");
            progressText.IsVisible = () => searchStatus != SearchStatus.Hidden;
            progressText.GetText = ProgressLabelText;

            var gs = Game.Settings.Game;
            Action<MPGameFilters> toggleFilterFlag = f =>
            {
                gs.MPGameFilters ^= f;
                Game.Settings.Save();
                RefreshServerList();
            };

            var filtersPanel = Ui.LoadWidget("MULTIPLAYER_FILTER_PANEL", null, new WidgetArgs());
            var showWaitingCheckbox = filtersPanel.GetOrNull<CheckboxWidget>("WAITING_FOR_PLAYERS");
            if (showWaitingCheckbox != null)
            {
                showWaitingCheckbox.IsChecked = () => gs.MPGameFilters.HasFlag(MPGameFilters.Waiting);
                showWaitingCheckbox.OnClick = () => toggleFilterFlag(MPGameFilters.Waiting);
            }

            var showEmptyCheckbox = filtersPanel.GetOrNull<CheckboxWidget>("EMPTY");
            if (showEmptyCheckbox != null)
            {
                showEmptyCheckbox.IsChecked = () => gs.MPGameFilters.HasFlag(MPGameFilters.Empty);
                showEmptyCheckbox.OnClick = () => toggleFilterFlag(MPGameFilters.Empty);
            }

            var showAlreadyStartedCheckbox = filtersPanel.GetOrNull<CheckboxWidget>("ALREADY_STARTED");
            if (showAlreadyStartedCheckbox != null)
            {
                showAlreadyStartedCheckbox.IsChecked = () => gs.MPGameFilters.HasFlag(MPGameFilters.Started);
                showAlreadyStartedCheckbox.OnClick = () => toggleFilterFlag(MPGameFilters.Started);
            }

            var showProtectedCheckbox = filtersPanel.GetOrNull<CheckboxWidget>("PASSWORD_PROTECTED");
            if (showProtectedCheckbox != null)
            {
                showProtectedCheckbox.IsChecked = () => gs.MPGameFilters.HasFlag(MPGameFilters.Protected);
                showProtectedCheckbox.OnClick = () => toggleFilterFlag(MPGameFilters.Protected);
            }

            var showIncompatibleCheckbox = filtersPanel.GetOrNull<CheckboxWidget>("INCOMPATIBLE_VERSION");
            if (showIncompatibleCheckbox != null)
            {
                showIncompatibleCheckbox.IsChecked = () => gs.MPGameFilters.HasFlag(MPGameFilters.Incompatible);
                showIncompatibleCheckbox.OnClick = () => toggleFilterFlag(MPGameFilters.Incompatible);
            }

            var filtersButton = widget.GetOrNull<DropDownButtonWidget>("FILTERS_DROPDOWNBUTTON");
            if (filtersButton != null)
            {
                filtersButton.OnMouseDown = _ =>
                {
                    filtersButton.RemovePanel();
                    filtersButton.AttachPanel(filtersPanel);
                };
            }

            var refreshButton = widget.Get<ButtonWidget>("REFRESH_BUTTON");
            refreshButton.GetText = () => searchStatus == SearchStatus.Fetching ? "Refreshing..." : "Refresh";
            refreshButton.OnClick = RefreshServerList;

            var mapPreview = widget.GetOrNull<MapPreviewWidget>("SELECTED_MAP_PREVIEW");
            if (mapPreview != null)
                mapPreview.Preview = () => currentMap;

            var mapTitle = widget.GetOrNull<LabelWidget>("SELECTED_MAP");
            if (mapTitle != null)
            {
                var font = Game.Renderer.Fonts[mapTitle.Font];
                var title = new CachedTransform<MapPreview, string>(m => m == null ? "No Server Selected" :
                    WidgetUtils.TruncateText(m.Title, mapTitle.Bounds.Width, font));
                mapTitle.GetText = () => title.Update(currentMap);
            }

            var ip = widget.GetOrNull<LabelWidget>("SELECTED_IP");
            if (ip != null)
            {
                ip.IsVisible = () => currentServer != null;
                ip.GetText = () => currentServer.Address;
            }

            var status = widget.GetOrNull<LabelWidget>("SELECTED_STATUS");
            if (status != null)
            {
                status.IsVisible = () => currentServer != null;
                status.GetText = () => GetStateLabel(currentServer);
                status.GetColor = () => GetStateColor(currentServer, status);
            }

            var modVersion = widget.GetOrNull<LabelWidget>("SELECTED_MOD_VERSION");
            if (modVersion != null)
            {
                modVersion.IsVisible = () => currentServer != null;
                modVersion.GetColor = () => currentServer.IsCompatible ? modVersion.TextColor : incompatibleVersionColor;

                var font = Game.Renderer.Fonts[modVersion.Font];
                var version = new CachedTransform<GameServer, string>(s => WidgetUtils.TruncateText(s.ModLabel, mapTitle.Bounds.Width, font));
                modVersion.GetText = () => version.Update(currentServer);
            }

            var players = widget.GetOrNull<LabelWidget>("SELECTED_PLAYERS");
            if (players != null)
            {
                players.IsVisible = () => currentServer != null;
                players.GetText = () => PlayersLabel(currentServer);
            }
        }
Exemple #7
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.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;
        }
Exemple #8
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;
        }
Exemple #9
0
        void SelectMap(MapPreview preview)
        {
            selectedMap = preview;

            // Cache the rules on a background thread to avoid jank
            var difficultyDisabled = true;
            var difficulties = new Dictionary<string, string>();

            var briefingVideo = "";
            var briefingVideoVisible = false;

            var infoVideo = "";
            var infoVideoVisible = false;

            new Thread(() =>
            {
                var mapDifficulty = preview.Rules.Actors["world"].TraitInfos<ScriptLobbyDropdownInfo>()
                    .FirstOrDefault(sld => sld.ID == "difficulty");

                if (mapDifficulty != null)
                {
                    difficulty = mapDifficulty.Default;
                    difficulties = mapDifficulty.Values;
                    difficultyDisabled = mapDifficulty.Locked;
                }

                var missionData = preview.Rules.Actors["world"].TraitInfoOrDefault<MissionDataInfo>();
                if (missionData != null)
                {
                    briefingVideo = missionData.BriefingVideo;
                    briefingVideoVisible = briefingVideo != null;

                    infoVideo = missionData.BackgroundVideo;
                    infoVideoVisible = infoVideo != null;

                    var briefing = WidgetUtils.WrapText(missionData.Briefing.Replace("\\n", "\n"), description.Bounds.Width, descriptionFont);
                    var height = descriptionFont.Measure(briefing).Y;
                    Game.RunAfterTick(() =>
                    {
                        if (preview == selectedMap)
                        {
                            description.Text = briefing;
                            description.Bounds.Height = height;
                            descriptionPanel.Layout.AdjustChildren();
                        }
                    });
                }
            }).Start();

            startBriefingVideoButton.IsVisible = () => briefingVideoVisible && playingVideo != PlayingVideo.Briefing;
            startBriefingVideoButton.OnClick = () => PlayVideo(videoPlayer, briefingVideo, PlayingVideo.Briefing);

            startInfoVideoButton.IsVisible = () => infoVideoVisible && playingVideo != PlayingVideo.Info;
            startInfoVideoButton.OnClick = () => PlayVideo(videoPlayer, infoVideo, PlayingVideo.Info);

            descriptionPanel.ScrollToTop();

            if (difficultyButton != null)
            {
                var difficultyName = new CachedTransform<string, string>(id => id == null || !difficulties.ContainsKey(id) ? "Normal" : difficulties[id]);
                difficultyButton.IsDisabled = () => difficultyDisabled;
                difficultyButton.GetText = () => difficultyName.Update(difficulty);
                difficultyButton.OnMouseDown = _ =>
                {
                    var options = difficulties.Select(kv => new DropDownOption
                    {
                        Title = kv.Value,
                        IsSelected = () => difficulty == kv.Key,
                        OnClick = () => difficulty = kv.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;
                    };

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

            if (gameSpeedButton != null)
            {
                var speeds = modData.Manifest.Get<GameSpeeds>().Speeds;
                gameSpeed = "default";

                gameSpeedButton.GetText = () => speeds[gameSpeed].Name;
                gameSpeedButton.OnMouseDown = _ =>
                {
                    var options = speeds.Select(s => new DropDownOption
                    {
                        Title = s.Value.Name,
                        IsSelected = () => gameSpeed == s.Key,
                        OnClick = () => gameSpeed = 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;
                    };

                    gameSpeedButton.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }
        }
		public GameInfoStatsLogic(Widget widget, World world)
		{
			var lp = world.LocalPlayer;

			var checkbox = widget.Get<CheckboxWidget>("STATS_CHECKBOX");
			checkbox.IsChecked = () => lp.WinState != WinState.Undefined;
			checkbox.GetCheckType = () => lp.WinState == WinState.Won ?
				"checked" : "crossed";
			if (lp.HasObjectives)
			{
				var mo = lp.PlayerActor.Trait<MissionObjectives>();
				checkbox.GetText = () => mo.Objectives.First().Description;
			}

			var statusLabel = widget.Get<LabelWidget>("STATS_STATUS");

			statusLabel.GetText = () => lp.WinState == WinState.Won ? "Accomplished" :
				lp.WinState == WinState.Lost ? "Failed" : "In progress";
			statusLabel.GetColor = () => lp.WinState == WinState.Won ? Color.LimeGreen :
				lp.WinState == WinState.Lost ? Color.Red : Color.White;

			var playerPanel = widget.Get<ScrollPanelWidget>("PLAYER_LIST");
			var playerTemplate = playerPanel.Get("PLAYER_TEMPLATE");
			playerPanel.RemoveChildren();

			foreach (var p in world.Players.Where(a => !a.NonCombatant))
			{
				var pp = p;
				var client = world.LobbyInfo.ClientWithIndex(pp.ClientIndex);
				var item = playerTemplate.Clone();
				var nameLabel = item.Get<LabelWidget>("NAME");
				var nameFont = Game.Renderer.Fonts[nameLabel.Font];

				var suffixLength = new CachedTransform<string, int>(s => nameFont.Measure(s).X);
				var name = new CachedTransform<Pair<string, int>, string>(c =>
					WidgetUtils.TruncateText(c.First, nameLabel.Bounds.Width - c.Second, nameFont));

				nameLabel.GetText = () =>
				{
					var suffix = pp.WinState == WinState.Undefined ? "" : " (" + pp.WinState + ")";
					if (client != null && client.State == Network.Session.ClientState.Disconnected)
						suffix = " (Gone)";

					var sl = suffixLength.Update(suffix);
					return name.Update(Pair.New(pp.PlayerName, sl)) + suffix;
				};
				nameLabel.GetColor = () => pp.Color.RGB;

				var flag = item.Get<ImageWidget>("FACTIONFLAG");
				flag.GetImageCollection = () => "flags";
				if (lp.Stances[pp] == Stance.Ally || lp.WinState != WinState.Undefined)
				{
					flag.GetImageName = () => pp.Faction.InternalName;
					item.Get<LabelWidget>("FACTION").GetText = () => pp.Faction.Name;
				}
				else
				{
					flag.GetImageName = () => pp.DisplayFaction.InternalName;
					item.Get<LabelWidget>("FACTION").GetText = () => pp.DisplayFaction.Name;
				}

				var team = item.Get<LabelWidget>("TEAM");
				var teamNumber = pp.PlayerReference.Playable ? ((client == null) ? 0 : client.Team) : pp.PlayerReference.Team;
				team.GetText = () => (teamNumber == 0) ? "-" : teamNumber.ToString();
				playerPanel.AddChild(item);

				var stats = pp.PlayerActor.TraitOrDefault<PlayerStatistics>();
				if (stats == null)
					break;
				var totalKills = stats.UnitsKilled + stats.BuildingsKilled;
				var totalDeaths = stats.UnitsDead + stats.BuildingsDead;
				item.Get<LabelWidget>("KILLS").GetText = () => totalKills.ToString();
				item.Get<LabelWidget>("DEATHS").GetText = () => totalDeaths.ToString();
			}
		}
        internal LobbyMapPreviewLogic(Widget widget, ModData modData, OrderManager orderManager, LobbyLogic lobby)
        {
            var available = widget.GetOrNull("MAP_AVAILABLE");
            if (available != null)
            {
                available.IsVisible = () => lobby.Map.Status == MapStatus.Available && (!lobby.Map.RulesLoaded || !lobby.Map.InvalidCustomRules);

                var preview = available.Get<MapPreviewWidget>("MAP_PREVIEW");
                preview.Preview = () => lobby.Map;
                preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi);
                preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map);

                var titleLabel = available.GetOrNull<LabelWidget>("MAP_TITLE");
                if (titleLabel != null)
                {
                    var font = Game.Renderer.Fonts[titleLabel.Font];
                    var title = new CachedTransform<MapPreview, string>(m => WidgetUtils.TruncateText(m.Title, titleLabel.Bounds.Width, font));
                    titleLabel.GetText = () => title.Update(lobby.Map);
                }

                var typeLabel = available.GetOrNull<LabelWidget>("MAP_TYPE");
                if (typeLabel != null)
                {
                    var type = new CachedTransform<MapPreview, string>(m => lobby.Map.Categories.FirstOrDefault() ?? "");
                    typeLabel.GetText = () => type.Update(lobby.Map);
                }

                var authorLabel = available.GetOrNull<LabelWidget>("MAP_AUTHOR");
                if (authorLabel != null)
                {
                    var font = Game.Renderer.Fonts[authorLabel.Font];
                    var author = new CachedTransform<MapPreview, string>(
                        m => WidgetUtils.TruncateText("Created by {0}".F(lobby.Map.Author), authorLabel.Bounds.Width, font));
                    authorLabel.GetText = () => author.Update(lobby.Map);
                }
            }

            var invalid = widget.GetOrNull("MAP_INVALID");
            if (invalid != null)
            {
                invalid.IsVisible = () => lobby.Map.Status == MapStatus.Available && lobby.Map.InvalidCustomRules;

                var preview = invalid.Get<MapPreviewWidget>("MAP_PREVIEW");
                preview.Preview = () => lobby.Map;
                preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi);
                preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map);

                var titleLabel = invalid.GetOrNull<LabelWidget>("MAP_TITLE");
                if (titleLabel != null)
                    titleLabel.GetText = () => lobby.Map.Title;

                var typeLabel = invalid.GetOrNull<LabelWidget>("MAP_TYPE");
                if (typeLabel != null)
                {
                    var type = new CachedTransform<MapPreview, string>(m => lobby.Map.Categories.FirstOrDefault() ?? "");
                    typeLabel.GetText = () => type.Update(lobby.Map);
                }
            }

            var download = widget.GetOrNull("MAP_DOWNLOADABLE");
            if (download != null)
            {
                download.IsVisible = () => lobby.Map.Status == MapStatus.DownloadAvailable;

                var preview = download.Get<MapPreviewWidget>("MAP_PREVIEW");
                preview.Preview = () => lobby.Map;
                preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi);
                preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map);

                var titleLabel = download.GetOrNull<LabelWidget>("MAP_TITLE");
                if (titleLabel != null)
                    titleLabel.GetText = () => lobby.Map.Title;

                var typeLabel = download.GetOrNull<LabelWidget>("MAP_TYPE");
                if (typeLabel != null)
                {
                    var type = new CachedTransform<MapPreview, string>(m => lobby.Map.Categories.FirstOrDefault() ?? "");
                    typeLabel.GetText = () => type.Update(lobby.Map);
                }

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

                var install = download.GetOrNull<ButtonWidget>("MAP_INSTALL");
                if (install != null)
                {
                    install.OnClick = () => lobby.Map.Install(() =>
                    {
                        lobby.Map.PreloadRules();
                        Game.RunAfterTick(() => orderManager.IssueOrder(Order.Command("state {0}".F(Session.ClientState.NotReady))));
                    });
                    install.IsHighlighted = () => installHighlighted;
                }
            }

            var progress = widget.GetOrNull("MAP_PROGRESS");
            if (progress != null)
            {
                progress.IsVisible = () => lobby.Map.Status != MapStatus.Available &&
                    lobby.Map.Status != MapStatus.DownloadAvailable;

                var preview = progress.Get<MapPreviewWidget>("MAP_PREVIEW");
                preview.Preview = () => lobby.Map;
                preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi);
                preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map);

                var titleLabel = progress.GetOrNull<LabelWidget>("MAP_TITLE");
                if (titleLabel != null)
                    titleLabel.GetText = () => lobby.Map.Title;

                var typeLabel = progress.GetOrNull<LabelWidget>("MAP_TYPE");
                if (typeLabel != null)
                if (typeLabel != null)
                {
                    var type = new CachedTransform<MapPreview, string>(m => lobby.Map.Categories.FirstOrDefault() ?? "");
                    typeLabel.GetText = () => type.Update(lobby.Map);
                }

                var statusSearching = progress.GetOrNull("MAP_STATUS_SEARCHING");
                if (statusSearching != null)
                    statusSearching.IsVisible = () => lobby.Map.Status == MapStatus.Searching;

                var statusUnavailable = progress.GetOrNull("MAP_STATUS_UNAVAILABLE");
                if (statusUnavailable != null)
                    statusUnavailable.IsVisible = () => lobby.Map.Status == MapStatus.Unavailable;

                var statusError = progress.GetOrNull("MAP_STATUS_ERROR");
                if (statusError != null)
                    statusError.IsVisible = () => lobby.Map.Status == MapStatus.DownloadError;

                var statusDownloading = progress.GetOrNull<LabelWidget>("MAP_STATUS_DOWNLOADING");
                if (statusDownloading != null)
                {
                    statusDownloading.IsVisible = () => lobby.Map.Status == MapStatus.Downloading;
                    statusDownloading.GetText = () =>
                    {
                        if (lobby.Map.DownloadBytes == 0)
                            return "Connecting...";

                        // Server does not provide the total file length
                        if (lobby.Map.DownloadPercentage == 0)
                            return "Downloading {0} kB".F(lobby.Map.DownloadBytes / 1024);

                        return "Downloading {0} kB ({1}%)".F(lobby.Map.DownloadBytes / 1024, lobby.Map.DownloadPercentage);
                    };
                }

                var retry = progress.GetOrNull<ButtonWidget>("MAP_RETRY");
                if (retry != null)
                {
                    retry.IsVisible = () => (lobby.Map.Status == MapStatus.DownloadError || lobby.Map.Status == MapStatus.Unavailable) &&
                        lobby.Map != MapCache.UnknownMap;
                    retry.OnClick = () =>
                    {
                        if (lobby.Map.Status == MapStatus.DownloadError)
                            lobby.Map.Install(() => orderManager.IssueOrder(Order.Command("state {0}".F(Session.ClientState.NotReady))));
                        else if (lobby.Map.Status == MapStatus.Unavailable)
                            modData.MapCache.QueryRemoteMapDetails(new[] { lobby.Map.Uid });
                    };

                    retry.GetText = () => lobby.Map.Status == MapStatus.DownloadError ? "Retry Install" : "Retry Search";
                }

                var progressbar = progress.GetOrNull<ProgressBarWidget>("MAP_PROGRESSBAR");
                if (progressbar != null)
                {
                    progressbar.IsIndeterminate = () => lobby.Map.DownloadPercentage == 0;
                    progressbar.GetPercentage = () => lobby.Map.DownloadPercentage;
                    progressbar.IsVisible = () => !retry.IsVisible();
                }
            }
        }
Exemple #12
0
        public GameInfoStatsLogic(Widget widget, World world, OrderManager orderManager)
        {
            var player = world.RenderPlayer ?? world.LocalPlayer;
            var playerPanel = widget.Get<ScrollPanelWidget>("PLAYER_LIST");

            if (player != null && !player.NonCombatant)
            {
                var checkbox = widget.Get<CheckboxWidget>("STATS_CHECKBOX");
                var statusLabel = widget.Get<LabelWidget>("STATS_STATUS");

                checkbox.IsChecked = () => player.WinState != WinState.Undefined;
                checkbox.GetCheckType = () => player.WinState == WinState.Won ?
                    "checked" : "crossed";

                if (player.HasObjectives)
                {
                    var mo = player.PlayerActor.Trait<MissionObjectives>();
                    checkbox.GetText = () => mo.Objectives.First().Description;
                }

                statusLabel.GetText = () => player.WinState == WinState.Won ? "Accomplished" :
                    player.WinState == WinState.Lost ? "Failed" : "In progress";
                statusLabel.GetColor = () => player.WinState == WinState.Won ? Color.LimeGreen :
                    player.WinState == WinState.Lost ? Color.Red : Color.White;
            }
            else
            {
                // Expand the stats window to cover the hidden objectives
                var objectiveGroup = widget.Get("OBJECTIVE");
                var statsHeader = widget.Get("STATS_HEADERS");

                objectiveGroup.Visible = false;
                statsHeader.Bounds.Y -= objectiveGroup.Bounds.Height;
                playerPanel.Bounds.Y -= objectiveGroup.Bounds.Height;
                playerPanel.Bounds.Height += objectiveGroup.Bounds.Height;
            }

            var teamTemplate = playerPanel.Get<ScrollItemWidget>("TEAM_TEMPLATE");
            var playerTemplate = playerPanel.Get("PLAYER_TEMPLATE");
            playerPanel.RemoveChildren();

            var teams = world.Players.Where(p => !p.NonCombatant && p.Playable)
                .Select(p => new Pair<Player, PlayerStatistics>(p, p.PlayerActor.TraitOrDefault<PlayerStatistics>()))
                .OrderByDescending(p => p.Second != null ? p.Second.Experience : 0)
                .GroupBy(p => (world.LobbyInfo.ClientWithIndex(p.First.ClientIndex) ?? new Session.Client()).Team)
                .OrderByDescending(g => g.Sum(gg => gg.Second != null ? gg.Second.Experience : 0));

            foreach (var t in teams)
            {
                if (teams.Count() > 1)
                {
                    var teamHeader = ScrollItemWidget.Setup(teamTemplate, () => true, () => { });
                    teamHeader.Get<LabelWidget>("TEAM").GetText = () => t.Key == 0 ? "No Team" : "Team {0}".F(t.Key);
                    var teamRating = teamHeader.Get<LabelWidget>("TEAM_SCORE");
                    teamRating.GetText = () => t.Sum(gg => gg.Second != null ? gg.Second.Experience : 0).ToString();

                    playerPanel.AddChild(teamHeader);
                }

                foreach (var p in t.ToList())
                {
                    var pp = p.First;
                    var client = world.LobbyInfo.ClientWithIndex(pp.ClientIndex);
                    var item = playerTemplate.Clone();
                    LobbyUtils.SetupClientWidget(item, client, orderManager, client != null && client.Bot == null);
                    var nameLabel = item.Get<LabelWidget>("NAME");
                    var nameFont = Game.Renderer.Fonts[nameLabel.Font];

                    var suffixLength = new CachedTransform<string, int>(s => nameFont.Measure(s).X);
                    var name = new CachedTransform<Pair<string, int>, string>(c =>
                        WidgetUtils.TruncateText(c.First, nameLabel.Bounds.Width - c.Second, nameFont));

                    nameLabel.GetText = () =>
                    {
                        var suffix = pp.WinState == WinState.Undefined ? "" : " (" + pp.WinState + ")";
                        if (client != null && client.State == Session.ClientState.Disconnected)
                            suffix = " (Gone)";

                        var sl = suffixLength.Update(suffix);
                        return name.Update(Pair.New(pp.PlayerName, sl)) + suffix;
                    };
                    nameLabel.GetColor = () => pp.Color.RGB;

                    var flag = item.Get<ImageWidget>("FACTIONFLAG");
                    flag.GetImageCollection = () => "flags";
                    if (player == null || player.Stances[pp] == Stance.Ally || player.WinState != WinState.Undefined)
                    {
                        flag.GetImageName = () => pp.Faction.InternalName;
                        item.Get<LabelWidget>("FACTION").GetText = () => pp.Faction.Name;
                    }
                    else
                    {
                        flag.GetImageName = () => pp.DisplayFaction.InternalName;
                        item.Get<LabelWidget>("FACTION").GetText = () => pp.DisplayFaction.Name;
                    }

                    var experience = p.Second != null ? p.Second.Experience : 0;
                    item.Get<LabelWidget>("SCORE").GetText = () => experience.ToString();

                    playerPanel.AddChild(item);
                }
            }

            var spectators = orderManager.LobbyInfo.Clients.Where(c => c.IsObserver).ToList();
            if (spectators.Any())
            {
                var spectatorHeader = ScrollItemWidget.Setup(teamTemplate, () => true, () => { });
                spectatorHeader.Get<LabelWidget>("TEAM").GetText = () => "Spectators";

                playerPanel.AddChild(spectatorHeader);

                foreach (var client in spectators)
                {
                    var item = playerTemplate.Clone();
                    LobbyUtils.SetupClientWidget(item, client, orderManager, client != null && client.Bot == null);
                    var nameLabel = item.Get<LabelWidget>("NAME");
                    var nameFont = Game.Renderer.Fonts[nameLabel.Font];

                    var suffixLength = new CachedTransform<string, int>(s => nameFont.Measure(s).X);
                    var name = new CachedTransform<Pair<string, int>, string>(c =>
                        WidgetUtils.TruncateText(c.First, nameLabel.Bounds.Width - c.Second, nameFont));

                    nameLabel.GetText = () =>
                    {
                        var suffix = client.State == Session.ClientState.Disconnected ? " (Gone)" : "";
                        var sl = suffixLength.Update(suffix);
                        return name.Update(Pair.New(client.Name, sl)) + suffix;
                    };

                    item.Get<ImageWidget>("FACTIONFLAG").IsVisible = () => false;
                    playerPanel.AddChild(item);
                }
            }
        }