diff --git a/Source/Client/Comp/World/MultiplayerWorldComp.cs b/Source/Client/Comp/World/MultiplayerWorldComp.cs index f30f1d71..78cbcbfc 100644 --- a/Source/Client/Comp/World/MultiplayerWorldComp.cs +++ b/Source/Client/Comp/World/MultiplayerWorldComp.cs @@ -78,6 +78,18 @@ void RemoveOpponentFaction() AddSpectatorFaction(); RemoveOpponentFaction(); } + + // Fix old save files by ensuring all factions have access to Anomaly research if + // it was enabled. This needs to be done since Anomaly state is shared by all players. + var anomaly = Find.Anomaly; + // Don't use anomaly.Level, as it'll return 0 due to monolith not being + // spawned. If we want to include that check then we'd need to move this + // code into a postfix to Building_VoidMonolith:SpawnSetup. + if (anomaly.level > 0 && anomaly.monolith != null) + { + foreach (var (_, data) in factionData) + data.researchManager.Notify_MonolithLevelChanged(anomaly.level); + } } private void ExposeFactionData() diff --git a/Source/Client/Factions/FactionCreator.cs b/Source/Client/Factions/FactionCreator.cs index 12e5d62b..03f167a0 100644 --- a/Source/Client/Factions/FactionCreator.cs +++ b/Source/Client/Factions/FactionCreator.cs @@ -114,6 +114,10 @@ private static void InitNewGame() { PawnUtility.GiveAllStartingPlayerPawnsThought(ThoughtDefOf.NewColonyOptimism); ResearchUtility.ApplyPlayerStartingResearch(); + // Initialize anomaly. Since the Anomaly comp is currently shared by all players, + // we need to ensure that any new factions have access to anomaly research if + // anomaly content was started. + Find.ResearchManager.Notify_MonolithLevelChanged(Find.Anomaly.Level); } private static void PrepareGameInitData(int sessionId) diff --git a/Source/Client/Factions/FactionRepeater.cs b/Source/Client/Factions/FactionRepeater.cs index 907d5370..6a8af268 100644 --- a/Source/Client/Factions/FactionRepeater.cs +++ b/Source/Client/Factions/FactionRepeater.cs @@ -175,4 +175,18 @@ ref ignore ); } + [HarmonyPatch(typeof(ResearchManager), nameof(ResearchManager.Notify_MonolithLevelChanged))] + static class MonolithLevelChangedPatch + { + static bool ignore; + + static bool Prefix(int newLevel) => + FactionRepeater.Template( + Multiplayer.game?.worldComp.factionData, + d => d.researchManager.Notify_MonolithLevelChanged(newLevel), + null, + ref ignore + ); + } + } diff --git a/Source/Client/Networking/HostUtil.cs b/Source/Client/Networking/HostUtil.cs index 225e717a..5036ae77 100644 --- a/Source/Client/Networking/HostUtil.cs +++ b/Source/Client/Networking/HostUtil.cs @@ -150,6 +150,14 @@ private static void SetupGameFromSingleplayer() factionData.researchManager.progress = new(playerFactionData.researchManager.progress); factionData.researchManager.techprints = new(playerFactionData.researchManager.techprints); + factionData.researchManager.anomalyKnowledge = new(playerFactionData.researchManager.anomalyKnowledge); + factionData.researchManager.currentAnomalyKnowledgeProjects = new(playerFactionData.researchManager.currentAnomalyKnowledgeProjects ?? Enumerable.Empty()); + factionData.researchManager.tabInfoVisibility = new(); + if (playerFactionData.researchManager.tabInfoVisibility != null) + { + foreach (var (def, value) in playerFactionData.researchManager.tabInfoVisibility) + factionData.researchManager.tabInfoVisibility[def] = value; + } } foreach (FactionWorldData data in worldComp.factionData.Values)