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();
		}
        public SimpleProductionTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, Player player, Func <ProductionIcon> getTooltipIcon)
        {
            var world    = player.World;
            var mapRules = world.Map.Rules;

            widget.IsVisible = () => getTooltipIcon() != null && getTooltipIcon().Actor != null;
            var nameLabel     = widget.Get <LabelWidget>("NAME");
            var hotkeyLabel   = widget.Get <LabelWidget>("HOTKEY");
            var requiresLabel = widget.Get <LabelWidget>("REQUIRES");
            var timeLabel     = widget.Get <LabelWidget>("TIME");
            var timeIcon      = widget.Get <ImageWidget>("TIME_ICON");
            var descLabel     = widget.Get <LabelWidget>("DESC");

            var iconMargin = timeIcon.Bounds.X;

            var font            = Game.Renderer.Fonts[nameLabel.Font];
            var descFont        = Game.Renderer.Fonts[descLabel.Font];
            var requiresFont    = Game.Renderer.Fonts[requiresLabel.Font];
            var formatBuildTime = new CachedTransform <int, string>(time => WidgetUtils.FormatTime(time, world.Timestep));
            var requiresFormat  = requiresLabel.Text;

            ActorInfo lastActor        = null;
            Hotkey    lastHotkey       = Hotkey.Invalid;
            var       descLabelY       = descLabel.Bounds.Y;
            var       descLabelPadding = descLabel.Bounds.Height;

            tooltipContainer.BeforeRender = () =>
            {
                var tooltipIcon = getTooltipIcon();
                if (tooltipIcon == null)
                {
                    return;
                }

                var actor = tooltipIcon.Actor;
                if (actor == null)
                {
                    return;
                }

                var hotkey = tooltipIcon.Hotkey != null?tooltipIcon.Hotkey.GetValue() : Hotkey.Invalid;

                if (actor == lastActor && hotkey == lastHotkey)
                {
                    return;
                }

                var tooltip   = actor.TraitInfos <TooltipInfo>().FirstOrDefault(info => info.EnabledByDefault);
                var name      = tooltip != null ? tooltip.Name : actor.Name;
                var buildable = actor.TraitInfo <BuildableInfo>();

                var cost = 0;
                if (tooltipIcon.ProductionQueue != null)
                {
                    cost = tooltipIcon.ProductionQueue.GetProductionCost(actor);
                }
                else
                {
                    var valued = actor.TraitInfoOrDefault <ValuedInfo>();
                    if (valued != null)
                    {
                        cost = valued.Cost;
                    }
                }

                nameLabel.Text = name;

                var nameSize    = font.Measure(name);
                var hotkeyWidth = 0;
                hotkeyLabel.Visible = hotkey.IsValid();

                if (hotkeyLabel.Visible)
                {
                    var hotkeyText = "({0})".F(hotkey.DisplayString());

                    hotkeyWidth          = font.Measure(hotkeyText).X + 2 * nameLabel.Bounds.X;
                    hotkeyLabel.Text     = hotkeyText;
                    hotkeyLabel.Bounds.X = nameSize.X + 2 * nameLabel.Bounds.X;
                }

                var prereqs = buildable.Prerequisites.Select(a => ActorName(mapRules, a))
                              .Where(s => !s.StartsWith("~", StringComparison.Ordinal) && !s.StartsWith("!", StringComparison.Ordinal));

                var requiresSize = int2.Zero;
                if (prereqs.Any())
                {
                    requiresLabel.Text    = requiresFormat.F(prereqs.JoinWith(", "));
                    requiresSize          = requiresFont.Measure(requiresLabel.Text);
                    requiresLabel.Visible = true;
                    descLabel.Bounds.Y    = descLabelY + requiresLabel.Bounds.Height;
                }
                else
                {
                    requiresLabel.Visible = false;
                    descLabel.Bounds.Y    = descLabelY;
                }

                var buildTime    = tooltipIcon.ProductionQueue == null ? 0 : tooltipIcon.ProductionQueue.GetBuildTime(actor, buildable);
                var timeModifier = tooltipIcon.ProductionQueue.Info.LowPowerModifier;

                timeLabel.Text      = formatBuildTime.Update(buildTime * timeModifier / 100);
                timeLabel.TextColor = tooltipIcon.ProductionQueue.Info.LowPowerModifier > 100 ? Color.Red : Color.White;
                var timeSize = font.Measure(timeLabel.Text);

                descLabel.Text = buildable.Description.Replace("\\n", "\n");
                var descSize = descFont.Measure(descLabel.Text);
                descLabel.Bounds.Width  = descSize.X;
                descLabel.Bounds.Height = descSize.Y + descLabelPadding;

                var leftWidth = new[] { nameSize.X + hotkeyWidth, requiresSize.X, descSize.X }.Aggregate(Math.Max);
                var rightWidth = new[] { timeSize.X }.Aggregate(Math.Max);

                timeIcon.Bounds.X   = leftWidth + 2 * nameLabel.Bounds.X;
                timeLabel.Bounds.X  = timeIcon.Bounds.Right + iconMargin;
                widget.Bounds.Width = leftWidth + rightWidth + 3 * nameLabel.Bounds.X + timeIcon.Bounds.Width + iconMargin;

                // Set the bottom margin to match the left margin
                var leftHeight = descLabel.Bounds.Bottom + descLabel.Bounds.X;

                // Set the bottom margin to match the top margin
                var rightHeight = timeIcon.Bounds.Bottom;

                widget.Bounds.Height = Math.Max(leftHeight, rightHeight);

                lastActor  = actor;
                lastHotkey = hotkey;
            };
        }
        ScrollItemWidget BasicStats(Player player)
        {
            basicStatsHeaders.Visible = true;
            var template = SetupPlayerScrollItemWidget(basicPlayerTemplate, player);

            AddPlayerFlagAndName(template, player);

            var playerName = template.Get <LabelWidget>("PLAYER");

            playerName.GetColor = () => Color.White;

            var playerColor    = template.Get <ColorBlockWidget>("PLAYER_COLOR");
            var playerGradient = template.Get <GradientColorBlockWidget>("PLAYER_GRADIENT");

            SetupPlayerColor(player, template, playerColor, playerGradient);

            var res      = player.PlayerActor.Trait <PlayerResources>();
            var cashText = new CachedTransform <int, string>(i => "$" + i);

            template.Get <LabelWidget>("CASH").GetText = () => cashText.Update(res.Cash + res.Resources);

            var powerRes = player.PlayerActor.TraitOrDefault <PowerManager>();

            if (powerRes != null)
            {
                var power     = template.Get <LabelWidget>("POWER");
                var powerText = new CachedTransform <Pair <int, int>, string>(p => p.First + "/" + p.Second);
                power.GetText  = () => powerText.Update(new Pair <int, int>(powerRes.PowerDrained, powerRes.PowerProvided));
                power.GetColor = () => GetPowerColor(powerRes.PowerState);
            }

            var stats = player.PlayerActor.TraitOrDefault <PlayerStatistics>();

            if (stats == null)
            {
                return(template);
            }

            var killsText = new CachedTransform <int, string>(i => i.ToString());

            template.Get <LabelWidget>("KILLS").GetText = () => killsText.Update(stats.UnitsKilled + stats.BuildingsKilled);

            var deathsText = new CachedTransform <int, string>(i => i.ToString());

            template.Get <LabelWidget>("DEATHS").GetText = () => deathsText.Update(stats.UnitsDead + stats.BuildingsDead);

            var destroyedText = new CachedTransform <int, string>(i => "$" + i);

            template.Get <LabelWidget>("ASSETS_DESTROYED").GetText = () => destroyedText.Update(stats.KillsCost);

            var lostText = new CachedTransform <int, string>(i => "$" + i);

            template.Get <LabelWidget>("ASSETS_LOST").GetText = () => lostText.Update(stats.DeathsCost);

            var experienceText = new CachedTransform <int, string>(i => i.ToString());

            template.Get <LabelWidget>("EXPERIENCE").GetText = () => experienceText.Update(stats.Experience);

            var actionsText = new CachedTransform <double, string>(d => AverageOrdersPerMinute(d));

            template.Get <LabelWidget>("ACTIONS_MIN").GetText = () => actionsText.Update(stats.OrderCount);

            return(template);
        }
        void RebuildOptions()
        {
            if (mapPreview == null || mapPreview.Rules == null || mapPreview.InvalidCustomRules)
            {
                return;
            }

            optionsContainer.RemoveChildren();
            optionsContainer.Bounds.Height = 0;
            var allOptions = mapPreview.Rules.Actors["player"].TraitInfos <ILobbyOptions>()
                             .Concat(mapPreview.Rules.Actors["world"].TraitInfos <ILobbyOptions>())
                             .SelectMany(t => t.LobbyOptions(mapPreview.Rules))
                             .Where(o => o.IsVisible)
                             .OrderBy(o => o.DisplayOrder)
                             .ToArray();

            Widget row             = null;
            var    checkboxColumns = new Queue <CheckboxWidget>();
            var    dropdownColumns = new Queue <DropDownButtonWidget>();

            foreach (var option in allOptions.Where(o => o is LobbyBooleanOption))
            {
                if (!checkboxColumns.Any())
                {
                    row          = checkboxRowTemplate.Clone();
                    row.Bounds.Y = optionsContainer.Bounds.Height;
                    optionsContainer.Bounds.Height += row.Bounds.Height;
                    foreach (var child in row.Children)
                    {
                        if (child is CheckboxWidget)
                        {
                            checkboxColumns.Enqueue((CheckboxWidget)child);
                        }
                    }

                    optionsContainer.AddChild(row);
                }

                var checkbox    = checkboxColumns.Dequeue();
                var optionValue = new CachedTransform <Session.Global, Session.LobbyOptionState>(
                    gs => gs.LobbyOptions[option.Id]);

                checkbox.GetText = () => option.Name;
                if (option.Description != null)
                {
                    checkbox.GetTooltipText = () => option.Description;
                }

                checkbox.IsVisible  = () => true;
                checkbox.IsChecked  = () => optionValue.Update(orderManager.LobbyInfo.GlobalSettings).IsEnabled;
                checkbox.IsDisabled = () => configurationDisabled() || optionValue.Update(orderManager.LobbyInfo.GlobalSettings).IsLocked;
                checkbox.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                        "option {0} {1}".F(option.Id, !optionValue.Update(orderManager.LobbyInfo.GlobalSettings).IsEnabled)));
            }

            foreach (var option in allOptions.Where(o => !(o is LobbyBooleanOption)))
            {
                if (!dropdownColumns.Any())
                {
                    row          = dropdownRowTemplate.Clone() as Widget;
                    row.Bounds.Y = optionsContainer.Bounds.Height;
                    optionsContainer.Bounds.Height += row.Bounds.Height;
                    foreach (var child in row.Children)
                    {
                        if (child is DropDownButtonWidget)
                        {
                            dropdownColumns.Enqueue((DropDownButtonWidget)child);
                        }
                    }

                    optionsContainer.AddChild(row);
                }

                var dropdown    = dropdownColumns.Dequeue();
                var optionValue = new CachedTransform <Session.Global, Session.LobbyOptionState>(
                    gs => gs.LobbyOptions[option.Id]);

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

                    return(value);
                });

                dropdown.GetText = () => getOptionLabel.Update(optionValue.Update(orderManager.LobbyInfo.GlobalSettings).Value);
                if (option.Description != null)
                {
                    dropdown.GetTooltipText = () => option.Description;
                }
                dropdown.IsVisible  = () => true;
                dropdown.IsDisabled = () => configurationDisabled() ||
                                      optionValue.Update(orderManager.LobbyInfo.GlobalSettings).IsLocked;

                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(option.Id, c.Key)));

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

                    dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", option.Values.Count() * 30, option.Values, setupItem);
                };

                var label = row.GetOrNull <LabelWidget>(dropdown.Id + "_DESC");
                if (label != null)
                {
                    label.GetText   = () => option.Name;
                    label.IsVisible = () => true;
                }
            }

            panel.ContentHeight       = yMargin + optionsContainer.Bounds.Height;
            optionsContainer.Bounds.Y = yMargin;
            if (panel.ContentHeight < panel.Bounds.Height)
            {
                optionsContainer.Bounds.Y += (panel.Bounds.Height - panel.ContentHeight) / 2;
            }

            panel.ScrollToTop();
        }
        public IntroductionPromptLogic(Widget widget, ModData modData, WorldRenderer worldRenderer, Action onComplete)
        {
            var ps = Game.Settings.Player;
            var ds = Game.Settings.Graphics;
            var gs = Game.Settings.Game;

            var escPressed    = false;
            var nameTextfield = widget.Get <TextFieldWidget>("PLAYERNAME");

            nameTextfield.IsDisabled  = () => worldRenderer.World.Type != WorldType.Shellmap;
            nameTextfield.Text        = Settings.SanitizedPlayerName(ps.Name);
            nameTextfield.OnLoseFocus = () =>
            {
                if (escPressed)
                {
                    escPressed = false;
                    return;
                }

                nameTextfield.Text = nameTextfield.Text.Trim();
                if (nameTextfield.Text.Length == 0)
                {
                    nameTextfield.Text = Settings.SanitizedPlayerName(ps.Name);
                }
                else
                {
                    nameTextfield.Text = Settings.SanitizedPlayerName(nameTextfield.Text);
                    ps.Name            = nameTextfield.Text;
                }
            };

            nameTextfield.OnEnterKey = () => { nameTextfield.YieldKeyboardFocus(); return(true); };
            nameTextfield.OnEscKey   = () =>
            {
                nameTextfield.Text = Settings.SanitizedPlayerName(ps.Name);
                escPressed         = true;
                nameTextfield.YieldKeyboardFocus();
                return(true);
            };

            var colorPreview = widget.Get <ColorPreviewManagerWidget>("COLOR_MANAGER");

            colorPreview.Color = ps.Color;

            var mouseControlDescClassic = widget.Get("MOUSE_CONTROL_DESC_CLASSIC");

            mouseControlDescClassic.IsVisible = () => gs.UseClassicMouseStyle;

            var mouseControlDescModern = widget.Get("MOUSE_CONTROL_DESC_MODERN");

            mouseControlDescModern.IsVisible = () => !gs.UseClassicMouseStyle;

            var mouseControlDropdown = widget.Get <DropDownButtonWidget>("MOUSE_CONTROL_DROPDOWN");

            mouseControlDropdown.OnMouseDown = _ => InputSettingsLogic.ShowMouseControlDropdown(mouseControlDropdown, gs);
            mouseControlDropdown.GetText     = () => gs.UseClassicMouseStyle ? "Classic" : "Modern";

            foreach (var container in new[] { mouseControlDescClassic, mouseControlDescModern })
            {
                var classicScrollRight = container.Get("DESC_SCROLL_RIGHT");
                classicScrollRight.IsVisible = () => gs.UseClassicMouseStyle ^ gs.UseAlternateScrollButton;

                var classicScrollMiddle = container.Get("DESC_SCROLL_MIDDLE");
                classicScrollMiddle.IsVisible = () => !gs.UseClassicMouseStyle ^ gs.UseAlternateScrollButton;

                var zoomDesc = container.Get("DESC_ZOOM");
                zoomDesc.IsVisible = () => gs.ZoomModifier == Modifiers.None;

                var zoomDescModifier = container.Get <LabelWidget>("DESC_ZOOM_MODIFIER");
                zoomDescModifier.IsVisible = () => gs.ZoomModifier != Modifiers.None;

                var zoomDescModifierTemplate = zoomDescModifier.Text;
                var zoomDescModifierLabel    = new CachedTransform <Modifiers, string>(
                    mod => zoomDescModifierTemplate.Replace("MODIFIER", mod.ToString()));
                zoomDescModifier.GetText = () => zoomDescModifierLabel.Update(gs.ZoomModifier);

                var edgescrollDesc = container.Get <LabelWidget>("DESC_EDGESCROLL");
                edgescrollDesc.IsVisible = () => gs.ViewportEdgeScroll;
            }

            SettingsUtils.BindCheckboxPref(widget, "EDGESCROLL_CHECKBOX", gs, "ViewportEdgeScroll");

            var colorDropdown = widget.Get <DropDownButtonWidget>("PLAYERCOLOR");

            colorDropdown.IsDisabled  = () => worldRenderer.World.Type != WorldType.Shellmap;
            colorDropdown.OnMouseDown = _ => ColorPickerLogic.ShowColorDropDown(colorDropdown, colorPreview, worldRenderer.World);
            colorDropdown.Get <ColorBlockWidget>("COLORBLOCK").GetColor = () => ps.Color;

            var viewportSizes             = modData.Manifest.Get <WorldViewportSizes>();
            var battlefieldCameraDropDown = widget.Get <DropDownButtonWidget>("BATTLEFIELD_CAMERA_DROPDOWN");
            var battlefieldCameraLabel    = new CachedTransform <WorldViewport, string>(vs => DisplaySettingsLogic.ViewportSizeNames[vs]);

            battlefieldCameraDropDown.OnMouseDown = _ => DisplaySettingsLogic.ShowBattlefieldCameraDropdown(battlefieldCameraDropDown, viewportSizes, ds);
            battlefieldCameraDropDown.GetText     = () => battlefieldCameraLabel.Update(ds.ViewportDistance);

            var uiScaleDropdown = widget.Get <DropDownButtonWidget>("UI_SCALE_DROPDOWN");
            var uiScaleLabel    = new CachedTransform <float, string>(s => "{0}%".F((int)(100 * s)));

            uiScaleDropdown.OnMouseDown = _ => DisplaySettingsLogic.ShowUIScaleDropdown(uiScaleDropdown, ds);
            uiScaleDropdown.GetText     = () => uiScaleLabel.Update(ds.UIScale);

            var minResolution  = viewportSizes.MinEffectiveResolution;
            var resolution     = Game.Renderer.Resolution;
            var disableUIScale = worldRenderer.World.Type != WorldType.Shellmap ||
                                 resolution.Width * ds.UIScale < 1.25f * minResolution.Width ||
                                 resolution.Height * ds.UIScale < 1.25f * minResolution.Height;

            uiScaleDropdown.IsDisabled = () => disableUIScale;

            SettingsUtils.BindCheckboxPref(widget, "CURSORDOUBLE_CHECKBOX", ds, "CursorDouble");

            widget.Get <ButtonWidget>("CONTINUE_BUTTON").OnClick = () =>
            {
                Game.Settings.Game.IntroductionPromptVersion = IntroductionVersion;
                Game.Settings.Save();
                Ui.CloseWindow();
                onComplete();
            };
        }
        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;
            }
        }
        public AssetBrowserLogic(Widget widget, Action onExit, ModData modData, WorldRenderer worldRenderer)
        {
            world        = worldRenderer.World;
            this.modData = modData;
            panel        = widget;

            var colorPickerPalettes = world.WorldActor.TraitsImplementing <IProvidesAssetBrowserColorPickerPalettes>()
                                      .SelectMany(p => p.ColorPickerPaletteNames)
                                      .ToArray();

            palettes = world.WorldActor.TraitsImplementing <IProvidesAssetBrowserPalettes>()
                       .SelectMany(p => p.PaletteNames)
                       .Concat(colorPickerPalettes)
                       .ToArray();

            var ticker = panel.GetOrNull <LogicTickerWidget>("ANIMATION_TICKER");

            if (ticker != null)
            {
                ticker.OnTick = () =>
                {
                    if (animateFrames && currentSprites != null)
                    {
                        SelectNextFrame();
                    }
                };
            }

            var sourceDropdown = panel.GetOrNull <DropDownButtonWidget>("SOURCE_SELECTOR");

            if (sourceDropdown != null)
            {
                sourceDropdown.OnMouseDown = _ => ShowSourceDropdown(sourceDropdown);
                var sourceName = new CachedTransform <IReadOnlyPackage, string>(GetSourceDisplayName);
                sourceDropdown.GetText = () => sourceName.Update(assetSource);
            }

            var spriteWidget = panel.GetOrNull <SpriteWidget>("SPRITE");

            if (spriteWidget != null)
            {
                spriteWidget.GetSprite  = () => currentSprites != null ? currentSprites[currentFrame] : null;
                currentPalette          = spriteWidget.Palette;
                spriteScale             = spriteWidget.Scale;
                spriteWidget.GetPalette = () => currentPalette;
                spriteWidget.IsVisible  = () => !isVideoLoaded && !isLoadError && currentSprites != null;
                spriteWidget.GetScale   = () => spriteScale;
            }

            var playerWidget = panel.GetOrNull <VideoPlayerWidget>("PLAYER");

            if (playerWidget != null)
            {
                playerWidget.IsVisible = () => isVideoLoaded && !isLoadError;
            }

            var modelWidget = panel.GetOrNull <ModelWidget>("VOXEL");

            if (modelWidget != null)
            {
                modelWidget.GetVoxel         = () => currentVoxel;
                currentPalette               = modelWidget.Palette;
                modelScale                   = modelWidget.Scale;
                modelWidget.GetPalette       = () => currentPalette;
                modelWidget.GetPlayerPalette = () => currentPalette;
                modelWidget.GetRotation      = () => modelOrientation;
                modelWidget.IsVisible        = () => !isVideoLoaded && !isLoadError && currentVoxel != null;
                modelWidget.GetScale         = () => modelScale;
            }

            var errorLabelWidget = panel.GetOrNull("ERROR");

            if (errorLabelWidget != null)
            {
                errorLabelWidget.IsVisible = () => isLoadError;
            }

            var paletteDropDown = panel.GetOrNull <DropDownButtonWidget>("PALETTE_SELECTOR");

            if (paletteDropDown != null)
            {
                paletteDropDown.OnMouseDown = _ => ShowPaletteDropdown(paletteDropDown);
                paletteDropDown.GetText     = () => currentPalette;
                paletteDropDown.IsVisible   = () => currentSprites != null || currentVoxel != null;
                panel.GetOrNull <LabelWidget>("PALETTE_DESC").IsVisible = () => currentSprites != null || currentVoxel != null;
            }

            var colorManager = modData.DefaultRules.Actors[SystemActors.World].TraitInfo <ColorPickerManagerInfo>();

            colorManager.Color = Game.Settings.Player.Color;

            var colorDropdown = panel.GetOrNull <DropDownButtonWidget>("COLOR");

            if (colorDropdown != null)
            {
                colorDropdown.IsDisabled  = () => !colorPickerPalettes.Contains(currentPalette);
                colorDropdown.OnMouseDown = _ => ColorPickerLogic.ShowColorDropDown(colorDropdown, colorManager, worldRenderer);
                colorDropdown.IsVisible   = () => currentSprites != null || currentVoxel != null;
                panel.Get <ColorBlockWidget>("COLORBLOCK").GetColor = () => colorManager.Color;
            }

            filenameInput = panel.Get <TextFieldWidget>("FILENAME_INPUT");
            filenameInput.OnTextEdited = () => ApplyFilter();
            filenameInput.OnEscKey     = _ =>
            {
                if (string.IsNullOrEmpty(filenameInput.Text))
                {
                    filenameInput.YieldKeyboardFocus();
                }
                else
                {
                    filenameInput.Text = "";
                    filenameInput.OnTextEdited();
                }

                return(true);
            };

            var frameContainer = panel.GetOrNull("FRAME_SELECTOR");

            if (frameContainer != null)
            {
                frameContainer.IsVisible = () => (currentSprites != null && currentSprites.Length > 1) ||
                                           (isVideoLoaded && player != null && player.Video != null && player.Video.FrameCount > 1) ||
                                           currentSoundFormat != null;
            }

            frameSlider = panel.GetOrNull <SliderWidget>("FRAME_SLIDER");
            if (frameSlider != null)
            {
                frameSlider.OnChange += x =>
                {
                    if (!isVideoLoaded)
                    {
                        currentFrame = (int)Math.Round(x);
                    }
                };

                frameSlider.GetValue = () =>
                {
                    if (isVideoLoaded)
                    {
                        return(player.Video.CurrentFrameIndex);
                    }

                    if (currentSound != null)
                    {
                        return(currentSound.SeekPosition * currentSoundFormat.SampleRate);
                    }

                    return(currentFrame);
                };

                frameSlider.IsDisabled = () => isVideoLoaded || currentSoundFormat != null;
            }

            var frameText = panel.GetOrNull <LabelWidget>("FRAME_COUNT");

            if (frameText != null)
            {
                frameText.GetText = () =>
                {
                    if (isVideoLoaded)
                    {
                        return($"{player.Video.CurrentFrameIndex + 1} / {player.Video.FrameCount}");
                    }

                    if (currentSoundFormat != null)
                    {
                        return($"{Math.Round(currentSoundFormat.LengthInSeconds, 3)} sec");
                    }

                    return($"{currentFrame} / {currentSprites.Length - 1}");
                };
            }

            var playButton = panel.GetOrNull <ButtonWidget>("BUTTON_PLAY");

            if (playButton != null)
            {
                playButton.OnClick = () =>
                {
                    if (isVideoLoaded)
                    {
                        player.Play();
                    }
                    else if (currentSoundFormat != null)
                    {
                        if (currentSound != null)
                        {
                            Game.Sound.StopSound(currentSound);
                        }

                        currentSound = Game.Sound.Play(currentSoundFormat, Game.Sound.SoundVolume);
                    }
                    else
                    {
                        animateFrames = true;
                    }
                };

                playButton.IsVisible = () => isVideoLoaded ? player.Paused : !animateFrames || currentSoundFormat != null;
            }

            var pauseButton = panel.GetOrNull <ButtonWidget>("BUTTON_PAUSE");

            if (pauseButton != null)
            {
                pauseButton.OnClick = () =>
                {
                    if (isVideoLoaded)
                    {
                        player.Pause();
                    }
                    else
                    {
                        animateFrames = false;
                    }
                };

                pauseButton.IsVisible = () => isVideoLoaded ? !player.Paused : (animateFrames && currentSoundFormat == null);
            }

            var stopButton = panel.GetOrNull <ButtonWidget>("BUTTON_STOP");

            if (stopButton != null)
            {
                stopButton.OnClick = () =>
                {
                    if (isVideoLoaded)
                    {
                        player.Stop();
                    }
                    else if (currentSound != null)
                    {
                        Game.Sound.StopSound(currentSound);
                    }
                    else
                    {
                        currentFrame  = 0;
                        animateFrames = false;
                    }

                    if (frameSlider != null)
                    {
                        frameSlider.Value = 0;
                    }
                };
            }

            var nextButton = panel.GetOrNull <ButtonWidget>("BUTTON_NEXT");

            if (nextButton != null)
            {
                nextButton.OnClick = () =>
                {
                    if (!isVideoLoaded)
                    {
                        nextButton.OnClick = SelectNextFrame;
                    }
                };

                nextButton.IsVisible = () => !isVideoLoaded && currentSoundFormat == null;
            }

            var prevButton = panel.GetOrNull <ButtonWidget>("BUTTON_PREV");

            if (prevButton != null)
            {
                prevButton.OnClick = () =>
                {
                    if (!isVideoLoaded)
                    {
                        SelectPreviousFrame();
                    }
                };

                prevButton.IsVisible = () => !isVideoLoaded && currentSoundFormat == null;
            }

            var spriteScaleSlider = panel.GetOrNull <SliderWidget>("SPRITE_SCALE_SLIDER");

            if (spriteScaleSlider != null)
            {
                spriteScaleSlider.OnChange += x => spriteScale = x;
                spriteScaleSlider.GetValue  = () => spriteScale;
                spriteScaleSlider.IsVisible = () => currentSprites != null;
                panel.GetOrNull <LabelWidget>("SPRITE_SCALE").IsVisible = () => currentSprites != null;
            }

            var voxelContainer = panel.GetOrNull("VOXEL_SELECTOR");

            if (voxelContainer != null)
            {
                voxelContainer.IsVisible = () => currentVoxel != null;
            }

            var rollSlider = panel.GetOrNull <SliderWidget>("ROLL_SLIDER");

            if (rollSlider != null)
            {
                rollSlider.OnChange += x =>
                {
                    var roll = (int)x;
                    modelOrientation = modelOrientation.WithRoll(new WAngle(roll));
                };

                rollSlider.GetValue = () => modelOrientation.Roll.Angle;
            }

            var pitchSlider = panel.GetOrNull <SliderWidget>("PITCH_SLIDER");

            if (pitchSlider != null)
            {
                pitchSlider.OnChange += x =>
                {
                    var pitch = (int)x;
                    modelOrientation = modelOrientation.WithPitch(new WAngle(pitch));
                };

                pitchSlider.GetValue = () => modelOrientation.Pitch.Angle;
            }

            var yawSlider = panel.GetOrNull <SliderWidget>("YAW_SLIDER");

            if (yawSlider != null)
            {
                yawSlider.OnChange += x =>
                {
                    var yaw = (int)x;
                    modelOrientation = modelOrientation.WithYaw(new WAngle(yaw));
                };

                yawSlider.GetValue = () => modelOrientation.Yaw.Angle;
            }

            var modelScaleSlider = panel.GetOrNull <SliderWidget>("MODEL_SCALE_SLIDER");

            if (modelScaleSlider != null)
            {
                modelScaleSlider.OnChange += x => modelScale = x;
                modelScaleSlider.GetValue  = () => modelScale;
                modelScaleSlider.IsVisible = () => currentVoxel != null;
                panel.GetOrNull <LabelWidget>("MODEL_SCALE").IsVisible = () => currentVoxel != null;
            }

            var assetBrowserModData = modData.Manifest.Get <AssetBrowser>();

            allowedSpriteExtensions = assetBrowserModData.SpriteExtensions;
            allowedModelExtensions  = assetBrowserModData.ModelExtensions;
            allowedAudioExtensions  = assetBrowserModData.AudioExtensions;
            allowedVideoExtensions  = assetBrowserModData.VideoExtensions;
            allowedExtensions       = allowedSpriteExtensions
                                      .Union(allowedModelExtensions)
                                      .Union(allowedAudioExtensions)
                                      .Union(allowedVideoExtensions)
                                      .ToArray();

            acceptablePackages = modData.ModFiles.MountedPackages.Where(p =>
                                                                        p.Contents.Any(c => allowedExtensions.Contains(Path.GetExtension(c).ToLowerInvariant())));

            assetList = panel.Get <ScrollPanelWidget>("ASSET_LIST");
            template  = panel.Get <ScrollItemWidget>("ASSET_TEMPLATE");
            PopulateAssetList();

            var closeButton = panel.GetOrNull <ButtonWidget>("CLOSE_BUTTON");

            if (closeButton != null)
            {
                closeButton.OnClick = () =>
                {
                    ClearLoadedAssets();
                    Ui.CloseWindow();
                    onExit();
                }
            }
            ;
        }

        void SelectNextFrame()
        {
            currentFrame++;
            if (currentFrame >= currentSprites.Length)
            {
                currentFrame = 0;
            }
        }

        void SelectPreviousFrame()
        {
            currentFrame--;
            if (currentFrame < 0)
            {
                currentFrame = currentSprites.Length - 1;
            }
        }
        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 ColorPickerLogic(Widget widget, ModData modData, World world, Color initialColor, string initialFaction, Action <Color> onChange,
                                Dictionary <string, MiniYaml> logicArgs)
        {
            var mixer = widget.Get <ColorMixerWidget>("MIXER");

            // Set the initial state
            // All users need to use the same TraitInfo instance, chosen as the default mod rules
            var colorManager = modData.DefaultRules.Actors[SystemActors.World].TraitInfo <ColorPickerManagerInfo>();

            mixer.SetColorLimits(colorManager.HsvSaturationRange[0], colorManager.HsvSaturationRange[1], colorManager.V);
            mixer.OnChange += () => onChange(mixer.Color);
            mixer.Set(initialColor);

            var randomButton = widget.GetOrNull <ButtonWidget>("RANDOM_BUTTON");

            if (randomButton != null)
            {
                var terrainColors = modData.DefaultTerrainInfo
                                    .SelectMany(t => t.Value.RestrictedPlayerColors)
                                    .Distinct()
                                    .ToList();
                var playerColors = Enumerable.Empty <Color>();
                randomButton.OnClick = () => mixer.Set(colorManager.RandomValidColor(world.LocalRandom, terrainColors, playerColors));
            }

            if (initialFaction == null || !colorManager.FactionPreviewActors.TryGetValue(initialFaction, out var actorType))
            {
                actorType = colorManager.PreviewActor;
            }

            if (actorType == null)
            {
                var message = "ColorPickerManager does not define a preview actor";
                if (initialFaction != null)
                {
                    message += " for faction " + initialFaction;
                }
                message += "!";

                throw new YamlException(message);
            }

            var preview = widget.GetOrNull <ActorPreviewWidget>("PREVIEW");
            var actor   = world.Map.Rules.Actors[actorType];

            var td = new TypeDictionary
            {
                new OwnerInit(world.WorldActor.Owner),
                new FactionInit(world.WorldActor.Owner.PlayerReference.Faction)
            };

            foreach (var api in actor.TraitInfos <IActorPreviewInitInfo>())
            {
                foreach (var o in api.ActorPreviewInits(actor, ActorPreviewType.ColorPicker))
                {
                    td.Add(o);
                }
            }

            preview?.SetPreview(actor, td);

            // HACK: the value returned from the color mixer will generally not
            // be equal to the given initialColor due to its internal RGB -> HSL -> RGB
            // conversion. This conversion can sometimes convert a valid initial value
            // into an invalid (too close to terrain / another player) color.
            // We use the original colour here instead of the mixer color to make sure
            // that we keep the player's previous colour value if they don't change anything
            onChange(initialColor);

            // Setup tab controls
            var mixerTab            = widget.Get("MIXER_TAB");
            var paletteTab          = widget.Get("PALETTE_TAB");
            var paletteTabPanel     = widget.Get("PALETTE_TAB_PANEL");
            var mixerTabButton      = widget.Get <ButtonWidget>("MIXER_TAB_BUTTON");
            var paletteTabButton    = widget.Get <ButtonWidget>("PALETTE_TAB_BUTTON");
            var presetArea          = paletteTabPanel.Get <ContainerWidget>("PRESET_AREA");
            var customArea          = paletteTabPanel.Get <ContainerWidget>("CUSTOM_AREA");
            var presetColorTemplate = paletteTabPanel.Get <ColorBlockWidget>("COLORPRESET");
            var customColorTemplate = paletteTabPanel.Get <ColorBlockWidget>("COLORCUSTOM");

            mixerTab.IsVisible           = () => !paletteTabOpenedLast;
            mixerTabButton.OnClick       = () => paletteTabOpenedLast = false;
            mixerTabButton.IsHighlighted = mixerTab.IsVisible;

            paletteTab.IsVisible           = () => paletteTabOpenedLast;
            paletteTabButton.OnClick       = () => paletteTabOpenedLast = true;
            paletteTabButton.IsHighlighted = () => paletteTab.IsVisible() || paletteTabHighlighted > 0;

            var paletteCols       = 8;
            var palettePresetRows = 2;
            var paletteCustomRows = 1;

            if (logicArgs.TryGetValue("PaletteColumns", out var yaml))
            {
                if (!int.TryParse(yaml.Value, out paletteCols))
                {
                    throw new YamlException($"Invalid value for PaletteColumns: {yaml.Value}");
                }
            }
            if (logicArgs.TryGetValue("PalettePresetRows", out yaml))
            {
                if (!int.TryParse(yaml.Value, out palettePresetRows))
                {
                    throw new YamlException($"Invalid value for PalettePresetRows: {yaml.Value}");
                }
            }
            if (logicArgs.TryGetValue("PaletteCustomRows", out yaml))
            {
                if (!int.TryParse(yaml.Value, out paletteCustomRows))
                {
                    throw new YamlException($"Invalid value for PaletteCustomRows: {yaml.Value}");
                }
            }

            var presetColors = colorManager.PresetColors().ToList();

            for (var j = 0; j < palettePresetRows; j++)
            {
                for (var i = 0; i < paletteCols; i++)
                {
                    var colorIndex = j * paletteCols + i;
                    if (colorIndex >= presetColors.Count)
                    {
                        break;
                    }

                    var color = presetColors[colorIndex];

                    var newSwatch = (ColorBlockWidget)presetColorTemplate.Clone();
                    newSwatch.GetColor  = () => color;
                    newSwatch.IsVisible = () => true;
                    newSwatch.Bounds.X  = i * newSwatch.Bounds.Width;
                    newSwatch.Bounds.Y  = j * newSwatch.Bounds.Height;
                    newSwatch.OnMouseUp = m =>
                    {
                        mixer.Set(color);
                        onChange(color);
                    };

                    presetArea.AddChild(newSwatch);
                }
            }

            for (var j = 0; j < paletteCustomRows; j++)
            {
                for (var i = 0; i < paletteCols; i++)
                {
                    var colorIndex = j * paletteCols + i;

                    var newSwatch = (ColorBlockWidget)customColorTemplate.Clone();
                    var getColor  = new CachedTransform <Color, Color>(c => colorManager.MakeValid(c, world.LocalRandom, Enumerable.Empty <Color>(), Enumerable.Empty <Color>()));

                    newSwatch.GetColor  = () => getColor.Update(Game.Settings.Player.CustomColors[colorIndex]);
                    newSwatch.IsVisible = () => Game.Settings.Player.CustomColors.Length > colorIndex;
                    newSwatch.Bounds.X  = i * newSwatch.Bounds.Width;
                    newSwatch.Bounds.Y  = j * newSwatch.Bounds.Height;
                    newSwatch.OnMouseUp = m =>
                    {
                        var color = newSwatch.GetColor();
                        mixer.Set(color);
                        onChange(color);
                    };

                    customArea.AddChild(newSwatch);
                }
            }

            // Store color button
            var storeButton = widget.Get <ButtonWidget>("STORE_BUTTON");

            if (storeButton != null)
            {
                storeButton.OnClick = () =>
                {
                    // Update the custom color list:
                    //  - Remove any duplicates of the new color
                    //  - Add the new color to the end
                    //  - Save the last N colors
                    Game.Settings.Player.CustomColors = Game.Settings.Player.CustomColors
                                                        .Where(c => c != mixer.Color)
                                                        .Append(mixer.Color)
                                                        .Reverse().Take(paletteCustomRows * paletteCols).Reverse()
                                                        .ToArray();
                    Game.Settings.Save();

                    // Flash the palette tab to show players that something has happened
                    if (!paletteTabOpenedLast)
                    {
                        paletteTabHighlighted = 4;
                    }
                };
            }
        }
        Func <bool> InitPanel(Widget panel)
        {
            hotkeyList        = panel.Get <ScrollPanelWidget>("HOTKEY_LIST");
            hotkeyList.Layout = new GridLayout(hotkeyList);
            headerTemplate    = hotkeyList.Get("HEADER");
            template          = hotkeyList.Get("TEMPLATE");
            emptyListMessage  = panel.Get("HOTKEY_EMPTY_LIST");
            remapDialog       = panel.Get("HOTKEY_REMAP_DIALOG");

            foreach (var hd in modData.Hotkeys.Definitions)
            {
                contexts.UnionWith(hd.Contexts);
            }

            filterInput = panel.Get <TextFieldWidget>("FILTER_INPUT");
            filterInput.OnTextEdited = () => InitHotkeyList();
            filterInput.OnEscKey     = _ =>
            {
                if (string.IsNullOrEmpty(filterInput.Text))
                {
                    filterInput.YieldKeyboardFocus();
                }
                else
                {
                    filterInput.Text = "";
                    filterInput.OnTextEdited();
                }

                return(true);
            };

            var contextDropdown = panel.GetOrNull <DropDownButtonWidget>("CONTEXT_DROPDOWN");

            if (contextDropdown != null)
            {
                contextDropdown.OnMouseDown = _ => ShowContextDropdown(contextDropdown);
                var contextName = new CachedTransform <string, string>(GetContextDisplayName);
                contextDropdown.GetText = () => contextName.Update(currentContext);
            }

            if (logicArgs.TryGetValue("HotkeyGroups", out var hotkeyGroupsYaml))
            {
                foreach (var hg in hotkeyGroupsYaml.Nodes)
                {
                    var typesNode = hg.Value.Nodes.FirstOrDefault(n => n.Key == "Types");
                    if (typesNode != null)
                    {
                        hotkeyGroups.Add(hg.Key, FieldLoader.GetValue <HashSet <string> >("Types", typesNode.Value.Value));
                    }
                }

                InitHotkeyRemapDialog(panel);
                InitHotkeyList();
            }

            return(() =>
            {
                hotkeyEntryWidget.Key =
                    selectedHotkeyDefinition != null ?
                    modData.Hotkeys[selectedHotkeyDefinition.Name].GetValue() :
                    Hotkey.Invalid;

                hotkeyEntryWidget.ForceYieldKeyboardFocus();

                return false;
            });
        }
        public GameInfoStatsLogic(Widget widget, World world, OrderManager orderManager)
        {
            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();
                LobbyUtils.SetupClientWidget(item, client, orderManager, 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 == 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();
            }
        }
        Func <bool> InitPanel(Widget panel)
        {
            var gs = Game.Settings.Game;

            SettingsUtils.BindCheckboxPref(panel, "ALTERNATE_SCROLL_CHECKBOX", gs, "UseAlternateScrollButton");
            SettingsUtils.BindCheckboxPref(panel, "EDGESCROLL_CHECKBOX", gs, "ViewportEdgeScroll");
            SettingsUtils.BindCheckboxPref(panel, "LOCKMOUSE_CHECKBOX", gs, "LockMouseWindow");
            SettingsUtils.BindSliderPref(panel, "ZOOMSPEED_SLIDER", gs, "ZoomSpeed");
            SettingsUtils.BindSliderPref(panel, "SCROLLSPEED_SLIDER", gs, "ViewportEdgeScrollStep");
            SettingsUtils.BindSliderPref(panel, "UI_SCROLLSPEED_SLIDER", gs, "UIScrollSpeed");

            var mouseControlDropdown = panel.Get <DropDownButtonWidget>("MOUSE_CONTROL_DROPDOWN");

            mouseControlDropdown.OnMouseDown = _ => ShowMouseControlDropdown(mouseControlDropdown, gs);
            mouseControlDropdown.GetText     = () => gs.UseClassicMouseStyle ? "Classic" : "Modern";

            var mouseScrollDropdown = panel.Get <DropDownButtonWidget>("MOUSE_SCROLL_TYPE_DROPDOWN");

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

            var mouseControlDescClassic = panel.Get("MOUSE_CONTROL_DESC_CLASSIC");

            mouseControlDescClassic.IsVisible = () => gs.UseClassicMouseStyle;

            var mouseControlDescModern = panel.Get("MOUSE_CONTROL_DESC_MODERN");

            mouseControlDescModern.IsVisible = () => !gs.UseClassicMouseStyle;

            foreach (var container in new[] { mouseControlDescClassic, mouseControlDescModern })
            {
                var classicScrollRight = container.Get("DESC_SCROLL_RIGHT");
                classicScrollRight.IsVisible = () => gs.UseClassicMouseStyle ^ gs.UseAlternateScrollButton;

                var classicScrollMiddle = container.Get("DESC_SCROLL_MIDDLE");
                classicScrollMiddle.IsVisible = () => !gs.UseClassicMouseStyle ^ gs.UseAlternateScrollButton;

                var zoomDesc = container.Get("DESC_ZOOM");
                zoomDesc.IsVisible = () => gs.ZoomModifier == Modifiers.None;

                var zoomDescModifier = container.Get <LabelWidget>("DESC_ZOOM_MODIFIER");
                zoomDescModifier.IsVisible = () => gs.ZoomModifier != Modifiers.None;

                var zoomDescModifierTemplate = zoomDescModifier.Text;
                var zoomDescModifierLabel    = new CachedTransform <Modifiers, string>(
                    mod => zoomDescModifierTemplate.Replace("MODIFIER", mod.ToString()));
                zoomDescModifier.GetText = () => zoomDescModifierLabel.Update(gs.ZoomModifier);

                var edgescrollDesc = container.Get <LabelWidget>("DESC_EDGESCROLL");
                edgescrollDesc.IsVisible = () => gs.ViewportEdgeScroll;
            }

            // Apply mouse focus preferences immediately
            var lockMouseCheckbox = panel.Get <CheckboxWidget>("LOCKMOUSE_CHECKBOX");
            var oldOnClick        = lockMouseCheckbox.OnClick;

            lockMouseCheckbox.OnClick = () =>
            {
                // Still perform the old behaviour for clicking the checkbox, before
                // applying the changes live.
                oldOnClick();

                MakeMouseFocusSettingsLive();
            };

            var zoomModifierDropdown = panel.Get <DropDownButtonWidget>("ZOOM_MODIFIER");

            zoomModifierDropdown.OnMouseDown = _ => ShowZoomModifierDropdown(zoomModifierDropdown, gs);
            zoomModifierDropdown.GetText     = () => gs.ZoomModifier.ToString();

            return(() => false);
        }
Exemple #14
0
        Func <bool> InitPanel(Widget panel)
        {
            var musicPlaylist = worldRenderer.World.WorldActor.Trait <MusicPlaylist>();
            var ss            = Game.Settings.Sound;
            var scrollPanel   = panel.Get <ScrollPanelWidget>("SETTINGS_SCROLLPANEL");

            SettingsUtils.BindCheckboxPref(panel, "CASH_TICKS", ss, "CashTicks");
            SettingsUtils.BindCheckboxPref(panel, "MUTE_SOUND", ss, "Mute");
            SettingsUtils.BindCheckboxPref(panel, "MUTE_BACKGROUND_MUSIC", ss, "MuteBackgroundMusic");

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

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

            muteCheckbox.IsChecked  = () => muteCheckboxIsChecked() || Game.Sound.DummyEngine;
            muteCheckbox.IsDisabled = () => Game.Sound.DummyEngine;
            muteCheckbox.OnClick    = () =>
            {
                muteCheckboxOnClick();

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

            var muteBackgroundMusicCheckbox        = panel.Get <CheckboxWidget>("MUTE_BACKGROUND_MUSIC");
            var muteBackgroundMusicCheckboxOnClick = muteBackgroundMusicCheckbox.OnClick;

            muteBackgroundMusicCheckbox.OnClick = () =>
            {
                muteBackgroundMusicCheckboxOnClick();

                if (!musicPlaylist.AllowMuteBackgroundMusic)
                {
                    return;
                }

                if (musicPlaylist.CurrentSongIsBackground)
                {
                    musicPlaylist.Stop();
                }
            };

            // Replace controls with a warning label if sound is disabled
            var noDeviceLabel = panel.GetOrNull("NO_AUDIO_DEVICE_CONTAINER");

            if (noDeviceLabel != null)
            {
                noDeviceLabel.Visible = Game.Sound.DummyEngine;
            }

            panel.Get("CASH_TICKS_CONTAINER").Visible            = !Game.Sound.DummyEngine;
            panel.Get("MUTE_SOUND_CONTAINER").Visible            = !Game.Sound.DummyEngine;
            panel.Get("MUTE_BACKGROUND_MUSIC_CONTAINER").Visible = !Game.Sound.DummyEngine;
            panel.Get("SOUND_VOLUME_CONTAINER").Visible          = !Game.Sound.DummyEngine;
            panel.Get("MUSIC_VOLUME_CONTAINER").Visible          = !Game.Sound.DummyEngine;
            panel.Get("VIDEO_VOLUME_CONTAINER").Visible          = !Game.Sound.DummyEngine;

            var soundVolumeSlider = panel.Get <SliderWidget>("SOUND_VOLUME");

            soundVolumeSlider.OnChange += x => Game.Sound.SoundVolume = x;

            var musicVolumeSlider = panel.Get <SliderWidget>("MUSIC_VOLUME");

            musicVolumeSlider.OnChange += x => Game.Sound.MusicVolume = x;

            var videoVolumeSlider = panel.Get <SliderWidget>("VIDEO_VOLUME");

            videoVolumeSlider.OnChange += x => Game.Sound.VideoVolume = x;

            var devices = Game.Sound.AvailableDevices();

            soundDevice = devices.FirstOrDefault(d => d.Device == ss.Device) ?? devices.First();

            var audioDeviceDropdown = panel.Get <DropDownButtonWidget>("AUDIO_DEVICE");

            audioDeviceDropdown.OnMouseDown = _ => ShowAudioDeviceDropdown(audioDeviceDropdown, devices, scrollPanel);

            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);

            var restartDesc = panel.Get("RESTART_REQUIRED_DESC");

            restartDesc.IsVisible = () => soundDevice.Device != OriginalSoundDevice;

            SettingsUtils.AdjustSettingsScrollPanelLayout(scrollPanel);

            return(() =>
            {
                ss.Device = soundDevice.Device;

                return ss.Device != OriginalSoundDevice;
            });
        }
        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();
                }
            }
        }
        Func <bool> InitPanel(Widget panel)
        {
            var ds = Game.Settings.Graphics;
            var gs = Game.Settings.Game;

            SettingsUtils.BindCheckboxPref(panel, "CURSORDOUBLE_CHECKBOX", ds, "CursorDouble");
            SettingsUtils.BindCheckboxPref(panel, "VSYNC_CHECKBOX", ds, "VSync");
            SettingsUtils.BindCheckboxPref(panel, "FRAME_LIMIT_CHECKBOX", ds, "CapFramerate");
            SettingsUtils.BindIntSliderPref(panel, "FRAME_LIMIT_SLIDER", ds, "MaxFramerate");
            SettingsUtils.BindCheckboxPref(panel, "PLAYER_STANCE_COLORS_CHECKBOX", gs, "UsePlayerStanceColors");
            if (panel.GetOrNull <CheckboxWidget>("PAUSE_SHELLMAP_CHECKBOX") != null)
            {
                SettingsUtils.BindCheckboxPref(panel, "PAUSE_SHELLMAP_CHECKBOX", gs, "PauseShellmap");
            }

            var windowModeDropdown = panel.Get <DropDownButtonWidget>("MODE_DROPDOWN");

            windowModeDropdown.OnMouseDown = _ => ShowWindowModeDropdown(windowModeDropdown, ds);
            windowModeDropdown.GetText     = () => ds.Mode == WindowMode.Windowed ?
                                             "Windowed" : ds.Mode == WindowMode.Fullscreen ? "Fullscreen (Legacy)" : "Fullscreen";

            var displaySelectionDropDown = panel.Get <DropDownButtonWidget>("DISPLAY_SELECTION_DROPDOWN");

            displaySelectionDropDown.OnMouseDown = _ => ShowDisplaySelectionDropdown(displaySelectionDropDown, ds);
            var displaySelectionLabel = new CachedTransform <int, string>(i => $"Display {i + 1}");

            displaySelectionDropDown.GetText    = () => displaySelectionLabel.Update(ds.VideoDisplay);
            displaySelectionDropDown.IsDisabled = () => Game.Renderer.DisplayCount < 2;

            var glProfileLabel    = new CachedTransform <GLProfile, string>(p => p.ToString());
            var glProfileDropdown = panel.Get <DropDownButtonWidget>("GL_PROFILE_DROPDOWN");
            var disableProfile    = Game.Renderer.SupportedGLProfiles.Length < 2 && ds.GLProfile == GLProfile.Automatic;

            glProfileDropdown.OnMouseDown = _ => ShowGLProfileDropdown(glProfileDropdown, ds);
            glProfileDropdown.GetText     = () => glProfileLabel.Update(ds.GLProfile);
            glProfileDropdown.IsDisabled  = () => disableProfile;

            var statusBarsDropDown = panel.Get <DropDownButtonWidget>("STATUS_BAR_DROPDOWN");

            statusBarsDropDown.OnMouseDown = _ => ShowStatusBarsDropdown(statusBarsDropDown, gs);
            statusBarsDropDown.GetText     = () => gs.StatusBars == StatusBarsType.Standard ?
                                             "Standard" : gs.StatusBars == StatusBarsType.DamageShow ? "Show On Damage" : "Always Show";

            var targetLinesDropDown = panel.Get <DropDownButtonWidget>("TARGET_LINES_DROPDOWN");

            targetLinesDropDown.OnMouseDown = _ => ShowTargetLinesDropdown(targetLinesDropDown, gs);
            targetLinesDropDown.GetText     = () => gs.TargetLines == TargetLinesType.Automatic ?
                                              "Automatic" : gs.TargetLines == TargetLinesType.Manual ? "Manual" : "Disabled";

            var battlefieldCameraDropDown = panel.Get <DropDownButtonWidget>("BATTLEFIELD_CAMERA_DROPDOWN");
            var battlefieldCameraLabel    = new CachedTransform <WorldViewport, string>(vs => ViewportSizeNames[vs]);

            battlefieldCameraDropDown.OnMouseDown = _ => ShowBattlefieldCameraDropdown(battlefieldCameraDropDown, viewportSizes, ds);
            battlefieldCameraDropDown.GetText     = () => battlefieldCameraLabel.Update(ds.ViewportDistance);

            BindTextNotificationPoolFilterSettings(panel, gs);

            // Update vsync immediately
            var vsyncCheckbox = panel.Get <CheckboxWidget>("VSYNC_CHECKBOX");
            var vsyncOnClick  = vsyncCheckbox.OnClick;

            vsyncCheckbox.OnClick = () =>
            {
                vsyncOnClick();
                Game.Renderer.SetVSyncEnabled(ds.VSync);
            };

            var uiScaleDropdown = panel.Get <DropDownButtonWidget>("UI_SCALE_DROPDOWN");
            var uiScaleLabel    = new CachedTransform <float, string>(s => $"{(int)(100 * s)}%");

            uiScaleDropdown.OnMouseDown = _ => ShowUIScaleDropdown(uiScaleDropdown, ds);
            uiScaleDropdown.GetText     = () => uiScaleLabel.Update(ds.UIScale);

            var minResolution  = viewportSizes.MinEffectiveResolution;
            var resolution     = Game.Renderer.Resolution;
            var disableUIScale = worldRenderer.World.Type != WorldType.Shellmap ||
                                 resolution.Width * ds.UIScale < 1.25f * minResolution.Width ||
                                 resolution.Height * ds.UIScale < 1.25f * minResolution.Height;

            uiScaleDropdown.IsDisabled = () => disableUIScale;

            panel.Get("DISPLAY_SELECTION").IsVisible = () => ds.Mode != WindowMode.Windowed;
            panel.Get("WINDOW_RESOLUTION").IsVisible = () => ds.Mode == WindowMode.Windowed;
            var windowWidth   = panel.Get <TextFieldWidget>("WINDOW_WIDTH");
            var origWidthText = windowWidth.Text = ds.WindowedSize.X.ToString();

            var windowHeight   = panel.Get <TextFieldWidget>("WINDOW_HEIGHT");
            var origHeightText = windowHeight.Text = ds.WindowedSize.Y.ToString();

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

            var restartDesc = panel.Get("RESTART_REQUIRED_DESC");

            restartDesc.IsVisible = () => ds.Mode != OriginalGraphicsMode || ds.VideoDisplay != OriginalVideoDisplay || ds.GLProfile != OriginalGLProfile ||
                                    (ds.Mode == WindowMode.Windowed && (origWidthText != windowWidth.Text || origHeightText != windowHeight.Text));

            var frameLimitCheckbox  = panel.Get <CheckboxWidget>("FRAME_LIMIT_CHECKBOX");
            var frameLimitOrigLabel = frameLimitCheckbox.Text;
            var frameLimitLabel     = new CachedTransform <int, string>(fps => frameLimitOrigLabel + $" ({fps} FPS)");

            frameLimitCheckbox.GetText = () => frameLimitLabel.Update(ds.MaxFramerate);

            // Player profile
            var ps = Game.Settings.Player;

            var escPressed    = false;
            var nameTextfield = panel.Get <TextFieldWidget>("PLAYERNAME");

            nameTextfield.IsDisabled  = () => worldRenderer.World.Type != WorldType.Shellmap;
            nameTextfield.Text        = Settings.SanitizedPlayerName(ps.Name);
            nameTextfield.OnLoseFocus = () =>
            {
                if (escPressed)
                {
                    escPressed = false;
                    return;
                }

                nameTextfield.Text = nameTextfield.Text.Trim();
                if (nameTextfield.Text.Length == 0)
                {
                    nameTextfield.Text = Settings.SanitizedPlayerName(ps.Name);
                }
                else
                {
                    nameTextfield.Text = Settings.SanitizedPlayerName(nameTextfield.Text);
                    ps.Name            = nameTextfield.Text;
                }
            };

            nameTextfield.OnEnterKey = _ => { nameTextfield.YieldKeyboardFocus(); return(true); };
            nameTextfield.OnEscKey   = _ =>
            {
                nameTextfield.Text = Settings.SanitizedPlayerName(ps.Name);
                escPressed         = true;
                nameTextfield.YieldKeyboardFocus();
                return(true);
            };

            var colorManager = modData.DefaultRules.Actors[SystemActors.World].TraitInfo <ColorPickerManagerInfo>();

            colorManager.Color = ps.Color;

            var colorDropdown = panel.Get <DropDownButtonWidget>("PLAYERCOLOR");

            colorDropdown.IsDisabled  = () => worldRenderer.World.Type != WorldType.Shellmap;
            colorDropdown.OnMouseDown = _ => ColorPickerLogic.ShowColorDropDown(colorDropdown, colorManager, worldRenderer, () =>
            {
                Game.Settings.Player.Color = colorManager.Color;
                Game.Settings.Save();
            });
            colorDropdown.Get <ColorBlockWidget>("COLORBLOCK").GetColor = () => ps.Color;

            return(() =>
            {
                Exts.TryParseIntegerInvariant(windowWidth.Text, out var x);
                Exts.TryParseIntegerInvariant(windowHeight.Text, out var y);
                ds.WindowedSize = new int2(x, y);
                nameTextfield.YieldKeyboardFocus();

                return ds.Mode != OriginalGraphicsMode ||
                ds.VideoDisplay != OriginalVideoDisplay ||
                ds.WindowedSize != OriginalGraphicsWindowedSize ||
                ds.FullscreenSize != OriginalGraphicsFullscreenSize ||
                ds.GLProfile != OriginalGLProfile;
            });
        }
Exemple #17
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;
            };
        }
        public ProductionTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, Player player, Func <ProductionIcon> getTooltipIcon)
        {
            var world    = player.World;
            var mapRules = world.Map.Rules;
            var pm       = player.PlayerActor.TraitOrDefault <PowerManager>();
            var pr       = player.PlayerActor.Trait <PlayerResources>();

            widget.IsVisible = () => getTooltipIcon() != null && getTooltipIcon().Actor != null;
            var nameLabel     = widget.Get <LabelWidget>("NAME");
            var hotkeyLabel   = widget.Get <LabelWidget>("HOTKEY");
            var requiresLabel = widget.Get <LabelWidget>("REQUIRES");
            var powerLabel    = widget.Get <LabelWidget>("POWER");
            var powerIcon     = widget.Get <ImageWidget>("POWER_ICON");
            var timeLabel     = widget.Get <LabelWidget>("TIME");
            var timeIcon      = widget.Get <ImageWidget>("TIME_ICON");
            var costLabel     = widget.Get <LabelWidget>("COST");
            var costIcon      = widget.Get <ImageWidget>("COST_ICON");
            var descLabel     = widget.Get <LabelWidget>("DESC");

            var iconMargin = timeIcon.Bounds.X;

            var font            = Game.Renderer.Fonts[nameLabel.Font];
            var descFont        = Game.Renderer.Fonts[descLabel.Font];
            var requiresFont    = Game.Renderer.Fonts[requiresLabel.Font];
            var formatBuildTime = new CachedTransform <int, string>(time => WidgetUtils.FormatTime(time, world.Timestep));
            var requiresFormat  = requiresLabel.Text;

            ActorInfo lastActor        = null;
            Hotkey    lastHotkey       = Hotkey.Invalid;
            var       lastPowerState   = pm?.PowerState ?? PowerState.Normal;
            var       descLabelY       = descLabel.Bounds.Y;
            var       descLabelPadding = descLabel.Bounds.Height;

            tooltipContainer.BeforeRender = () =>
            {
                var tooltipIcon = getTooltipIcon();

                var actor = tooltipIcon?.Actor;
                if (actor == null)
                {
                    return;
                }

                var hotkey = tooltipIcon.Hotkey?.GetValue() ?? Hotkey.Invalid;
                if (actor == lastActor && hotkey == lastHotkey && (pm == null || pm.PowerState == lastPowerState))
                {
                    return;
                }

                var tooltip   = actor.TraitInfos <TooltipInfo>().FirstOrDefault(info => info.EnabledByDefault);
                var name      = tooltip?.Name ?? actor.Name;
                var buildable = actor.TraitInfo <BuildableInfo>();

                var cost = 0;
                if (tooltipIcon.ProductionQueue != null)
                {
                    cost = tooltipIcon.ProductionQueue.GetProductionCost(actor);
                }
                else
                {
                    var valued = actor.TraitInfoOrDefault <ValuedInfo>();
                    if (valued != null)
                    {
                        cost = valued.Cost;
                    }
                }

                nameLabel.Text = name;

                var nameSize    = font.Measure(name);
                var hotkeyWidth = 0;
                hotkeyLabel.Visible = hotkey.IsValid();

                if (hotkeyLabel.Visible)
                {
                    var hotkeyText = "({0})".F(hotkey.DisplayString());

                    hotkeyWidth          = font.Measure(hotkeyText).X + 2 * nameLabel.Bounds.X;
                    hotkeyLabel.Text     = hotkeyText;
                    hotkeyLabel.Bounds.X = nameSize.X + 2 * nameLabel.Bounds.X;
                }

                var prereqs = buildable.Prerequisites.Select(a => ActorName(mapRules, a))
                              .Where(s => !s.StartsWith("~", StringComparison.Ordinal) && !s.StartsWith("!", StringComparison.Ordinal));

                var requiresSize = int2.Zero;
                if (prereqs.Any())
                {
                    requiresLabel.Text    = requiresFormat.F(prereqs.JoinWith(", "));
                    requiresSize          = requiresFont.Measure(requiresLabel.Text);
                    requiresLabel.Visible = true;
                    descLabel.Bounds.Y    = descLabelY + requiresLabel.Bounds.Height;
                }
                else
                {
                    requiresLabel.Visible = false;
                    descLabel.Bounds.Y    = descLabelY;
                }

                var powerSize = new int2(0, 0);
                if (pm != null)
                {
                    var power = actor.TraitInfos <PowerInfo>().Where(i => i.EnabledByDefault).Sum(i => i.Amount);
                    powerLabel.Text     = power.ToString();
                    powerLabel.GetColor = () => ((pm.PowerProvided - pm.PowerDrained) >= -power || power > 0)
                                                ? Color.White : Color.Red;
                    powerLabel.Visible = power != 0;
                    powerIcon.Visible  = power != 0;
                    powerSize          = font.Measure(powerLabel.Text);
                }

                var buildTime    = tooltipIcon.ProductionQueue?.GetBuildTime(actor, buildable) ?? 0;
                var timeModifier = pm != null && pm.PowerState != PowerState.Normal ? tooltipIcon.ProductionQueue.Info.LowPowerModifier : 100;

                timeLabel.Text      = formatBuildTime.Update((buildTime * timeModifier) / 100);
                timeLabel.TextColor = (pm != null && pm.PowerState != PowerState.Normal && tooltipIcon.ProductionQueue.Info.LowPowerModifier > 100) ? Color.Red : Color.White;
                var timeSize = font.Measure(timeLabel.Text);

                costLabel.Text     = cost.ToString();
                costLabel.GetColor = () => pr.Cash + pr.Resources >= cost ? Color.White : Color.Red;
                var costSize = font.Measure(costLabel.Text);

                descLabel.Text = buildable.Description.Replace("\\n", "\n");
                var descSize = descFont.Measure(descLabel.Text);
                descLabel.Bounds.Width  = descSize.X;
                descLabel.Bounds.Height = descSize.Y + descLabelPadding;

                var leftWidth = new[] { nameSize.X + hotkeyWidth, requiresSize.X, descSize.X }.Aggregate(Math.Max);
                var rightWidth = new[] { powerSize.X, timeSize.X, costSize.X }.Aggregate(Math.Max);

                timeIcon.Bounds.X   = powerIcon.Bounds.X = costIcon.Bounds.X = leftWidth + 2 * nameLabel.Bounds.X;
                timeLabel.Bounds.X  = powerLabel.Bounds.X = costLabel.Bounds.X = timeIcon.Bounds.Right + iconMargin;
                widget.Bounds.Width = leftWidth + rightWidth + 3 * nameLabel.Bounds.X + timeIcon.Bounds.Width + iconMargin;

                // Set the bottom margin to match the left margin
                var leftHeight = descLabel.Bounds.Bottom + descLabel.Bounds.X;

                // Set the bottom margin to match the top margin
                var rightHeight = (powerLabel.Visible ? powerIcon.Bounds.Bottom : timeIcon.Bounds.Bottom) + costIcon.Bounds.Top;

                widget.Bounds.Height = Math.Max(leftHeight, rightHeight);

                lastActor  = actor;
                lastHotkey = hotkey;
                if (pm != null)
                {
                    lastPowerState = pm.PowerState;
                }
            };
        }
Exemple #19
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);
                }
            }
        }
Exemple #20
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);
                }
            }
        }
        public ProductionTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, Player player, Func <ProductionIcon> getTooltipIcon)
        {
            var world    = player.World;
            var mapRules = world.Map.Rules;
            var pm       = player.PlayerActor.Trait <PowerManager>();
            var pr       = player.PlayerActor.Trait <PlayerResources>();

            widget.IsVisible = () => getTooltipIcon() != null && getTooltipIcon().Actor != null;
            var nameLabel     = widget.Get <LabelWidget>("NAME");
            var hotkeyLabel   = widget.Get <LabelWidget>("HOTKEY");
            var requiresLabel = widget.Get <LabelWidget>("REQUIRES");
            var powerLabel    = widget.Get <LabelWidget>("POWER");
            var powerIcon     = widget.Get <ImageWidget>("POWER_ICON");
            var timeLabel     = widget.Get <LabelWidget>("TIME");
            var timeIcon      = widget.Get <ImageWidget>("TIME_ICON");
            var costLabel     = widget.Get <LabelWidget>("COST");
            var costIcon      = widget.Get <ImageWidget>("COST_ICON");
            var descLabel     = widget.Get <LabelWidget>("DESC");

            var iconMargin = timeIcon.Bounds.X;

            var font            = Game.Renderer.Fonts[nameLabel.Font];
            var descFont        = Game.Renderer.Fonts[descLabel.Font];
            var requiresFont    = Game.Renderer.Fonts[requiresLabel.Font];
            var formatBuildTime = new CachedTransform <int, string>(time => WidgetUtils.FormatTime(time, world.Timestep));
            var requiresFormat  = requiresLabel.Text;

            ActorInfo lastActor      = null;
            Hotkey    lastHotkey     = Hotkey.Invalid;
            var       lastPowerState = pm.PowerState;

            tooltipContainer.BeforeRender = () =>
            {
                var tooltipIcon = getTooltipIcon();
                if (tooltipIcon == null)
                {
                    return;
                }

                var actor = tooltipIcon.Actor;
                if (actor == null)
                {
                    return;
                }

                var hotkey = tooltipIcon.Hotkey != null?tooltipIcon.Hotkey.GetValue() : Hotkey.Invalid;

                if (actor == lastActor && hotkey == lastHotkey && pm.PowerState == lastPowerState)
                {
                    return;
                }

                var tooltip   = actor.TraitInfos <TooltipInfo>().FirstOrDefault(Exts.IsTraitEnabled);
                var name      = tooltip != null ? tooltip.Name : actor.Name;
                var buildable = actor.TraitInfo <BuildableInfo>();
                var cost      = actor.TraitInfo <ValuedInfo>().Cost;

                nameLabel.Text = name;

                var nameSize    = font.Measure(name);
                var hotkeyWidth = 0;
                hotkeyLabel.Visible = hotkey.IsValid();

                if (hotkeyLabel.Visible)
                {
                    var hotkeyText = "({0})".F(hotkey.DisplayString());

                    hotkeyWidth          = font.Measure(hotkeyText).X + 2 * nameLabel.Bounds.X;
                    hotkeyLabel.Text     = hotkeyText;
                    hotkeyLabel.Bounds.X = nameSize.X + 2 * nameLabel.Bounds.X;
                }

                var prereqs = buildable.Prerequisites.Select(a => ActorName(mapRules, a)).Where(s => !s.StartsWith("~", StringComparison.Ordinal));
                requiresLabel.Text = prereqs.Any() ? requiresFormat.F(prereqs.JoinWith(", ")) : "";
                var requiresSize = requiresFont.Measure(requiresLabel.Text);

                var power = actor.TraitInfos <PowerInfo>().Where(i => i.EnabledByDefault).Sum(i => i.Amount);
                powerLabel.Text     = power.ToString();
                powerLabel.GetColor = () => ((pm.PowerProvided - pm.PowerDrained) >= -power || power > 0)
                                        ? Color.White : Color.Red;
                powerLabel.Visible = power != 0;
                powerIcon.Visible  = power != 0;
                var powerSize = font.Measure(powerLabel.Text);

                var buildTime      = tooltipIcon.ProductionQueue == null ? 0 : tooltipIcon.ProductionQueue.GetBuildTime(actor, buildable);
                var timeMultiplier = pm.PowerState != PowerState.Normal ? tooltipIcon.ProductionQueue.Info.LowPowerSlowdown : 1;

                timeLabel.Text      = formatBuildTime.Update(buildTime * timeMultiplier);
                timeLabel.TextColor = pm.PowerState != PowerState.Normal ? Color.Red : Color.White;
                var timeSize = font.Measure(timeLabel.Text);

                costLabel.Text     = cost.ToString();
                costLabel.GetColor = () => pr.Cash + pr.Resources >= cost ? Color.White : Color.Red;
                var costSize = font.Measure(costLabel.Text);

                descLabel.Text = buildable.Description.Replace("\\n", "\n");
                var descSize = descFont.Measure(descLabel.Text);

                var leftWidth = new[] { nameSize.X + hotkeyWidth, requiresSize.X, descSize.X }.Aggregate(Math.Max);
                var rightWidth = new[] { powerSize.X, timeSize.X, costSize.X }.Aggregate(Math.Max);

                timeIcon.Bounds.X   = powerIcon.Bounds.X = costIcon.Bounds.X = leftWidth + 2 * nameLabel.Bounds.X;
                timeLabel.Bounds.X  = powerLabel.Bounds.X = costLabel.Bounds.X = timeIcon.Bounds.Right + iconMargin;
                widget.Bounds.Width = leftWidth + rightWidth + 3 * nameLabel.Bounds.X + timeIcon.Bounds.Width + iconMargin;

                var leftHeight  = nameSize.Y + requiresSize.Y + descSize.Y;
                var rightHeight = powerSize.Y + timeSize.Y + costSize.Y;
                widget.Bounds.Height = Math.Max(leftHeight, rightHeight) * 3 / 2 + 3 * nameLabel.Bounds.Y;

                lastActor      = actor;
                lastHotkey     = hotkey;
                lastPowerState = pm.PowerState;
            };
        }
		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();
			}
		}
Exemple #23
0
        public ReplayBrowserLogic(Widget widget, ModData modData, Action onExit, Action onStart)
        {
            map   = MapCache.UnknownMap;
            panel = widget;

            services              = modData.Manifest.Get <WebServices>();
            this.modData          = modData;
            this.onStart          = onStart;
            Game.BeforeGameStart += OnGameStart;

            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 = modData.Manifest;
            var dir = Path.Combine(Platform.SupportDir, "Replays", mod.Id, mod.Metadata.Version);

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

            var watch = panel.Get <ButtonWidget>("WATCH_BUTTON");

            watch.IsDisabled = () => selectedReplay == null || map.Status != MapStatus.Available;
            watch.OnClick    = () => { WatchReplay(); };

            var mapPreviewRoot = panel.Get("MAP_PREVIEW_ROOT");

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

            var spawnOccupants = new CachedTransform <ReplayMetadata, Dictionary <int, SpawnOccupant> >(r =>
            {
                // Avoid using .ToDictionary to improve robustness against replays defining duplicate spawn assignments
                var occupants = new Dictionary <int, SpawnOccupant>();
                foreach (var p in r.GameInfo.Players)
                {
                    if (p.SpawnPoint != 0)
                    {
                        occupants[p.SpawnPoint] = new SpawnOccupant(p);
                    }
                }

                return(occupants);
            });

            var noSpawns            = new HashSet <int>();
            var disabledSpawnPoints = new CachedTransform <ReplayMetadata, HashSet <int> >(r => r.GameInfo.DisabledSpawnPoints ?? noSpawns);

            Ui.LoadWidget("MAP_PREVIEW", mapPreviewRoot, new WidgetArgs
            {
                { "orderManager", null },
                { "getMap", (Func <MapPreview>)(() => map) },
                { "onMouseDown", (Action <MapPreviewWidget, MapPreview, MouseInput>)((preview, mapPreview, mi) => { }) },
                { "getSpawnOccupants", (Func <Dictionary <int, SpawnOccupant> >)(() => spawnOccupants.Update(selectedReplay)) },
                { "getDisabledSpawnPoints", (Func <HashSet <int> >)(() => disabledSpawnPoints.Update(selectedReplay)) },
                { "showUnoccupiedSpawnpoints", false },
            });

            var replayDuration = new CachedTransform <ReplayMetadata, string>(r =>
                                                                              "Duration: {0}".F(WidgetUtils.FormatTimeSeconds((int)selectedReplay.GameInfo.Duration.TotalSeconds)));

            panel.Get <LabelWidget>("DURATION").GetText = () => replayDuration.Update(selectedReplay);

            SetupFilters();
            SetupManagement();
        }
        public ServerCreationLogic(Widget widget, ModData modData, Action onExit, Action openLobby)
        {
            panel       = widget;
            onCreate    = openLobby;
            this.onExit = onExit;

            var settings = Game.Settings;

            preview = modData.MapCache[modData.MapCache.ChooseInitialMap(Game.Settings.Server.Map, Game.CosmeticRandom)];

            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 = 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.AllowPortForward;

            var labelUPnP = panel.GetOrNull <LabelWidget>("UPNP_NOTICE");

            if (labelUPnP != null)
            {
                labelUPnP.IsVisible = () => !Game.Settings.Server.DiscoverNatDevices;
            }

            var labelUPnPUnsupported = panel.GetOrNull <LabelWidget>("UPNP_UNSUPPORTED_NOTICE");

            if (labelUPnPUnsupported != null)
            {
                labelUPnPUnsupported.IsVisible = () => Game.Settings.Server.DiscoverNatDevices && !Game.Settings.Server.AllowPortForward;
            }

            var passwordField = panel.GetOrNull <PasswordFieldWidget>("PASSWORD");

            if (passwordField != null)
            {
                passwordField.Text = Game.Settings.Server.Password;
            }
        }
Exemple #25
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 filtersPanel        = Ui.LoadWidget("MULTIPLAYER_FILTER_PANEL", null, new WidgetArgs());
            var showWaitingCheckbox = filtersPanel.GetOrNull <CheckboxWidget>("WAITING_FOR_PLAYERS");

            if (showWaitingCheckbox != null)
            {
                showWaitingCheckbox.IsChecked = () => showWaiting;
                showWaitingCheckbox.OnClick   = () => { showWaiting ^= true; RefreshServerList(); };
            }

            var showEmptyCheckbox = filtersPanel.GetOrNull <CheckboxWidget>("EMPTY");

            if (showEmptyCheckbox != null)
            {
                showEmptyCheckbox.IsChecked = () => showEmpty;
                showEmptyCheckbox.OnClick   = () => { showEmpty ^= true; RefreshServerList(); };
            }

            var showAlreadyStartedCheckbox = filtersPanel.GetOrNull <CheckboxWidget>("ALREADY_STARTED");

            if (showAlreadyStartedCheckbox != null)
            {
                showAlreadyStartedCheckbox.IsChecked = () => showStarted;
                showAlreadyStartedCheckbox.OnClick   = () => { showStarted ^= true; RefreshServerList(); };
            }

            var showProtectedCheckbox = filtersPanel.GetOrNull <CheckboxWidget>("PASSWORD_PROTECTED");

            if (showProtectedCheckbox != null)
            {
                showProtectedCheckbox.IsChecked = () => showProtected;
                showProtectedCheckbox.OnClick   = () => { showProtected ^= true; RefreshServerList(); };
            }

            var showIncompatibleCheckbox = filtersPanel.GetOrNull <CheckboxWidget>("INCOMPATIBLE_VERSION");

            if (showIncompatibleCheckbox != null)
            {
                showIncompatibleCheckbox.IsChecked = () => showIncompatible;
                showIncompatibleCheckbox.OnClick   = () => { showIncompatible ^= true; RefreshServerList(); };
            }

            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 #26
0
        public AssetBrowserLogic(Widget widget, Action onExit, ModData modData, World world, Dictionary <string, MiniYaml> logicArgs)
        {
            this.world   = world;
            this.modData = modData;
            panel        = widget;

            var ticker = panel.GetOrNull <LogicTickerWidget>("ANIMATION_TICKER");

            if (ticker != null)
            {
                ticker.OnTick = () =>
                {
                    if (animateFrames)
                    {
                        SelectNextFrame();
                    }
                };
            }

            var sourceDropdown = panel.GetOrNull <DropDownButtonWidget>("SOURCE_SELECTOR");

            if (sourceDropdown != null)
            {
                sourceDropdown.OnMouseDown = _ => ShowSourceDropdown(sourceDropdown);
                var sourceName = new CachedTransform <IReadOnlyPackage, string>(GetSourceDisplayName);
                sourceDropdown.GetText = () => sourceName.Update(assetSource);
            }

            var spriteWidget = panel.GetOrNull <SpriteWidget>("SPRITE");

            if (spriteWidget != null)
            {
                spriteWidget.GetSprite  = () => currentSprites != null ? currentSprites[currentFrame] : null;
                currentPalette          = spriteWidget.Palette;
                spriteWidget.GetPalette = () => currentPalette;
                spriteWidget.IsVisible  = () => !isVideoLoaded && !isLoadError && currentSprites != null;
            }

            var playerWidget = panel.GetOrNull <VideoPlayerWidget>("PLAYER");

            if (playerWidget != null)
            {
                playerWidget.IsVisible = () => isVideoLoaded && !isLoadError;
            }

            var modelWidget = panel.GetOrNull <ModelWidget>("VOXEL");

            if (modelWidget != null)
            {
                modelWidget.GetVoxel         = () => currentVoxel;
                currentPalette               = modelWidget.Palette;
                modelWidget.GetPalette       = () => currentPalette;
                modelWidget.GetPlayerPalette = () => currentPalette;
                modelWidget.GetRotation      = () => modelOrientation;
                modelWidget.IsVisible        = () => !isVideoLoaded && !isLoadError && currentVoxel != null;
            }

            var errorLabelWidget = panel.GetOrNull("ERROR");

            if (errorLabelWidget != null)
            {
                errorLabelWidget.IsVisible = () => isLoadError;
            }

            var paletteDropDown = panel.GetOrNull <DropDownButtonWidget>("PALETTE_SELECTOR");

            if (paletteDropDown != null)
            {
                paletteDropDown.OnMouseDown = _ => ShowPaletteDropdown(paletteDropDown, world);
                paletteDropDown.GetText     = () => currentPalette;
            }

            var colorPreview = panel.GetOrNull <ColorPreviewManagerWidget>("COLOR_MANAGER");

            if (colorPreview != null)
            {
                colorPreview.Color = Game.Settings.Player.Color;
            }

            var colorDropdown = panel.GetOrNull <DropDownButtonWidget>("COLOR");

            if (colorDropdown != null)
            {
                colorDropdown.IsDisabled  = () => currentPalette != colorPreview.PaletteName;
                colorDropdown.OnMouseDown = _ => ColorPickerLogic.ShowColorDropDown(colorDropdown, colorPreview, world);
                panel.Get <ColorBlockWidget>("COLORBLOCK").GetColor = () => Game.Settings.Player.Color;
            }

            filenameInput = panel.Get <TextFieldWidget>("FILENAME_INPUT");
            filenameInput.OnTextEdited = () => ApplyFilter();
            filenameInput.OnEscKey     = filenameInput.YieldKeyboardFocus;

            var frameContainer = panel.GetOrNull("FRAME_SELECTOR");

            if (frameContainer != null)
            {
                frameContainer.IsVisible = () => (currentSprites != null && currentSprites.Length > 1) ||
                                           (isVideoLoaded && player != null && player.Video != null && player.Video.Frames > 1);
            }

            frameSlider = panel.GetOrNull <SliderWidget>("FRAME_SLIDER");
            if (frameSlider != null)
            {
                frameSlider.OnChange += x =>
                {
                    if (!isVideoLoaded)
                    {
                        currentFrame = (int)Math.Round(x);
                    }
                };

                frameSlider.GetValue   = () => isVideoLoaded ? player.Video.CurrentFrame : currentFrame;
                frameSlider.IsDisabled = () => isVideoLoaded;
            }

            var frameText = panel.GetOrNull <LabelWidget>("FRAME_COUNT");

            if (frameText != null)
            {
                frameText.GetText = () =>
                                    isVideoLoaded ? $"{player.Video.CurrentFrame + 1} / {player.Video.Frames}"
                                                : $"{currentFrame} / {currentSprites.Length - 1}";
            }

            var playButton = panel.GetOrNull <ButtonWidget>("BUTTON_PLAY");

            if (playButton != null)
            {
                playButton.OnClick = () =>
                {
                    if (isVideoLoaded)
                    {
                        player.Play();
                    }
                    else
                    {
                        animateFrames = true;
                    }
                };

                playButton.IsVisible = () => isVideoLoaded ? player.Paused : !animateFrames;
            }

            var pauseButton = panel.GetOrNull <ButtonWidget>("BUTTON_PAUSE");

            if (pauseButton != null)
            {
                pauseButton.OnClick = () =>
                {
                    if (isVideoLoaded)
                    {
                        player.Pause();
                    }
                    else
                    {
                        animateFrames = false;
                    }
                };

                pauseButton.IsVisible = () => isVideoLoaded ? !player.Paused : animateFrames;
            }

            var stopButton = panel.GetOrNull <ButtonWidget>("BUTTON_STOP");

            if (stopButton != null)
            {
                stopButton.OnClick = () =>
                {
                    if (isVideoLoaded)
                    {
                        player.Stop();
                    }
                    else
                    {
                        if (frameSlider != null)
                        {
                            frameSlider.Value = 0;
                        }

                        currentFrame  = 0;
                        animateFrames = false;
                    }
                };
            }

            var nextButton = panel.GetOrNull <ButtonWidget>("BUTTON_NEXT");

            if (nextButton != null)
            {
                nextButton.OnClick = () =>
                {
                    if (!isVideoLoaded)
                    {
                        nextButton.OnClick = SelectNextFrame;
                    }
                };

                nextButton.IsVisible = () => !isVideoLoaded;
            }

            var prevButton = panel.GetOrNull <ButtonWidget>("BUTTON_PREV");

            if (prevButton != null)
            {
                prevButton.OnClick = () =>
                {
                    if (!isVideoLoaded)
                    {
                        SelectPreviousFrame();
                    }
                };

                prevButton.IsVisible = () => !isVideoLoaded;
            }

            var voxelContainer = panel.GetOrNull("VOXEL_SELECTOR");

            if (voxelContainer != null)
            {
                voxelContainer.IsVisible = () => currentVoxel != null;
            }

            var rollSlider = panel.GetOrNull <SliderWidget>("ROLL_SLIDER");

            if (rollSlider != null)
            {
                rollSlider.OnChange += x =>
                {
                    var roll = (int)x;
                    modelOrientation = modelOrientation.WithRoll(new WAngle(roll));
                };

                rollSlider.GetValue = () => modelOrientation.Roll.Angle;
            }

            var pitchSlider = panel.GetOrNull <SliderWidget>("PITCH_SLIDER");

            if (pitchSlider != null)
            {
                pitchSlider.OnChange += x =>
                {
                    var pitch = (int)x;
                    modelOrientation = modelOrientation.WithPitch(new WAngle(pitch));
                };

                pitchSlider.GetValue = () => modelOrientation.Pitch.Angle;
            }

            var yawSlider = panel.GetOrNull <SliderWidget>("YAW_SLIDER");

            if (yawSlider != null)
            {
                yawSlider.OnChange += x =>
                {
                    var yaw = (int)x;
                    modelOrientation = modelOrientation.WithYaw(new WAngle(yaw));
                };

                yawSlider.GetValue = () => modelOrientation.Yaw.Angle;
            }

            var assetBrowserModData = modData.Manifest.Get <AssetBrowser>();

            allowedExtensions = assetBrowserModData.SupportedExtensions;

            acceptablePackages = modData.ModFiles.MountedPackages.Where(p =>
                                                                        p.Contents.Any(c => allowedExtensions.Contains(Path.GetExtension(c).ToLowerInvariant())));

            assetList = panel.Get <ScrollPanelWidget>("ASSET_LIST");
            template  = panel.Get <ScrollItemWidget>("ASSET_TEMPLATE");
            PopulateAssetList();

            var closeButton = panel.GetOrNull <ButtonWidget>("CLOSE_BUTTON");

            if (closeButton != null)
            {
                closeButton.OnClick = () =>
                {
                    if (isVideoLoaded)
                    {
                        player.Stop();
                    }
                    Ui.CloseWindow();
                    onExit();
                }
            }
            ;
        }

        void SelectNextFrame()
        {
            currentFrame++;
            if (currentFrame >= currentSprites.Length)
            {
                currentFrame = 0;
            }
        }

        void SelectPreviousFrame()
        {
            currentFrame--;
            if (currentFrame < 0)
            {
                currentFrame = currentSprites.Length - 1;
            }
        }

        Dictionary <string, bool> assetVisByName = new Dictionary <string, bool>();

        bool FilterAsset(string filename)
        {
            var filter = filenameInput.Text;

            if (string.IsNullOrWhiteSpace(filter))
            {
                return(true);
            }

            if (filename.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0)
            {
                return(true);
            }

            return(false);
        }

        void ApplyFilter()
        {
            assetVisByName.Clear();
            assetList.Layout.AdjustChildren();
            assetList.ScrollToTop();

            // Select the first visible
            var firstVisible = assetVisByName.FirstOrDefault(kvp => kvp.Value);

            if (firstVisible.Key != null && modData.DefaultFileSystem.TryGetPackageContaining(firstVisible.Key, out var package, out var filename))
            {
                LoadAsset(package, filename);
            }
        }

        void AddAsset(ScrollPanelWidget list, string filepath, IReadOnlyPackage package, ScrollItemWidget template)
        {
            var item = ScrollItemWidget.Setup(template,
                                              () => currentFilename == filepath && currentPackage == package,
                                              () => { LoadAsset(package, filepath); });

            var label = item.Get <LabelWithTooltipWidget>("TITLE");

            WidgetUtils.TruncateLabelToTooltip(label, filepath);

            item.IsVisible = () =>
            {
                if (assetVisByName.TryGetValue(filepath, out var visible))
                {
                    return(visible);
                }

                visible = FilterAsset(filepath);
                assetVisByName.Add(filepath, visible);
                return(visible);
            };

            list.AddChild(item);
        }

        bool LoadAsset(IReadOnlyPackage package, string filename)
        {
            if (isVideoLoaded)
            {
                player.Stop();
                player        = null;
                isVideoLoaded = false;
            }

            if (string.IsNullOrEmpty(filename))
            {
                return(false);
            }

            if (!package.Contains(filename))
            {
                return(false);
            }

            isLoadError = false;

            try
            {
                currentPackage  = package;
                currentFilename = filename;
                var prefix = "";

                if (modData.DefaultFileSystem is OpenRA.FileSystem.FileSystem fs)
                {
                    prefix = fs.GetPrefix(package);
                    if (prefix != null)
                    {
                        prefix += "|";
                    }
                }

                var video = VideoLoader.GetVideo(Game.ModData.DefaultFileSystem.Open(filename), Game.ModData.VideoLoaders);
                if (video != null)
                {
                    player = panel.Get <VideoPlayerWidget>("PLAYER");
                    player.Load(prefix + filename);
                    player.DrawOverlay = false;
                    isVideoLoaded      = true;

                    if (frameSlider != null)
                    {
                        frameSlider.MaximumValue = (float)player.Video.Frames - 1;
                        frameSlider.Ticks        = 0;
                    }

                    return(true);
                }

                if (Path.GetExtension(filename.ToLowerInvariant()) == ".vxl")
                {
                    var voxelName = Path.GetFileNameWithoutExtension(filename);
                    currentVoxel   = world.ModelCache.GetModel(voxelName);
                    currentSprites = null;
                }
                else
                {
                    currentSprites = world.Map.Rules.Sequences.SpriteCache[prefix + filename];
                    currentFrame   = 0;

                    if (frameSlider != null)
                    {
                        frameSlider.MaximumValue = (float)currentSprites.Length - 1;
                        frameSlider.Ticks        = currentSprites.Length;
                    }

                    currentVoxel = null;
                }
            }
            catch (Exception ex)
            {
                isLoadError = true;
                Log.AddChannel("assetbrowser", "assetbrowser.log");
                Log.Write("assetbrowser", "Error reading {0}:{3} {1}{3}{2}", filename, ex.Message, ex.StackTrace, Environment.NewLine);

                return(false);
            }

            return(true);
        }

        bool ShowSourceDropdown(DropDownButtonWidget dropdown)
        {
            var sourceName = new CachedTransform <IReadOnlyPackage, string>(GetSourceDisplayName);
            Func <IReadOnlyPackage, ScrollItemWidget, ScrollItemWidget> setupItem = (source, itemTemplate) =>
            {
                var item = ScrollItemWidget.Setup(itemTemplate,
                                                  () => assetSource == source,
                                                  () => { assetSource = source; PopulateAssetList(); });

                item.Get <LabelWidget>("LABEL").GetText = () => sourceName.Update(source);
                return(item);
            };

            var sources = new[] { (IReadOnlyPackage)null }.Concat(acceptablePackages);

            dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 280, sources, setupItem);
            return(true);
        }

        void PopulateAssetList()
        {
            assetList.RemoveChildren();

            var files = new SortedList <string, List <IReadOnlyPackage> >();

            if (assetSource != null)
            {
                foreach (var content in assetSource.Contents)
                {
                    files.Add(content, new List <IReadOnlyPackage> {
                        assetSource
                    });
                }
            }
            else
            {
                foreach (var mountedPackage in modData.ModFiles.MountedPackages)
                {
                    foreach (var content in mountedPackage.Contents)
                    {
                        if (!files.ContainsKey(content))
                        {
                            files.Add(content, new List <IReadOnlyPackage> {
                                mountedPackage
                            });
                        }
                        else
                        {
                            files[content].Add(mountedPackage);
                        }
                    }
                }
            }

            foreach (var file in files.OrderBy(s => s.Key))
            {
                if (!allowedExtensions.Any(ext => file.Key.EndsWith(ext, true, CultureInfo.InvariantCulture)))
                {
                    continue;
                }

                foreach (var package in file.Value)
                {
                    AddAsset(assetList, file.Key, package, template);
                }
            }
        }

        bool ShowPaletteDropdown(DropDownButtonWidget dropdown, World world)
        {
            Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (name, itemTemplate) =>
            {
                var item = ScrollItemWidget.Setup(itemTemplate,
                                                  () => currentPalette == name,
                                                  () => currentPalette = name);
                item.Get <LabelWidget>("LABEL").GetText = () => name;

                return(item);
            };

            var palettes = world.WorldActor.TraitsImplementing <IProvidesAssetBrowserPalettes>()
                           .SelectMany(p => p.PaletteNames);

            dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 280, palettes, setupItem);
            return(true);
        }

        string GetSourceDisplayName(IReadOnlyPackage source)
        {
            if (source == null)
            {
                return("All Packages");
            }

            // Packages that are explicitly mounted in the filesystem use their explicit mount name
            var fs   = (OpenRA.FileSystem.FileSystem)modData.DefaultFileSystem;
            var name = fs.GetPrefix(source);

            // Fall back to the path relative to the mod, engine, or support dir
            if (name == null)
            {
                name = source.Name;
                var compare = Platform.CurrentPlatform == PlatformType.Windows ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
                if (name.StartsWith(modData.Manifest.Package.Name, compare))
                {
                    name = "$" + modData.Manifest.Id + "/" + name.Substring(modData.Manifest.Package.Name.Length + 1);
                }
                else if (name.StartsWith(Platform.EngineDir, compare))
                {
                    name = "./" + name.Substring(Platform.EngineDir.Length);
                }
                else if (name.StartsWith(Platform.SupportDir, compare))
                {
                    name = "^" + name.Substring(Platform.SupportDir.Length);
                }
            }

            if (name.Length > 18)
            {
                name = "..." + name.Substring(name.Length - 15);
            }

            return(name);
        }
    }
Exemple #27
0
        public ServerListLogic(Widget widget, ModData modData, Action <GameServer> onJoin)
        {
            this.modData = modData;
            this.onJoin  = onJoin;

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

            incompatibleVersionColor       = ChromeMetrics.Get <Color>("IncompatibleVersionColor");
            incompatibleGameColor          = ChromeMetrics.Get <Color>("IncompatibleGameColor");
            incompatibleProtectedGameColor = ChromeMetrics.Get <Color>("IncompatibleProtectedGameColor");
            protectedGameColor             = ChromeMetrics.Get <Color>("ProtectedGameColor");
            waitingGameColor             = ChromeMetrics.Get <Color>("WaitingGameColor");
            incompatibleWaitingGameColor = ChromeMetrics.Get <Color>("IncompatibleWaitingGameColor");
            gameStartedColor             = ChromeMetrics.Get <Color>("GameStartedColor");
            incompatibleGameStartedColor = ChromeMetrics.Get <Color>("IncompatibleGameStartedColor");

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

            noticeContainer = widget.GetOrNull("NOTICE_CONTAINER");
            if (noticeContainer != null)
            {
                noticeContainer.IsVisible = () => showNotices;
                noticeContainer.Get("OUTDATED_VERSION_LABEL").IsVisible   = () => services.ModVersionStatus == ModVersionStatus.Outdated;
                noticeContainer.Get("UNKNOWN_VERSION_LABEL").IsVisible    = () => services.ModVersionStatus == ModVersionStatus.Unknown;
                noticeContainer.Get("PLAYTEST_AVAILABLE_LABEL").IsVisible = () => services.ModVersionStatus == ModVersionStatus.PlaytestAvailable;
            }

            var noticeWatcher = widget.Get <LogicTickerWidget>("NOTICE_WATCHER");

            if (noticeWatcher != null && noticeContainer != null)
            {
                var containerHeight = noticeContainer.Bounds.Height;
                noticeWatcher.OnTick = () =>
                {
                    var show = services.ModVersionStatus != ModVersionStatus.NotChecked && services.ModVersionStatus != ModVersionStatus.Latest;
                    if (show != showNotices)
                    {
                        var dir = show ? 1 : -1;
                        serverList.Bounds.Y      += dir * containerHeight;
                        serverList.Bounds.Height -= dir * containerHeight;
                        showNotices = show;
                    }
                };
            }

            joinButton = widget.GetOrNull <ButtonWidget>("JOIN_BUTTON");
            if (joinButton != null)
            {
                joinButton.IsVisible  = () => currentServer != null;
                joinButton.IsDisabled = () => !currentServer.IsJoinable;
                joinButton.OnClick    = () => onJoin(currentServer);
                joinButtonY           = joinButton.Bounds.Y;
            }

            // 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 filtersButton = widget.GetOrNull <DropDownButtonWidget>("FILTERS_DROPDOWNBUTTON");

            if (filtersButton != null)
            {
                // HACK: MULTIPLAYER_FILTER_PANEL doesn't follow our normal procedure for dropdown creation
                // but we still need to be able to set the dropdown width based on the parent
                // The yaml should use PARENT_RIGHT instead of DROPDOWN_WIDTH
                var filtersPanel = Ui.LoadWidget("MULTIPLAYER_FILTER_PANEL", filtersButton, new WidgetArgs());
                filtersButton.Children.Remove(filtersPanel);

                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);
                }

                filtersButton.IsDisabled  = () => searchStatus == SearchStatus.Fetching;
                filtersButton.OnMouseDown = _ =>
                {
                    filtersButton.RemovePanel();
                    filtersButton.AttachPanel(filtersPanel);
                };
            }

            var reloadButton = widget.GetOrNull <ButtonWidget>("RELOAD_BUTTON");

            if (reloadButton != null)
            {
                reloadButton.IsDisabled = () => searchStatus == SearchStatus.Fetching;
                reloadButton.OnClick    = RefreshServerList;

                var reloadIcon = reloadButton.GetOrNull <ImageWidget>("IMAGE_RELOAD");
                if (reloadIcon != null)
                {
                    var disabledFrame = 0;
                    var disabledImage = "disabled-" + disabledFrame.ToString();
                    reloadIcon.GetImageName = () => searchStatus == SearchStatus.Fetching ? disabledImage : reloadIcon.ImageName;

                    var reloadTicker = reloadIcon.Get <LogicTickerWidget>("ANIMATION");
                    if (reloadTicker != null)
                    {
                        reloadTicker.OnTick = () =>
                        {
                            disabledFrame = searchStatus == SearchStatus.Fetching ? (disabledFrame + 1) % 12 : 0;
                            disabledImage = "disabled-" + disabledFrame.ToString();
                        };
                    }
                }
            }

            var playersLabel = widget.GetOrNull <LabelWidget>("PLAYER_COUNT");

            if (playersLabel != null)
            {
                var playersText = new CachedTransform <int, string>(c => c == 1 ? "1 Player Online" : c.ToString() + " Players Online");
                playersLabel.IsVisible = () => playerCount != 0;
                playersLabel.GetText   = () => playersText.Update(playerCount);
            }

            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 =>
                                                                     WidgetUtils.TruncateText(m.Title, mapTitle.Bounds.Width, font));

                mapTitle.GetText = () =>
                {
                    if (currentMap == null)
                    {
                        return("No Server Selected");
                    }

                    if (currentMap.Status == MapStatus.Searching)
                    {
                        return("Searching...");
                    }

                    if (currentMap.Class == MapClassification.Unknown)
                    {
                        return("Unknown Map");
                    }

                    return(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, modVersion.Bounds.Width, font));
                modVersion.GetText = () => version.Update(currentServer);
            }

            var players = widget.GetOrNull <LabelWidget>("SELECTED_PLAYERS");

            if (players != null)
            {
                players.IsVisible = () => currentServer != null && (clientContainer == null || !currentServer.Clients.Any());
                players.GetText   = () => PlayersLabel(currentServer);
            }

            clientContainer = widget.GetOrNull("CLIENT_LIST_CONTAINER");
            if (clientContainer != null)
            {
                clientList           = Ui.LoadWidget("MULTIPLAYER_CLIENT_LIST", clientContainer, new WidgetArgs()) as ScrollPanelWidget;
                clientList.IsVisible = () => currentServer != null && currentServer.Clients.Any();
                clientHeader         = clientList.Get <ScrollItemWidget>("HEADER");
                clientTemplate       = clientList.Get <ScrollItemWidget>("TEMPLATE");
                clientList.RemoveChildren();
            }

            lanGameLocations = new List <BeaconLocation>();
            try
            {
                lanGameProbe = new Probe("OpenRALANGame");
                lanGameProbe.BeaconsUpdated += locations => lanGameLocations = locations;
                lanGameProbe.Start();
            }
            catch (Exception ex)
            {
                Log.Write("debug", "BeaconLib.Probe: " + ex.Message);
            }

            RefreshServerList();
        }
Exemple #28
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, OrderManager orderManager, WorldRenderer worldRenderer, Action <bool> hideMenu)
        {
            var player      = 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");
            var spectatorTemplate = playerPanel.Get("SPECTATOR_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");
                    var scoreCache       = new CachedTransform <int, string>(s => s.ToString());
                    var teamMemberScores = t.Select(tt => tt.Second).Where(s => s != null).ToArray().Select(s => s.Experience);
                    teamRating.GetText = () => scoreCache.Update(teamMemberScores.Sum());

                    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.SetupProfileWidget(item, client, orderManager, worldRenderer);

                    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, string>, string>(c =>
                                                                                           WidgetUtils.TruncateText(c.First, nameLabel.Bounds.Width - suffixLength.Update(c.Second), nameFont) + c.Second);

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

                        return(name.Update(Pair.New(pp.PlayerName, suffix)));
                    };
                    nameLabel.GetColor = () => pp.Color;

                    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 scoreCache = new CachedTransform <int, string>(s => s.ToString());
                    item.Get <LabelWidget>("SCORE").GetText = () => scoreCache.Update(p.Second != null ? p.Second.Experience : 0);

                    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 = spectatorTemplate.Clone();
                    LobbyUtils.SetupProfileWidget(item, client, orderManager, worldRenderer);

                    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, string>, string>(c =>
                                                                                           WidgetUtils.TruncateText(c.First, nameLabel.Bounds.Width - suffixLength.Update(c.Second), nameFont) + c.Second);

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

                    var kickButton = item.Get <ButtonWidget>("KICK");
                    kickButton.IsVisible = () => Game.IsHost && client.Index != orderManager.LocalClient.Index && client.State != Session.ClientState.Disconnected;
                    kickButton.OnClick   = () =>
                    {
                        hideMenu(true);
                        ConfirmationDialogs.ButtonPrompt(
                            title: "Kick {0}?".F(client.Name),
                            text: "They will not be able to rejoin this game.",
                            onConfirm: () =>
                        {
                            orderManager.IssueOrder(Order.Command("kick {0} {1}".F(client.Index, false)));
                            hideMenu(false);
                        },
                            onCancel: () => hideMenu(false),
                            confirmText: "Kick");
                    };

                    playerPanel.AddChild(item);
                }
            }
        }
Exemple #30
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 #31
0
        public ServerCreationLogic(Widget widget, ModData modData, Action onExit, Action openLobby)
        {
            panel       = widget;
            onCreate    = openLobby;
            this.onExit = onExit;

            var settings = Game.Settings;

            preview = modData.MapCache[modData.MapCache.ChooseInitialMap(Game.Settings.Server.Map, Game.CosmeticRandom)];

            panel.Get <ButtonWidget>("BACK_BUTTON").OnClick   = () => { Ui.CloseWindow(); onExit(); };
            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 = modData.MapCache[uid]) },
                        { "filter", MapVisibility.Lobby },
                        { "onStart", () => { } }
                    });
                };

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

                var titleLabel = panel.GetOrNull <LabelWithTooltipWidget>("MAP_TITLE");
                if (titleLabel != null)
                {
                    var font  = Game.Renderer.Fonts[titleLabel.Font];
                    var title = new CachedTransform <MapPreview, string>(m =>
                    {
                        var truncated = WidgetUtils.TruncateText(m.Title, titleLabel.Bounds.Width, font);

                        if (m.Title != truncated)
                        {
                            titleLabel.GetTooltipText = () => m.Title;
                        }
                        else
                        {
                            titleLabel.GetTooltipText = null;
                        }

                        return(truncated);
                    });
                    titleLabel.GetText = () => title.Update(preview);
                }

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

                var authorLabel = panel.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 {m.Author}", authorLabel.Bounds.Width, font));
                    authorLabel.GetText = () => author.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 advertiseCheckbox = panel.Get <CheckboxWidget>("ADVERTISE_CHECKBOX");

            advertiseCheckbox.IsChecked = () => advertiseOnline;
            advertiseCheckbox.OnClick   = () =>
            {
                advertiseOnline ^= true;
                BuildNotices();
            };

            var passwordField = panel.GetOrNull <PasswordFieldWidget>("PASSWORD");

            if (passwordField != null)
            {
                passwordField.Text = Game.Settings.Server.Password;
            }

            noticesLabelA = panel.GetOrNull <LabelWidget>("NOTICES_HEADER_A");
            noticesLabelB = panel.GetOrNull <LabelWidget>("NOTICES_HEADER_B");
            noticesLabelC = panel.GetOrNull <LabelWidget>("NOTICES_HEADER_C");

            var noticesNoUPnP = panel.GetOrNull("NOTICES_NO_UPNP");

            if (noticesNoUPnP != null)
            {
                noticesNoUPnP.IsVisible = () => advertiseOnline &&
                                          (Nat.Status == NatStatus.NotSupported || Nat.Status == NatStatus.Disabled);

                var settingsA = noticesNoUPnP.GetOrNull("SETTINGS_A");
                if (settingsA != null)
                {
                    settingsA.IsVisible = () => Nat.Status == NatStatus.Disabled;
                }

                var settingsB = noticesNoUPnP.GetOrNull("SETTINGS_B");
                if (settingsB != null)
                {
                    settingsB.IsVisible = () => Nat.Status == NatStatus.Disabled;
                }
            }

            var noticesUPnP = panel.GetOrNull("NOTICES_UPNP");

            if (noticesUPnP != null)
            {
                noticesUPnP.IsVisible = () => advertiseOnline && Nat.Status == NatStatus.Enabled;
            }

            var noticesLAN = panel.GetOrNull("NOTICES_LAN");

            if (noticesLAN != null)
            {
                noticesLAN.IsVisible = () => !advertiseOnline;
            }

            BuildNotices();
        }
Exemple #32
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 #33
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);
            }
        }
        internal LobbyMapPreviewLogic(Widget widget, OrderManager orderManager, LobbyLogic lobby)
        {
            var available = widget.GetOrNull("MAP_AVAILABLE");

            if (available != null)
            {
                available.IsVisible = () => lobby.Map.Status == MapStatus.Available && lobby.Map.RuleStatus == MapRuleStatus.Cached;

                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)
                {
                    typeLabel.GetText = () => lobby.Map.Type;
                }

                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.RuleStatus == MapRuleStatus.Invalid;

                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 title = invalid.GetOrNull <LabelWidget>("MAP_TITLE");
                if (title != null)
                {
                    title.GetText = () => lobby.Map.Title;
                }

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

            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 title = download.GetOrNull <LabelWidget>("MAP_TITLE");
                if (title != null)
                {
                    title.GetText = () => lobby.Map.Title;
                }

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

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

                var install = download.GetOrNull <ButtonWidget>("MAP_INSTALL");
                if (install != null)
                {
                    install.OnClick = () => lobby.Map.Install();
                }
            }

            var progress = widget.GetOrNull("MAP_PROGRESS");

            if (progress != null)
            {
                progress.IsVisible = () =>
                                     (lobby.Map.Status != MapStatus.Available || lobby.Map.RuleStatus == MapRuleStatus.Unknown) &&
                                     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 title = progress.GetOrNull <LabelWidget>("MAP_TITLE");
                if (title != null)
                {
                    title.GetText = () => lobby.Map.Title;
                }

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

                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();
                        }
                        else if (lobby.Map.Status == MapStatus.Unavailable)
                        {
                            Game.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();
                }
            }
        }
		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 #36
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 #37
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 ReplayBrowserLogic(Widget widget, ModData modData, Action onExit, Action onStart)
        {
            panel = widget;

            this.modData          = modData;
            this.onStart          = onStart;
            Game.BeforeGameStart += OnGameStart;

            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 = modData.Manifest;
            var dir = Platform.ResolvePath("^", "Replays", mod.Id, mod.Metadata.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)
            {
                var mapType = new CachedTransform <MapPreview, string>(m => m.Categories.FirstOrDefault() ?? "");
                type.GetText = () => mapType.Update(selectedReplay.GameInfo.MapPreview);
            }

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

            SetupFilters();
            SetupManagement();
        }