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" ]
}