Example #1
0
        public static void SetupChatLine(ContainerWidget template, DateTime time, TextNotification chatLine)
        {
            var nameLabel = template.Get <LabelWidget>("NAME");
            var timeLabel = template.Get <LabelWidget>("TIME");
            var textLabel = template.Get <LabelWidget>("TEXT");

            var nameText = chatLine.Prefix + ":";
            var font     = Game.Renderer.Fonts[nameLabel.Font];
            var nameSize = font.Measure(nameText);

            timeLabel.GetText = () => $"{time.Hour:D2}:{time.Minute:D2}";

            nameLabel.GetColor     = () => chatLine.PrefixColor;
            nameLabel.GetText      = () => nameText;
            nameLabel.Bounds.Width = nameSize.X;

            textLabel.GetColor      = () => chatLine.TextColor;
            textLabel.Bounds.X     += nameSize.X;
            textLabel.Bounds.Width -= nameSize.X;

            // Hack around our hacky wordwrap behavior: need to resize the widget to fit the text
            var text = WidgetUtils.WrapText(chatLine.Text, textLabel.Bounds.Width, font);

            textLabel.GetText = () => text;
            var dh = font.Measure(text).Y - textLabel.Bounds.Height;

            if (dh > 0)
            {
                textLabel.Bounds.Height += dh;
                template.Bounds.Height  += dh;
            }
        }
Example #2
0
        void DisplayNews(IEnumerable <NewsItem> newsItems)
        {
            newsPanel.RemoveChildren();
            SetNewsStatus("");

            foreach (var i in newsItems)
            {
                var item = i;

                var newsItem = newsTemplate.Clone();

                var titleLabel = newsItem.Get <LabelWidget>("TITLE");
                titleLabel.GetText = () => item.Title;

                var authorDateTimeLabel = newsItem.Get <LabelWidget>("AUTHOR_DATETIME");
                var authorDateTime      = authorDateTimeLabel.Text.F(item.Author, item.DateTime.ToLocalTime());
                authorDateTimeLabel.GetText = () => authorDateTime;

                var contentLabel = newsItem.Get <LabelWidget>("CONTENT");
                var content      = item.Content.Replace("\\n", "\n");
                content = WidgetUtils.WrapText(content, contentLabel.Bounds.Width, Game.Renderer.Fonts[contentLabel.Font]);
                contentLabel.GetText       = () => content;
                contentLabel.Bounds.Height = Game.Renderer.Fonts[contentLabel.Font].Measure(content).Y;
                newsItem.Bounds.Height    += contentLabel.Bounds.Height;

                newsPanel.AddChild(newsItem);
                newsPanel.Layout.AdjustChildren();
            }
        }
Example #3
0
        void SelectMap(Map map)
        {
            StopVideo();

            selectedMapPreview = Game.modData.MapCache[map.Uid];

            // Cache the rules on a background thread to avoid jank
            new Thread(selectedMapPreview.CacheRules).Start();

            var video         = selectedMapPreview.Map.PreviewVideo;
            var videoVisible  = video != null;
            var videoDisabled = !(videoVisible && GlobalFileSystem.Exists(video));

            startVideoButton.IsVisible  = () => videoVisible && !showVideoPlayer;
            startVideoButton.IsDisabled = () => videoDisabled;
            startVideoButton.OnClick    = () =>
            {
                showVideoPlayer = true;
                videoPlayer.Load(video);
                videoPlayer.PlayThen(StopVideo);

                // Mute other distracting sounds
                cachedSoundVolume = Sound.SoundVolume;
                cachedMusicVolume = Sound.MusicVolume;
                Sound.SoundVolume = Sound.MusicVolume = 0;
            };

            var text = map.Description != null?map.Description.Replace("\\n", "\n") : "";

            text                      = WidgetUtils.WrapText(text, description.Bounds.Width, descriptionFont);
            description.Text          = text;
            description.Bounds.Height = descriptionFont.Measure(text).Y;
            descriptionPanel.ScrollToTop();
            descriptionPanel.Layout.AdjustChildren();
        }
Example #4
0
        public static void SetupChatLine(ContainerWidget template, DateTime time, string name, Color nameColor, string text, Color textColor)
        {
            var nameLabel = template.Get <LabelWidget>("NAME");
            var timeLabel = template.Get <LabelWidget>("TIME");
            var textLabel = template.Get <LabelWidget>("TEXT");

            var nameText = name + ":";
            var font     = Game.Renderer.Fonts[nameLabel.Font];
            var nameSize = font.Measure(nameText);

            timeLabel.GetText = () => "{0:D2}:{1:D2}".F(time.Hour, time.Minute);

            nameLabel.GetColor     = () => nameColor;
            nameLabel.GetText      = () => nameText;
            nameLabel.Bounds.Width = nameSize.X;

            textLabel.GetColor      = () => textColor;
            textLabel.Bounds.X     += nameSize.X;
            textLabel.Bounds.Width -= nameSize.X;

            // Hack around our hacky wordwrap behavior: need to resize the widget to fit the text
            text = WidgetUtils.WrapText(text, textLabel.Bounds.Width, font);
            textLabel.GetText = () => text;
            var dh = font.Measure(text).Y - textLabel.Bounds.Height;

            if (dh > 0)
            {
                textLabel.Bounds.Height += dh;
                template.Bounds.Height  += dh;
            }
        }
        void SetupWidget(Widget widget, LabelWidget objectiveText, LabelWidget objectiveStatus, Objective objective)
        {
            var font = Game.Renderer.Fonts[objectiveText.Font];
            var text = WidgetUtils.WrapText(objective.Text, objectiveText.Bounds.Width, font);

            widget.Bounds.Height    = objectiveText.Bounds.Height = objectiveStatus.Bounds.Height = font.Measure(text).Y;
            objectiveText.GetText   = () => text;
            objectiveStatus.GetText = () => GetObjectiveStatusText(objective.Status);
        }
Example #6
0
        void SelectMap(Map map)
        {
            selectedMapPreview = Game.ModData.MapCache[map.Uid];

            // Cache the rules on a background thread to avoid jank
            new Thread(selectedMapPreview.CacheRules).Start();

            var briefingVideo         = selectedMapPreview.Map.Videos.Briefing;
            var briefingVideoVisible  = briefingVideo != null;
            var briefingVideoDisabled = !(briefingVideoVisible && GlobalFileSystem.Exists(briefingVideo));

            var infoVideo         = selectedMapPreview.Map.Videos.BackgroundInfo;
            var infoVideoVisible  = infoVideo != null;
            var infoVideoDisabled = !(infoVideoVisible && GlobalFileSystem.Exists(infoVideo));

            startBriefingVideoButton.IsVisible  = () => briefingVideoVisible && playingVideo != PlayingVideo.Briefing;
            startBriefingVideoButton.IsDisabled = () => briefingVideoDisabled || playingVideo != PlayingVideo.None;
            startBriefingVideoButton.OnClick    = () => PlayVideo(videoPlayer, briefingVideo, PlayingVideo.Briefing, () => StopVideo(videoPlayer));

            startInfoVideoButton.IsVisible  = () => infoVideoVisible && playingVideo != PlayingVideo.Info;
            startInfoVideoButton.IsDisabled = () => infoVideoDisabled || playingVideo != PlayingVideo.None;
            startInfoVideoButton.OnClick    = () => PlayVideo(videoPlayer, infoVideo, PlayingVideo.Info, () => StopVideo(videoPlayer));

            var text = map.Description != null?map.Description.Replace("\\n", "\n") : "";

            text                      = WidgetUtils.WrapText(text, description.Bounds.Width, descriptionFont);
            description.Text          = text;
            description.Bounds.Height = descriptionFont.Measure(text).Y;
            descriptionPanel.ScrollToTop();
            descriptionPanel.Layout.AdjustChildren();

            difficultyButton.IsVisible = () => map.Options.Difficulties.Any();
            if (!map.Options.Difficulties.Any())
            {
                return;
            }

            difficulty = map.Options.Difficulties.First();
            difficultyButton.OnMouseDown = _ =>
            {
                var options = map.Options.Difficulties.Select(d => new DropDownOption
                {
                    Title      = d,
                    IsSelected = () => difficulty == d,
                    OnClick    = () => difficulty = 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);
                };
                difficultyButton.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
            };
        }
Example #7
0
        Widget MakeLabelWidget(LabelWidget template, object item)
        {
            var itemString = item.ToString();
            var widget     = (LabelWidget)template.Clone();
            var font       = Game.Renderer.Fonts[widget.Font];

            itemString           = WidgetUtils.WrapText(itemString, widget.Bounds.Width, font);
            widget.Bounds.Height = font.Measure(itemString).Y;
            widget.GetText       = () => itemString;
            return(widget);
        }
Example #8
0
        void SelectMap(Map map)
        {
            selectedMapPreview = Game.modData.MapCache[map.Uid];

            var text = map.Description != null?map.Description.Replace("\\n", "\n") : "";

            text                      = WidgetUtils.WrapText(text, description.Bounds.Width, descriptionFont);
            description.Text          = text;
            description.Bounds.Height = descriptionFont.Measure(text).Y;
            descriptionPanel.Layout.AdjustChildren();
        }
Example #9
0
        void AddChatLine(Color c, string from, string text, bool replayCache)
        {
            if (!replayCache && chatOverlayDisplay != null)
            {
                chatOverlayDisplay.AddLine(c, from, text);
            }

            var template  = chatTemplate.Clone();
            var nameLabel = template.Get <LabelWidget>("NAME");
            var textLabel = template.Get <LabelWidget>("TEXT");

            var name = "";

            if (!string.IsNullOrEmpty(from))
            {
                name = from + ":";
            }

            var font     = Game.Renderer.Fonts[nameLabel.Font];
            var nameSize = font.Measure(from);

            nameLabel.GetColor      = () => c;
            nameLabel.GetText       = () => name;
            nameLabel.Bounds.Width  = nameSize.X;
            textLabel.Bounds.X     += nameSize.X;
            textLabel.Bounds.Width -= nameSize.X;

            // Hack around our hacky wordwrap behavior: need to resize the widget to fit the text
            text = WidgetUtils.WrapText(text, textLabel.Bounds.Width, font);
            textLabel.GetText = () => text;
            var dh = font.Measure(text).Y - textLabel.Bounds.Height;

            if (dh > 0)
            {
                textLabel.Bounds.Height += dh;
                template.Bounds.Height  += dh;
            }

            var scrolledToBottom = chatScrollPanel.ScrolledToBottom;

            chatScrollPanel.AddChild(template);
            if (scrolledToBottom)
            {
                chatScrollPanel.ScrollToBottom(smooth: true);
            }

            if (!replayCache)
            {
                Game.Sound.PlayNotification(modRules, null, "Sounds", "ChatLine", null);
            }
        }
Example #10
0
        void AddChatLine(TextNotification chatLine, bool suppressSound)
        {
            var template  = chatTemplate.Clone();
            var nameLabel = template.Get <LabelWidget>("NAME");
            var textLabel = template.Get <LabelWidget>("TEXT");

            var name = "";

            if (!string.IsNullOrEmpty(chatLine.Prefix))
            {
                name = chatLine.Prefix + ":";
            }

            var font     = Game.Renderer.Fonts[nameLabel.Font];
            var nameSize = font.Measure(chatLine.Prefix);

            nameLabel.GetColor     = () => chatLine.PrefixColor;
            nameLabel.GetText      = () => name;
            nameLabel.Bounds.Width = nameSize.X;

            textLabel.GetColor      = () => chatLine.TextColor;
            textLabel.Bounds.X     += nameSize.X;
            textLabel.Bounds.Width -= nameSize.X;

            // Hack around our hacky wordwrap behavior: need to resize the widget to fit the text
            var text = WidgetUtils.WrapText(chatLine.Text, textLabel.Bounds.Width, font);

            textLabel.GetText = () => text;
            var dh = font.Measure(text).Y - textLabel.Bounds.Height;

            if (dh > 0)
            {
                textLabel.Bounds.Height += dh;
                template.Bounds.Height  += dh;
            }

            var scrolledToBottom = chatScrollPanel.ScrolledToBottom;

            chatScrollPanel.AddChild(template);
            if (scrolledToBottom)
            {
                chatScrollPanel.ScrollToBottom(smooth: true);
            }

            if (!suppressSound)
            {
                Game.Sound.PlayNotification(modRules, null, "Sounds", chatLineSound, null);
            }
        }
Example #11
0
        public GameInfoBriefingLogic(Widget widget, World world)
        {
            var previewWidget = widget.Get <MapPreviewWidget>("MAP_PREVIEW");

            previewWidget.Preview = () => Game.modData.MapCache[world.Map.Uid];

            var mapDescriptionPanel = widget.Get <ScrollPanelWidget>("MAP_DESCRIPTION_PANEL");
            var mapDescription      = widget.Get <LabelWidget>("MAP_DESCRIPTION");
            var mapFont             = Game.Renderer.Fonts[mapDescription.Font];
            var text = world.Map.Description != null?world.Map.Description.Replace("\\n", "\n") : "";

            text = WidgetUtils.WrapText(text, mapDescription.Bounds.Width, mapFont);
            mapDescription.Text          = text;
            mapDescription.Bounds.Height = mapFont.Measure(text).Y;
            mapDescriptionPanel.ScrollToTop();
            mapDescriptionPanel.Layout.AdjustChildren();
        }
Example #12
0
        Widget MakeHistoryWidget(object o)
        {
            var message = (ChatMessage)o;
            var widget  = (LabelWidget)historyTemplate.Clone();
            var font    = Game.Renderer.Fonts[widget.Font];

            var color = message.Type == ChatMessageType.Notification ?
                        ChromeMetrics.Get <Color>("GlobalChatNotificationColor") :
                        ChromeMetrics.Get <Color>("GlobalChatTextColor");

            var display = WidgetUtils.WrapText(message.ToString(), widget.Bounds.Width, font);

            widget.Bounds.Height = font.Measure(display).Y;
            widget.GetText       = () => display;
            widget.GetColor      = () => color;
            widget.Id            = message.UID;
            return(widget);
        }
Example #13
0
        void AddChatLine(Color c, string from, string text)
        {
            lobbyChatUnreadMessages += 1;

            var template  = chatTemplate.Clone();
            var nameLabel = template.Get <LabelWidget>("NAME");
            var timeLabel = template.Get <LabelWidget>("TIME");
            var textLabel = template.Get <LabelWidget>("TEXT");

            var name     = from + ":";
            var font     = Game.Renderer.Fonts[nameLabel.Font];
            var nameSize = font.Measure(from);

            var time = DateTime.Now;

            timeLabel.GetText = () => "{0:D2}:{1:D2}".F(time.Hour, time.Minute);

            nameLabel.GetColor      = () => c;
            nameLabel.GetText       = () => name;
            nameLabel.Bounds.Width  = nameSize.X;
            textLabel.Bounds.X     += nameSize.X;
            textLabel.Bounds.Width -= nameSize.X;

            // Hack around our hacky wordwrap behavior: need to resize the widget to fit the text
            text = WidgetUtils.WrapText(text, textLabel.Bounds.Width, font);
            textLabel.GetText = () => text;
            var dh = font.Measure(text).Y - textLabel.Bounds.Height;

            if (dh > 0)
            {
                textLabel.Bounds.Height += dh;
                template.Bounds.Height  += dh;
            }

            var scrolledToBottom = lobbyChatPanel.ScrolledToBottom;

            lobbyChatPanel.AddChild(template);
            if (scrolledToBottom)
            {
                lobbyChatPanel.ScrollToBottom(smooth: true);
            }

            Game.Sound.PlayNotification(modRules, null, "Sounds", "ChatLine", null);
        }
Example #14
0
        public GameInfoBriefingLogic(Widget widget, ModData modData, World world)
        {
            var previewWidget = widget.Get <MapPreviewWidget>("MAP_PREVIEW");

            previewWidget.Preview = () => modData.MapCache[world.Map.Uid];

            var mapDescriptionPanel = widget.Get <ScrollPanelWidget>("MAP_DESCRIPTION_PANEL");
            var mapDescription      = widget.Get <LabelWidget>("MAP_DESCRIPTION");
            var mapFont             = Game.Renderer.Fonts[mapDescription.Font];

            var missionData = world.Map.Rules.Actors[SystemActors.World].TraitInfoOrDefault <MissionDataInfo>();

            if (missionData != null)
            {
                var text = WidgetUtils.WrapText(missionData.Briefing.Replace("\\n", "\n"), mapDescription.Bounds.Width, mapFont);
                mapDescription.Text          = text;
                mapDescription.Bounds.Height = mapFont.Measure(text).Y;
                mapDescriptionPanel.ScrollToTop();
                mapDescriptionPanel.Layout.AdjustChildren();
            }
        }
Example #15
0
        void AddChatLine(Color c, string from, string text)
        {
            var template  = chatTemplate.Clone();
            var nameLabel = template.GetWidget <LabelWidget>("NAME");
            var timeLabel = template.GetWidget <LabelWidget>("TIME");
            var textLabel = template.GetWidget <LabelWidget>("TEXT");

            var name     = from + ":";
            var font     = Game.Renderer.Fonts[nameLabel.Font];
            var nameSize = font.Measure(from);

            var time = DateTime.Now;

            timeLabel.GetText = () => "{0:D2}:{1:D2}".F(time.Hour, time.Minute);

            nameLabel.GetColor      = () => c;
            nameLabel.GetText       = () => name;
            nameLabel.Bounds.Width  = nameSize.X;
            textLabel.Bounds.X     += nameSize.X;
            textLabel.Bounds.Width -= nameSize.X;

            // Hack around our hacky wordwrap behavior: need to resize the widget to fit the text
            text = WidgetUtils.WrapText(text, textLabel.Bounds.Width, font);
            textLabel.GetText = () => text;
            var dh = font.Measure(text).Y - textLabel.Bounds.Height;

            if (dh > 0)
            {
                textLabel.Bounds.Height += dh;
                template.Bounds.Height  += dh;
            }

            chatPanel.AddChild(template);
            chatPanel.ScrollToBottom();
            Sound.Play("scold1.aud");
        }
Example #16
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.WorldActorInfo.TraitInfos <ScriptLobbyDropdownInfo>()
                                    .FirstOrDefault(sld => sld.ID == "difficulty");

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

                var missionData = preview.WorldActorInfo.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);
                };
            }
        }
Example #17
0
        public MainMenuLogic(Widget widget, World world)
        {
            rootMenu = widget;
            rootMenu.Get <LabelWidget>("VERSION_LABEL").Text = Game.modData.Manifest.Mod.Version;

            // Menu buttons
            var mainMenu = widget.Get("MAIN_MENU");

            mainMenu.IsVisible = () => menuType == MenuType.Main;

            mainMenu.Get <ButtonWidget>("SINGLEPLAYER_BUTTON").OnClick = () => menuType = MenuType.Singleplayer;

            mainMenu.Get <ButtonWidget>("MULTIPLAYER_BUTTON").OnClick = () =>
            {
                menuType = MenuType.None;
                Ui.OpenWindow("SERVERBROWSER_PANEL", new WidgetArgs
                {
                    { "onStart", RemoveShellmapUI },
                    { "onExit", () => menuType = MenuType.Main }
                });
            };

            mainMenu.Get <ButtonWidget>("MODS_BUTTON").OnClick = () =>
            {
                Game.Settings.Game.PreviousMod = Game.modData.Manifest.Mod.Id;
                Game.InitializeMod("modchooser", null);
            };

            mainMenu.Get <ButtonWidget>("SETTINGS_BUTTON").OnClick = () =>
            {
                menuType = MenuType.None;
                Game.OpenWindow("SETTINGS_PANEL", new WidgetArgs
                {
                    { "onExit", () => menuType = MenuType.Main }
                });
            };

            mainMenu.Get <ButtonWidget>("EXTRAS_BUTTON").OnClick = () => menuType = MenuType.Extras;

            mainMenu.Get <ButtonWidget>("QUIT_BUTTON").OnClick = Game.Exit;

            // Singleplayer menu
            var singleplayerMenu = widget.Get("SINGLEPLAYER_MENU");

            singleplayerMenu.IsVisible = () => menuType == MenuType.Singleplayer;

            var missionsButton = singleplayerMenu.Get <ButtonWidget>("MISSIONS_BUTTON");

            missionsButton.OnClick = () =>
            {
                menuType = MenuType.None;
                Game.OpenWindow("MISSIONBROWSER_PANEL", new WidgetArgs
                {
                    { "onExit", () => menuType = MenuType.Singleplayer },
                    { "onStart", RemoveShellmapUI }
                });
            };

            var hasCampaign = Game.modData.Manifest.Missions.Any();
            var hasMissions = Game.modData.MapCache
                              .Any(p => p.Status == MapStatus.Available && p.Map.Type == "Mission" && !p.Map.Selectable);

            missionsButton.Disabled = !hasCampaign && !hasMissions;

            singleplayerMenu.Get <ButtonWidget>("SKIRMISH_BUTTON").OnClick = StartSkirmishGame;

            singleplayerMenu.Get <ButtonWidget>("BACK_BUTTON").OnClick = () => menuType = MenuType.Main;

            // Extras menu
            var extrasMenu = widget.Get("EXTRAS_MENU");

            extrasMenu.IsVisible = () => menuType == MenuType.Extras;

            extrasMenu.Get <ButtonWidget>("REPLAYS_BUTTON").OnClick = () =>
            {
                menuType = MenuType.None;
                Ui.OpenWindow("REPLAYBROWSER_PANEL", new WidgetArgs
                {
                    { "onExit", () => menuType = MenuType.Extras },
                    { "onStart", RemoveShellmapUI }
                });
            };

            extrasMenu.Get <ButtonWidget>("MUSIC_BUTTON").OnClick = () =>
            {
                menuType = MenuType.None;
                Ui.OpenWindow("MUSIC_PANEL", new WidgetArgs
                {
                    { "onExit", () => menuType = MenuType.Extras },
                    { "world", world }
                });
            };

            var assetBrowserButton = extrasMenu.GetOrNull <ButtonWidget>("ASSETBROWSER_BUTTON");

            if (assetBrowserButton != null)
            {
                assetBrowserButton.OnClick = () =>
                {
                    menuType = MenuType.None;
                    Game.OpenWindow("ASSETBROWSER_PANEL", new WidgetArgs
                    {
                        { "onExit", () => menuType = MenuType.Extras },
                    });
                }
            }
            ;

            extrasMenu.Get <ButtonWidget>("CREDITS_BUTTON").OnClick = () =>
            {
                menuType = MenuType.None;
                Ui.OpenWindow("CREDITS_PANEL", new WidgetArgs
                {
                    { "onExit", () => menuType = MenuType.Extras },
                });
            };

            extrasMenu.Get <ButtonWidget>("BACK_BUTTON").OnClick = () => menuType = MenuType.Main;

            var newsBG = widget.GetOrNull("NEWS_BG");

            if (newsBG != null)
            {
                newsBG.IsVisible = () => Game.Settings.Game.FetchNews && menuType != MenuType.None;

                newsPanel    = Ui.LoadWidget <ScrollPanelWidget>("NEWS_PANEL", null, new WidgetArgs());
                newsTemplate = newsPanel.Get("NEWS_ITEM_TEMPLATE");
                newsPanel.RemoveChild(newsTemplate);

                newsStatus = newsPanel.Get <LabelWidget>("NEWS_STATUS");
                SetNewsStatus("Loading news");

                var cacheFile   = Platform.ResolvePath("^", "news.yaml");
                var currentNews = ParseNews(cacheFile);
                if (currentNews != null)
                {
                    DisplayNews(currentNews);
                }

                // Only query for new stories once per day
                var cacheValid = currentNews != null && DateTime.Today.ToUniversalTime() <= Game.Settings.Game.NewsFetchedDate;
                if (!cacheValid)
                {
                    new Download(Game.Settings.Game.NewsUrl, cacheFile, e => { }, (e, c) => NewsDownloadComplete(e, c, cacheFile, currentNews));
                }

                var newsButton = newsBG.GetOrNull <DropDownButtonWidget>("NEWS_BUTTON");
                newsButton.OnClick = () =>
                {
                    newsButton.AttachPanel(newsPanel);
                    newsHighlighted = false;
                };

                newsButton.IsHighlighted = () => newsHighlighted && Game.LocalTick % 50 < 25;
            }
        }

        void SetNewsStatus(string message)
        {
            message            = WidgetUtils.WrapText(message, newsStatus.Bounds.Width, Game.Renderer.Fonts[newsStatus.Font]);
            newsStatus.GetText = () => message;
        }
Example #18
0
        void SelectMap(MapPreview preview)
        {
            selectedMap = preview;

            // Cache the rules on a background thread to avoid jank
            var difficultyDisabled = true;
            var difficulties       = new string[0];

            var briefingVideo         = "";
            var briefingVideoVisible  = false;
            var briefingVideoDisabled = true;

            var infoVideo         = "";
            var infoVideoVisible  = false;
            var infoVideoDisabled = true;

            new Thread(() =>
            {
                var mapOptions = preview.Rules.Actors["world"].TraitInfo <MapOptionsInfo>();

                difficulty         = mapOptions.Difficulty ?? mapOptions.Difficulties.FirstOrDefault();
                difficulties       = mapOptions.Difficulties;
                difficultyDisabled = mapOptions.DifficultyLocked || mapOptions.Difficulties.Length <= 1;

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

                    infoVideo         = missionData.BackgroundVideo;
                    infoVideoVisible  = infoVideo != null;
                    infoVideoDisabled = !(infoVideoVisible && modData.DefaultFileSystem.Exists(infoVideo));

                    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.IsDisabled = () => briefingVideoDisabled || playingVideo != PlayingVideo.None;
            startBriefingVideoButton.OnClick    = () => PlayVideo(videoPlayer, briefingVideo, PlayingVideo.Briefing, () => StopVideo(videoPlayer));

            startInfoVideoButton.IsVisible  = () => infoVideoVisible && playingVideo != PlayingVideo.Info;
            startInfoVideoButton.IsDisabled = () => infoVideoDisabled || playingVideo != PlayingVideo.None;
            startInfoVideoButton.OnClick    = () => PlayVideo(videoPlayer, infoVideo, PlayingVideo.Info, () => StopVideo(videoPlayer));

            descriptionPanel.ScrollToTop();

            if (difficultyButton != null)
            {
                difficultyButton.IsDisabled  = () => difficultyDisabled;
                difficultyButton.GetText     = () => difficulty ?? "Normal";
                difficultyButton.OnMouseDown = _ =>
                {
                    var options = difficulties.Select(d => new DropDownOption
                    {
                        Title      = d,
                        IsSelected = () => difficulty == d,
                        OnClick    = () => difficulty = 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);
                    };

                    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);
                };
            }
        }
Example #19
0
        public MainMenuLogic(Widget widget, World world)
        {
            rootMenu = widget;
            rootMenu.Get <LabelWidget>("VERSION_LABEL").Text = Game.ModData.Manifest.Mod.Version;

            // Menu buttons
            var mainMenu = widget.Get("MAIN_MENU");

            mainMenu.IsVisible = () => menuType == MenuType.Main;

            mainMenu.Get <ButtonWidget>("SINGLEPLAYER_BUTTON").OnClick = () => menuType = MenuType.Singleplayer;

            mainMenu.Get <ButtonWidget>("MULTIPLAYER_BUTTON").OnClick = () =>
            {
                menuType = MenuType.None;
                Ui.OpenWindow("SERVERBROWSER_PANEL", new WidgetArgs
                {
                    { "onStart", RemoveShellmapUI },
                    { "onExit", () => menuType = MenuType.Main },
                    { "directConnectHost", null },
                    { "directConnectPort", 0 },
                });
            };

            mainMenu.Get <ButtonWidget>("MODS_BUTTON").OnClick = () =>
            {
                Game.Settings.Game.PreviousMod = Game.ModData.Manifest.Mod.Id;
                Game.InitializeMod("modchooser", null);
            };

            mainMenu.Get <ButtonWidget>("SETTINGS_BUTTON").OnClick = () =>
            {
                menuType = MenuType.None;
                Game.OpenWindow("SETTINGS_PANEL", new WidgetArgs
                {
                    { "onExit", () => menuType = MenuType.Main }
                });
            };

            mainMenu.Get <ButtonWidget>("EXTRAS_BUTTON").OnClick = () => menuType = MenuType.Extras;

            mainMenu.Get <ButtonWidget>("QUIT_BUTTON").OnClick = Game.Exit;

            // Singleplayer menu
            var singleplayerMenu = widget.Get("SINGLEPLAYER_MENU");

            singleplayerMenu.IsVisible = () => menuType == MenuType.Singleplayer;

            var missionsButton = singleplayerMenu.Get <ButtonWidget>("MISSIONS_BUTTON");

            missionsButton.OnClick = () =>
            {
                menuType = MenuType.None;
                Game.OpenWindow("MISSIONBROWSER_PANEL", new WidgetArgs
                {
                    { "onExit", () => menuType = MenuType.Singleplayer },
                    { "onStart", RemoveShellmapUI }
                });
            };

            var hasCampaign = Game.ModData.Manifest.Missions.Any();
            var hasMissions = Game.ModData.MapCache
                              .Any(p => p.Status == MapStatus.Available && p.Map.Visibility.HasFlag(MapVisibility.MissionSelector));

            missionsButton.Disabled = !hasCampaign && !hasMissions;

            singleplayerMenu.Get <ButtonWidget>("SKIRMISH_BUTTON").OnClick = StartSkirmishGame;

            singleplayerMenu.Get <ButtonWidget>("BACK_BUTTON").OnClick = () => menuType = MenuType.Main;

            // Extras menu
            var extrasMenu = widget.Get("EXTRAS_MENU");

            extrasMenu.IsVisible = () => menuType == MenuType.Extras;

            extrasMenu.Get <ButtonWidget>("REPLAYS_BUTTON").OnClick = () =>
            {
                menuType = MenuType.None;
                Ui.OpenWindow("REPLAYBROWSER_PANEL", new WidgetArgs
                {
                    { "onExit", () => menuType = MenuType.Extras },
                    { "onStart", RemoveShellmapUI }
                });
            };

            extrasMenu.Get <ButtonWidget>("MUSIC_BUTTON").OnClick = () =>
            {
                menuType = MenuType.None;
                Ui.OpenWindow("MUSIC_PANEL", new WidgetArgs
                {
                    { "onExit", () => menuType = MenuType.Extras },
                    { "world", world }
                });
            };

            extrasMenu.Get <ButtonWidget>("MAP_EDITOR_BUTTON").OnClick = () => menuType = MenuType.MapEditor;

            var assetBrowserButton = extrasMenu.GetOrNull <ButtonWidget>("ASSETBROWSER_BUTTON");

            if (assetBrowserButton != null)
            {
                assetBrowserButton.OnClick = () =>
                {
                    menuType = MenuType.None;
                    Game.OpenWindow("ASSETBROWSER_PANEL", new WidgetArgs
                    {
                        { "onExit", () => menuType = MenuType.Extras },
                    });
                }
            }
            ;

            extrasMenu.Get <ButtonWidget>("CREDITS_BUTTON").OnClick = () =>
            {
                menuType = MenuType.None;
                Ui.OpenWindow("CREDITS_PANEL", new WidgetArgs
                {
                    { "onExit", () => menuType = MenuType.Extras },
                });
            };

            extrasMenu.Get <ButtonWidget>("BACK_BUTTON").OnClick = () => menuType = MenuType.Main;

            // Map editor menu
            var mapEditorMenu = widget.Get("MAP_EDITOR_MENU");

            mapEditorMenu.IsVisible = () => menuType == MenuType.MapEditor;

            var onSelect = new Action <string>(uid =>
            {
                RemoveShellmapUI();
                LoadMapIntoEditor(Game.ModData.MapCache[uid].Map);
            });

            var newMapButton = widget.Get <ButtonWidget>("NEW_MAP_BUTTON");

            newMapButton.OnClick = () =>
            {
                menuType = MenuType.None;
                Game.OpenWindow("NEW_MAP_BG", new WidgetArgs()
                {
                    { "onSelect", onSelect },
                    { "onExit", () => menuType = MenuType.MapEditor }
                });
            };

            var loadMapButton = widget.Get <ButtonWidget>("LOAD_MAP_BUTTON");

            loadMapButton.OnClick = () =>
            {
                menuType = MenuType.None;
                Game.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
                {
                    { "initialMap", null },
                    { "initialTab", MapClassification.User },
                    { "onExit", () => menuType = MenuType.MapEditor },
                    { "onSelect", onSelect },
                    { "filter", MapVisibility.Lobby | MapVisibility.Shellmap | MapVisibility.MissionSelector },
                });
            };

            mapEditorMenu.Get <ButtonWidget>("BACK_BUTTON").OnClick = () => menuType = MenuType.Extras;

            var newsBG = widget.GetOrNull("NEWS_BG");

            if (newsBG != null)
            {
                newsBG.IsVisible = () => Game.Settings.Game.FetchNews && menuType != MenuType.None;

                newsPanel    = Ui.LoadWidget <ScrollPanelWidget>("NEWS_PANEL", null, new WidgetArgs());
                newsTemplate = newsPanel.Get("NEWS_ITEM_TEMPLATE");
                newsPanel.RemoveChild(newsTemplate);

                newsStatus = newsPanel.Get <LabelWidget>("NEWS_STATUS");
                SetNewsStatus("Loading news");

                var cacheFile   = Platform.ResolvePath("^", "news.yaml");
                var currentNews = ParseNews(cacheFile);
                if (currentNews != null)
                {
                    DisplayNews(currentNews);
                }

                // Only query for new stories once per day
                var cacheValid = currentNews != null && DateTime.Today.ToUniversalTime() <= Game.Settings.Game.NewsFetchedDate;
                if (!cacheValid)
                {
                    new Download(Game.Settings.Game.NewsUrl, cacheFile, e => { }, (e, c) => NewsDownloadComplete(e, c, cacheFile, currentNews));
                }

                var newsButton = newsBG.GetOrNull <DropDownButtonWidget>("NEWS_BUTTON");
                newsButton.OnClick = () =>
                {
                    newsButton.AttachPanel(newsPanel);
                    newsHighlighted = false;
                };

                newsButton.IsHighlighted = () => newsHighlighted && Game.LocalTick % 50 < 25;
            }

            Game.OnRemoteDirectConnect += (host, port) =>
            {
                menuType = MenuType.None;
                Ui.OpenWindow("SERVERBROWSER_PANEL", new WidgetArgs
                {
                    { "onStart", RemoveShellmapUI },
                    { "onExit", () => menuType = MenuType.Main },
                    { "directConnectHost", host },
                    { "directConnectPort", port },
                });
            };
        }

        void LoadMapIntoEditor(Map map)
        {
            ConnectionLogic.Connect(System.Net.IPAddress.Loopback.ToString(),
                                    Game.CreateLocalServer(map.Uid),
                                    "",
                                    () => { Game.LoadEditor(map.Uid); },
                                    () => { Game.CloseServer(); menuType = MenuType.MapEditor; });
        }

        void SetNewsStatus(string message)
        {
            message            = WidgetUtils.WrapText(message, newsStatus.Bounds.Width, Game.Renderer.Fonts[newsStatus.Font]);
            newsStatus.GetText = () => message;
        }
Example #20
0
        public CustomMainMenuLogic(Widget widget, World world, ModData modData)
        {
            rootMenu = widget;
            rootMenu.Get <LabelWidget>("VERSION_LABEL").Text = modData.Manifest.Metadata.Version;

            // Menu buttons
            var mainMenu = widget.Get("MAIN_MENU");

            mainMenu.IsVisible = () => menuType == MenuType.Main;

            mainMenu.Get <ButtonWidget>("SINGLEPLAYER_BUTTON").OnClick = () => SwitchMenu(MenuType.Singleplayer);

            mainMenu.Get <ButtonWidget>("MULTIPLAYER_BUTTON").OnClick = OpenMultiplayerPanel;

            mainMenu.Get <ButtonWidget>("CONTENT_BUTTON").OnClick = () =>
            {
                // Switching mods changes the world state (by disposing it),
                // so we can't do this inside the input handler.
                Game.RunAfterTick(() =>
                {
                    var content = modData.Manifest.Get <ModContent>();
                    Game.InitializeMod(content.ContentInstallerMod, new Arguments(new[] { "Content.Mod=" + modData.Manifest.Id }));
                });
            };

            mainMenu.Get <ButtonWidget>("SETTINGS_BUTTON").OnClick = () =>
            {
                SwitchMenu(MenuType.None);
                Game.OpenWindow("SETTINGS_PANEL", new WidgetArgs
                {
                    { "onExit", () => SwitchMenu(MenuType.Main) }
                });
            };

            mainMenu.Get <ButtonWidget>("EXTRAS_BUTTON").OnClick = () => SwitchMenu(MenuType.Extras);

            mainMenu.Get <ButtonWidget>("QUIT_BUTTON").OnClick = Game.Exit;

            // Singleplayer menu
            var singleplayerMenu = widget.Get("SINGLEPLAYER_MENU");

            singleplayerMenu.IsVisible = () => menuType == MenuType.Singleplayer;

            var missionsButton = singleplayerMenu.Get <ButtonWidget>("MISSIONS_BUTTON");

            missionsButton.OnClick = OpenMissionBrowserPanel;

            var hasCampaign = modData.Manifest.Missions.Any();
            var hasMissions = modData.MapCache
                              .Any(p => p.Status == MapStatus.Available && p.Visibility.HasFlag(MapVisibility.MissionSelector));

            missionsButton.Disabled = !hasCampaign && !hasMissions;

            var hasMaps        = modData.MapCache.Any(p => p.Visibility.HasFlag(MapVisibility.Lobby));
            var skirmishButton = singleplayerMenu.Get <ButtonWidget>("SKIRMISH_BUTTON");

            skirmishButton.OnClick  = StartSkirmishGame;
            skirmishButton.Disabled = !hasMaps;

            var loadButton = singleplayerMenu.Get <ButtonWidget>("LOAD_BUTTON");

            loadButton.IsDisabled = () => !GameSaveBrowserLogic.IsLoadPanelEnabled(modData.Manifest);
            loadButton.OnClick    = OpenGameSaveBrowserPanel;

            singleplayerMenu.Get <ButtonWidget>("BACK_BUTTON").OnClick = () => SwitchMenu(MenuType.Main);

            // Extras menu
            var extrasMenu = widget.Get("EXTRAS_MENU");

            extrasMenu.IsVisible = () => menuType == MenuType.Extras;

            extrasMenu.Get <ButtonWidget>("REPLAYS_BUTTON").OnClick = OpenReplayBrowserPanel;

            extrasMenu.Get <ButtonWidget>("MUSIC_BUTTON").OnClick = () =>
            {
                SwitchMenu(MenuType.None);
                Ui.OpenWindow("MUSIC_PANEL", new WidgetArgs
                {
                    { "onExit", () => SwitchMenu(MenuType.Extras) },
                    { "world", world }
                });
            };

            extrasMenu.Get <ButtonWidget>("MAP_EDITOR_BUTTON").OnClick = () => SwitchMenu(MenuType.MapEditor);

            var assetBrowserButton = extrasMenu.GetOrNull <ButtonWidget>("ASSETBROWSER_BUTTON");

            if (assetBrowserButton != null)
            {
                assetBrowserButton.OnClick = () =>
                {
                    SwitchMenu(MenuType.None);
                    Game.OpenWindow("ASSETBROWSER_PANEL", new WidgetArgs
                    {
                        { "onExit", () => SwitchMenu(MenuType.Extras) },
                    });
                }
            }
            ;

            extrasMenu.Get <ButtonWidget>("CREDITS_BUTTON").OnClick = () =>
            {
                SwitchMenu(MenuType.None);
                Ui.OpenWindow("CREDITS_PANEL", new WidgetArgs
                {
                    { "onExit", () => SwitchMenu(MenuType.Extras) },
                });
            };

            extrasMenu.Get <ButtonWidget>("BACK_BUTTON").OnClick = () => SwitchMenu(MenuType.Main);

            // Map editor menu
            var mapEditorMenu = widget.Get("MAP_EDITOR_MENU");

            mapEditorMenu.IsVisible = () => menuType == MenuType.MapEditor;

            // Loading into the map editor
            Game.BeforeGameStart += RemoveShellmapUI;

            var onSelect = new Action <string>(uid => LoadMapIntoEditor(modData.MapCache[uid].Uid));

            var newMapButton = widget.Get <ButtonWidget>("NEW_MAP_BUTTON");

            newMapButton.OnClick = () =>
            {
                SwitchMenu(MenuType.None);
                Game.OpenWindow("NEW_MAP_BG", new WidgetArgs()
                {
                    { "onSelect", onSelect },
                    { "onExit", () => SwitchMenu(MenuType.MapEditor) }
                });
            };

            var loadMapButton = widget.Get <ButtonWidget>("LOAD_MAP_BUTTON");

            loadMapButton.OnClick = () =>
            {
                SwitchMenu(MenuType.None);
                Game.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
                {
                    { "initialMap", null },
                    { "initialTab", MapClassification.User },
                    { "onExit", () => SwitchMenu(MenuType.MapEditor) },
                    { "onSelect", onSelect },
                    { "filter", MapVisibility.Lobby | MapVisibility.Shellmap | MapVisibility.MissionSelector },
                });
            };

            loadMapButton.Disabled = !hasMaps;

            mapEditorMenu.Get <ButtonWidget>("BACK_BUTTON").OnClick = () => SwitchMenu(MenuType.Extras);

            var newsBG = widget.GetOrNull("NEWS_BG");

            if (newsBG != null)
            {
                newsBG.IsVisible = () => Game.Settings.Game.FetchNews && menuType != MenuType.None && menuType != MenuType.StartupPrompts;

                newsPanel    = Ui.LoadWidget <ScrollPanelWidget>("NEWS_PANEL", null, new WidgetArgs());
                newsTemplate = newsPanel.Get("NEWS_ITEM_TEMPLATE");
                newsPanel.RemoveChild(newsTemplate);

                newsStatus = newsPanel.Get <LabelWidget>("NEWS_STATUS");
                SetNewsStatus("Loading news");
            }

            Game.OnRemoteDirectConnect += OnRemoteDirectConnect;

            // Check for updates in the background
            var webServices = modData.Manifest.Get <GitHubWebServices>();

            if (Game.Settings.Debug.CheckVersion)
            {
                webServices.FetchRelease(() => LoadAndDisplayNews(webServices, newsBG));
            }

            var updateLabel = rootMenu.GetOrNull("UPDATE_NOTICE");

            if (updateLabel != null)
            {
                updateLabel.IsVisible = () => !newsOpen && menuType != MenuType.None &&
                                        menuType != MenuType.StartupPrompts &&
                                        webServices.ModVersionStatus == ModVersionStatus.Outdated;
            }

            var playerProfile = widget.GetOrNull("PLAYER_PROFILE_CONTAINER");

            if (playerProfile != null)
            {
                Func <bool> minimalProfile = () => Ui.CurrentWindow() != null;
                Game.LoadWidget(world, "LOCAL_PROFILE_PANEL", playerProfile, new WidgetArgs()
                {
                    { "minimalProfile", minimalProfile }
                });
            }

            menuType = MenuType.StartupPrompts;

            Action onIntroductionComplete = () =>
            {
                Action onSysInfoComplete = () =>
                {
                    SwitchMenu(MenuType.Main);
                };

                if (SystemInfoPromptLogic.ShouldShowPrompt())
                {
                    Ui.OpenWindow("MAINMENU_SYSTEM_INFO_PROMPT", new WidgetArgs
                    {
                        { "onComplete", onSysInfoComplete }
                    });
                }
                else
                {
                    onSysInfoComplete();
                }
            };

            if (IntroductionPromptLogic.ShouldShowPrompt())
            {
                Game.OpenWindow("MAINMENU_INTRODUCTION_PROMPT", new WidgetArgs
                {
                    { "onComplete", onIntroductionComplete }
                });
            }
            else
            {
                onIntroductionComplete();
            }

            Game.OnShellmapLoaded += OpenMenuBasedOnLastGame;

            DiscordService.UpdateStatus(DiscordState.InMenu);
        }

        void LoadAndDisplayNews(GitHubWebServices webServices, Widget newsBG)
        {
            if (newsBG != null && Game.Settings.Game.FetchNews)
            {
                var newsButton = newsBG.GetOrNull <DropDownButtonWidget>("NEWS_BUTTON");
                if (newsButton != null)
                {
                    DisplayNews(webServices);
                    newsButton.OnClick = () => OpenNewsPanel(newsButton);

                    if (webServices.NewsAlert)
                    {
                        OpenNewsPanel(newsButton);
                    }
                }
            }
        }

        void DisplayNews(GitHubWebServices webServices)
        {
            newsPanel.RemoveChildren();
            SetNewsStatus("");

            var newsWidget = newsTemplate.Clone();

            var titleLabel = newsWidget.Get <LabelWidget>("TITLE");
            var newsItem   = webServices.NewsItem;

            if (newsItem == null)
            {
                SetNewsStatus("Failed to retrieve news");
                return;
            }

            titleLabel.GetText = () => newsItem.Title;

            var authorDateTimeLabel = newsWidget.Get <LabelWidget>("AUTHOR_DATETIME");
            var authorDateTime      = authorDateTimeLabel.Text.F(newsItem.Author, newsItem.DateTime.ToLocalTime());

            authorDateTimeLabel.GetText = () => authorDateTime;

            var contentLabel = newsWidget.Get <LabelWidget>("CONTENT");
            var content      = newsItem.Content;

            content = WidgetUtils.WrapText(content, contentLabel.Bounds.Width, Game.Renderer.Fonts[contentLabel.Font]);
            contentLabel.GetText       = () => content;
            contentLabel.Bounds.Height = Game.Renderer.Fonts[contentLabel.Font].Measure(content).Y;
            newsWidget.Bounds.Height  += contentLabel.Bounds.Height;

            newsPanel.AddChild(newsWidget);
            newsPanel.Layout.AdjustChildren();
        }

        void OpenNewsPanel(DropDownButtonWidget button)
        {
            newsOpen = true;
            button.AttachPanel(newsPanel, () => newsOpen = false);
        }

        void OnRemoteDirectConnect(ConnectionTarget endpoint)
        {
            SwitchMenu(MenuType.None);
            Ui.OpenWindow("MULTIPLAYER_PANEL", new WidgetArgs
            {
                { "onStart", RemoveShellmapUI },
                { "onExit", () => SwitchMenu(MenuType.Main) },
                { "directConnectEndPoint", endpoint },
            });
        }

        void LoadMapIntoEditor(string uid)
        {
            ConnectionLogic.Connect(Game.CreateLocalServer(uid),
                                    "",
                                    () => { Game.LoadEditor(uid); },
                                    () => { Game.CloseServer(); SwitchMenu(MenuType.MapEditor); });

            DiscordService.UpdateStatus(DiscordState.InMapEditor);

            lastGameState = MenuPanel.MapEditor;
        }

        void SetNewsStatus(string message)
        {
            message            = WidgetUtils.WrapText(message, newsStatus.Bounds.Width, Game.Renderer.Fonts[newsStatus.Font]);
            newsStatus.GetText = () => message;
        }

        void RemoveShellmapUI()
        {
            rootMenu.Parent.RemoveChild(rootMenu);
        }

        void StartSkirmishGame()
        {
            var map = Game.ModData.MapCache.ChooseInitialMap(Game.Settings.Server.Map, Game.CosmeticRandom);

            Game.Settings.Server.Map = map;
            Game.Settings.Save();

            ConnectionLogic.Connect(Game.CreateLocalServer(map),
                                    "",
                                    OpenSkirmishLobbyPanel,
                                    () => { Game.CloseServer(); SwitchMenu(MenuType.Main); });
        }

        void OpenMissionBrowserPanel()
        {
            SwitchMenu(MenuType.None);
            Game.OpenWindow("MISSIONBROWSER_PANEL", new WidgetArgs
            {
                { "onExit", () => SwitchMenu(MenuType.Singleplayer) },
                { "onStart", () => { RemoveShellmapUI(); lastGameState = MenuPanel.Missions; } }
            });
        }

        void OpenSkirmishLobbyPanel()
        {
            SwitchMenu(MenuType.None);
            Game.OpenWindow("SERVER_LOBBY", new WidgetArgs
            {
                { "onExit", () => { Game.Disconnect(); SwitchMenu(MenuType.Singleplayer); } },
                { "onStart", () => { RemoveShellmapUI(); lastGameState = MenuPanel.Skirmish; } },
                { "skirmishMode", true }
            });
        }

        void OpenMultiplayerPanel()
        {
            SwitchMenu(MenuType.None);
            Ui.OpenWindow("MULTIPLAYER_PANEL", new WidgetArgs
            {
                { "onStart", () => { RemoveShellmapUI(); lastGameState = MenuPanel.Multiplayer; } },
                { "onExit", () => SwitchMenu(MenuType.Main) },
                { "directConnectEndPoint", null },
            });
        }

        void OpenReplayBrowserPanel()
        {
            SwitchMenu(MenuType.None);
            Ui.OpenWindow("REPLAYBROWSER_PANEL", new WidgetArgs
            {
                { "onExit", () => SwitchMenu(MenuType.Extras) },
                { "onStart", () => { RemoveShellmapUI(); lastGameState = MenuPanel.Replays; } }
            });
        }

        void OpenGameSaveBrowserPanel()
        {
            SwitchMenu(MenuType.None);
            Ui.OpenWindow("GAMESAVE_BROWSER_PANEL", new WidgetArgs
            {
                { "onExit", () => SwitchMenu(MenuType.Singleplayer) },
                { "onStart", () => { RemoveShellmapUI(); lastGameState = MenuPanel.GameSaves; } },
                { "isSavePanel", false },
                { "world", null }
            });
        }
Example #21
0
 void SetNewsStatus(string message)
 {
     message            = WidgetUtils.WrapText(message, newsStatus.Bounds.Width, Game.Renderer.Fonts[newsStatus.Font]);
     newsStatus.GetText = () => message;
 }
Example #22
0
        public MainMenuLogic(Widget widget, World world, ModData modData)
        {
            rootMenu = widget;
            rootMenu.Get <LabelWidget>("VERSION_LABEL").Text = modData.Manifest.Metadata.Version;

            // Menu buttons
            var mainMenu = widget.Get("MAIN_MENU");

            mainMenu.IsVisible = () => menuType == MenuType.Main;

            mainMenu.Get <ButtonWidget>("SINGLEPLAYER_BUTTON").OnClick = () => SwitchMenu(MenuType.Singleplayer);

            mainMenu.Get <ButtonWidget>("MULTIPLAYER_BUTTON").OnClick = () =>
            {
                SwitchMenu(MenuType.None);
                Ui.OpenWindow("MULTIPLAYER_PANEL", new WidgetArgs
                {
                    { "onStart", RemoveShellmapUI },
                    { "onExit", () => SwitchMenu(MenuType.Main) },
                    { "directConnectHost", null },
                    { "directConnectPort", 0 },
                });
            };

            mainMenu.Get <ButtonWidget>("CONTENT_BUTTON").OnClick = () =>
            {
                // Switching mods changes the world state (by disposing it),
                // so we can't do this inside the input handler.
                Game.RunAfterTick(() =>
                {
                    Game.InitializeMod("modcontent", new Arguments(new[] { "Content.Mod=" + modData.Manifest.Id }));
                });
            };

            mainMenu.Get <ButtonWidget>("SETTINGS_BUTTON").OnClick = () =>
            {
                SwitchMenu(MenuType.None);
                Game.OpenWindow("SETTINGS_PANEL", new WidgetArgs
                {
                    { "onExit", () => SwitchMenu(MenuType.Main) }
                });
            };

            mainMenu.Get <ButtonWidget>("EXTRAS_BUTTON").OnClick = () => SwitchMenu(MenuType.Extras);

            mainMenu.Get <ButtonWidget>("QUIT_BUTTON").OnClick = Game.Exit;

            // Singleplayer menu
            var singleplayerMenu = widget.Get("SINGLEPLAYER_MENU");

            singleplayerMenu.IsVisible = () => menuType == MenuType.Singleplayer;

            var missionsButton = singleplayerMenu.Get <ButtonWidget>("MISSIONS_BUTTON");

            missionsButton.OnClick = () =>
            {
                SwitchMenu(MenuType.None);
                Game.OpenWindow("MISSIONBROWSER_PANEL", new WidgetArgs
                {
                    { "onExit", () => SwitchMenu(MenuType.Singleplayer) },
                    { "onStart", RemoveShellmapUI }
                });
            };

            var hasCampaign = modData.Manifest.Missions.Any();
            var hasMissions = modData.MapCache
                              .Any(p => p.Status == MapStatus.Available && p.Visibility.HasFlag(MapVisibility.MissionSelector));

            missionsButton.Disabled = !hasCampaign && !hasMissions;

            singleplayerMenu.Get <ButtonWidget>("SKIRMISH_BUTTON").OnClick = StartSkirmishGame;

            singleplayerMenu.Get <ButtonWidget>("BACK_BUTTON").OnClick = () => SwitchMenu(MenuType.Main);

            // Extras menu
            var extrasMenu = widget.Get("EXTRAS_MENU");

            extrasMenu.IsVisible = () => menuType == MenuType.Extras;

            extrasMenu.Get <ButtonWidget>("REPLAYS_BUTTON").OnClick = () =>
            {
                SwitchMenu(MenuType.None);
                Ui.OpenWindow("REPLAYBROWSER_PANEL", new WidgetArgs
                {
                    { "onExit", () => SwitchMenu(MenuType.Extras) },
                    { "onStart", RemoveShellmapUI }
                });
            };

            extrasMenu.Get <ButtonWidget>("MUSIC_BUTTON").OnClick = () =>
            {
                SwitchMenu(MenuType.None);
                Ui.OpenWindow("MUSIC_PANEL", new WidgetArgs
                {
                    { "onExit", () => SwitchMenu(MenuType.Extras) },
                    { "world", world }
                });
            };

            extrasMenu.Get <ButtonWidget>("MAP_EDITOR_BUTTON").OnClick = () => SwitchMenu(MenuType.MapEditor);

            var assetBrowserButton = extrasMenu.GetOrNull <ButtonWidget>("ASSETBROWSER_BUTTON");

            if (assetBrowserButton != null)
            {
                assetBrowserButton.OnClick = () =>
                {
                    SwitchMenu(MenuType.None);
                    Game.OpenWindow("ASSETBROWSER_PANEL", new WidgetArgs
                    {
                        { "onExit", () => SwitchMenu(MenuType.Extras) },
                    });
                }
            }
            ;

            extrasMenu.Get <ButtonWidget>("CREDITS_BUTTON").OnClick = () =>
            {
                SwitchMenu(MenuType.None);
                Ui.OpenWindow("CREDITS_PANEL", new WidgetArgs
                {
                    { "onExit", () => SwitchMenu(MenuType.Extras) },
                });
            };

            extrasMenu.Get <ButtonWidget>("BACK_BUTTON").OnClick = () => SwitchMenu(MenuType.Main);

            // Map editor menu
            var mapEditorMenu = widget.Get("MAP_EDITOR_MENU");

            mapEditorMenu.IsVisible = () => menuType == MenuType.MapEditor;

            // Loading into the map editor
            Game.BeforeGameStart += RemoveShellmapUI;

            var onSelect = new Action <string>(uid => LoadMapIntoEditor(modData.MapCache[uid].Uid));

            var newMapButton = widget.Get <ButtonWidget>("NEW_MAP_BUTTON");

            newMapButton.OnClick = () =>
            {
                SwitchMenu(MenuType.None);
                Game.OpenWindow("NEW_MAP_BG", new WidgetArgs()
                {
                    { "onSelect", onSelect },
                    { "onExit", () => SwitchMenu(MenuType.MapEditor) }
                });
            };

            var loadMapButton = widget.Get <ButtonWidget>("LOAD_MAP_BUTTON");

            loadMapButton.OnClick = () =>
            {
                SwitchMenu(MenuType.None);
                Game.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
                {
                    { "initialMap", null },
                    { "initialTab", MapClassification.User },
                    { "onExit", () => SwitchMenu(MenuType.MapEditor) },
                    { "onSelect", onSelect },
                    { "filter", MapVisibility.Lobby | MapVisibility.Shellmap | MapVisibility.MissionSelector },
                });
            };

            mapEditorMenu.Get <ButtonWidget>("BACK_BUTTON").OnClick = () => SwitchMenu(MenuType.Extras);

            var newsBG = widget.GetOrNull("NEWS_BG");

            if (newsBG != null)
            {
                newsBG.IsVisible = () => Game.Settings.Game.FetchNews && menuType != MenuType.None && menuType != MenuType.SystemInfoPrompt;

                newsPanel    = Ui.LoadWidget <ScrollPanelWidget>("NEWS_PANEL", null, new WidgetArgs());
                newsTemplate = newsPanel.Get("NEWS_ITEM_TEMPLATE");
                newsPanel.RemoveChild(newsTemplate);

                newsStatus = newsPanel.Get <LabelWidget>("NEWS_STATUS");
                SetNewsStatus("Loading news");
            }

            Game.OnRemoteDirectConnect += OnRemoteDirectConnect;

            var newsURL = modData.Manifest.Get <WebServices>().GameNews;

            // System information opt-out prompt
            var sysInfoPrompt = widget.Get("SYSTEM_INFO_PROMPT");

            sysInfoPrompt.IsVisible = () => menuType == MenuType.SystemInfoPrompt;
            if (Game.Settings.Debug.SystemInformationVersionPrompt < SystemInformationVersion)
            {
                menuType = MenuType.SystemInfoPrompt;

                var sysInfoCheckbox = sysInfoPrompt.Get <CheckboxWidget>("SYSINFO_CHECKBOX");
                sysInfoCheckbox.IsChecked = () => Game.Settings.Debug.SendSystemInformation;
                sysInfoCheckbox.OnClick   = () => Game.Settings.Debug.SendSystemInformation ^= true;

                var sysInfoData = sysInfoPrompt.Get <ScrollPanelWidget>("SYSINFO_DATA");
                var template    = sysInfoData.Get <LabelWidget>("DATA_TEMPLATE");
                sysInfoData.RemoveChildren();

                foreach (var info in GetSystemInformation().Values)
                {
                    var label = template.Clone() as LabelWidget;
                    var text  = info.First + ": " + info.Second;
                    label.GetText = () => text;
                    sysInfoData.AddChild(label);
                }

                sysInfoPrompt.Get <ButtonWidget>("BACK_BUTTON").OnClick = () =>
                {
                    Game.Settings.Debug.SystemInformationVersionPrompt = SystemInformationVersion;
                    Game.Settings.Save();
                    SwitchMenu(MenuType.Main);
                    LoadAndDisplayNews(newsURL, newsBG);
                };
            }
            else
            {
                LoadAndDisplayNews(newsURL, newsBG);
            }
        }

        void LoadAndDisplayNews(string newsURL, Widget newsBG)
        {
            if (newsBG != null)
            {
                var cacheFile   = Platform.ResolvePath("^", "news.yaml");
                var currentNews = ParseNews(cacheFile);
                if (currentNews != null)
                {
                    DisplayNews(currentNews);
                }

                var newsButton = newsBG.GetOrNull <DropDownButtonWidget>("NEWS_BUTTON");
                if (newsButton != null)
                {
                    if (!fetchedNews)
                    {
                        // Send the mod and engine version to support version-filtered news (update prompts)
                        newsURL += "?version={0}&mod={1}&modversion={2}".F(
                            Uri.EscapeUriString(Game.Mods["modcontent"].Metadata.Version),
                            Uri.EscapeUriString(Game.ModData.Manifest.Id),
                            Uri.EscapeUriString(Game.ModData.Manifest.Metadata.Version));

                        // Append system profile data if the player has opted in
                        if (Game.Settings.Debug.SendSystemInformation)
                        {
                            newsURL += "&sysinfoversion={0}&".F(SystemInformationVersion)
                                       + GetSystemInformation()
                                       .Select(kv => kv.Key + "=" + Uri.EscapeUriString(kv.Value.Second))
                                       .JoinWith("&");
                        }

                        new Download(newsURL, cacheFile, e => { },
                                     e => NewsDownloadComplete(e, cacheFile, currentNews,
                                                               () => newsButton.AttachPanel(newsPanel)));
                    }

                    newsButton.OnClick = () => newsButton.AttachPanel(newsPanel);
                }
            }
        }

        void OnRemoteDirectConnect(string host, int port)
        {
            SwitchMenu(MenuType.None);
            Ui.OpenWindow("MULTIPLAYER_PANEL", new WidgetArgs
            {
                { "onStart", RemoveShellmapUI },
                { "onExit", () => SwitchMenu(MenuType.Main) },
                { "directConnectHost", host },
                { "directConnectPort", port },
            });
        }

        void LoadMapIntoEditor(string uid)
        {
            ConnectionLogic.Connect(IPAddress.Loopback.ToString(),
                                    Game.CreateLocalServer(uid),
                                    "",
                                    () => { Game.LoadEditor(uid); },
                                    () => { Game.CloseServer(); SwitchMenu(MenuType.MapEditor); });
        }

        void SetNewsStatus(string message)
        {
            message            = WidgetUtils.WrapText(message, newsStatus.Bounds.Width, Game.Renderer.Fonts[newsStatus.Font]);
            newsStatus.GetText = () => message;
        }
Example #23
0
        public MainMenuLogic(Widget widget, World world, ModData modData)
        {
            rootMenu = widget;
            rootMenu.Get <LabelWidget>("VERSION_LABEL").Text = modData.Manifest.Metadata.Version;

            // Menu buttons
            var mainMenu = widget.Get("MAIN_MENU");

            mainMenu.IsVisible = () => menuType == MenuType.Main;

            mainMenu.Get <ButtonWidget>("SINGLEPLAYER_BUTTON").OnClick = () => SwitchMenu(MenuType.Singleplayer);

            mainMenu.Get <ButtonWidget>("MULTIPLAYER_BUTTON").OnClick = OpenMultiplayerPanel;

            mainMenu.Get <ButtonWidget>("CONTENT_BUTTON").OnClick = () =>
            {
                // Switching mods changes the world state (by disposing it),
                // so we can't do this inside the input handler.
                Game.RunAfterTick(() =>
                {
                    var content = modData.Manifest.Get <ModContent>();
                    Game.InitializeMod(content.ContentInstallerMod, new Arguments(new[] { "Content.Mod=" + modData.Manifest.Id }));
                });
            };

            mainMenu.Get <ButtonWidget>("SETTINGS_BUTTON").OnClick = () =>
            {
                SwitchMenu(MenuType.None);
                Game.OpenWindow("SETTINGS_PANEL", new WidgetArgs
                {
                    { "onExit", () => SwitchMenu(MenuType.Main) }
                });
            };

            mainMenu.Get <ButtonWidget>("EXTRAS_BUTTON").OnClick = () => SwitchMenu(MenuType.Extras);

            mainMenu.Get <ButtonWidget>("QUIT_BUTTON").OnClick = Game.Exit;

            // Singleplayer menu
            var singleplayerMenu = widget.Get("SINGLEPLAYER_MENU");

            singleplayerMenu.IsVisible = () => menuType == MenuType.Singleplayer;

            var missionsButton = singleplayerMenu.Get <ButtonWidget>("MISSIONS_BUTTON");

            missionsButton.OnClick = OpenMissionBrowserPanel;

            var hasCampaign = modData.Manifest.Missions.Any();
            var hasMissions = modData.MapCache
                              .Any(p => p.Status == MapStatus.Available && p.Visibility.HasFlag(MapVisibility.MissionSelector));

            missionsButton.Disabled = !hasCampaign && !hasMissions;

            var hasMaps        = modData.MapCache.Any(p => p.Visibility.HasFlag(MapVisibility.Lobby));
            var skirmishButton = singleplayerMenu.Get <ButtonWidget>("SKIRMISH_BUTTON");

            skirmishButton.OnClick  = StartSkirmishGame;
            skirmishButton.Disabled = !hasMaps;

            var loadButton = singleplayerMenu.Get <ButtonWidget>("LOAD_BUTTON");

            loadButton.IsDisabled = () => !GameSaveBrowserLogic.IsLoadPanelEnabled(modData.Manifest);
            loadButton.OnClick    = OpenGameSaveBrowserPanel;

            singleplayerMenu.Get <ButtonWidget>("BACK_BUTTON").OnClick = () => SwitchMenu(MenuType.Main);

            // Extras menu
            var extrasMenu = widget.Get("EXTRAS_MENU");

            extrasMenu.IsVisible = () => menuType == MenuType.Extras;

            extrasMenu.Get <ButtonWidget>("REPLAYS_BUTTON").OnClick = OpenReplayBrowserPanel;

            extrasMenu.Get <ButtonWidget>("MUSIC_BUTTON").OnClick = () =>
            {
                SwitchMenu(MenuType.None);
                Ui.OpenWindow("MUSIC_PANEL", new WidgetArgs
                {
                    { "onExit", () => SwitchMenu(MenuType.Extras) },
                    { "world", world }
                });
            };

            extrasMenu.Get <ButtonWidget>("MAP_EDITOR_BUTTON").OnClick = () => SwitchMenu(MenuType.MapEditor);

            var assetBrowserButton = extrasMenu.GetOrNull <ButtonWidget>("ASSETBROWSER_BUTTON");

            if (assetBrowserButton != null)
            {
                assetBrowserButton.OnClick = () =>
                {
                    SwitchMenu(MenuType.None);
                    Game.OpenWindow("ASSETBROWSER_PANEL", new WidgetArgs
                    {
                        { "onExit", () => SwitchMenu(MenuType.Extras) },
                    });
                }
            }
            ;

            extrasMenu.Get <ButtonWidget>("CREDITS_BUTTON").OnClick = () =>
            {
                SwitchMenu(MenuType.None);
                Ui.OpenWindow("CREDITS_PANEL", new WidgetArgs
                {
                    { "onExit", () => SwitchMenu(MenuType.Extras) },
                });
            };

            extrasMenu.Get <ButtonWidget>("BACK_BUTTON").OnClick = () => SwitchMenu(MenuType.Main);

            // Map editor menu
            var mapEditorMenu = widget.Get("MAP_EDITOR_MENU");

            mapEditorMenu.IsVisible = () => menuType == MenuType.MapEditor;

            // Loading into the map editor
            Game.BeforeGameStart += RemoveShellmapUI;

            var onSelect = new Action <string>(uid => LoadMapIntoEditor(modData.MapCache[uid].Uid));

            var newMapButton = widget.Get <ButtonWidget>("NEW_MAP_BUTTON");

            newMapButton.OnClick = () =>
            {
                SwitchMenu(MenuType.None);
                Game.OpenWindow("NEW_MAP_BG", new WidgetArgs()
                {
                    { "onSelect", onSelect },
                    { "onExit", () => SwitchMenu(MenuType.MapEditor) }
                });
            };

            var loadMapButton = widget.Get <ButtonWidget>("LOAD_MAP_BUTTON");

            loadMapButton.OnClick = () =>
            {
                SwitchMenu(MenuType.None);
                Game.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
                {
                    { "initialMap", null },
                    { "initialTab", MapClassification.User },
                    { "onExit", () => SwitchMenu(MenuType.MapEditor) },
                    { "onSelect", onSelect },
                    { "filter", MapVisibility.Lobby | MapVisibility.Shellmap | MapVisibility.MissionSelector },
                });
            };

            loadMapButton.Disabled = !hasMaps;

            mapEditorMenu.Get <ButtonWidget>("BACK_BUTTON").OnClick = () => SwitchMenu(MenuType.Extras);

            var newsBG = widget.GetOrNull("NEWS_BG");

            if (newsBG != null)
            {
                newsBG.IsVisible = () => Game.Settings.Game.FetchNews && menuType != MenuType.None && menuType != MenuType.StartupPrompts;

                newsPanel    = Ui.LoadWidget <ScrollPanelWidget>("NEWS_PANEL", null, new WidgetArgs());
                newsTemplate = newsPanel.Get("NEWS_ITEM_TEMPLATE");
                newsPanel.RemoveChild(newsTemplate);

                newsStatus = newsPanel.Get <LabelWidget>("NEWS_STATUS");
                SetNewsStatus("Loading news");
            }

            Game.OnRemoteDirectConnect += OnRemoteDirectConnect;

            // Check for updates in the background
            var webServices = modData.Manifest.Get <WebServices>();

            if (Game.Settings.Debug.CheckVersion)
            {
                webServices.CheckModVersion();
            }

            var updateLabel = rootMenu.GetOrNull("UPDATE_NOTICE");

            if (updateLabel != null)
            {
                updateLabel.IsVisible = () => !newsOpen && menuType != MenuType.None &&
                                        menuType != MenuType.StartupPrompts &&
                                        webServices.ModVersionStatus == ModVersionStatus.Outdated;
            }

            var playerProfile = widget.GetOrNull("PLAYER_PROFILE_CONTAINER");

            if (playerProfile != null)
            {
                Func <bool> minimalProfile = () => Ui.CurrentWindow() != null;
                Game.LoadWidget(world, "LOCAL_PROFILE_PANEL", playerProfile, new WidgetArgs()
                {
                    { "minimalProfile", minimalProfile }
                });
            }

            menuType = MenuType.StartupPrompts;

            Action onIntroductionComplete = () =>
            {
                Action onSysInfoComplete = () =>
                {
                    LoadAndDisplayNews(webServices.GameNews, newsBG);
                    SwitchMenu(MenuType.Main);
                };

                if (SystemInfoPromptLogic.ShouldShowPrompt())
                {
                    Ui.OpenWindow("MAINMENU_SYSTEM_INFO_PROMPT", new WidgetArgs
                    {
                        { "onComplete", onSysInfoComplete }
                    });
                }
                else
                {
                    onSysInfoComplete();
                }
            };

            if (IntroductionPromptLogic.ShouldShowPrompt())
            {
                Game.OpenWindow("MAINMENU_INTRODUCTION_PROMPT", new WidgetArgs
                {
                    { "onComplete", onIntroductionComplete }
                });
            }
            else
            {
                onIntroductionComplete();
            }

            Game.OnShellmapLoaded += OpenMenuBasedOnLastGame;
        }

        void LoadAndDisplayNews(string newsURL, Widget newsBG)
        {
            if (newsBG != null && Game.Settings.Game.FetchNews)
            {
                var cacheFile   = Platform.ResolvePath(Platform.SupportDirPrefix, "news.yaml");
                var currentNews = ParseNews(cacheFile);
                if (currentNews != null)
                {
                    DisplayNews(currentNews);
                }

                var newsButton = newsBG.GetOrNull <DropDownButtonWidget>("NEWS_BUTTON");
                if (newsButton != null)
                {
                    if (!fetchedNews)
                    {
                        // Send the mod and engine version to support version-filtered news (update prompts)
                        newsURL += "?version={0}&mod={1}&modversion={2}".F(
                            Uri.EscapeUriString(Game.EngineVersion),
                            Uri.EscapeUriString(Game.ModData.Manifest.Id),
                            Uri.EscapeUriString(Game.ModData.Manifest.Metadata.Version));

                        // Parameter string is blank if the player has opted out
                        newsURL += SystemInfoPromptLogic.CreateParameterString();

                        new Download(newsURL, cacheFile, e => { },
                                     e => NewsDownloadComplete(e, cacheFile, currentNews,
                                                               () => OpenNewsPanel(newsButton)));
                    }

                    newsButton.OnClick = () => OpenNewsPanel(newsButton);
                }
            }
        }

        void OpenNewsPanel(DropDownButtonWidget button)
        {
            newsOpen = true;
            button.AttachPanel(newsPanel, () => newsOpen = false);
        }

        void OnRemoteDirectConnect(ConnectionTarget endpoint)
        {
            SwitchMenu(MenuType.None);
            Ui.OpenWindow("MULTIPLAYER_PANEL", new WidgetArgs
            {
                { "onStart", RemoveShellmapUI },
                { "onExit", () => SwitchMenu(MenuType.Main) },
                { "directConnectEndPoint", endpoint },
            });
        }

        void LoadMapIntoEditor(string uid)
        {
            ConnectionLogic.Connect(Game.CreateLocalServer(uid),
                                    "",
                                    () => { Game.LoadEditor(uid); },
                                    () => { Game.CloseServer(); SwitchMenu(MenuType.MapEditor); });

            lastGameState = MenuPanel.MapEditor;
        }

        void SetNewsStatus(string message)
        {
            message            = WidgetUtils.WrapText(message, newsStatus.Bounds.Width, Game.Renderer.Fonts[newsStatus.Font]);
            newsStatus.GetText = () => message;
        }