From 0eb9cad5ebd4bb05293813b9876dcba0cd28c8ad Mon Sep 17 00:00:00 2001 From: SokyranTheDragon <36712560+SokyranTheDragon@users.noreply.github.com> Date: Wed, 11 Dec 2024 05:50:41 +0100 Subject: [PATCH] Fix VEF issue with thing spawning on map generation (including Vanilla Vehicles Tier 3 wrecks) (#502) This should fix issues with things being spawned on map generation (ObjectSpawnsDef) by seeding the relevant method. The issue is that a method passed to `LongEventHandler.ExecuteWhenFinished` during a `MapGenerator:GenerateMap` call (perhaps others as well?) would have a different seed between players. Should this be something we fix in MP? It doesn't affect vanilla only game, as (I believe) every affected `ExecuteWhenFinished` call seeds the RNG. And almost every `ExecuteWhenFinished` call is affecting graphics/audio, so it doesn't affect Multiplayer. --- Source/Mods/VanillaExpandedFramework.cs | 27 +++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Source/Mods/VanillaExpandedFramework.cs b/Source/Mods/VanillaExpandedFramework.cs index 180508c..bd58a51 100644 --- a/Source/Mods/VanillaExpandedFramework.cs +++ b/Source/Mods/VanillaExpandedFramework.cs @@ -51,6 +51,7 @@ public VanillaExpandedFramework(ModContentPack mod) (PatchStaticCaches, "Static caches", false), (PatchGraphicCustomizationDialog, "Graphic Customization Dialog", true), (PatchDraftedAi, "Drafted AI", true), + (PatchMapObjectGeneration, "Thing spawning on map generation (ObjectSpawnsDef)", false), ]; foreach (var (patchMethod, componentName, latePatch) in patches) @@ -1701,5 +1702,31 @@ private static void SyncDraftedActionData(SyncWorker sync, ref object draftedAct } #endregion + + #region Thing spawning on map generation (ObjectSpawnsDef) + + private static void PatchMapObjectGeneration() + { + // When calling "LongEventHandler.ExecuteWhenFinished" inside a + // "MapGenerator:GenerateMap" call the seed will differ between + // players. Is this something we should look into in MP itself? + MpCompat.harmony.Patch(AccessTools.DeclaredMethod("VFECore.MapGenerator_GenerateMap_Patch:DoMapSpawns"), + prefix: new HarmonyMethod(PreDoSpawns), + finalizer: new HarmonyMethod(PostDoSpawns)); + } + + private static void PreDoSpawns(Map map) + { + if (MP.IsInMultiplayer) + Rand.PushState(Gen.HashCombineInt(Gen.HashCombineInt(map.uniqueID, map.Tile), Find.TickManager.TicksGame)); + } + + private static void PostDoSpawns() + { + if (MP.IsInMultiplayer) + Rand.PopState(); + } + + #endregion } } \ No newline at end of file