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 @@
TargetFrameworkLibrarynet48
- 8
- annotations
+ 10
+ enablefalse
@@ -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