From 11e4bc70225c12ee6b2966ab6e996abce98a373c Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 5 Sep 2022 00:34:25 -0400 Subject: [PATCH] MenuFramework support, outdated version popup, one shot popups for addons --- NewHorizons/Assets/translations/english.json | 3 +- NewHorizons/Assets/translations/french.json | 3 +- NewHorizons/External/Configs/AddonConfig.cs | 5 ++ NewHorizons/External/NewHorizonsData.cs | 21 ++++++- NewHorizons/Main.cs | 38 ++++++++---- .../OtherMods/MenuFramework/IMenuAPI.cs | 20 +++++++ .../OtherMods/MenuFramework/MenuHandler.cs | 60 +++++++++++++++++++ NewHorizons/Utility/VersionUtility.cs | 25 ++++++++ NewHorizons/manifest.json | 2 +- 9 files changed, 160 insertions(+), 17 deletions(-) create mode 100644 NewHorizons/OtherMods/MenuFramework/IMenuAPI.cs create mode 100644 NewHorizons/OtherMods/MenuFramework/MenuHandler.cs create mode 100644 NewHorizons/Utility/VersionUtility.cs diff --git a/NewHorizons/Assets/translations/english.json b/NewHorizons/Assets/translations/english.json index b7aae651..ef553f33 100644 --- a/NewHorizons/Assets/translations/english.json +++ b/NewHorizons/Assets/translations/english.json @@ -14,7 +14,8 @@ "WARP_LOCKED": "AUTOPILOT LOCKED TO:\n{0}", "LOCK_AUTOPILOT_WARP": "Lock Autopilot to Star System", "RICH_PRESENCE_EXPLORING": "Exploring {0}.", - "RICH_PRESENCE_WARPING": "Warping to {0}." + "RICH_PRESENCE_WARPING": "Warping to {0}.", + "OUTDATED_VERSION_WARNING": "WARNING\n\nNew Horizons only works on version {0} or higher. You're on version {1}.\n\nPlease update your game or uninstall NH." }, "AchievementTranslations": { "NH_EATEN_OUTSIDE_BRAMBLE": { diff --git a/NewHorizons/Assets/translations/french.json b/NewHorizons/Assets/translations/french.json index 37adf8ac..48dc1d4c 100644 --- a/NewHorizons/Assets/translations/french.json +++ b/NewHorizons/Assets/translations/french.json @@ -14,7 +14,8 @@ "WARP_LOCKED": "PILOTE AUTOMATIQUE VISÉ SUR:\n{0}", "LOCK_AUTOPILOT_WARP": "Visez le pilote automatique", "RICH_PRESENCE_EXPLORING": "En explorant {0}.", - "RICH_PRESENCE_WARPING": "En route vers {0}." + "RICH_PRESENCE_WARPING": "En route vers {0}.", + "OUTDATED_VERSION_WARNING": "AVERTISSEMENT\n\nNew Horizons fonctionne seulement sur la version {0} ou plus récente. Vous êtes sur la version {1}.\n\nVeuillez mettre à jour votre jeu ou désinstaller NH." }, "AchievementTranslations": { "NH_EATEN_OUTSIDE_BRAMBLE": { diff --git a/NewHorizons/External/Configs/AddonConfig.cs b/NewHorizons/External/Configs/AddonConfig.cs index 08069e00..00257080 100644 --- a/NewHorizons/External/Configs/AddonConfig.cs +++ b/NewHorizons/External/Configs/AddonConfig.cs @@ -28,5 +28,10 @@ namespace NewHorizons.External.Configs /// Credits info for this mod. A list of contributors and their roles separated by #. For example: xen#New Horizons dev. /// public string[] credits; + + /// + /// A pop-up message for the first time a user runs the add-on + /// + public string popupMessage; } } diff --git a/NewHorizons/External/NewHorizonsData.cs b/NewHorizons/External/NewHorizonsData.cs index f90cb479..52a8cbf1 100644 --- a/NewHorizons/External/NewHorizonsData.cs +++ b/NewHorizons/External/NewHorizonsData.cs @@ -19,7 +19,7 @@ namespace NewHorizons.External _activeProfileName = GetProfileName(); if (_activeProfileName == null) { - Logger.LogError("Couldn't find active profile, are you on Gamepass?"); + Logger.LogWarning("Couldn't find active profile, are you on Gamepass?"); _activeProfileName = "XboxGamepassDefaultProfile"; } @@ -82,12 +82,13 @@ namespace NewHorizons.External KnownFrequencies = new List(); KnownSignals = new List(); NewlyRevealedFactIDs = new List(); + PopupsRead = new List(); } public List KnownFrequencies { get; } public List KnownSignals { get; } - public List NewlyRevealedFactIDs { get; } + public List PopupsRead { get; } } #region Frequencies @@ -155,5 +156,21 @@ namespace NewHorizons.External } #endregion + + #region Read popups + + public static void ReadOneTimePopup(string id) + { + _activeProfile?.PopupsRead.Add(id); + Save(); + } + + public static bool HasReadOneTimePopup(string id) + { + // To avoid spam, we'll just say the popup has been read if we can't load the profile + return _activeProfile?.PopupsRead.Contains(id) ?? true; + } + + #endregion } } \ No newline at end of file diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index 80f5dc53..5eaaeb8f 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -24,6 +24,7 @@ using UnityEngine.SceneManagement; using Logger = NewHorizons.Utility.Logger; using NewHorizons.OtherMods.OWRichPresence; using NewHorizons.Components.SizeControllers; +using NewHorizons.OtherMods.MenuFramework; namespace NewHorizons { @@ -164,11 +165,21 @@ namespace NewHorizons TextTranslation.Get().SetLanguage(TextTranslation.Get().GetLanguage()); } + public void Awake() + { + Instance = this; + } + public void Start() { // Patches Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly()); + // Has to go before popups + LoadTranslations(ModHelper.Manifest.ModFolderPath + "Assets/", this); + + MenuHandler.Init(); + OnChangeStarSystem = new StarSystemEvent(); OnStarSystemLoaded = new StarSystemEvent(); OnPlanetLoaded = new StarSystemEvent(); @@ -176,7 +187,6 @@ namespace NewHorizons SceneManager.sceneLoaded += OnSceneLoaded; SceneManager.sceneUnloaded += OnSceneUnloaded; - Instance = this; GlobalMessenger.AddListener("PlayerDeath", OnDeath); GlobalMessenger.AddListener("WakeUp", OnWakeUp); @@ -310,9 +320,6 @@ namespace NewHorizons BrambleNodeBuilder.Init(BodyDict[CurrentStarSystem].Select(x => x.Config).Where(x => x.Bramble?.dimension != null).ToArray()); StarEvolutionController.Init(); - // Has to go before loading planets else the Discord Rich Presence mod won't show the right text - LoadTranslations(ModHelper.Manifest.ModFolderPath + "Assets/", this); - if (isSolarSystem) { foreach (var supernovaPlanetEffectController in GameObject.FindObjectsOfType()) @@ -539,16 +546,19 @@ namespace NewHorizons } } } - // Has to go before translations for achievements + if (Directory.Exists(folder + @"translations\")) + { + LoadTranslations(folder, mod); + } + // Has to go before translations for achievements but after regular ones (for popups) if (File.Exists(folder + "addon-manifest.json")) { LoadAddonManifest("addon-manifest.json", mod); } if (Directory.Exists(folder + @"translations\")) { - LoadTranslations(folder, mod); + LoadAchievementTranslations(mod); } - } catch (Exception ex) { @@ -564,6 +574,7 @@ namespace NewHorizons if (addonConfig.achievements != null) AchievementHandler.RegisterAddon(addonConfig, mod as ModBehaviour); if (addonConfig.credits != null) CreditsHandler.RegisterCredits(mod.ModHelper.Manifest.Name, addonConfig.credits); + if (!string.IsNullOrEmpty(addonConfig.popupMessage)) MenuHandler.RegisterOneTimePopup(mod, addonConfig.popupMessage); } private void LoadTranslations(string folder, IModBehaviour mod) @@ -584,16 +595,19 @@ namespace NewHorizons foundFile = true; TranslationHandler.RegisterTranslation(language, config); - - if (AchievementHandler.Enabled) - { - AchievementHandler.RegisterTranslationsFromFiles(mod as ModBehaviour, "translations"); - } } } if (!foundFile) Logger.LogWarning($"{mod.ModHelper.Manifest.Name} has a folder for translations but none were loaded"); } + private void LoadAchievementTranslations(IModBehaviour mod) + { + if (AchievementHandler.Enabled) + { + AchievementHandler.RegisterTranslationsFromFiles(mod as ModBehaviour, "translations"); + } + } + public NewHorizonsBody LoadConfig(IModBehaviour mod, string relativePath) { NewHorizonsBody body = null; diff --git a/NewHorizons/OtherMods/MenuFramework/IMenuAPI.cs b/NewHorizons/OtherMods/MenuFramework/IMenuAPI.cs new file mode 100644 index 00000000..f44aecdf --- /dev/null +++ b/NewHorizons/OtherMods/MenuFramework/IMenuAPI.cs @@ -0,0 +1,20 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace NewHorizons.OtherMods.MenuFramework +{ + public interface IMenuAPI + { + GameObject TitleScreen_MakeMenuOpenButton(string name, int index, Menu menuToOpen); + GameObject TitleScreen_MakeSceneLoadButton(string name, int index, SubmitActionLoadScene.LoadableScenes sceneToLoad, PopupMenu confirmPopup = null); + Button TitleScreen_MakeSimpleButton(string name, int index); + GameObject PauseMenu_MakeMenuOpenButton(string name, Menu menuToOpen, Menu customMenu = null); + GameObject PauseMenu_MakeSceneLoadButton(string name, SubmitActionLoadScene.LoadableScenes sceneToLoad, PopupMenu confirmPopup = null, Menu customMenu = null); + Button PauseMenu_MakeSimpleButton(string name, Menu customMenu = null); + Menu PauseMenu_MakePauseListMenu(string title); + PopupMenu MakeTwoChoicePopup(string message, string confirmText, string cancelText); + PopupInputMenu MakeInputFieldPopup(string message, string placeholderMessage, string confirmText, string cancelText); + PopupMenu MakeInfoPopup(string message, string continueButtonText); + void RegisterStartupPopup(string message); + } +} diff --git a/NewHorizons/OtherMods/MenuFramework/MenuHandler.cs b/NewHorizons/OtherMods/MenuFramework/MenuHandler.cs new file mode 100644 index 00000000..7d66258e --- /dev/null +++ b/NewHorizons/OtherMods/MenuFramework/MenuHandler.cs @@ -0,0 +1,60 @@ +using NewHorizons.External; +using NewHorizons.Handlers; +using NewHorizons.Utility; +using OWML.Common; +using System.Collections.Generic; +using System.Net.Mail; +using UnityEngine; +using static UnityEngine.InputSystem.InputRemoting; +using Logger = NewHorizons.Utility.Logger; + +namespace NewHorizons.OtherMods.MenuFramework +{ + public static class MenuHandler + { + private static IMenuAPI _menuApi; + + private static List<(IModBehaviour mod, string message)> _registeredPopups; + + public static void Init() + { + _menuApi = Main.Instance.ModHelper.Interaction.TryGetModApi("_nebula.MenuFramework"); + + TextTranslation.Get().OnLanguageChanged += OnLanguageChanged; + + _registeredPopups = new(); + } + + public static void OnLanguageChanged() + { + // Have to load save data before doing popups + NewHorizonsData.Load(); + + if (!VersionUtility.CheckUpToDate()) + { + var warning = string.Format(TranslationHandler.GetTranslation("OUTDATED_VERSION_WARNING", TranslationHandler.TextType.UI), + VersionUtility.RequiredVersionString, + Application.version); + + Logger.LogError(warning); + _menuApi.RegisterStartupPopup(warning); + } + + foreach(var (mod, message) in _registeredPopups) + { + if (!NewHorizonsData.HasReadOneTimePopup(mod.ModHelper.Manifest.UniqueName)) + { + _menuApi.RegisterStartupPopup(TranslationHandler.GetTranslation(message, TranslationHandler.TextType.UI)); + NewHorizonsData.ReadOneTimePopup(mod.ModHelper.Manifest.UniqueName); + } + } + + _registeredPopups.Clear(); + + // Just wanted to do this when the language is loaded in initially + TextTranslation.Get().OnLanguageChanged -= OnLanguageChanged; + } + + public static void RegisterOneTimePopup(IModBehaviour mod, string message) => _registeredPopups.Add((mod, message)); + } +} diff --git a/NewHorizons/Utility/VersionUtility.cs b/NewHorizons/Utility/VersionUtility.cs new file mode 100644 index 00000000..e7c0ea23 --- /dev/null +++ b/NewHorizons/Utility/VersionUtility.cs @@ -0,0 +1,25 @@ +using System.Linq; +using UnityEngine; + +namespace NewHorizons.Utility +{ + internal static class VersionUtility + { + public static int[] RequiredVersion => new int[] {1, 1, 12}; + public static string RequiredVersionString => string.Join(".", RequiredVersion); + + public static bool CheckUpToDate() + { + // If they're using an outdated game version we create an error popup here + var version = Application.version.Split('.').Select(x => int.Parse(x)).ToArray(); + var major = version[0]; + var minor = version[1]; + var patch = version[2]; + + // Must be at least 1.1.12 + return major > RequiredVersion[0] || + (major == RequiredVersion[0] && minor > RequiredVersion[1]) || + (major == RequiredVersion[0] && minor == RequiredVersion[1] && patch >= RequiredVersion[2]); + } + } +} diff --git a/NewHorizons/manifest.json b/NewHorizons/manifest.json index 5696ae38..a4be9c22 100644 --- a/NewHorizons/manifest.json +++ b/NewHorizons/manifest.json @@ -6,7 +6,7 @@ "uniqueName": "xen.NewHorizons", "version": "1.5.1", "owmlVersion": "2.6.0", - "dependencies": [ "JohnCorby.VanillaFix" ], + "dependencies": [ "JohnCorby.VanillaFix", "_nebula.MenuFramework" ], "conflicts": [ "Raicuparta.QuantumSpaceBuddies", "PacificEngine.OW_Randomizer" ], "pathsToPreserve": [ "planets", "systems", "translations" ] }