From 663832cd6697d4646ffeda183e62c0e2fa5ddd48 Mon Sep 17 00:00:00 2001 From: Sam Byass Date: Thu, 17 Feb 2022 13:37:51 +0000 Subject: [PATCH] 3.3: Big cleanup + ShitRimworldSays support --- 1.3/Assemblies/BetterLoading.dll | Bin 80896 -> 89088 bytes 1.3/Assemblies/Tomlet.dll | Bin 0 -> 70144 bytes About/About.xml | 2 +- About/Manifest.xml | 2 +- README.md | 10 +- Source/BetterLoading.csproj | 5 +- Source/BetterLoading.sln | 9 + Source/BetterLoadingConfig.cs | 33 ++++ Source/BetterLoadingConfigManager.cs | 61 ++++++ Source/BetterLoadingMain.cs | 102 ++++------ Source/BetterLoadingTip.cs | 13 ++ Source/Compat/HugsLib/StageHugsLibInit.cs | 16 +- Source/Compat/ShitRimworldSaysCompat.cs | 100 ++++++++++ Source/LoadingScreen.cs | 182 ++++++------------ Source/LoadingScreenTipManager.cs | 132 +++++++++++++ Source/Stage/InitialLoad/0StageInitMods.cs | 6 +- Source/Stage/InitialLoad/1StageReadXML.cs | 4 +- Source/Stage/InitialLoad/2StageUnifyXML.cs | 4 +- .../Stage/InitialLoad/3StageApplyPatches.cs | 6 +- .../Stage/InitialLoad/4StageRegisterDefs.cs | 4 +- .../Stage/InitialLoad/5StageConstructDefs.cs | 10 +- .../InitialLoad/6StageResolveDefDatabases.cs | 11 +- .../7StageRunPostLoadPreFinalizeCallbacks.cs | 6 +- .../InitialLoad/8StageRunStaticCctors.cs | 4 +- .../9StageRunPostFinalizeCallbacks.cs | 4 +- Source/Stage/LoadingStage.cs | 2 +- Source/Stage/SaveLoad/0LoadSmallComponents.cs | 2 +- Source/Stage/SaveLoad/1LoadWorldMap.cs | 8 +- Source/Stage/SaveLoad/2LoadMaps.cs | 8 +- Source/Stage/SaveLoad/3FinalizeScribeLoad.cs | 2 +- Source/Stage/SaveLoad/4SpawnAllThings.cs | 6 +- Source/StageTimingData.cs | 2 +- 32 files changed, 505 insertions(+), 251 deletions(-) create mode 100644 1.3/Assemblies/Tomlet.dll create mode 100644 Source/BetterLoadingConfig.cs create mode 100644 Source/BetterLoadingConfigManager.cs create mode 100644 Source/BetterLoadingTip.cs create mode 100644 Source/Compat/ShitRimworldSaysCompat.cs create mode 100644 Source/LoadingScreenTipManager.cs diff --git a/1.3/Assemblies/BetterLoading.dll b/1.3/Assemblies/BetterLoading.dll index c11350464f19b89ed796345776e76c465db0930c..512f35e6d436e8327318b398c5b887fdb2253ee5 100644 GIT binary patch literal 89088 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 literal 80896 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

$ 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 Dn&i+d diff --git a/1.3/Assemblies/Tomlet.dll b/1.3/Assemblies/Tomlet.dll new file mode 100644 index 0000000000000000000000000000000000000000..a2dfea7d85c4106f628a63f17e6258be1556dc1b GIT binary patch literal 70144 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 T7h`|;`uA&s|3B{k%M|!O2(qjt literal 0 HcmV?d00001 diff --git a/About/About.xml b/About/About.xml index e16671d..3e5ddd9 100755 --- a/About/About.xml +++ b/About/About.xml @@ -3,7 +3,7 @@ BetterLoading Samboy063 me.samboycoding.betterloading.dev - + https://github.com/SamboyCoding/RimworldBetterLoading

  • 1.0
  • 1.1
  • diff --git a/About/Manifest.xml b/About/Manifest.xml index 077d643..829f743 100755 --- a/About/Manifest.xml +++ b/About/Manifest.xml @@ -1,7 +1,7 @@ BetterLoading - 3.2.0.1 + 3.3.0.0
  • Core >= 1.0
  • Startupimpact
  • diff --git a/README.md b/README.md index d7a4e4b..a23bbfe 100755 --- a/README.md +++ b/README.md @@ -1,5 +1,11 @@ -# RimworldBetterLoading +# BetterLoading +## A mod to make RimWorld loading screens look nice See the [steam workshop](https://steamcommunity.com/sharedfiles/filedetails/?id=1999454301) page for a full description. -If you encounter issues, feel free to @ me on the Rimworld discord (my name there is `Samboy [BetterLoading]`) or DM me (Samboy#0063) - I do want to know of them, and will fix them ASAP. +If you encounter issues, I would really appreciate knowing about them. You can reach me via several methods: +- I have a [dedicated discord server](https://discord.gg/https://discord.gg/3d8xvnBJgX) for my code projects, including BetterLoading. +- I'm in the [official RimWorld discord](https://discord.gg/rimworld) as `Samboy [BetterLoading]`, and you can mention me in the mod-general channel. +- You can DM me (Samboy#0063) on discord, I accept random friend requests. +- You can leave a comment on the steam workshop page (though these don't get checked quite as often) +- You can open an issue here on github, which will send a message to my discord server. diff --git a/Source/BetterLoading.csproj b/Source/BetterLoading.csproj index bafcf52..c87506c 100755 --- a/Source/BetterLoading.csproj +++ b/Source/BetterLoading.csproj @@ -3,8 +3,8 @@ TargetFramework Library net48 - 8 - annotations + 10 + enable false @@ -45,5 +45,6 @@ + \ No newline at end of file diff --git a/Source/BetterLoading.sln b/Source/BetterLoading.sln index 60e100f..37b2f27 100644 --- a/Source/BetterLoading.sln +++ b/Source/BetterLoading.sln @@ -5,6 +5,15 @@ VisualStudioVersion = 16.0.30011.22 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BetterLoading", "BetterLoading.csproj", "{E08CFC22-1BA8-41FE-A60B-491C308B8B65}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{46226B08-22BA-455E-8B99-F496E90EDCBC}" + ProjectSection(SolutionItems) = preProject + .gitignore = ..\.gitignore + README.md = ..\README.md + LoadFolders.xml = ..\LoadFolders.xml + About\About.xml = ..\About\About.xml + About\Manifest.xml = ..\About\Manifest.xml + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/Source/BetterLoadingConfig.cs b/Source/BetterLoadingConfig.cs new file mode 100644 index 0000000..0de9c36 --- /dev/null +++ b/Source/BetterLoadingConfig.cs @@ -0,0 +1,33 @@ +using System; +using Tomlet.Attributes; + +namespace BetterLoading; + +public class BetterLoadingConfig +{ + + public static BetterLoadingConfig CreateDefault() + { + return new() + { + TipCache = new() + { + Version = TipCacheConfig.SupportedVersion, + } + }; + } + + [TomlPrecedingComment("The TipCache caches information about loading screen tips so that they can be displayed as soon as the loading screen starts after the first run.")] + public TipCacheConfig TipCache; + + [TomlDoNotInlineObject] + public class TipCacheConfig + { + public static readonly int SupportedVersion = 1; + + [TomlPrecedingComment("The internal version number of the TipCache tip blob. If this number is different from the one expected by the mod, the TipCache will be cleared.")] + public int Version; + [TomlPrecedingComment("The raw tip blob. NOT intended to be manually edited.")] + public byte[] Tips = Array.Empty(); + } +} \ No newline at end of file diff --git a/Source/BetterLoadingConfigManager.cs b/Source/BetterLoadingConfigManager.cs new file mode 100644 index 0000000..a031e83 --- /dev/null +++ b/Source/BetterLoadingConfigManager.cs @@ -0,0 +1,61 @@ +using System; +using System.IO; +using Tomlet; +using Tomlet.Exceptions; +using Tomlet.Models; +using Verse; + +namespace BetterLoading; + +/// +/// This class exists because XML is the spawn of the devil and I refuse to use it for config files. +/// +public static class BetterLoadingConfigManager +{ + private static string _oldCachedLoadingTipsPath = Path.Combine(GenFilePaths.ConfigFolderPath, "BetterLoading_Cached_Tips"); + public static string ConfigFilePath = Path.Combine(GenFilePaths.ConfigFolderPath, "BetterLoading.toml"); + + public static BetterLoadingConfig Config { get; private set; } = new(); + + static BetterLoadingConfigManager() + { + //Register a byte array <=> base64 string converter + TomletMain.RegisterMapper(bytes => new TomlString(Convert.ToBase64String(bytes ?? throw new NullReferenceException("Cannot serialize a null byte array"))), tomlValue => + { + if (tomlValue is not TomlString tomlString) + throw new TomlTypeMismatchException(typeof(TomlString), tomlValue.GetType(), typeof(byte[])); + return Convert.FromBase64String(tomlString.Value); + }); + } + + public static void Load() + { + if(File.Exists(_oldCachedLoadingTipsPath)) + File.Delete(_oldCachedLoadingTipsPath); + + if (!File.Exists(ConfigFilePath)) + { + Config = BetterLoadingConfig.CreateDefault(); + return; + } + + try + { + var doc = TomlParser.ParseFile(ConfigFilePath); + Config = TomletMain.To(doc); + LoadingScreenTipManager.TryReadCachedTipsFromConfig(); + } + catch (TomlException e) + { + Log.Error($"[BetterLoading] {e.GetType()} thrown while parsing config file: {e.Message}. Config will be reset."); + File.Delete(ConfigFilePath); + Config = BetterLoadingConfig.CreateDefault(); + } + } + + public static void Save() + { + var tomlString = TomletMain.TomlStringFrom(Config); + File.WriteAllText(ConfigFilePath, tomlString); + } +} \ No newline at end of file diff --git a/Source/BetterLoadingMain.cs b/Source/BetterLoadingMain.cs index 4288152..2d7fe16 100755 --- a/Source/BetterLoadingMain.cs +++ b/Source/BetterLoadingMain.cs @@ -3,11 +3,10 @@ using System.IO; using System.Linq; using System.Reflection; +using BetterLoading.Compat; using BetterLoading.Stage.SaveLoad; using HarmonyLib; -using JetBrains.Annotations; using RimWorld; -using RimWorld.Planet; using UnityEngine; using Verse; using Object = UnityEngine.Object; @@ -17,10 +16,10 @@ namespace BetterLoading public sealed class BetterLoadingMain : Mod { public static ModContentPack? ourContentPack; - public static Harmony? hInstance; + public static Harmony hInstance = new("me.samboycoding.blm"); public static LoadingScreen? LoadingScreen; - public static readonly Dictionary> DllPathsThatFailedToLoad = new Dictionary>(); + public static readonly Dictionary> DllPathsThatFailedToLoad = new(); public class DllLoadError { @@ -32,10 +31,9 @@ public BetterLoadingMain(ModContentPack content) : base(content) { ourContentPack = content; - hInstance = new Harmony("me.samboycoding.blm"); if (Camera.main == null) return; //Just in case - - hInstance.Patch(AccessTools.Method(typeof(PlayDataLoader), nameof(PlayDataLoader.ClearAllPlayData)), new HarmonyMethod(typeof(BetterLoadingMain), nameof(OnClearPlayData))); + + hInstance.Patch(AccessTools.Method(typeof(PlayDataLoader), nameof(PlayDataLoader.ClearAllPlayData)), new(typeof(BetterLoadingMain), nameof(OnClearPlayData))); LogMsg("[BetterLoading] Verifying all mods loaded properly..."); @@ -73,7 +71,7 @@ public BetterLoadingMain(ModContentPack content) : base(content) ) .ToList(); - Log.Error($"[BetterLoading] {dllsThatShouldBeLoaded.Count - dllsActuallyLoaded.Count} assemblies for {pack.Name} failed to load! The ones that didn't load are: {string.Join(", ",didntLoad)}"); + Log.Error($"[BetterLoading] {dllsThatShouldBeLoaded.Count - dllsActuallyLoaded.Count} assemblies for {pack.Name} failed to load! The ones that didn't load are: {string.Join(", ", didntLoad)}"); Log.Error($"[BetterLoading] Got {failures.Count} messages that identify those failures."); DllPathsThatFailedToLoad[pack] = failures; @@ -82,6 +80,9 @@ public BetterLoadingMain(ModContentPack content) : base(content) if (DllPathsThatFailedToLoad.Count == 0) { + BetterLoadingConfigManager.Load(); + ShitRimworldSaysCompat.PatchShitRimworldSaysIfPresent(); + //Prepatcher re-launches the game... var alreadyCreatedLoadScreens = Object.FindObjectsOfType().Where(c => c.GetType().FullName.Contains("LoadingScreen")).ToList(); if (alreadyCreatedLoadScreens.Count > 0) @@ -90,14 +91,15 @@ public BetterLoadingMain(ModContentPack content) : base(content) alreadyCreatedLoadScreens.ForEach(Object.Destroy); LoadingScreen = null; } + Log.Message("[BetterLoading] Injecting into main UI."); LoadingScreen = Object.FindObjectOfType().gameObject.AddComponent(); - InitLoadingScreenBG(); + InitLoadingScreenBackground(); hInstance.Patch(AccessTools.Method(typeof(LongEventHandler), nameof(LongEventHandler.LongEventsOnGUI)), - new HarmonyMethod(typeof(BetterLoadingMain), nameof(DisableVanillaLoadScreen))); + new(typeof(BetterLoadingMain), nameof(DisableVanillaLoadScreen))); - hInstance.Patch(AccessTools.Method(typeof(Game), nameof(Game.LoadGame)), new HarmonyMethod(typeof(BetterLoadingMain), nameof(OnGameLoadStart))); + hInstance.Patch(AccessTools.Method(typeof(Game), nameof(Game.LoadGame)), new(typeof(BetterLoadingMain), nameof(OnGameLoadStart))); BetterLoadingApi.OnGameLoadComplete += CreateTimingReport; } @@ -105,13 +107,13 @@ public BetterLoadingMain(ModContentPack content) : base(content) { Log.Message("[BetterLoading] Not showing loading screen, not all mods loaded successfully so we would be unstable."); - hInstance.Patch(AccessTools.Method(typeof(UIRoot_Entry), nameof(UIRoot_Entry.Init)), postfix: new HarmonyMethod(typeof(BetterLoadingMain), nameof(DisplayFailedLoadDialog))); + hInstance.Patch(AccessTools.Method(typeof(UIRoot_Entry), nameof(UIRoot_Entry.Init)), postfix: new(typeof(BetterLoadingMain), nameof(DisplayFailedLoadDialog))); } //Harmony.PatchAll(Assembly.GetExecutingAssembly()); } - private static void InitLoadingScreenBG() + private static void InitLoadingScreenBackground() { try { @@ -131,7 +133,7 @@ private void CreateTimingReport() var timeRunningCctors = TimeSpan.FromTicks(GlobalTimingData.TicksStartedPostFinalize - GlobalTimingData.TicksStartedCctors); var timeRunningPostFinalize = TimeSpan.FromTicks(GlobalTimingData.TicksFinishedPostFinalize - GlobalTimingData.TicksStartedPostFinalize); var totalLoadTime = TimeSpan.FromTicks(DateTime.UtcNow.Ticks - GlobalTimingData.TicksStarted); - + Log.Message($"[BetterLoading] Game load has finished. Timing data follows:\n" + $"Spent {timeBuildingXml.TotalMilliseconds}ms reading, building, and patching XML tree.\n" + $"Spent {timeConstructingDefs.TotalMilliseconds}ms turning XML into def instances.\n" + @@ -170,7 +172,7 @@ BetterLoading did not display because not all of your modded .dll files (assembl Log.Warning($"[BetterLoading] \t{dllLoadError.dllName}.dll failed to load, but we couldn't work out why. Possibly intentional? For safety reasons, the loading screen will not show."); continue; } - + var loaderErrors = GetLoaderErrors(dllLoadError.reasonMessage.text); if (loaderErrors.Count > 0) { @@ -198,14 +200,14 @@ BetterLoading did not display because not all of your modded .dll files (assembl if (dependentMods.Count > 0) { - Log.Warning($"[BetterLoading] \t{dllLoadError.dllName} appears to have a dependency on these mod(s): {dependentMods.Select(m => m.Name).ToStringSafeEnumerable()}"); + Log.Warning($"[BetterLoading] \t{dllLoadError.dllName} appears to have a dependency on these mod(s): {dependentMods.Select(m => m?.Name).ToStringSafeEnumerable()}"); - var notLoaded = dependentMods.Where(requiredMod => LoadedModManager.RunningMods.All(runningMod => runningMod.Name != requiredMod.Name)).ToList(); + var notLoaded = dependentMods.Where(requiredMod => LoadedModManager.RunningMods.All(runningMod => runningMod.Name != requiredMod?.Name)).ToList(); if (notLoaded.Count > 0) - notLoaded.ForEach(m => Log.Warning($"[BetterLoading] \t{modThatFailedLoad.Name} depends on {m.Name} which is not enabled, so it didn't load properly.")); + notLoaded.ForEach(m => Log.Warning($"[BetterLoading] \t{modThatFailedLoad.Name} depends on {m?.Name} which is not enabled, so it didn't load properly.")); var modsLoadedAfterTarget = LoadedModManager.RunningMods.Skip(LoadedModManager.RunningModsListForReading.FindIndex(i => i.Name == modThatFailedLoad.Name)).Take(int.MaxValue).ToList(); - var depsLoadedAfterDependent = modsLoadedAfterTarget.Where(loadedAfter => dependentMods.Any(dep => dep.Name == loadedAfter.Name)).ToList(); + var depsLoadedAfterDependent = modsLoadedAfterTarget.Where(loadedAfter => dependentMods.Any(dep => dep?.Name == loadedAfter.Name)).ToList(); if (depsLoadedAfterDependent.Count > 0) depsLoadedAfterDependent.ForEach(m => Log.Warning($"[BetterLoading] \t{modThatFailedLoad.Name} is loaded before {m.Name} but depends on it, so must be loaded after. It didn't load properly because of this.")); } @@ -216,7 +218,7 @@ BetterLoading did not display because not all of your modded .dll files (assembl .Where(asm => ModLister.AllInstalledMods.All(m => !ModContainsAssembly(m, asm))) .Select(asm => $"{asm}.dll") .ToList(); - + Log.Warning($"[BetterLoading] \t{dllLoadError.dllName} (also) depends on these DLL(s) which couldn't be found in any installed mods: {notInAnyMods.ToStringSafeEnumerable()}"); } } @@ -231,9 +233,9 @@ private static bool ModContainsAssembly(ModMetaData mod, string assemblyName) var searchPaths = new List(); //Sourced from ModContentPack#InitLoadFolders - if (mod.LoadFoldersForVersion(VersionControl.CurrentVersionStringWithoutBuild) is {} forBuild) + if (mod.LoadFoldersForVersion(VersionControl.CurrentVersionStringWithoutBuild) is { } forBuild) searchPaths.AddRange(forBuild.Select(p => p.folderName)); - if (mod.LoadFoldersForVersion("default") is {} forDefault) + if (mod.LoadFoldersForVersion("default") is { } forDefault) searchPaths.AddRange(forDefault.Select(p => p.folderName)); if (searchPaths.Count == 0) @@ -264,7 +266,7 @@ private static bool ModContainsAssembly(ModMetaData mod, string assemblyName) private static List<(string type, string asm)> GetLoaderErrors(string messageText) { - if (!messageText.Contains("Loader exceptions:")) return new List<(string type, string asm)>(); + if (!messageText.Contains("Loader exceptions:")) return new(); try { @@ -272,7 +274,7 @@ private static bool ModContainsAssembly(ModMetaData mod, string assemblyName) var split = messageText.Split(new[] {"=> "}, StringSplitOptions.None).Skip(1).Take(int.MaxValue).ToList(); var target = "from typeref, class/assembly "; - var errorDetail = split.Select(e => e.Substring(e.IndexOf(target) + target.Length)).ToList(); + var errorDetail = split.Select(e => e.Substring(e.IndexOf(target, StringComparison.Ordinal) + target.Length)).ToList(); var attemptedLoadOf = errorDetail.Select(e => e.Split(',')).Select(arr => (type: arr[0].Trim(), asm: arr[1].Trim())).ToList(); @@ -282,28 +284,28 @@ private static bool ModContainsAssembly(ModMetaData mod, string assemblyName) { //We really don't want this to fail, it's just gonna be a pain Log.Warning("[BetterLoading] Failed to scrape Loader Errors."); - return new List<(string type, string asm)>(); + return new(); } } public static bool DisableVanillaLoadScreen() { //Disable when our load screen is shown - return !LoadingScreen.shouldShow; + return !LoadingScreen!.shouldShow; } public static void OnGameLoadStart() { - if (ModLister.AllInstalledMods.FirstOrDefault(m => m.enabled && m.Name.ToLowerInvariant().Contains("multiplayer")) is {} mpMod) + if (ModLister.AllInstalledMods.FirstOrDefault(m => m.enabled && m.Name.ToLowerInvariant().Contains("multiplayer")) is { } mpMod) { Log.Warning($"[BetterLoading] Not showing game load/save screen because we've detected what we believe to be a multiplayer mod: {mpMod.Name}"); return; } - - + + LoadingScreen = Object.FindObjectOfType().gameObject .AddComponent(); - InitLoadingScreenBG(); + InitLoadingScreenBackground(); //Try and work out how many maps we have LoadMaps.CountMaps(); @@ -319,45 +321,13 @@ private static void LogMsg(string message) public static void OnClearPlayData() { //Reset our harmony patches. - hInstance?.UnpatchAll("me.samboycoding.blm"); - - if(LoadingScreen == null) + hInstance.UnpatchAll("me.samboycoding.blm"); + + if (LoadingScreen == null) return; - + //Destroy loading screen. Object.Destroy(LoadingScreen); } - - //Following code kept as reference - - #region Save Game Loading Patches - - [HarmonyPatch(typeof(WorldGenStep))] - [HarmonyPatch(nameof(WorldGenStep.GenerateFromScribe))] - [UsedImplicitly] - public class WorldGenStepExecPatch - { - [UsedImplicitly] - public static void Prefix(WorldGenStep __instance) - { - LoadingScreen.Instance.numWorldGeneratorsRun++; - LoadingScreen.Instance.currentWorldGenStep = __instance; - } - } - - [HarmonyPatch(typeof(WorldGenStep))] - [HarmonyPatch(nameof(WorldGenStep.GenerateWithoutWorldData))] - [UsedImplicitly] - public class WorldGenStepExecPatch2 - { - [UsedImplicitly] - public static void Prefix(WorldGenStep __instance) - { - LoadingScreen.Instance.numWorldGeneratorsRun++; - LoadingScreen.Instance.currentWorldGenStep = __instance; - } - } - - #endregion } } \ No newline at end of file diff --git a/Source/BetterLoadingTip.cs b/Source/BetterLoadingTip.cs new file mode 100644 index 0000000..fe1968d --- /dev/null +++ b/Source/BetterLoadingTip.cs @@ -0,0 +1,13 @@ +using Verse; + +namespace BetterLoading +{ + //Class for cross-compatibility between vanilla tips and ShitRimworldSays tips + public class BetterLoadingTip + { +#pragma warning disable CS8618 + public string TipBody; + public string Source; +#pragma warning restore CS8618 + } +} \ No newline at end of file diff --git a/Source/Compat/HugsLib/StageHugsLibInit.cs b/Source/Compat/HugsLib/StageHugsLibInit.cs index bbffb45..af11c56 100755 --- a/Source/Compat/HugsLib/StageHugsLibInit.cs +++ b/Source/Compat/HugsLib/StageHugsLibInit.cs @@ -82,19 +82,19 @@ public override void DoPatching(Harmony instance) var hlAssembly = LoadedModManager.RunningMods.First(m => m.Name == "HugsLib").assemblies.loadedAssemblies.Find(a => a.GetName().Name == "HugsLib"); - var controllerType = hlAssembly.GetTypes().FirstOrDefault(t => t.Name == "HugsLibController") ?? throw new Exception("Type HugsLibController is missing"); + var controllerType = hlAssembly.GetTypes().FirstOrDefault(t => t.Name == "HugsLibController") ?? throw new("Type HugsLibController is missing"); - _modIdentifierProperty = hlAssembly.GetTypes().First(t => t.Name == "ModBase").GetProperty("ModIdentifier") ?? throw new Exception("Property ModBase.ModIdentifier is missing"); + _modIdentifierProperty = hlAssembly.GetTypes().First(t => t.Name == "ModBase").GetProperty("ModIdentifier") ?? throw new("Property ModBase.ModIdentifier is missing"); Log.Message($"[BetterLoading:HugsLib Compat] Resolved required HugsLib types as follows: Controller: {controllerType.FullName} / Mod Identifier (Property): {_modIdentifierProperty.Name}"); hInstance.Patch( - AccessTools.Method(controllerType, "LoadReloadInitialize") ?? throw new Exception("Method HugsLibController.LoadReloadInitialize is missing"), - postfix: new HarmonyMethod(typeof(StageHugsLibInit), nameof(PostLRI)) + AccessTools.Method(controllerType, "LoadReloadInitialize") ?? throw new("Method HugsLibController.LoadReloadInitialize is missing"), + postfix: new(typeof(StageHugsLibInit), nameof(PostLRI)) ); hInstance.Patch( - AccessTools.Method(controllerType, "EnumerateChildMods") ?? throw new Exception("Method HugsLibController.EnumerateChildMods is missing"), - postfix: new HarmonyMethod(typeof(StageHugsLibInit), nameof(PostEnumerateChildren)) + AccessTools.Method(controllerType, "EnumerateChildMods") ?? throw new("Method HugsLibController.EnumerateChildMods is missing"), + postfix: new(typeof(StageHugsLibInit), nameof(PostEnumerateChildren)) ); Log.Message("[BetterLoading:HugsLib Compat] Successfully blind-patched HugsLib."); @@ -120,10 +120,10 @@ public static void PostEnumerateChildren(object ___childMods, Dictionary? TipsFromShitRimWorldSays; + private static Assembly? _srwsAssembly; + + public static void PatchShitRimworldSaysIfPresent() + { + //We can postfix-patch TipDatabase#Notify_TipsUpdated which is called when tips update + //Then we look for the field "_quotes" and read into our tip list + + _srwsAssembly = LoadedModManager.RunningMods.FirstOrDefault(m => m.Name == "Shit Rimworld Says")?.assemblies.loadedAssemblies.Find(a => a.GetName().Name == "ShitRimWorldSays"); + + if(_srwsAssembly == null) + return; + + Log.Message("Shit Rimworld Says found: " + (_srwsAssembly)); + + + var tipDbType = _srwsAssembly.GetType("ShitRimWorldSays.TipDatabase"); + + if(tipDbType == null) + return; + + var tipQuoteType = _srwsAssembly.GetType("ShitRimWorldSays.Tip_Quote"); + + if (tipQuoteType == null) + { + Log.Error("[BetterLoading|ShitRimWorldSays Compat] Found a TipDatabase but couldn't find Tip_Quote? Has the mod been updated? Please report this."); + return; + } + + Log.Message("[BetterLoading|ShitRimWorldSays Compat] Found ShitRimWorldSays, enabling compatibility. Enjoy your warcrime tips."); + + //These are public instance fields, so no binding flags needed + _tipQuoteAuthorField = tipQuoteType.GetField("author"); + _tipQuoteBodyField = tipQuoteType.GetField("body"); + + var srwsModType = _srwsAssembly.GetType("ShitRimWorldSays.ShitRimWorldSays"); + + BetterLoadingMain.hInstance!.Patch(AccessTools.Method(tipDbType, "Notify_TipsUpdated"), postfix: new(typeof(ShitRimworldSaysCompat), nameof(Notify_TipsUpdated_Postfix))); + BetterLoadingMain.hInstance!.Patch(AccessTools.FirstConstructor(srwsModType, ctor => ctor.GetParameters().Length == 1), postfix: new(typeof(ShitRimworldSaysCompat), nameof(ShitRimworldSays_ctor_Postfix))); + } + + public static bool UserWantsToHideVanillaTips() + { + if (_srwsAssembly == null) + //Not loaded, so don't hide tips + return false; + + var settingsProp = _srwsAssembly.GetType("ShitRimWorldSays.ShitRimWorldSays")!.GetProperty("Settings") ?? throw new("Failed to find ShitRimWorldSays.ShitRimWorldSays.Settings property"); + var settings = settingsProp.GetValue(null) ?? throw new("Failed to get ShitRimWorldSays.ShitRimWorldSays.Settings"); + var replaceGameTipsProp = _srwsAssembly.GetType("ShitRimWorldSays.Settings")!.GetField("replaceGameTips") ?? throw new("Failed to find ShitRimWorldSays.ShitRimWorldSays.Settings.replaceGameTips field"); + + return (bool)replaceGameTipsProp.GetValue(settings); + } + + // ReSharper disable once InconsistentNaming + public static void Notify_TipsUpdated_Postfix(HashSet ____quotes) + { + TipsFromShitRimWorldSays = new(); + + //Each of the quotes is a Tip_Quote object. + foreach (var quote in ____quotes) + { + var body = (string) _tipQuoteBodyField!.GetValue(quote); + var author = (string) _tipQuoteAuthorField!.GetValue(quote); + + if(body == "[removed]" || author == "[deleted]") + continue; //Skip removed tips + + if(body.Length > 500) + continue; //Skip too long tips + + TipsFromShitRimWorldSays.Add(new() {Source = $"u/{author}, on r/ShitRimworldSays", TipBody = body}); + } + + Log.Message($"[BetterLoading|ShitRimWorldSays Compat] ShitRimWorldSays loaded {TipsFromShitRimWorldSays.Count} tips from reddit."); + LoadingScreenTipManager.OnAvailableTipSetChanged(); + } + + public static void ShitRimworldSays_ctor_Postfix() + { + if (UserWantsToHideVanillaTips()) + { + Log.Message("[BetterLoading|ShitRimWorldSays Compat] Hiding vanilla loading tips, as you have disabled them in SRWS mod settings."); + LoadingScreenTipManager.HideVanillaTips = true; + } + } +} \ No newline at end of file diff --git a/Source/LoadingScreen.cs b/Source/LoadingScreen.cs index e485700..1636bec 100755 --- a/Source/LoadingScreen.cs +++ b/Source/LoadingScreen.cs @@ -2,7 +2,6 @@ using BetterLoading.Stage.InitialLoad; using System; using System.Collections.Generic; -using System.IO; using System.Linq; using BetterLoading.Stage.SaveLoad; using UnityEngine; @@ -12,24 +11,14 @@ namespace BetterLoading { public sealed class LoadingScreen : MonoBehaviour { - public static LoadingScreen Instance { get; private set; } - - private static string _cachedLoadingTipsPath = Path.Combine(GenFilePaths.ConfigFolderPath, "BetterLoading_Cached_Tips"); - - private static bool _tipsAvailable; - - private static List _tips = File.Exists(_cachedLoadingTipsPath) ? File.ReadAllText(_cachedLoadingTipsPath).Split('\0').ToList() : new List(); - private static string? _currentTip; - private static long _timeLastTipShown; - private const int _ticksPerTip = 5 * 10_000_000; //3 seconds - + public static LoadingScreen? Instance { get; private set; } /// /// The load list used at game boot. /// - internal static List BootLoadList = new List + internal static List BootLoadList = new() { //For all of these stages, vanilla just shows "..." - new StageInitMods(BetterLoadingMain.hInstance!), + new StageInitMods(BetterLoadingMain.hInstance), new StageReadXML(BetterLoadingMain.hInstance), new StageUnifyXML(BetterLoadingMain.hInstance), new StageApplyPatches(BetterLoadingMain.hInstance), @@ -46,10 +35,10 @@ public sealed class LoadingScreen : MonoBehaviour /// /// The load list used at game boot. /// - internal static List LoadSaveFileLoadList = new List + internal static List LoadSaveFileLoadList = new() { //For all of these stages, vanilla just shows "..." - new LoadSmallComponents(BetterLoadingMain.hInstance!), + new LoadSmallComponents(BetterLoadingMain.hInstance), new LoadWorldMap(BetterLoadingMain.hInstance), new LoadMaps(BetterLoadingMain.hInstance), new FinalizeScribeLoad(BetterLoadingMain.hInstance), @@ -57,39 +46,26 @@ public sealed class LoadingScreen : MonoBehaviour new FinalizeGameState(BetterLoadingMain.hInstance) }; - private static Dictionary _loadingStagesByType = new Dictionary(); + private static Dictionary _loadingStagesByType = new(); public Texture2D? Background; - private Texture2D errorBarColor; - private Texture2D warningBarColor; - private Texture2D loadingBarBgColor; - private Texture2D loadingBarDefaultColor; - private Texture2D loadingBarWhiteColor; + private Texture2D? _errorBarColor; + private Texture2D? _warningBarColor; + private Texture2D? _loadingBarBgColor; + private Texture2D? _loadingBarDefaultColor; + private Texture2D? _loadingBarWhiteColor; private LoadingStage _currentStage = BootLoadList[0]; public bool shouldShow = true; - public EnumLoadingStage currentStage = EnumLoadingStage.CreateClasses; - - //------------File Loading-------------- - public int numWorldGeneratorsToRun; - public int numWorldGeneratorsRun; - public WorldGenStep? currentWorldGenStep; - - public List maps = new List(); - - public int mapIndexSpawningItems = -1; - public int numObjectsToSpawnCurrentMap; - public int numObjectsSpawnedCurrentMap; - private float totalLoadLerpSpeed = 1.5f; private float stageLoadLerpSpeed = 3.0f; - private float totalLoadPercentLerp; - private float stageLoadPercentLerp; - private float bgLerp = 0f; - private Texture2D? bgSolidColor; - private Texture2D? bgContrastReducer; + private float _totalLoadPercentLerp; + private float _stageLoadPercentLerp; + private float _bgLerp; + private Texture2D? _bgSolidColor; + private Texture2D? _bgContrastReducer; public void StartSaveLoad() { @@ -104,7 +80,7 @@ public LoadingScreen() BootLoadList.ForEach(s => _loadingStagesByType[s.GetType()] = s); _currentStage.BecomeActive(); - StageTimingData.ExecutedStages.Add(new StageTimingData + StageTimingData.ExecutedStages.Add(new() { start = DateTime.Now, stage = _currentStage @@ -139,21 +115,19 @@ internal static T GetStageInstance() where T: LoadingStage public void Awake() { Log.Message("[BetterLoading] Injected into main UI."); - _tipsAvailable = _tips.Count > 0; } - private void DrawBG() + private void DrawBackground() { - const float TARGET_DARKNESS = 0.25f; - const bool SOLID_COLOR_BG = false; + const float targetDarkness = 0.25f; - bgContrastReducer ??= SolidColorMaterials.NewSolidColorTexture(new Color(1, 1, 1, 1)); - bgSolidColor ??= SolidColorMaterials.NewSolidColorTexture(new Color(0.1f, 0.1f, 0.1f, 1)); + _bgContrastReducer ??= SolidColorMaterials.NewSolidColorTexture(new(1, 1, 1, 1)); + _bgSolidColor ??= SolidColorMaterials.NewSolidColorTexture(new(0.1f, 0.1f, 0.1f, 1)); - if (SOLID_COLOR_BG || this.Background == null) + if (Background == null) { var bgRect = new Rect(0, 0, Screen.width, Screen.height); - GUI.DrawTexture(bgRect, bgSolidColor); + GUI.DrawTexture(bgRect, _bgSolidColor); return; } @@ -164,31 +138,31 @@ private void DrawBG() { float height = Screen.height; var num = Screen.height * (size.x / size.y); - rect = new Rect((Screen.width * 0.5f) - num / 2f, 0f, num, height); + rect = new((Screen.width * 0.5f) - num / 2f, 0f, num, height); } else { float width = Screen.width; var num2 = Screen.width * (size.y / size.x); - rect = new Rect(0f, (Screen.height * 0.5f) - num2 / 2f, width, num2); + rect = new(0f, (Screen.height * 0.5f) - num2 / 2f, width, num2); } // From the moment the loading screen spawns, darken the background gradually. - bgLerp = Mathf.MoveTowards(bgLerp, 1f, Time.deltaTime * Mathf.Abs(1f - bgLerp) * 0.5f); - var bgDarkness = Mathf.Lerp(1f, TARGET_DARKNESS, bgLerp); + _bgLerp = Mathf.MoveTowards(_bgLerp, 1f, Time.deltaTime * Mathf.Abs(1f - _bgLerp) * 0.5f); + var bgDarkness = Mathf.Lerp(1f, targetDarkness, _bgLerp); var oldCol = GUI.color; //Draw default rimworld loading background. - GUI.color = new Color(bgDarkness, bgDarkness, bgDarkness, 1f); + GUI.color = new(bgDarkness, bgDarkness, bgDarkness, 1f); GUI.DrawTexture(rect, Background, ScaleMode.ScaleToFit); // Draw solid color, with transparency - it's the easiest way to reduce background contrast. - const float COL = 0.2f; - var alpha = Mathf.Lerp(0f, 0.5f, bgLerp); - GUI.color = new Color(COL, COL, COL, alpha); + const float graynessLevel = 0.2f; + var alpha = Mathf.Lerp(0f, 0.5f, _bgLerp); + GUI.color = new(graynessLevel, graynessLevel, graynessLevel, alpha); var rect2 = new Rect(0, 0, Screen.width, Screen.height); - GUI.DrawTexture(rect2, bgContrastReducer); + GUI.DrawTexture(rect2, _bgContrastReducer); GUI.color = oldCol; } @@ -207,13 +181,13 @@ public void OnGUI() return; } - if (warningBarColor == null) + if (_warningBarColor == null) { - warningBarColor = SolidColorMaterials.NewSolidColorTexture(new Color(0.89f, 0.8f, 0.11f)); //RGB (226,203,29) - errorBarColor = SolidColorMaterials.NewSolidColorTexture(new Color(0.73f, 0.09f, 0.09f)); //RGB(185, 24, 24) - loadingBarBgColor = SolidColorMaterials.NewSolidColorTexture(new Color(0.5f, 0.5f, 0.5f, 1f)); - loadingBarDefaultColor = SolidColorMaterials.NewSolidColorTexture(new Color(0.2f, 0.8f, 0.85f)); - loadingBarWhiteColor = SolidColorMaterials.NewSolidColorTexture(new Color(1f, 1f, 1f, 1f)); + _warningBarColor = SolidColorMaterials.NewSolidColorTexture(new(0.89f, 0.8f, 0.11f)); //RGB (226,203,29) + _errorBarColor = SolidColorMaterials.NewSolidColorTexture(new(0.73f, 0.09f, 0.09f)); //RGB(185, 24, 24) + _loadingBarBgColor = SolidColorMaterials.NewSolidColorTexture(new(0.5f, 0.5f, 0.5f, 1f)); + _loadingBarDefaultColor = SolidColorMaterials.NewSolidColorTexture(new(0.2f, 0.8f, 0.85f)); + _loadingBarWhiteColor = SolidColorMaterials.NewSolidColorTexture(new(1f, 1f, 1f, 1f)); } try @@ -268,7 +242,7 @@ public void OnGUI() Log.Error($"[BetterLoading] The stage {_currentStage} errored during BecomeActive: {e}"); } - StageTimingData.ExecutedStages.Add(new StageTimingData + StageTimingData.ExecutedStages.Add(new() { start = DateTime.Now, stage = _currentStage @@ -287,13 +261,13 @@ public void OnGUI() if (currentProgress > maxProgress) { - Log.Error( - $"[BetterLoading] Clamping! The stage of type {_currentStage.GetType().FullName} has returned currentProgress {currentProgress} > maxProgress {maxProgress}. Please report this!"); + // Log.Error( + // $"[BetterLoading] Clamping! The stage of type {_currentStage.GetType().FullName} has returned currentProgress {currentProgress} > maxProgress {maxProgress}. Please report this!"); currentProgress = maxProgress; } //Draw background - DrawBG(); + DrawBackground(); //Draw title Text.Font = GameFont.Medium; @@ -321,20 +295,20 @@ public void OnGUI() // Also clamp between 1% and 100% (there was a bug where pct was < 0) var pct = Mathf.Clamp(currentProgress / (float) maxProgress, 0.01f, 1f); var lerpScalar = 1f; - if (pct < stageLoadPercentLerp) + if (pct < _stageLoadPercentLerp) lerpScalar = 3f; - var dst = Mathf.Abs(pct - stageLoadPercentLerp); - stageLoadPercentLerp = Mathf.MoveTowards(stageLoadPercentLerp, pct, Time.deltaTime * dst * stageLoadLerpSpeed * lerpScalar); + var dst = Mathf.Abs(pct - _stageLoadPercentLerp); + _stageLoadPercentLerp = Mathf.MoveTowards(_stageLoadPercentLerp, pct, Time.deltaTime * dst * stageLoadLerpSpeed * lerpScalar); if (subStageText != null) currentStageText = $"{subStageText}"; var rect = new Rect(450, currentBarHeight, Screen.width - 900, 26); - var color = _currentStage.HasError() ? errorBarColor : _currentStage.HasWarning() ? warningBarColor : null; + var color = _currentStage.HasError() ? _errorBarColor : _currentStage.HasWarning() ? _warningBarColor : null; - GUI.DrawTexture(rect.ExpandedBy(2), loadingBarWhiteColor); - Widgets.FillableBar(rect, stageLoadPercentLerp, color != null ? color : loadingBarDefaultColor, loadingBarBgColor, false); + GUI.DrawTexture(rect.ExpandedBy(2), _loadingBarWhiteColor); + Widgets.FillableBar(rect, _stageLoadPercentLerp, color != null ? color : _loadingBarDefaultColor, _loadingBarBgColor, false); Widgets.Label(rect, $"{pct.ToStringPercent()}, {currentProgress} of {maxProgress}"); @@ -345,49 +319,25 @@ public void OnGUI() Widgets.Label(rect, "Current: " + currentStageText); //Draw loading lines + rect.height += 100; Text.Font = GameFont.Medium; rect.y += 120; - if (!_tipsAvailable) - { - Widgets.Label(rect, "Gameplay tips will be shown here once the game loads them (after stage 7 completes)"); - } - else - { - //Load tips if required - if (_currentTip == null || (DateTime.Now.Ticks - _timeLastTipShown) >= _ticksPerTip) - { - //No tip chosen yet, or time for next tip - pick another and reset timer. - - if (_tips.NullOrEmpty()) - { - _currentTip = "BetterLoading Warning: No tips could be located in your game. This is probably a bug with another mod"; - } - else - { - _currentTip = _tips.Pop(); - } - - _timeLastTipShown = DateTime.Now.Ticks; - } - - //Draw tip. - Widgets.Label(rect, _currentTip); - } + Widgets.Label(rect, LoadingScreenTipManager.GetTipToDisplay()); Text.Font = GameFont.Small; - rect.height -= 100; //Remove increased height + rect.height -= 200; //Remove increased height //Render global progress bar. - rect = new Rect(200, globalBarHeight, Screen.width - 400, 36); + rect = new(200, globalBarHeight, Screen.width - 400, 36); Text.Anchor = TextAnchor.MiddleCenter; // Takes the current stage progress to give a more accurate percentage. pct = Mathf.Clamp01((idx + 1) / (float) currentList.Count + currentProgress / (float)maxProgress * 1f / currentList.Count); - dst = Mathf.Abs(pct - totalLoadPercentLerp); - totalLoadPercentLerp = Mathf.MoveTowards(totalLoadPercentLerp, pct, Time.deltaTime * dst * totalLoadLerpSpeed); - GUI.DrawTexture(rect.ExpandedBy(2), loadingBarWhiteColor); - Widgets.FillableBar(rect, totalLoadPercentLerp, loadingBarDefaultColor, loadingBarBgColor, false); + dst = Mathf.Abs(pct - _totalLoadPercentLerp); + _totalLoadPercentLerp = Mathf.MoveTowards(_totalLoadPercentLerp, pct, Time.deltaTime * dst * totalLoadLerpSpeed); + GUI.DrawTexture(rect.ExpandedBy(2), _loadingBarWhiteColor); + Widgets.FillableBar(rect, _totalLoadPercentLerp, _loadingBarDefaultColor, _loadingBarBgColor, false); Widgets.Label(rect, $"{pct.ToStringPercent()}"); Text.Anchor = TextAnchor.UpperLeft; @@ -398,25 +348,5 @@ public void OnGUI() Log.ErrorOnce($"Encountered exception while rendering loading screen: {e}", 0xBEEF99); } } - - private static List LoadGameplayTips() - { - return DefDatabase.AllDefsListForReading.SelectMany(set => set.tips).InRandomOrder().ToList(); - } - - public static void MarkTipsNowAvailable() - { - Log.Message("[BetterLoading] Tips should now be available. Showing..."); - - var tips = LoadGameplayTips(); - var cachedTips = File.Exists(_cachedLoadingTipsPath) ? File.ReadAllText(_cachedLoadingTipsPath).Split('\0').ToList() : new List(); - if (!tips.SequenceEqual(cachedTips)) - { - File.WriteAllText(_cachedLoadingTipsPath, string.Join("\0", tips)); - _tips = tips; - } - - _tipsAvailable = true; - } } } \ No newline at end of file diff --git a/Source/LoadingScreenTipManager.cs b/Source/LoadingScreenTipManager.cs new file mode 100644 index 0000000..32d1d00 --- /dev/null +++ b/Source/LoadingScreenTipManager.cs @@ -0,0 +1,132 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using BetterLoading.Compat; +using Verse; + +namespace BetterLoading +{ + public static class LoadingScreenTipManager + { + private static bool _hasAttemptedToLoadTips; + private static bool _tipDatabaseHasLoadedBackingField; + private static bool _hideVanillaTipsBackingField; + + public static bool GameTipDatabaseHasLoaded + { + get => _tipDatabaseHasLoadedBackingField; + set + { + _tipDatabaseHasLoadedBackingField = value; + if (value) OnAvailableTipSetChanged(); + } + } + + public static bool HideVanillaTips + { + get => _hideVanillaTipsBackingField; + set + { + _hideVanillaTipsBackingField = value; + OnAvailableTipSetChanged(); + } + } + + + public static string? LastShownTip; + public static DateTime TimeLastTipShown = DateTime.MinValue; + public static int TicksPerTip = 5 * 10_000_000; //3 seconds + + public static List Tips = new(); + + public static void OnAvailableTipSetChanged() + { + _hasAttemptedToLoadTips = true; + + Tips.Clear(); + + if (!HideVanillaTips) + ReadTipsFromGameDatabase(); + + if (ShitRimworldSaysCompat.TipsFromShitRimWorldSays != null) + Tips.AddRange(ShitRimworldSaysCompat.TipsFromShitRimWorldSays); + + Tips = Tips.InRandomOrder().ToList(); + + if (Tips.Count == 0) + TryReadCachedTipsFromConfig(); + else + TryWriteCachedTipsToConfig(); + } + + private static void ReadTipsFromGameDatabase() + { + if (!GameTipDatabaseHasLoaded) + return; + + var allTips = DefDatabase.AllDefsListForReading.SelectMany(set => set.tips.Select(t => new BetterLoadingTip {TipBody = t, Source = set.modContentPack.Name})).ToList(); + + Tips = allTips; + } + + public static void TryReadCachedTipsFromConfig() + { + var version = BetterLoadingConfigManager.Config.TipCache.Version; + + if (version != BetterLoadingConfig.TipCacheConfig.SupportedVersion) + return; + + var blobString = Encoding.UTF8.GetString(BetterLoadingConfigManager.Config.TipCache.Tips); + var tips = blobString.Split('\0'); + + Tips = tips + .Select(t => t.Split('\u0001')) + .Select(split => new BetterLoadingTip() {TipBody = split[0], Source = split[1]}) + .InRandomOrder() + .ToList(); + + Log.Message($"[BetterLoading] Read tip cache of {Tips.Count} tips from config."); + } + + public static void TryWriteCachedTipsToConfig() + { + if (Tips.Count == 0) + return; + + var blobString = string.Join("\0", Tips.Select(t => t.TipBody + "\u0001" + t.Source)); + var blob = Encoding.UTF8.GetBytes(blobString); + + BetterLoadingConfigManager.Config.TipCache.Version = BetterLoadingConfig.TipCacheConfig.SupportedVersion; + BetterLoadingConfigManager.Config.TipCache.Tips = blob; + + BetterLoadingConfigManager.Save(); + } + + private static string FormatTip(BetterLoadingTip tip) + { + return $"{tip.TipBody}\n\n-{tip.Source}"; + } + + public static string GetTipToDisplay() + { + if (Tips.Count == 0 && (!GameTipDatabaseHasLoaded || HideVanillaTips)) + return HideVanillaTips ? "Gameplay tips will be shown here once they are loaded" : "Gameplay tips will be shown here once the game loads them (after stage 7 completes)"; + + var timeCurrentTipShownFor = (DateTime.Now - TimeLastTipShown).Ticks; + + if (LastShownTip != null && timeCurrentTipShownFor < TicksPerTip) + //We have a tip and it's not been long enough to change to the next one yet, return the last one + return LastShownTip; + + //No tip chosen yet, or time for next tip - pick another and reset timer. + LastShownTip = Tips.NullOrEmpty() + ? "BetterLoading Warning: No tips could be located in your game. This is probably a bug with another mod" + : FormatTip(Tips.Pop()); + + TimeLastTipShown = DateTime.Now; + + return LastShownTip; + } + } +} \ No newline at end of file diff --git a/Source/Stage/InitialLoad/0StageInitMods.cs b/Source/Stage/InitialLoad/0StageInitMods.cs index 9f23562..f87ceea 100755 --- a/Source/Stage/InitialLoad/0StageInitMods.cs +++ b/Source/Stage/InitialLoad/0StageInitMods.cs @@ -54,7 +54,7 @@ public override void BecomeInactive() public override void DoPatching(Harmony instance) { - instance.Patch(AccessTools.Method(typeof(Activator), nameof(Activator.CreateInstance), new[] {typeof(Type), typeof(object[])}), new HarmonyMethod(typeof(StageInitMods), nameof(OnActivatorCreateInstance))); + instance.Patch(AccessTools.Method(typeof(Activator), nameof(Activator.CreateInstance), new[] {typeof(Type), typeof(object[])}), new(typeof(StageInitMods), nameof(OnActivatorCreateInstance))); } public override bool IsCompleted() @@ -72,9 +72,7 @@ public static void OnActivatorCreateInstance(Type type, params object[] args) { if (_completed) return; //If we're done, don't go again. if (!typeof(Mod).IsAssignableFrom(type)) return; //If we're not constructing a mod bail out. - if (args.Length != 1 || !(args[0] is ModContentPack) && args[0] != null) return; //Check the constructor we're using matches the required pattern. - - var pack = (ModContentPack) args[0]; + if (args.Length != 1 || args[0] is not ModContentPack pack) return; //Check the constructor we're using matches the required pattern. // Log.Message($"[BetterLoading] Class {type?.FullName} is being created for mod {pack}"); _currentModIdx++; diff --git a/Source/Stage/InitialLoad/1StageReadXML.cs b/Source/Stage/InitialLoad/1StageReadXML.cs index 09ccbaa..7ca46d0 100755 --- a/Source/Stage/InitialLoad/1StageReadXML.cs +++ b/Source/Stage/InitialLoad/1StageReadXML.cs @@ -40,8 +40,8 @@ public override int GetMaximumProgress() public override void DoPatching(Harmony instance) { - instance.Patch(AccessTools.Method(typeof(LoadedModManager), nameof(LoadedModManager.LoadModXML)), new HarmonyMethod(typeof(Utils), nameof(Utils.HarmonyPatchCancelMethod)), new HarmonyMethod(typeof(StageReadXML), nameof(AlternativeLoadModXml))); - instance.Patch(AccessTools.Method(typeof(ModContentPack), nameof(ModContentPack.LoadDefs)), postfix: new HarmonyMethod(typeof(StageReadXML), nameof(OnLoadDefsComplete))); + instance.Patch(AccessTools.Method(typeof(LoadedModManager), nameof(LoadedModManager.LoadModXML)), new(typeof(Utils), nameof(Utils.HarmonyPatchCancelMethod)), new(typeof(StageReadXML), nameof(AlternativeLoadModXml))); + instance.Patch(AccessTools.Method(typeof(ModContentPack), nameof(ModContentPack.LoadDefs)), postfix: new(typeof(StageReadXML), nameof(OnLoadDefsComplete))); } public override void BecomeActive() diff --git a/Source/Stage/InitialLoad/2StageUnifyXML.cs b/Source/Stage/InitialLoad/2StageUnifyXML.cs index cfdbf02..42e644c 100755 --- a/Source/Stage/InitialLoad/2StageUnifyXML.cs +++ b/Source/Stage/InitialLoad/2StageUnifyXML.cs @@ -48,10 +48,10 @@ public override int GetMaximumProgress() public override void DoPatching(Harmony instance) { instance.Patch(AccessTools.Method(typeof(LoadedModManager), nameof(LoadedModManager.CombineIntoUnifiedXML)), - new HarmonyMethod(typeof(StageUnifyXML), nameof(PreUnifyXML))); + new(typeof(StageUnifyXML), nameof(PreUnifyXML))); instance.Patch(AccessTools.Method(typeof(XmlDocument), "get_" + nameof(XmlDocument.DocumentElement)), - postfix: new HarmonyMethod(typeof(StageUnifyXML), nameof(PostGetDocumentElement))); + postfix: new(typeof(StageUnifyXML), nameof(PostGetDocumentElement))); } public static void PreUnifyXML(List xmls) diff --git a/Source/Stage/InitialLoad/3StageApplyPatches.cs b/Source/Stage/InitialLoad/3StageApplyPatches.cs index 449c50f..295b708 100755 --- a/Source/Stage/InitialLoad/3StageApplyPatches.cs +++ b/Source/Stage/InitialLoad/3StageApplyPatches.cs @@ -76,11 +76,11 @@ public override bool IsCompleted() public override void DoPatching(Harmony instance) { - instance.Patch(AccessTools.Method(typeof(LoadedModManager), nameof(LoadedModManager.ApplyPatches)), new HarmonyMethod(typeof(StageApplyPatches), nameof(PreApplyPatches))); + instance.Patch(AccessTools.Method(typeof(LoadedModManager), nameof(LoadedModManager.ApplyPatches)), new(typeof(StageApplyPatches), nameof(PreApplyPatches))); - instance.Patch(AccessTools.PropertyGetter(typeof(ModContentPack), nameof(ModContentPack.Patches)), new HarmonyMethod(typeof(StageApplyPatches), nameof(PreLoadPatches)), new HarmonyMethod(typeof(StageApplyPatches), nameof(PostLoadPatches))); + instance.Patch(AccessTools.PropertyGetter(typeof(ModContentPack), nameof(ModContentPack.Patches)), new(typeof(StageApplyPatches), nameof(PreLoadPatches)), new(typeof(StageApplyPatches), nameof(PostLoadPatches))); - instance.Patch(AccessTools.Method(typeof(PatchOperation), nameof(PatchOperation.Apply)), postfix: new HarmonyMethod(typeof(StageApplyPatches), nameof(PostApplyPatch))); + instance.Patch(AccessTools.Method(typeof(PatchOperation), nameof(PatchOperation.Apply)), postfix: new(typeof(StageApplyPatches), nameof(PostApplyPatch))); } public static void PreApplyPatches() diff --git a/Source/Stage/InitialLoad/4StageRegisterDefs.cs b/Source/Stage/InitialLoad/4StageRegisterDefs.cs index 25bb6cd..f955ede 100755 --- a/Source/Stage/InitialLoad/4StageRegisterDefs.cs +++ b/Source/Stage/InitialLoad/4StageRegisterDefs.cs @@ -54,8 +54,8 @@ public override int GetMaximumProgress() public override void DoPatching(Harmony instance) { - instance.Patch(AccessTools.Method(typeof(LoadedModManager), nameof(LoadedModManager.ParseAndProcessXML)), new HarmonyMethod(typeof(StageRegisterDefs), nameof(PreParseProcXml))); - instance.Patch(AccessTools.Method(typeof(XmlInheritance), nameof(XmlInheritance.TryRegister)), new HarmonyMethod(typeof(StageRegisterDefs), nameof(PreRegisterDef))); + instance.Patch(AccessTools.Method(typeof(LoadedModManager), nameof(LoadedModManager.ParseAndProcessXML)), new(typeof(StageRegisterDefs), nameof(PreParseProcXml))); + instance.Patch(AccessTools.Method(typeof(XmlInheritance), nameof(XmlInheritance.TryRegister)), new(typeof(StageRegisterDefs), nameof(PreRegisterDef))); } public static void PreParseProcXml(XmlDocument xmlDoc) diff --git a/Source/Stage/InitialLoad/5StageConstructDefs.cs b/Source/Stage/InitialLoad/5StageConstructDefs.cs index 4e07a42..c31c2d7 100755 --- a/Source/Stage/InitialLoad/5StageConstructDefs.cs +++ b/Source/Stage/InitialLoad/5StageConstructDefs.cs @@ -19,8 +19,8 @@ public class StageConstructDefs : LoadingStage private static StageConstructDefs inst; - private static readonly ConcurrentDictionary> objectFromXmlMethods = new ConcurrentDictionary>(); - private static ConcurrentDictionary typeCache = new ConcurrentDictionary(EqualityComparer.Default); + private static readonly ConcurrentDictionary> objectFromXmlMethods = new(); + private static ConcurrentDictionary typeCache = new(EqualityComparer.Default); private static MethodInfo GetTypeInternal = typeof(GenTypes).GetMethod("GetTypeInAnyAssemblyInt", BindingFlags.Static | BindingFlags.NonPublic); @@ -73,9 +73,9 @@ public override int GetMaximumProgress() public override void DoPatching(Harmony instance) { - instance.Patch(AccessTools.Method(typeof(LoadedModManager), nameof(LoadedModManager.ParseAndProcessXML)), new HarmonyMethod(typeof(StageConstructDefs), nameof(PreParseProcXml)), new HarmonyMethod(typeof(StageConstructDefs), nameof(PostParseProcessXml))/*, new HarmonyMethod(typeof(StageConstructDefs), nameof(ParallelParseAndProcessXML))*/); - instance.Patch(AccessTools.Method(typeof(DirectXmlLoader), nameof(DirectXmlLoader.DefFromNode)), new HarmonyMethod(typeof(StageConstructDefs), nameof(PreDefFromNode))); - instance.Patch(AccessTools.Method(typeof(GenTypes), nameof(GenTypes.GetTypeInAnyAssembly)), new HarmonyMethod(typeof(Utils), nameof(Utils.HarmonyPatchCancelMethod)),new HarmonyMethod(typeof(StageConstructDefs), nameof(ThreadSafeGetTypeInAnyAssembly))); + instance.Patch(AccessTools.Method(typeof(LoadedModManager), nameof(LoadedModManager.ParseAndProcessXML)), new(typeof(StageConstructDefs), nameof(PreParseProcXml)), new(typeof(StageConstructDefs), nameof(PostParseProcessXml))/*, new HarmonyMethod(typeof(StageConstructDefs), nameof(ParallelParseAndProcessXML))*/); + instance.Patch(AccessTools.Method(typeof(DirectXmlLoader), nameof(DirectXmlLoader.DefFromNode)), new(typeof(StageConstructDefs), nameof(PreDefFromNode))); + instance.Patch(AccessTools.Method(typeof(GenTypes), nameof(GenTypes.GetTypeInAnyAssembly)), new(typeof(Utils), nameof(Utils.HarmonyPatchCancelMethod)),new(typeof(StageConstructDefs), nameof(ThreadSafeGetTypeInAnyAssembly))); } public static void ThreadSafeGetTypeInAnyAssembly(string typeName, string namespaceIfAmbiguous, ref Type __result) diff --git a/Source/Stage/InitialLoad/6StageResolveDefDatabases.cs b/Source/Stage/InitialLoad/6StageResolveDefDatabases.cs index 65a8968..5816104 100755 --- a/Source/Stage/InitialLoad/6StageResolveDefDatabases.cs +++ b/Source/Stage/InitialLoad/6StageResolveDefDatabases.cs @@ -24,7 +24,7 @@ public override string GetStageName() return "Reloading Def Databases"; } - public override string? GetCurrentStepName() + public override string GetCurrentStepName() { return _currentDatabase?.FullName ?? ""; } @@ -52,17 +52,18 @@ public override void BecomeActive() public override void BecomeInactive() { base.BecomeInactive(); - LoadingScreen.MarkTipsNowAvailable(); + Log.Message("[BetterLoading] Tips should now be available. Showing..."); + LoadingScreenTipManager.GameTipDatabaseHasLoaded = true; } public override void DoPatching(Harmony instance) { instance.Patch( AccessTools.Method(typeof(GenGeneric), "MethodOnGenericType", new[] {typeof(Type), typeof(Type), typeof(string)}), - new HarmonyMethod(typeof(StageResolveDefDatabases), nameof(PreMOGT)), - new HarmonyMethod(typeof(StageResolveDefDatabases), nameof(PostMOGT))); + new(typeof(StageResolveDefDatabases), nameof(PreMOGT)), + new(typeof(StageResolveDefDatabases), nameof(PostMOGT))); - instance.Patch(AccessTools.Method(typeof(DefGenerator), nameof(DefGenerator.GenerateImpliedDefs_PostResolve)), new HarmonyMethod(typeof(StageResolveDefDatabases), nameof(PreGenImplied))); + instance.Patch(AccessTools.Method(typeof(DefGenerator), nameof(DefGenerator.GenerateImpliedDefs_PostResolve)), new(typeof(StageResolveDefDatabases), nameof(PreGenImplied))); } public static void PreMOGT(Type genericParam, string methodName) diff --git a/Source/Stage/InitialLoad/7StageRunPostLoadPreFinalizeCallbacks.cs b/Source/Stage/InitialLoad/7StageRunPostLoadPreFinalizeCallbacks.cs index 60986a8..b4035c3 100755 --- a/Source/Stage/InitialLoad/7StageRunPostLoadPreFinalizeCallbacks.cs +++ b/Source/Stage/InitialLoad/7StageRunPostLoadPreFinalizeCallbacks.cs @@ -62,8 +62,8 @@ public override void BecomeActive() public override void DoPatching(Harmony instance) { - instance.Patch(AccessTools.Method(typeof(LongEventHandler), "ExecuteToExecuteWhenFinished"), new HarmonyMethod(typeof(StageRunPostLoadPreFinalizeCallbacks), nameof(PreExecToExecWhenFinished))); - instance.Patch(AccessTools.Method(typeof(LongEventHandler), "UpdateCurrentSynchronousEvent"), new HarmonyMethod(typeof(StageRunPostLoadPreFinalizeCallbacks), nameof(PreUpdateCurrentSynchronousEvent))); + instance.Patch(AccessTools.Method(typeof(LongEventHandler), "ExecuteToExecuteWhenFinished"), new(typeof(StageRunPostLoadPreFinalizeCallbacks), nameof(PreExecToExecWhenFinished))); + instance.Patch(AccessTools.Method(typeof(LongEventHandler), "UpdateCurrentSynchronousEvent"), new(typeof(StageRunPostLoadPreFinalizeCallbacks), nameof(PreUpdateCurrentSynchronousEvent))); } public static bool PreExecToExecWhenFinished(List ___toExecuteWhenFinished) @@ -82,7 +82,7 @@ public static bool PreExecToExecWhenFinished(List ___toExecuteWhenFinish _hasBeenCalled = true; - var targetTypeName = typeof(PlayDataLoader).FullName ?? throw new Exception("WTF where has playdataloader gone."); + var targetTypeName = typeof(PlayDataLoader).FullName ?? throw new("WTF where has playdataloader gone."); // var last = ___toExecuteWhenFinished.Skip(2900).Take(int.MaxValue).Select(i => i.Method.DeclaringType).ToList(); // Debug.Log($"BL Debug: last few task defining types: {last.ToStringSafeEnumerable()}"); diff --git a/Source/Stage/InitialLoad/8StageRunStaticCctors.cs b/Source/Stage/InitialLoad/8StageRunStaticCctors.cs index 018116e..f011204 100755 --- a/Source/Stage/InitialLoad/8StageRunStaticCctors.cs +++ b/Source/Stage/InitialLoad/8StageRunStaticCctors.cs @@ -58,7 +58,7 @@ public override bool IsCompleted() public override void DoPatching(Harmony instance) { - instance.Patch(AccessTools.Method(typeof(StaticConstructorOnStartupUtility), nameof(StaticConstructorOnStartupUtility.CallAll)), new HarmonyMethod(typeof(StageRunStaticCctors), nameof(PreCallAll))); + instance.Patch(AccessTools.Method(typeof(StaticConstructorOnStartupUtility), nameof(StaticConstructorOnStartupUtility.CallAll)), new(typeof(StageRunStaticCctors), nameof(PreCallAll))); // instance.Patch(AccessTools.Method(typeof(RuntimeHelpers), nameof(RuntimeHelpers.RunClassConstructor), new []{typeof(RuntimeTypeHandle)}), new HarmonyMethod(typeof(StageRunStaticCctors), nameof(PreRunClassConstructor))); } @@ -181,7 +181,7 @@ public static bool PreCallAll() _queue = result; // Log.Message($"[BetterLoading] Updating field in LEH to a new list of size {result.Count}...", true); - LongEventHandlerMirror.ToExecuteWhenFinished = new List(); + LongEventHandlerMirror.ToExecuteWhenFinished = new(); LongEventHandler.QueueLongEvent(WaitForStaticCtors, null, true, null); diff --git a/Source/Stage/InitialLoad/9StageRunPostFinalizeCallbacks.cs b/Source/Stage/InitialLoad/9StageRunPostFinalizeCallbacks.cs index e4743d1..304a567 100755 --- a/Source/Stage/InitialLoad/9StageRunPostFinalizeCallbacks.cs +++ b/Source/Stage/InitialLoad/9StageRunPostFinalizeCallbacks.cs @@ -60,8 +60,8 @@ public override void BecomeActive() public override void DoPatching(Harmony instance) { - instance.Patch(AccessTools.Method(typeof(LongEventHandler), "ExecuteToExecuteWhenFinished"), new HarmonyMethod(typeof(StageRunPostFinalizeCallbacks), nameof(PreExecToExecWhenFinished))); - instance.Patch(AccessTools.Method(typeof(LongEventHandler), "UpdateCurrentSynchronousEvent"), new HarmonyMethod(typeof(StageRunPostFinalizeCallbacks), nameof(PreUpdateCurrentSynchronousEvent))); + instance.Patch(AccessTools.Method(typeof(LongEventHandler), "ExecuteToExecuteWhenFinished"), new(typeof(StageRunPostFinalizeCallbacks), nameof(PreExecToExecWhenFinished))); + instance.Patch(AccessTools.Method(typeof(LongEventHandler), "UpdateCurrentSynchronousEvent"), new(typeof(StageRunPostFinalizeCallbacks), nameof(PreUpdateCurrentSynchronousEvent))); } public static bool PreExecToExecWhenFinished(List ___toExecuteWhenFinished) diff --git a/Source/Stage/LoadingStage.cs b/Source/Stage/LoadingStage.cs index 38db0b5..4afdd70 100755 --- a/Source/Stage/LoadingStage.cs +++ b/Source/Stage/LoadingStage.cs @@ -6,7 +6,7 @@ namespace BetterLoading.Stage { public abstract class LoadingStage { - private static List _initializedStages = new List(); + private static List _initializedStages = new(); /// /// Required public no-args constructor /// diff --git a/Source/Stage/SaveLoad/0LoadSmallComponents.cs b/Source/Stage/SaveLoad/0LoadSmallComponents.cs index bab33e1..8514d5f 100644 --- a/Source/Stage/SaveLoad/0LoadSmallComponents.cs +++ b/Source/Stage/SaveLoad/0LoadSmallComponents.cs @@ -44,7 +44,7 @@ public override void BecomeInactive() public override void DoPatching(Harmony instance) { - instance.Patch(AccessTools.Method(typeof(World), nameof(World.ExposeData)), new HarmonyMethod(typeof(LoadSmallComponents), nameof(OnLoadWorldStart))); + instance.Patch(AccessTools.Method(typeof(World), nameof(World.ExposeData)), new(typeof(LoadSmallComponents), nameof(OnLoadWorldStart))); } public static void OnLoadWorldStart() diff --git a/Source/Stage/SaveLoad/1LoadWorldMap.cs b/Source/Stage/SaveLoad/1LoadWorldMap.cs index 092105e..21bc5d4 100644 --- a/Source/Stage/SaveLoad/1LoadWorldMap.cs +++ b/Source/Stage/SaveLoad/1LoadWorldMap.cs @@ -62,10 +62,10 @@ public override void BecomeInactive() public override void DoPatching(Harmony instance) { - instance.Patch(AccessTools.Method(typeof(World), nameof(World.ExposeData)), postfix: new HarmonyMethod(typeof(LoadWorldMap), nameof(OnLoadWorldEnd))); - instance.Patch(AccessTools.Method(typeof(WorldGenerator), nameof(WorldGenerator.GenerateFromScribe)), new HarmonyMethod(typeof(LoadWorldMap), nameof(OnStartLoadGeneratedData))); - instance.Patch(AccessTools.Method(typeof(WorldGenerator), nameof(WorldGenerator.GenerateWithoutWorldData)), new HarmonyMethod(typeof(LoadWorldMap), nameof(OnStartGenerateFreshData))); - instance.Patch(AccessTools.Method(typeof(World), nameof(World.FinalizeInit)), postfix: new HarmonyMethod(typeof(LoadWorldMap), nameof(OnFinalizeWorldInitEnd))); + instance.Patch(AccessTools.Method(typeof(World), nameof(World.ExposeData)), postfix: new(typeof(LoadWorldMap), nameof(OnLoadWorldEnd))); + instance.Patch(AccessTools.Method(typeof(WorldGenerator), nameof(WorldGenerator.GenerateFromScribe)), new(typeof(LoadWorldMap), nameof(OnStartLoadGeneratedData))); + instance.Patch(AccessTools.Method(typeof(WorldGenerator), nameof(WorldGenerator.GenerateWithoutWorldData)), new(typeof(LoadWorldMap), nameof(OnStartGenerateFreshData))); + instance.Patch(AccessTools.Method(typeof(World), nameof(World.FinalizeInit)), postfix: new(typeof(LoadWorldMap), nameof(OnFinalizeWorldInitEnd))); } public static void OnStartLoadGeneratedData() diff --git a/Source/Stage/SaveLoad/2LoadMaps.cs b/Source/Stage/SaveLoad/2LoadMaps.cs index 23ce03e..9c5efa7 100644 --- a/Source/Stage/SaveLoad/2LoadMaps.cs +++ b/Source/Stage/SaveLoad/2LoadMaps.cs @@ -98,10 +98,10 @@ public override void BecomeInactive() public override void DoPatching(Harmony instance) { - instance.Patch(AccessTools.Method(typeof(Map), nameof(Map.ExposeData)), new HarmonyMethod(typeof(LoadMaps), nameof(OnMapLoadStart))); - instance.Patch(AccessTools.Method(typeof(Map), "ExposeComponents"), new HarmonyMethod(typeof(LoadMaps), nameof(OnMapComponentsLoadStart))); - instance.Patch(AccessTools.Method(typeof(MapFileCompressor), nameof(MapFileCompressor.ExposeData)), new HarmonyMethod(typeof(LoadMaps), nameof(OnMapCompressedDataLoadStart)), new HarmonyMethod(typeof(LoadMaps), nameof(OnMapCompressedDataLoadEnd))); - instance.Patch(AccessTools.Method(typeof(CameraDriver), nameof(CameraDriver.Expose)), postfix: new HarmonyMethod(typeof(LoadMaps), nameof(OnAllMapsLoaded))); + instance.Patch(AccessTools.Method(typeof(Map), nameof(Map.ExposeData)), new(typeof(LoadMaps), nameof(OnMapLoadStart))); + instance.Patch(AccessTools.Method(typeof(Map), "ExposeComponents"), new(typeof(LoadMaps), nameof(OnMapComponentsLoadStart))); + instance.Patch(AccessTools.Method(typeof(MapFileCompressor), nameof(MapFileCompressor.ExposeData)), new(typeof(LoadMaps), nameof(OnMapCompressedDataLoadStart)), new(typeof(LoadMaps), nameof(OnMapCompressedDataLoadEnd))); + instance.Patch(AccessTools.Method(typeof(CameraDriver), nameof(CameraDriver.Expose)), postfix: new(typeof(LoadMaps), nameof(OnAllMapsLoaded))); } public static void OnMapLoadStart(Map __instance) diff --git a/Source/Stage/SaveLoad/3FinalizeScribeLoad.cs b/Source/Stage/SaveLoad/3FinalizeScribeLoad.cs index 767353d..e446c05 100644 --- a/Source/Stage/SaveLoad/3FinalizeScribeLoad.cs +++ b/Source/Stage/SaveLoad/3FinalizeScribeLoad.cs @@ -44,7 +44,7 @@ public override void BecomeInactive() public override void DoPatching(Harmony instance) { - instance.Patch(AccessTools.Method(typeof(ScribeLoader), nameof(ScribeLoader.FinalizeLoading)), postfix: new HarmonyMethod(typeof(FinalizeScribeLoad), nameof(OnResolvingComplete))); + instance.Patch(AccessTools.Method(typeof(ScribeLoader), nameof(ScribeLoader.FinalizeLoading)), postfix: new(typeof(FinalizeScribeLoad), nameof(OnResolvingComplete))); } public static void OnResolvingComplete() diff --git a/Source/Stage/SaveLoad/4SpawnAllThings.cs b/Source/Stage/SaveLoad/4SpawnAllThings.cs index af72bf2..106bcf6 100644 --- a/Source/Stage/SaveLoad/4SpawnAllThings.cs +++ b/Source/Stage/SaveLoad/4SpawnAllThings.cs @@ -55,16 +55,16 @@ public override void BecomeInactive() public override void DoPatching(Harmony instance) { - instance.Patch(AccessTools.Method(typeof(Map), nameof(Map.FinalizeLoading)), new HarmonyMethod(typeof(SpawnAllThings), nameof(OnMapStartFinalizing)), new HarmonyMethod(typeof(SpawnAllThings), nameof(OnMapFinishFinalizing))); + instance.Patch(AccessTools.Method(typeof(Map), nameof(Map.FinalizeLoading)), new(typeof(SpawnAllThings), nameof(OnMapStartFinalizing)), new(typeof(SpawnAllThings), nameof(OnMapFinishFinalizing))); //Things instance.Patch( AccessTools.Method(typeof(GenSpawn), nameof(GenSpawn.Spawn), new[] {typeof(Thing), typeof(IntVec3), typeof(Map), typeof(Rot4), typeof(WipeMode), typeof(bool)}), - new HarmonyMethod(typeof(SpawnAllThings), nameof(OnThingAboutToSpawn)) + new(typeof(SpawnAllThings), nameof(OnThingAboutToSpawn)) ); //Buildings - instance.Patch(AccessTools.Method(typeof(GenSpawn), nameof(GenSpawn.SpawnBuildingAsPossible)), new HarmonyMethod(typeof(SpawnAllThings), nameof(OnThingAboutToSpawn))); + instance.Patch(AccessTools.Method(typeof(GenSpawn), nameof(GenSpawn.SpawnBuildingAsPossible)), new(typeof(SpawnAllThings), nameof(OnThingAboutToSpawn))); } public static void OnMapStartFinalizing() diff --git a/Source/StageTimingData.cs b/Source/StageTimingData.cs index e027f0b..105fba1 100755 --- a/Source/StageTimingData.cs +++ b/Source/StageTimingData.cs @@ -6,7 +6,7 @@ namespace BetterLoading { public class StageTimingData { - internal static readonly List ExecutedStages = new List(); + internal static readonly List ExecutedStages = new(); public DateTime start; public DateTime end;