diff --git a/1.1-1.2/Assemblies/BetterLoading.dll b/1.1-1.2/Assemblies/BetterLoading.dll index 7be7a77..19309f4 100644 Binary files a/1.1-1.2/Assemblies/BetterLoading.dll and b/1.1-1.2/Assemblies/BetterLoading.dll differ diff --git a/1.3/Assemblies/BetterLoading.dll b/1.3/Assemblies/BetterLoading.dll index b544aa0..9a8098c 100644 Binary files a/1.3/Assemblies/BetterLoading.dll and b/1.3/Assemblies/BetterLoading.dll differ diff --git a/About/Manifest.xml b/About/Manifest.xml index a5f7f30..51f3564 100755 --- a/About/Manifest.xml +++ b/About/Manifest.xml @@ -1,7 +1,7 @@ BetterLoading - 3.1.3.2 + 3.2.0.0
  • Core >= 1.0
  • Startupimpact
  • diff --git a/Source/BetterLoadingMain.cs b/Source/BetterLoadingMain.cs index 385861d..693f151 100755 --- a/Source/BetterLoadingMain.cs +++ b/Source/BetterLoadingMain.cs @@ -3,6 +3,7 @@ using System.IO; using System.Linq; using System.Reflection; +using BetterLoading.Stage.SaveLoad; using HarmonyLib; using JetBrains.Annotations; using RimWorld; @@ -296,6 +297,10 @@ public static void OnGameLoadStart() LoadingScreen = Object.FindObjectOfType().gameObject .AddComponent(); InitLoadingScreenBG(); + + //Try and work out how many maps we have + LoadMaps.CountMaps(); + LoadingScreen!.StartSaveLoad(); } @@ -320,67 +325,6 @@ public static void OnClearPlayData() #region Save Game Loading Patches - [HarmonyPatch(typeof(Game))] - [HarmonyPatch(nameof(Game.LoadGame))] - [UsedImplicitly] - public class LoadGamePatch - { - [UsedImplicitly] - public static void Prefix() - { - Resources.FindObjectsOfTypeAll()[0].gameObject - .AddComponent(); - LogMsg("Loading Screen Manager :: Load Small Components :: Start"); - - LoadingScreen.Instance.shouldShow = true; - LoadingScreen.Instance.currentStage = EnumLoadingStage.LoadSmallComponents; - } - } - - [HarmonyPatch(typeof(World))] - [HarmonyPatch(nameof(World.ExposeData))] - [UsedImplicitly] - public class LoadWorldPatch - { - [UsedImplicitly] - public static void Prefix() - { - if (LoadingScreen.Instance.currentStage == EnumLoadingStage.LoadSmallComponents) - { - LogMsg("Loading Screen Manager :: Load World Map :: Start"); - LoadingScreen.Instance.currentStage = EnumLoadingStage.LoadWorldMap; - } - } - } - - [HarmonyPatch(typeof(WorldGenerator))] - [HarmonyPatch(nameof(WorldGenerator.GenerateFromScribe))] - [UsedImplicitly] - public class GenerateWorldPatch - { - [UsedImplicitly] - public static void Prefix() - { - LogMsg("Loading Screen Manager :: Generate World Data :: Start"); - LoadingScreen.Instance.currentStage = EnumLoadingStage.GenerateWorldData; - LoadingScreen.Instance.numWorldGeneratorsToRun = WorldGenerator.GenStepsInOrder.Count() - 2; - } - } - - [HarmonyPatch(typeof(WorldGenerator))] - [HarmonyPatch(nameof(WorldGenerator.GenerateWithoutWorldData))] - [UsedImplicitly] - public class GenerateWorldPatch2 - { - [UsedImplicitly] - public static void Prefix() - { - LogMsg("Loading Screen Manager :: Generate World Data :: Start"); - LoadingScreen.Instance.currentStage = EnumLoadingStage.GenerateWorldData; - LoadingScreen.Instance.numWorldGeneratorsToRun = WorldGenerator.GenStepsInOrder.Count() - 2; - } - } - [HarmonyPatch(typeof(WorldGenStep))] [HarmonyPatch(nameof(WorldGenStep.GenerateFromScribe))] [UsedImplicitly] @@ -407,204 +351,6 @@ public static void Prefix(WorldGenStep __instance) } } - [HarmonyPatch(typeof(World))] - [HarmonyPatch(nameof(World.FinalizeInit))] - [UsedImplicitly] - public class WorldFinalizePatch - { - [UsedImplicitly] - public static void Prefix() - { - LogMsg("Loading Screen Manager :: Finalize World Data :: Start"); - LoadingScreen.Instance.currentStage = EnumLoadingStage.FinalizeWorld; - } - } - - [HarmonyPatch(typeof(Map))] - [HarmonyPatch(nameof(Map.ExposeData))] - [UsedImplicitly] - public class MapExposePatch - { - [UsedImplicitly] - public static void Prefix(Map __instance) - { - if (LoadingScreen.Instance.currentStage >= EnumLoadingStage.FinalizeWorld && - LoadingScreen.Instance.currentStage <= EnumLoadingStage.LoadMaps_LoadData) - { - LogMsg("Loading Screen Manager :: Load Map (Construct Components) :: Start"); - LoadingScreen.Instance.currentStage = EnumLoadingStage.LoadMaps_ConstructComponents; - LoadingScreen.Instance.maps.Add(__instance); - } - } - } - - [HarmonyPatch(typeof(Map))] - [HarmonyPatch("ExposeComponents")] - [UsedImplicitly] - public class MapLoadPatch - { - [UsedImplicitly] - public static void Prefix() - { - if (LoadingScreen.Instance.currentStage == EnumLoadingStage.LoadMaps_ConstructComponents) - { - LogMsg("Loading Screen Manager :: Load Map (Load Components) :: Start"); - LoadingScreen.Instance.currentStage = EnumLoadingStage.LoadMaps_LoadComponents; - } - } - } - - [HarmonyPatch(typeof(MapFileCompressor))] - [HarmonyPatch(nameof(MapFileCompressor.ExposeData))] - [UsedImplicitly] - public class MapLoadCompressedPatch - { - [UsedImplicitly] - public static void Prefix() - { - if (LoadingScreen.Instance.currentStage == EnumLoadingStage.LoadMaps_LoadComponents) - { - LogMsg("Loading Screen Manager :: Load Map (Load Objects) :: Start"); - LoadingScreen.Instance.currentStage = EnumLoadingStage.LoadMaps_LoadData; - } - } - } - - [HarmonyPatch(typeof(CameraDriver))] - [HarmonyPatch(nameof(CameraDriver.Expose))] - [UsedImplicitly] - public class CameraLoadPatch - { - [UsedImplicitly] - public static void Prefix() - { - if (LoadingScreen.Instance.currentStage == EnumLoadingStage.LoadMaps_LoadData) - { - LogMsg("Loading Screen Manager :: Init Camera :: Start"); - LoadingScreen.Instance.currentStage = EnumLoadingStage.InitCamera; - } - } - } - - [HarmonyPatch(typeof(ScribeLoader))] - [HarmonyPatch(nameof(ScribeLoader.FinalizeLoading))] - [UsedImplicitly] - public class ResolveSaveFileReferencesPatch - { - [UsedImplicitly] - public static void Prefix() - { - if (LoadingScreen.Instance.currentStage != EnumLoadingStage.InitCamera) return; - - LogMsg("Loading Screen Manager :: Resolve Cross-References :: Start"); - LoadingScreen.Instance.currentStage = EnumLoadingStage.ResolveSaveFileCrossReferences; - } - } - - [HarmonyPatch(typeof(Map))] - [HarmonyPatch(nameof(Map.FinalizeLoading))] - [UsedImplicitly] - public class MapFinalizeLoadPatch - { - [UsedImplicitly] - public static void Prefix(Map __instance) - { - LogMsg("Loading Screen Manager :: Spawn Things (Non-Buildings) :: Start"); - LoadingScreen.Instance.currentStage = EnumLoadingStage.SpawnThings_NonBuildings; - LoadingScreen.Instance.mapIndexSpawningItems++; - - //Reflection, fuck yeah! -// LoadingScreen.Instance.numObjectsToSpawnCurrentMap = __instance.compressor.ThingsToSpawnAfterLoad().Count() + -// Traverse.Create(__instance).Field>("loadedFullThings") -// .Value.Count; -// LoadingScreen.Instance.numObjectsSpawnedCurrentMap = 0; - } - } - - [HarmonyPatch(typeof(GenSpawn))] - [HarmonyPatch(nameof(GenSpawn.Spawn))] - [HarmonyPatch(new[] - {typeof(Thing), typeof(IntVec3), typeof(Map), typeof(Rot4), typeof(WipeMode), typeof(bool)})] - [UsedImplicitly] - public class GenSpawnSpawnPatch - { - [UsedImplicitly] - public static void Prefix() - { - if (LoadingScreen.Instance.currentStage == EnumLoadingStage.SpawnThings_NonBuildings) - LoadingScreen.Instance.numObjectsSpawnedCurrentMap++; - } - } - - [HarmonyPatch(typeof(GenSpawn))] - [HarmonyPatch(nameof(GenSpawn.SpawnBuildingAsPossible))] - [UsedImplicitly] - public class GenSpawnSpawnBuildingPatch - { - [UsedImplicitly] - public static void Prefix(Map __instance) - { - if (LoadingScreen.Instance.currentStage == EnumLoadingStage.SpawnThings_NonBuildings) - { - LogMsg("Loading Screen Manager :: Spawn Things (Buildings) :: Start"); - LoadingScreen.Instance.currentStage = EnumLoadingStage.SpawnThings_Buildings; - } - - if (LoadingScreen.Instance.currentStage == EnumLoadingStage.SpawnThings_Buildings) - LoadingScreen.Instance.numObjectsSpawnedCurrentMap++; - } - } - - [HarmonyPatch(typeof(GenPlace))] - [HarmonyPatch(nameof(GenPlace.TryPlaceThing))] - [HarmonyPatch(new[] - { - typeof(Thing), typeof(IntVec3), typeof(Map), typeof(ThingPlaceMode), typeof(Action), - typeof(Predicate) - })] - [UsedImplicitly] - public class GenPlaceTryPlacePatch - { - [UsedImplicitly] - public static void Prefix() - { - if (LoadingScreen.Instance.currentStage == EnumLoadingStage.SpawnThings_Buildings) - { - LogMsg("Loading Screen Manager :: Spawn Things (Back-Compat) :: Start"); - LoadingScreen.Instance.currentStage = EnumLoadingStage.SpawnThings_BackCompat; - } - - if (LoadingScreen.Instance.currentStage == EnumLoadingStage.SpawnThings_BackCompat) - LoadingScreen.Instance.numObjectsSpawnedCurrentMap++; - } - } - - [HarmonyPatch(typeof(Map))] - [HarmonyPatch(nameof(Map.FinalizeInit))] - [UsedImplicitly] - public class MapFinalizeInitPatch - { - [UsedImplicitly] - public static void Prefix() - { - LogMsg("Loading Screen Manager :: Spawn Things (Rebuild/Recalc) :: Start"); - LoadingScreen.Instance.currentStage = EnumLoadingStage.SpawnThings_RebuildRecalc; - } - } - - [HarmonyPatch(typeof(Game))] - [HarmonyPatch(nameof(Game.FinalizeInit))] - [UsedImplicitly] - public class GameFinalizeInitPatch - { - [UsedImplicitly] - public static void Prefix() - { - LogMsg("Loading Screen Manager :: Finalize Load :: Start"); - LoadingScreen.Instance.currentStage = EnumLoadingStage.FinalizeLoad; - } - } - #endregion } } \ No newline at end of file diff --git a/Source/LoadingScreen.cs b/Source/LoadingScreen.cs index 5ca690a..e485700 100755 --- a/Source/LoadingScreen.cs +++ b/Source/LoadingScreen.cs @@ -51,10 +51,8 @@ public sealed class LoadingScreen : MonoBehaviour //For all of these stages, vanilla just shows "..." new LoadSmallComponents(BetterLoadingMain.hInstance!), new LoadWorldMap(BetterLoadingMain.hInstance), - new FinalizeWorld(BetterLoadingMain.hInstance), new LoadMaps(BetterLoadingMain.hInstance), - new SetUpCamera(BetterLoadingMain.hInstance), - new ResolveDefCrossRefs(BetterLoadingMain.hInstance), + new FinalizeScribeLoad(BetterLoadingMain.hInstance), new SpawnAllThings(BetterLoadingMain.hInstance), new FinalizeGameState(BetterLoadingMain.hInstance) }; @@ -203,7 +201,9 @@ public void OnGUI() { Log.Message("[BetterLoading] Long event has finished, hiding loading screen."); shouldShow = false; - BetterLoadingApi.DispatchLoadComplete(); + + if(BootLoadList.Contains(_currentStage)) + BetterLoadingApi.DispatchLoadComplete(); return; } @@ -404,285 +404,6 @@ private static List LoadGameplayTips() return DefDatabase.AllDefsListForReading.SelectMany(set => set.tips).InRandomOrder().ToList(); } - private void DrawSaveFileLoad() - { - //Draw window - var rect = new Rect(100, 100, Screen.width - 200, Screen.height - 200); - rect = rect.Rounded(); - UIMenuBackgroundManager.background.BackgroundOnGUI(); - Widgets.DrawShadowAround(rect); - Widgets.DrawWindowBackground(rect); - - Text.Font = GameFont.Medium; - Text.Anchor = TextAnchor.UpperCenter; - - rect.y += 20; //Nudge down for title - - Widgets.Label(rect, "BetterLoading :: Loading Save File..."); - - Text.Font = GameFont.Small; - Text.Anchor = TextAnchor.UpperLeft; - - rect.x += 20; //Indent - rect.width -= 20; - - //Stages for this, in terms of actual time consuming events: - //Scene Load is triggered for "Play" scene, which triggers Verse.Root_Play#Start - //This then calls QueueLongEvent (Action, string, bool, Action) with the action being call SavedGameLoaderNow.LoadGameFromSaveFileNow - which is probably where the ACTUAL save file logic is. - // The event name is "LoadingLongEvent" and it's async - //If something goes wrong it calls GameAndMapInitExceptionHandlers.ErrorWhileLoadingGame - cleanup this? - //The key clue that the game load has begun is ScribeLoader#InitLoading being called which buffers the save file into an XmlDocument, and saves it into ScribeLoader.curXmlParent - // Scribe.mode is set to LoadingVars once the file is buffered in - but this doesn't have a setter to hook. - //Once the file is read then Game#LoadGame is called. This is the time consuming bit. - // - //Stage one could be "Load Small Components" (Game#ExposeSmallComponents) as this picks up a few small details such as research, the tutor, the scenario, etc. - // - //Second stage start coincides with vanilla's "Loading World" and hook could go in World's constructor or World#ExposeData - // This is split up into loading of the world info (i.e. seed, coverage, etc) which is quick - // And the grid, which may not be. - // Then WorldGenerator.GenerateFromScribe (or MAYBE GenerateWithoutWorldData) will be called - // -Progress bar this? We can do a hook in WorldGenStep#GenerateFromScribe/GenerateWithoutWorldData to increment, and the total is equal to WorldGenerator.GenStepsInOrder.Length - // Then World#FinalizeInit is called, which recalcs paths and has a callback for all WorldComponents (FinalizeInit method). - // - //Next Stage is vanilla's "Loading Map" - // This is deceptively simple as it just calls Map#ExposeData once per map. - // First part of this instantiates 80-odd classes and a bunch of MapComponents, but SHOULD be quite quick? (Call to Map#ConstructComponents) - // Second part populates all 80 classes and map components with saved data (call to Map#ExposeComponents) - // Third part loads compressed stuff as a byte array (Call to MapFileCompressor#ExposeData) - // Fourth part loads uncompressed stuff, and it's a direct call to Scribe_Collections#Look - // It then sets the current map index - // - //Next is vanilla's "Initializing Game" which actually just loads the camera pos (CameraDriver#Expose) - // - //Next is "Finalize Loading" which resolves cross references, sets the current load mode to Inactive, and calls post-load callbacks - // - //Then "Spawning All Things" - // This first off calls Map#FinalizeLoading for each map, which: - // Merges Map#loadedFullThings and MapCompressor#ThingsToSpawnAfterLoad()'s return value (hook said after load method?) - // Actually spawns stuff - // GenSpawn.Spawn for every non-building item in the new list (get total based on size of the two?) - // GenSpawn#SpawnBuildingAsPossible for every building in same list. - // Then calls GenPlace#TryPlaceThing for a few things if loading an older version - // Finally calls Map#FinalizeInit which recalculates and rebuilds a bunch of stuff and calls PostMapInit for each - // - //Finally Game#FinalizeInit is called, which flushes the log file, applies research mods, and calls GameComponent#FinalizeInit for each component in Current.Game.components - - //----------------Load Small Components------------ - rect.y += 50; - Widgets.Label(rect, - currentStage == EnumLoadingStage.LoadSmallComponents - ? "Loading Misc Game Data..." - : "Basic Game Data Loaded"); - - //bar - var barRect = new Rect(rect.x, rect.y + 25, rect.width - 24, 20); - Widgets.FillableBar(barRect, currentStage == EnumLoadingStage.LoadSmallComponents ? 0 : 1); - - //----------------Load World Map------------ - rect.y += 50; - Widgets.Label(rect, - currentStage < EnumLoadingStage.LoadWorldMap ? "Waiting for game data load..." : - currentStage == EnumLoadingStage.LoadWorldMap ? "Loading World Map..." : "World Map Loaded"); - - //bar - barRect = new Rect(rect.x, rect.y + 25, rect.width - 24, 20); - Widgets.FillableBar(barRect, currentStage <= EnumLoadingStage.LoadWorldMap ? 0 : 1); - - //----------------Generate World Features------------ - rect.y += 50; - Widgets.Label(rect, currentStage < EnumLoadingStage.GenerateWorldData - ? "Waiting for world map..." - : currentStage == EnumLoadingStage.GenerateWorldData - ? $"Generating World Feature: {currentWorldGenStep} ({numWorldGeneratorsRun}/{numWorldGeneratorsToRun})" - : "World Features Generated"); - - //bar - barRect = new Rect(rect.x, rect.y + 25, rect.width - 24, 20); - Widgets.FillableBar(barRect, - numWorldGeneratorsToRun == 0 ? 0 : (float) numWorldGeneratorsRun / numWorldGeneratorsToRun); - - //----------------Finalizing World------------ - rect.y += 50; - Widgets.Label(rect, currentStage < EnumLoadingStage.FinalizeWorld - ? "Waiting for feature generation..." - : currentStage == EnumLoadingStage.FinalizeWorld - ? "Applying finishing touches to world..." - : "World Finalized."); - - //bar - barRect = new Rect(rect.x, rect.y + 25, rect.width - 24, 20); - Widgets.FillableBar(barRect, currentStage <= EnumLoadingStage.FinalizeWorld ? 0 : 1); - - //----------------Map Loading------------ - rect.y += 50; - - if (currentStage >= EnumLoadingStage.LoadMaps_ConstructComponents) - { - if (currentStage <= EnumLoadingStage.LoadMaps_LoadData) - { - Widgets.Label(rect, "Loading Maps..."); - barRect = new Rect(rect.x, rect.y + 25, rect.width - 24, 20); - Widgets.FillableBar(barRect, 0.2f); - } - else - { - Widgets.Label(rect, "Maps Loaded"); - barRect = new Rect(rect.x, rect.y + 25, rect.width - 24, 20); - Widgets.FillableBar(barRect, 1); - } - - rect.y += 50; - rect.x += 25; //Indent - rect.width -= 25; - - var num = 0; - foreach (var unused in maps) - { - if (num < maps.Count - 1 || currentStage > EnumLoadingStage.LoadMaps_LoadData) - { - //This map is loaded fully - Widgets.Label(rect, "Map " + (num + 1) + ": Loaded"); - - //bar - barRect = new Rect(rect.x, rect.y + 25, rect.width - 24, 20); - Widgets.FillableBar(barRect, 1); - } - else - { - //This map is partially loaded - Widgets.Label(rect, - "Map " + (num + 1) + ": " + (currentStage == EnumLoadingStage.LoadMaps_ConstructComponents - ? "Constructing Components..." - : currentStage == EnumLoadingStage.LoadMaps_LoadComponents - ? "Loading Misc Map Details..." - : "Reading Object Data...")); - - barRect = new Rect(rect.x, rect.y + 25, rect.width - 24, 20); - Widgets.FillableBar(barRect, - (float) (currentStage + 1 - EnumLoadingStage.LoadMaps_ConstructComponents) / 5); - } - - num++; - rect.y += 50; - } - - rect.x -= 25; //Unindent - rect.width += 25; - } - else if (currentStage < EnumLoadingStage.LoadMaps_LoadComponents) - { - Widgets.Label(rect, "Waiting for map data..."); - barRect = new Rect(rect.x, rect.y + 25, rect.width - 24, 20); - Widgets.FillableBar(barRect, 0); - } - - //----------------Init Camera------------ - Widgets.Label(rect, currentStage < EnumLoadingStage.InitCamera - ? "Waiting for maps to finish loading..." - : currentStage == EnumLoadingStage.InitCamera - ? "Setting up camera..." - : "Camera Setup Complete"); - - //bar - barRect = new Rect(rect.x, rect.y + 25, rect.width - 24, 20); - Widgets.FillableBar(barRect, currentStage <= EnumLoadingStage.InitCamera ? 0 : 1); - - //----------------Resolve Cross-References------------ - rect.y += 50; - Widgets.Label(rect, currentStage < EnumLoadingStage.ResolveSaveFileCrossReferences - ? "Waiting for camera setup..." - : currentStage == EnumLoadingStage.ResolveSaveFileCrossReferences - ? "Resolving Def Cross-References..." - : "Defs Successfully Cross-Referenced"); - - //bar - barRect = new Rect(rect.x, rect.y + 25, rect.width - 24, 20); - Widgets.FillableBar(barRect, currentStage <= EnumLoadingStage.ResolveSaveFileCrossReferences ? 0 : 1); - - //----------------Spawning All Things------------ - rect.y += 50; - - - if (currentStage > EnumLoadingStage.SpawnThings_RebuildRecalc) - { - Widgets.Label(rect, "Things Spawned"); - barRect = new Rect(rect.x, rect.y + 25, rect.width - 24, 20); - Widgets.FillableBar(barRect, 1); - } - else if (currentStage >= EnumLoadingStage.SpawnThings_NonBuildings) - { - Widgets.Label(rect, "Spawning all things..."); - barRect = new Rect(rect.x, rect.y + 25, rect.width - 24, 20); - Widgets.FillableBar(barRect, (mapIndexSpawningItems + 1f) / (maps.Count + 1f)); - } - else - { - Widgets.Label(rect, "Waiting for defs to be cross-referenced..."); - barRect = new Rect(rect.x, rect.y + 25, rect.width - 24, 20); - Widgets.FillableBar(barRect, 0); - } - - rect.y += 50; - rect.x += 25; //Indent - rect.width -= 25; - - var num2 = 0; - foreach (var unused in maps) - { - if (num2 < mapIndexSpawningItems || currentStage > EnumLoadingStage.SpawnThings_RebuildRecalc) - { - //This map is loaded fully - Widgets.Label(rect, "Map " + (num2 + 1) + ": Everything Spawned"); - - //bar - barRect = new Rect(rect.x, rect.y + 25, rect.width - 24, 20); - Widgets.FillableBar(barRect, 1); - } - else if (num2 == mapIndexSpawningItems) - { - //This map is partially loaded - Widgets.Label(rect, - "Map " + (num2 + 1) + ": " + (currentStage == EnumLoadingStage.SpawnThings_NonBuildings - ? "Spawning Items..." - : currentStage == EnumLoadingStage.SpawnThings_Buildings - ? "Spawning Buildings..." - : currentStage == EnumLoadingStage.SpawnThings_BackCompat - ? "Upgrading Level Format..." - : "Rebuilding & Recalculating Pathfinding Map etc...")); - - barRect = new Rect(rect.x, rect.y + 25, rect.width - 24, 20); - Widgets.FillableBar(barRect, - (float) (currentStage + 1 - EnumLoadingStage.SpawnThings_NonBuildings) / 5); - } - else - { - //This map is not yet loaded - Widgets.Label(rect, "Map " + (num2 + 1) + ": Waiting..."); - - //bar - barRect = new Rect(rect.x, rect.y + 25, rect.width - 24, 20); - Widgets.FillableBar(barRect, 0); - } - - num2++; - rect.y += 50; - } - - rect.x -= 25; //Unindent - rect.width += 25; - - //----------------Finalize Load------------ - Widgets.Label(rect, currentStage < EnumLoadingStage.FinalizeLoad - ? "Waiting for things to finish spawning..." - : currentStage == EnumLoadingStage.FinalizeLoad - ? "Finalizing Game State..." - : "Load Complete."); - - //bar - barRect = new Rect(rect.x, rect.y + 25, rect.width - 24, 20); - Widgets.FillableBar(barRect, currentStage <= EnumLoadingStage.FinalizeLoad ? 0 : 1); - } - public static void MarkTipsNowAvailable() { Log.Message("[BetterLoading] Tips should now be available. Showing..."); diff --git a/Source/Stage/SaveLoad/2FinalizeWorld.cs b/Source/Stage/SaveLoad/2FinalizeWorld.cs deleted file mode 100644 index 37050d3..0000000 --- a/Source/Stage/SaveLoad/2FinalizeWorld.cs +++ /dev/null @@ -1,35 +0,0 @@ -using HarmonyLib; -using JetBrains.Annotations; - -namespace BetterLoading.Stage.SaveLoad -{ - public class FinalizeWorld : LoadingStage { - public FinalizeWorld([NotNull] Harmony instance) : base(instance) - { - } - - public override string GetStageName() - { - throw new System.NotImplementedException(); - } - - public override string? GetCurrentStepName() - { - throw new System.NotImplementedException(); - } - - public override int GetCurrentProgress() - { - throw new System.NotImplementedException(); - } - - public override int GetMaximumProgress() - { - throw new System.NotImplementedException(); - } - - public override void DoPatching(Harmony instance) - { - } - } -} \ No newline at end of file diff --git a/Source/Stage/SaveLoad/2LoadMaps.cs b/Source/Stage/SaveLoad/2LoadMaps.cs new file mode 100644 index 0000000..de073be --- /dev/null +++ b/Source/Stage/SaveLoad/2LoadMaps.cs @@ -0,0 +1,136 @@ +using HarmonyLib; +using JetBrains.Annotations; +using Verse; + +namespace BetterLoading.Stage.SaveLoad +{ + public class LoadMaps : LoadingStage { + public static int NumMaps; + + private static int _currMapNum = -1; + private static Map _currMap; + + private static bool _currMapInitialized; + private static bool _currMapLoadedComponents; + private static bool _currMapLoadedCompressed; + + private static bool _allMapsLoaded; + + public static void CountMaps() + { + if (!Scribe.EnterNode("maps")) + return; + + try + { + NumMaps = Scribe.loader.curXmlParent.ChildNodes.Count; + Log.Message($"[BetterLoading] This save file contains {NumMaps} map(s)."); + } + finally + { + //Make sure we absolutely exit the node because if we don't we risk corrupting the save file. + Scribe.ExitNode(); + } + } + + public LoadMaps([NotNull] Harmony instance) : base(instance) + { + } + + public override string GetStageName() + { + return "Loading Maps"; + } + + public override string? GetCurrentStepName() + { + if (_currMapNum == -1) + return "Waiting..."; + + var text = $"Map {_currMapNum + 1} of {NumMaps}: "; + + if (_currMapLoadedCompressed) + return text + "Loading Things"; + + if (_currMapLoadedComponents) + return text + "Loading Compressed Map Data"; + + if (_currMapInitialized) + return text + "Loading Components"; + + return text + "Reading Data"; + } + + public override int GetCurrentProgress() + { + if (_currMapNum == -1) + return 0; + + var baseValue = _currMapNum * 4; + + if (_currMapLoadedCompressed) + return baseValue + 3; + + if (_currMapLoadedComponents) + return baseValue + 2; + + if (_currMapInitialized) + return baseValue + 1; + + return baseValue; + } + + public override int GetMaximumProgress() + { + return NumMaps * 4; + } + + public override bool IsCompleted() + { + return _allMapsLoaded; + } + + public override void BecomeInactive() + { + _allMapsLoaded = false; + } + + 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))); + } + + public static void OnMapLoadStart(Map __instance) + { + _currMap = __instance; + _currMapNum++; + + _currMapInitialized = false; + _currMapLoadedComponents = false; + _currMapLoadedCompressed = false; + } + + public static void OnMapComponentsLoadStart() + { + _currMapInitialized = true; + } + + public static void OnMapCompressedDataLoadStart() + { + _currMapLoadedComponents = true; + } + + public static void OnMapCompressedDataLoadEnd() + { + _currMapLoadedCompressed = true; + } + + public static void OnAllMapsLoaded() + { + _allMapsLoaded = true; + } + } +} \ No newline at end of file diff --git a/Source/Stage/SaveLoad/3FinalizeScribeLoad.cs b/Source/Stage/SaveLoad/3FinalizeScribeLoad.cs new file mode 100644 index 0000000..767353d --- /dev/null +++ b/Source/Stage/SaveLoad/3FinalizeScribeLoad.cs @@ -0,0 +1,55 @@ +using HarmonyLib; +using JetBrains.Annotations; +using Verse; + +namespace BetterLoading.Stage.SaveLoad +{ + public class FinalizeScribeLoad : LoadingStage + { + private static bool _complete; + + public FinalizeScribeLoad([NotNull] Harmony instance) : base(instance) + { + } + + public override string GetStageName() + { + return "Finishing file load and cleaning up..."; + } + + public override string? GetCurrentStepName() + { + return null; + } + + public override int GetCurrentProgress() + { + return 0; + } + + public override int GetMaximumProgress() + { + return 1; + } + + public override bool IsCompleted() + { + return _complete; + } + + public override void BecomeInactive() + { + _complete = false; + } + + public override void DoPatching(Harmony instance) + { + instance.Patch(AccessTools.Method(typeof(ScribeLoader), nameof(ScribeLoader.FinalizeLoading)), postfix: new HarmonyMethod(typeof(FinalizeScribeLoad), nameof(OnResolvingComplete))); + } + + public static void OnResolvingComplete() + { + _complete = true; + } + } +} \ No newline at end of file diff --git a/Source/Stage/SaveLoad/3LoadMaps.cs b/Source/Stage/SaveLoad/3LoadMaps.cs deleted file mode 100644 index 2fa8fdf..0000000 --- a/Source/Stage/SaveLoad/3LoadMaps.cs +++ /dev/null @@ -1,35 +0,0 @@ -using HarmonyLib; -using JetBrains.Annotations; - -namespace BetterLoading.Stage.SaveLoad -{ - public class LoadMaps : LoadingStage { - public LoadMaps([NotNull] Harmony instance) : base(instance) - { - } - - public override string GetStageName() - { - throw new System.NotImplementedException(); - } - - public override string? GetCurrentStepName() - { - throw new System.NotImplementedException(); - } - - public override int GetCurrentProgress() - { - throw new System.NotImplementedException(); - } - - public override int GetMaximumProgress() - { - throw new System.NotImplementedException(); - } - - public override void DoPatching(Harmony instance) - { - } - } -} \ No newline at end of file diff --git a/Source/Stage/SaveLoad/4SetUpCamera.cs b/Source/Stage/SaveLoad/4SetUpCamera.cs deleted file mode 100644 index 8509cc2..0000000 --- a/Source/Stage/SaveLoad/4SetUpCamera.cs +++ /dev/null @@ -1,35 +0,0 @@ -using HarmonyLib; -using JetBrains.Annotations; - -namespace BetterLoading.Stage.SaveLoad -{ - public class SetUpCamera : LoadingStage { - public SetUpCamera([NotNull] Harmony instance) : base(instance) - { - } - - public override string GetStageName() - { - throw new System.NotImplementedException(); - } - - public override string? GetCurrentStepName() - { - throw new System.NotImplementedException(); - } - - public override int GetCurrentProgress() - { - throw new System.NotImplementedException(); - } - - public override int GetMaximumProgress() - { - throw new System.NotImplementedException(); - } - - public override void DoPatching(Harmony instance) - { - } - } -} \ No newline at end of file diff --git a/Source/Stage/SaveLoad/4SpawnAllThings.cs b/Source/Stage/SaveLoad/4SpawnAllThings.cs new file mode 100644 index 0000000..70d7166 --- /dev/null +++ b/Source/Stage/SaveLoad/4SpawnAllThings.cs @@ -0,0 +1,87 @@ +using HarmonyLib; +using JetBrains.Annotations; +using Verse; + +namespace BetterLoading.Stage.SaveLoad +{ + public class SpawnAllThings : LoadingStage + { + private static int _currMapIdx = -1; + private static int _numThingsThisMapSoFar; + + private static bool _finished; + + public SpawnAllThings([NotNull] Harmony instance) : base(instance) + { + } + + public override string GetStageName() + { + return "Spawning all things"; + } + + public override string? GetCurrentStepName() + { + if (_currMapIdx == -1) + return "Waiting..."; + + return $"Map {_currMapIdx + 1} of {LoadMaps.NumMaps}: {_numThingsThisMapSoFar} spawned so far"; + } + + public override int GetCurrentProgress() + { + if (_currMapIdx == -1) + return 0; + + return _currMapIdx; + } + + public override int GetMaximumProgress() + { + return LoadMaps.NumMaps; + } + + public override bool IsCompleted() + { + return _finished; + } + + public override void BecomeInactive() + { + _finished = false; + _currMapIdx = 0; + _numThingsThisMapSoFar = 0; + } + + 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))); + + //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)) + ); + + //Buildings + instance.Patch(AccessTools.Method(typeof(GenSpawn), nameof(GenSpawn.SpawnBuildingAsPossible)), new HarmonyMethod(typeof(SpawnAllThings), nameof(OnThingAboutToSpawn))); + } + + public static void OnMapStartFinalizing() + { + _currMapIdx++; + _numThingsThisMapSoFar = 0; + } + + public static void OnMapFinishFinalizing() + { + if (_currMapIdx == LoadMaps.NumMaps - 1) + _finished = true; + } + + public static void OnThingAboutToSpawn() + { + _numThingsThisMapSoFar++; + } + } +} \ No newline at end of file diff --git a/Source/Stage/SaveLoad/7FinalizeGameState.cs b/Source/Stage/SaveLoad/5FinalizeGameState.cs similarity index 73% rename from Source/Stage/SaveLoad/7FinalizeGameState.cs rename to Source/Stage/SaveLoad/5FinalizeGameState.cs index 2cafec7..27fab5a 100644 --- a/Source/Stage/SaveLoad/7FinalizeGameState.cs +++ b/Source/Stage/SaveLoad/5FinalizeGameState.cs @@ -10,22 +10,22 @@ public FinalizeGameState([NotNull] Harmony instance) : base(instance) public override string GetStageName() { - throw new System.NotImplementedException(); + return "Setting up final game controllers"; } public override string? GetCurrentStepName() { - throw new System.NotImplementedException(); + return null; } public override int GetCurrentProgress() { - throw new System.NotImplementedException(); + return 0; } public override int GetMaximumProgress() { - throw new System.NotImplementedException(); + return 1; } public override void DoPatching(Harmony instance) diff --git a/Source/Stage/SaveLoad/5ResolveDefCrossRefs.cs b/Source/Stage/SaveLoad/5ResolveDefCrossRefs.cs deleted file mode 100644 index b2f4887..0000000 --- a/Source/Stage/SaveLoad/5ResolveDefCrossRefs.cs +++ /dev/null @@ -1,35 +0,0 @@ -using HarmonyLib; -using JetBrains.Annotations; - -namespace BetterLoading.Stage.SaveLoad -{ - public class ResolveDefCrossRefs : LoadingStage { - public ResolveDefCrossRefs([NotNull] Harmony instance) : base(instance) - { - } - - public override string GetStageName() - { - throw new System.NotImplementedException(); - } - - public override string? GetCurrentStepName() - { - throw new System.NotImplementedException(); - } - - public override int GetCurrentProgress() - { - throw new System.NotImplementedException(); - } - - public override int GetMaximumProgress() - { - throw new System.NotImplementedException(); - } - - public override void DoPatching(Harmony instance) - { - } - } -} \ No newline at end of file diff --git a/Source/Stage/SaveLoad/6SpawnAllThings.cs b/Source/Stage/SaveLoad/6SpawnAllThings.cs deleted file mode 100644 index 7791468..0000000 --- a/Source/Stage/SaveLoad/6SpawnAllThings.cs +++ /dev/null @@ -1,35 +0,0 @@ -using HarmonyLib; -using JetBrains.Annotations; - -namespace BetterLoading.Stage.SaveLoad -{ - public class SpawnAllThings : LoadingStage { - public SpawnAllThings([NotNull] Harmony instance) : base(instance) - { - } - - public override string GetStageName() - { - throw new System.NotImplementedException(); - } - - public override string? GetCurrentStepName() - { - throw new System.NotImplementedException(); - } - - public override int GetCurrentProgress() - { - throw new System.NotImplementedException(); - } - - public override int GetMaximumProgress() - { - throw new System.NotImplementedException(); - } - - public override void DoPatching(Harmony instance) - { - } - } -} \ No newline at end of file