diff --git a/Source/Client/Comp/Map/FactionMapData.cs b/Source/Client/Comp/Map/FactionMapData.cs index 71d6c210f..f3bfa916a 100644 --- a/Source/Client/Comp/Map/FactionMapData.cs +++ b/Source/Client/Comp/Map/FactionMapData.cs @@ -1,4 +1,5 @@ using Multiplayer.Client.Factions; +using Multiplayer.Client.Persistent; using RimWorld; using Verse; @@ -23,6 +24,7 @@ public class FactionMapData : IExposable public ListerFilthInHomeArea listerFilthInHomeArea; public ListerMergeables listerMergeables; + public GravshipCache gravshipCache; private FactionMapData() { } // Loading ctor @@ -35,6 +37,8 @@ public FactionMapData(Map map) resourceCounter = new ResourceCounter(map); listerFilthInHomeArea = new ListerFilthInHomeArea(map); listerMergeables = new ListerMergeables(map); + + gravshipCache = new GravshipCache(map); } private FactionMapData(int factionId, Map map) : this(map) @@ -65,6 +69,8 @@ public void ExposeData() planManager ??= new PlanManager(map); } + gravshipCache = new GravshipCache(map); + ExposeActor.OnPostInit(() => map.PopFaction()); } @@ -89,6 +95,8 @@ public static FactionMapData NewFromMap(Map map, int factionId) resourceCounter = map.resourceCounter, listerFilthInHomeArea = map.listerFilthInHomeArea, listerMergeables = map.listerMergeables, + + gravshipCache = new GravshipCache(map) }; } } diff --git a/Source/Client/Comp/Map/MultiplayerMapComp.cs b/Source/Client/Comp/Map/MultiplayerMapComp.cs index 541a9233e..2373f061d 100644 --- a/Source/Client/Comp/Map/MultiplayerMapComp.cs +++ b/Source/Client/Comp/Map/MultiplayerMapComp.cs @@ -136,6 +136,8 @@ public void SetFaction(Faction faction) map.resourceCounter = data.resourceCounter; map.listerFilthInHomeArea = data.listerFilthInHomeArea; map.listerMergeables = data.listerMergeables; + + data?.gravshipCache.Apply(); } public CustomFactionMapData GetCurrentCustomFactionData() diff --git a/Source/Client/Comp/World/FactionWorldData.cs b/Source/Client/Comp/World/FactionWorldData.cs index 20b43fe7b..fd3ed16fe 100644 --- a/Source/Client/Comp/World/FactionWorldData.cs +++ b/Source/Client/Comp/World/FactionWorldData.cs @@ -1,3 +1,4 @@ +using Multiplayer.Client.Persistent; using RimWorld; using Verse; @@ -17,6 +18,7 @@ public class FactionWorldData : IExposable public Storyteller storyteller; public StoryWatcher storyWatcher; + public GravshipCache gravshipCache; public FactionWorldData() { } public void ExposeData() @@ -74,7 +76,9 @@ public static FactionWorldData New(int factionId) history = new History(), storyteller = new Storyteller(Find.Storyteller.def, Find.Storyteller.difficultyDef, Find.Storyteller.difficulty), - storyWatcher = new StoryWatcher() + storyWatcher = new StoryWatcher(), + + gravshipCache = new GravshipCache(), }; } @@ -92,7 +96,9 @@ public static FactionWorldData FromCurrent(int factionId) history = Find.History, storyteller = Find.Storyteller, - storyWatcher = Find.StoryWatcher + storyWatcher = Find.StoryWatcher, + + gravshipCache = new GravshipCache() }; } } diff --git a/Source/Client/Comp/World/MultiplayerWorldComp.cs b/Source/Client/Comp/World/MultiplayerWorldComp.cs index a505856af..9ffd22049 100644 --- a/Source/Client/Comp/World/MultiplayerWorldComp.cs +++ b/Source/Client/Comp/World/MultiplayerWorldComp.cs @@ -126,6 +126,7 @@ private void ExposeFactionData() // Game manager order? factionData[currentFactionId] = FactionWorldData.FromCurrent(currentFactionId); } + } public void WriteSessionData(ByteWriter writer) @@ -164,6 +165,8 @@ public void SetFaction(Faction faction) game.history = data.history; game.storyteller = data.storyteller; game.storyWatcher = data.storyWatcher; + + //data?.gravshipCache.Apply(); } public void DirtyColonyTradeForMap(Map map) diff --git a/Source/Client/Patches/GravshipCache.cs b/Source/Client/Patches/GravshipCache.cs new file mode 100644 index 000000000..2eb54f025 --- /dev/null +++ b/Source/Client/Patches/GravshipCache.cs @@ -0,0 +1,60 @@ +using HarmonyLib; +using Multiplayer.Client.Util; +using RimWorld; +using System.Collections.Generic; +using Verse; + +namespace Multiplayer.Client.Persistent +{ + [HarmonyPatch(typeof(GravshipUtility), nameof(GravshipUtility.GetPlayerGravEngine_NewTemp))] + public static class PatchGravshipUtilityGetPlayerGravEngine_NewTemp + { + static bool Prefix(Map map, Building_GravEngine __result, Building_GravEngine __state) + { + if (!ModsConfig.OdysseyActive || Faction.OfPlayer.loadID < 0) + { + return false; + } + GravshipCache cache = map.MpComp().factionData.GetValueOrDefault(Faction.OfPlayer.loadID).gravshipCache; + if (cache != null) + { + Building_GravEngine cachedGravEngine = __state = cache.cachedGravEngine; + + // uptime cache + if (Find.TickManager.TicksGame == cache.lastCachedEngineTick) + { + __result = cachedGravEngine; + return false; + } + // no cache, default to search for one + if (cachedGravEngine == null) + { + //MpLog.Debug($"Allowed searching for gravengine of {Faction.OfPlayer} at {map.GetUniqueLoadID()} tick.{Find.TickManager.TicksGame}"); + return true; + } + // cached but old, validate cache available + if (cachedGravEngine.Map == map && !cachedGravEngine.Destroyed) + { + return false; + } + } + return true; + } + static void Finalizer(Building_GravEngine __result, Building_GravEngine __state, Map map) + { + if (Faction.OfPlayer.loadID > 0) + { + GravshipCache cache = map.MpComp().factionData.GetValueOrDefault(Faction.OfPlayer.loadID).gravshipCache; + if(cache != null) + { + // if engine updated + if (__result != __state) + cache.cachedGravEngine = __result; + + cache.lastCachedEngineTick = Find.TickManager.TicksGame; + } + } + + } + } +} diff --git a/Source/Client/Persistent/GravshipCache.cs b/Source/Client/Persistent/GravshipCache.cs new file mode 100644 index 000000000..0a11320c8 --- /dev/null +++ b/Source/Client/Persistent/GravshipCache.cs @@ -0,0 +1,32 @@ +using RimWorld; +using Verse; + +namespace Multiplayer.Client.Persistent +{ + public class GravshipCache + { + public Map parent; + public Building_GravEngine cachedGravEngine; + public int lastCachedEngineTick; + public GravshipCache(Map map = null) + { + parent = map; + } + public void Apply() + { + if (cachedGravEngine != null) + { + GravshipUtility.lastCachedEngineTick = lastCachedEngineTick; + GravshipUtility.cachedGravEngine = cachedGravEngine; + GravshipUtility.lastCachedEngineMapID = parent.uniqueID; + } + else + { + //comment out so default fall to world status + GravshipUtility.lastCachedEngineTick = -1; + GravshipUtility.cachedGravEngine = null; + GravshipUtility.lastCachedEngineMapID = -1; + } + } + } +}