diff --git a/.github/workflows/build-workshop.yml b/.github/workflows/build-workshop.yml
index 5565ff02..90626c7d 100644
--- a/.github/workflows/build-workshop.yml
+++ b/.github/workflows/build-workshop.yml
@@ -1,6 +1,7 @@
name: Build workshop
on:
+ workflow_dispatch:
push:
tags:
- 'v*'
diff --git a/About/About.xml b/About/About.xml
index 0704b06d..f8070db9 100644
--- a/About/About.xml
+++ b/About/About.xml
@@ -3,12 +3,12 @@
rwmt.Multiplayer
Multiplayer
- 1.4
+ 1.5
RimWorld Multiplayer Team
https://github.com/rwmt/Multiplayer
<color=red><b>Important: </b> This mod should be placed right below Core and expansions in the mod list to work properly!
-Requires Rimworld >= v1.4.3901</color>\n
+Requires Rimworld >= v1.5.4034</color>\n
Multiplayer mod for RimWorld.
FAQ - https://hackmd.io/@rimworldmultiplayer/docs/
diff --git a/Source/Client/AsyncTime/AsyncTimePatches.cs b/Source/Client/AsyncTime/AsyncTimePatches.cs
index b8c3b635..85b50ef4 100644
--- a/Source/Client/AsyncTime/AsyncTimePatches.cs
+++ b/Source/Client/AsyncTime/AsyncTimePatches.cs
@@ -169,7 +169,7 @@ static void Postfix()
}
}
- [HarmonyPatch(typeof(LetterStack), nameof(LetterStack.ReceiveLetter), typeof(Letter), typeof(string))]
+ [HarmonyPatch(typeof(LetterStack), nameof(LetterStack.ReceiveLetter), typeof(Letter), typeof(string), typeof(int), typeof(bool))]
static class ReceiveLetterPause
{
static IEnumerable Transpiler(IEnumerable insts)
diff --git a/Source/Client/AsyncTime/TimeControlUI.cs b/Source/Client/AsyncTime/TimeControlUI.cs
index 380a334e..c4edd005 100644
--- a/Source/Client/AsyncTime/TimeControlUI.cs
+++ b/Source/Client/AsyncTime/TimeControlUI.cs
@@ -1,4 +1,4 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using HarmonyLib;
@@ -283,6 +283,10 @@ public static class ColonistBarTimeControl
public static float btnWidth = TimeControls.TimeButSize.x;
public static float btnHeight = TimeControls.TimeButSize.y;
+ private static Dictionary flashDict = new Dictionary();
+ private static float flashInterval = 6f;
+ private static Color flashColor = Color.red;
+
static void Prefix(ref bool __state)
{
if (Event.current.type is EventType.MouseDown or EventType.MouseUp)
@@ -316,6 +320,7 @@ static void DrawButtons()
Rect groupBar = bar.drawer.GroupFrameRect(entry.group);
float drawXPos = groupBar.x;
Color bgColor = (entryTickable.ActualRateMultiplier(TimeSpeed.Normal) == 0f) ? pauseBgColor : normalBgColor;
+ Vector2 flashPos = new Vector2(drawXPos + btnWidth / 2, groupBar.yMax + btnHeight / 2);
if (Multiplayer.GameComp.asyncTime)
{
@@ -337,6 +342,24 @@ static void DrawButtons()
Rect button = new Rect(drawXPos, groupBar.yMax, btnWidth, btnHeight);
MpTimeControls.TimeIndicateBlockingPause(button, bgColor);
drawXPos += TimeControls.TimeButSize.x;
+
+ float pauseTime = flashDict.GetValueOrDefault(flashPos);
+ if (flashDict.ContainsKey(flashPos))
+ {
+ // Draw flash for ongoing blocking pause
+ DrawPauseFlash(flashPos);
+ }
+ else
+ {
+ // There is a new blocking pause
+ flashDict.Add(flashPos, Time.time);
+ }
+ }
+
+ if (entryTickable.ActualRateMultiplier(TimeSpeed.Normal) != 0f && flashDict.ContainsKey(flashPos))
+ {
+ // No longer any blocking pauses, stop flashing here
+ flashDict.Remove(flashPos);
}
List options = GetBlockingWindowOptions(entry, entryTickable);
@@ -375,6 +398,18 @@ static void SwitchToMapOrWorld(Map map)
Current.Game.CurrentMap = map;
}
}
+
+ static void DrawPauseFlash(Vector2 pos)
+ {
+ float pauseTime = flashDict.GetValueOrDefault(pos);
+ float pauseDuration = Time.time - pauseTime;
+
+ // Only flash at flashInterval from the time the blocking pause began
+ if (pauseDuration > 0f && pauseDuration % flashInterval < 1f)
+ {
+ GenUI.DrawFlash(pos.x, pos.y, UI.screenWidth * 0.6f, Pulser.PulseBrightness(1f, 1f, pauseDuration) * 0.4f, flashColor);
+ }
+ }
}
[HarmonyPatch(typeof(MainButtonWorker), nameof(MainButtonWorker.DoButton))]
diff --git a/Source/Client/Comp/World/FactionWorldData.cs b/Source/Client/Comp/World/FactionWorldData.cs
index d04fdd0f..2fe75f02 100644
--- a/Source/Client/Comp/World/FactionWorldData.cs
+++ b/Source/Client/Comp/World/FactionWorldData.cs
@@ -45,12 +45,12 @@ public void ExposeData()
public void ReassignIds()
{
foreach (DrugPolicy p in drugPolicyDatabase.policies)
- p.uniqueId = Find.UniqueIDsManager.GetNextThingID();
+ p.id = Find.UniqueIDsManager.GetNextThingID();
- foreach (Outfit o in outfitDatabase.outfits)
- o.uniqueId = Find.UniqueIDsManager.GetNextThingID();
+ foreach (ApparelPolicy o in outfitDatabase.outfits)
+ o.id = Find.UniqueIDsManager.GetNextThingID();
- foreach (FoodRestriction o in foodRestrictionDatabase.foodRestrictions)
+ foreach (FoodPolicy o in foodRestrictionDatabase.foodRestrictions)
o.id = Find.UniqueIDsManager.GetNextThingID();
}
diff --git a/Source/Client/Debug/DebugActions.cs b/Source/Client/Debug/DebugActions.cs
index 8459db96..4da0937e 100644
--- a/Source/Client/Debug/DebugActions.cs
+++ b/Source/Client/Debug/DebugActions.cs
@@ -7,6 +7,7 @@
using System.Text;
using HarmonyLib;
+using LudeonTK;
using RimWorld;
using RimWorld.Planet;
using UnityEngine;
@@ -134,17 +135,20 @@ public static void SaveGame()
public static void DumpSyncTypes()
{
var dict = new Dictionary() {
- {"ThingComp", RwImplSerialization.thingCompTypes},
- {"AbilityComp", RwImplSerialization.abilityCompTypes},
{"Designator", RwImplSerialization.designatorTypes},
- {"WorldObjectComp", RwImplSerialization.worldObjectCompTypes},
- {"HediffComp", RwImplSerialization.hediffCompTypes},
- {"IStoreSettingsParent", RwImplSerialization.storageParents},
+ {"IStoreSettingsParent", RwImplSerialization.storageSettingsParent},
{"IPlantToGrowSettable", RwImplSerialization.plantToGrowSettables},
+ {"ISlotGroup", RwImplSerialization.slotGroupTypes},
+ {"ISlotGroupParent", RwImplSerialization.slotGroupParents},
- {"GameComponent", RwImplSerialization.gameCompTypes},
- {"WorldComponent", RwImplSerialization.worldCompTypes},
- {"MapComponent", RwImplSerialization.mapCompTypes},
+ {"ThingComp", CompSerialization.thingCompTypes},
+ {"AbilityComp", CompSerialization.abilityCompTypes},
+ {"WorldObjectComp", CompSerialization.worldObjectCompTypes},
+ {"HediffComp", CompSerialization.hediffCompTypes},
+
+ {"GameComponent", CompSerialization.gameCompTypes},
+ {"WorldComponent", CompSerialization.worldCompTypes},
+ {"MapComponent", CompSerialization.mapCompTypes},
};
foreach(var kv in dict) {
diff --git a/Source/Client/Debug/DebugPatches.cs b/Source/Client/Debug/DebugPatches.cs
index 45a9c51f..04bcb062 100644
--- a/Source/Client/Debug/DebugPatches.cs
+++ b/Source/Client/Debug/DebugPatches.cs
@@ -35,7 +35,7 @@ static void Prefixfactionman()
!trace.Contains("Client.FactionContext") &&
!trace.Contains("Thing.ExposeData")
)
- Log.Message($"factionman call {trace}", true);
+ Log.Message($"factionman call {trace}");
}
}
}
diff --git a/Source/Client/Debug/DebugSync.cs b/Source/Client/Debug/DebugSync.cs
index a28b7502..0515d756 100644
--- a/Source/Client/Debug/DebugSync.cs
+++ b/Source/Client/Debug/DebugSync.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using HarmonyLib;
+using LudeonTK;
using Multiplayer.Common;
using RimWorld;
diff --git a/Source/Client/EarlyInit.cs b/Source/Client/EarlyInit.cs
index 4dddeb97..0c23bcd1 100644
--- a/Source/Client/EarlyInit.cs
+++ b/Source/Client/EarlyInit.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Reflection;
using HarmonyLib;
using Multiplayer.Client.Patches;
@@ -55,10 +56,12 @@ internal static void EarlyPatches(Harmony harmony)
internal static void InitSync()
{
- using (DeepProfilerWrapper.Section("Multiplayer SyncSerialization.Init"))
- SyncSerialization.Init();
+ MpReflection.allAssembliesHook = RwAllAssemblies;
- using (DeepProfilerWrapper.Section("Multiplayer SyncGame"))
+ using (DeepProfilerWrapper.Section("Multiplayer RwSerialization.Init"))
+ RwSerialization.Init();
+
+ using (DeepProfilerWrapper.Section("Multiplayer SyncGame.Init"))
SyncGame.Init();
using (DeepProfilerWrapper.Section("Multiplayer Sync register attributes"))
@@ -68,6 +71,18 @@ internal static void InitSync()
Sync.ValidateAll();
}
+ private static IEnumerable RwAllAssemblies()
+ {
+ yield return Assembly.GetAssembly(typeof(Game));
+
+ foreach (ModContentPack mod in LoadedModManager.RunningMods)
+ foreach (Assembly assembly in mod.assemblies.loadedAssemblies)
+ yield return assembly;
+
+ if (Assembly.GetEntryAssembly() != null)
+ yield return Assembly.GetEntryAssembly();
+ }
+
internal static void LatePatches()
{
if (MpVersion.IsDebug)
diff --git a/Source/Client/EarlyPatches/SettingsPatches.cs b/Source/Client/EarlyPatches/SettingsPatches.cs
index 12d9a6e4..f9aa984b 100644
--- a/Source/Client/EarlyPatches/SettingsPatches.cs
+++ b/Source/Client/EarlyPatches/SettingsPatches.cs
@@ -14,7 +14,6 @@ static class PrefGettersInMultiplayer
{
static IEnumerable TargetMethods()
{
- yield return AccessTools.PropertyGetter(typeof(Prefs), nameof(Prefs.PauseOnError));
yield return AccessTools.PropertyGetter(typeof(Prefs), nameof(Prefs.AutomaticPauseMode));
yield return AccessTools.PropertyGetter(typeof(Prefs), nameof(Prefs.PauseOnLoad));
yield return AccessTools.PropertyGetter(typeof(Prefs), nameof(Prefs.AdaptiveTrainingEnabled));
@@ -29,7 +28,6 @@ static class PrefSettersInMultiplayer
{
static IEnumerable TargetMethods()
{
- yield return AccessTools.PropertySetter(typeof(Prefs), nameof(Prefs.PauseOnError));
yield return AccessTools.PropertySetter(typeof(Prefs), nameof(Prefs.AutomaticPauseMode));
yield return AccessTools.PropertySetter(typeof(Prefs), nameof(Prefs.PauseOnLoad));
yield return AccessTools.PropertySetter(typeof(Prefs), nameof(Prefs.AdaptiveTrainingEnabled));
diff --git a/Source/Client/Factions/Blueprints.cs b/Source/Client/Factions/Blueprints.cs
index f65962f9..55da6117 100644
--- a/Source/Client/Factions/Blueprints.cs
+++ b/Source/Client/Factions/Blueprints.cs
@@ -15,7 +15,7 @@ namespace Multiplayer.Client
// Don't draw other factions' blueprints
// Don't link graphics of different factions' blueprints
- [HarmonyPatch(typeof(GenConstruct), nameof(GenConstruct.CanPlaceBlueprintAt))]
+ [HarmonyPatch(typeof(GenConstruct), nameof(GenConstruct.CanPlaceBlueprintAt_NewTemp))]
static class CanPlaceBlueprintAtPatch
{
static MethodInfo CanPlaceBlueprintOver = AccessTools.Method(typeof(GenConstruct), nameof(GenConstruct.CanPlaceBlueprintOver));
@@ -49,7 +49,7 @@ static IEnumerable Transpiler(IEnumerable e, M
}
- [HarmonyPatch(typeof(GenConstruct), nameof(GenConstruct.CanPlaceBlueprintAt))]
+ [HarmonyPatch(typeof(GenConstruct), nameof(GenConstruct.CanPlaceBlueprintAt_NewTemp))]
static class CanPlaceBlueprintAtPatch2
{
static IEnumerable Transpiler(IEnumerable e, MethodBase original)
diff --git a/Source/Client/Factions/FactionContextSetters.cs b/Source/Client/Factions/FactionContextSetters.cs
index 6d6cbe3c..55036296 100644
--- a/Source/Client/Factions/FactionContextSetters.cs
+++ b/Source/Client/Factions/FactionContextSetters.cs
@@ -103,10 +103,9 @@ static void Prefix(Bill_Production __instance, ref Map __state)
{
if (Multiplayer.Client == null) return;
- var zoneManager = __instance.storeZone?.zoneManager ?? __instance.includeFromZone?.zoneManager;
- if (__instance.Map != null && zoneManager != null)
+ if (__instance.Map != null && __instance.billStack?.billGiver is Thing { Faction: { } faction })
{
- __instance.Map.PushFaction(zoneManager.map.MpComp().GetFactionId(zoneManager));
+ __instance.Map.PushFaction(faction);
__state = __instance.Map;
}
}
diff --git a/Source/Client/Factions/FactionCreationPatches.cs b/Source/Client/Factions/FactionCreationPatches.cs
index 2665a7ca..c3488029 100644
--- a/Source/Client/Factions/FactionCreationPatches.cs
+++ b/Source/Client/Factions/FactionCreationPatches.cs
@@ -19,11 +19,12 @@ static void Finalizer(ProgramState __state)
}
}
-[HarmonyPatch(typeof(Page_ConfigureStartingPawns), nameof(Page_ConfigureStartingPawns.RandomizeCurPawn))]
-static class ConfigureStartingPawns_RandomizeCurPawn_Patch
+[HarmonyPatch(typeof(StartingPawnUtility), nameof(StartingPawnUtility.RandomizePawn))]
+static class StartingPawnUtility_RandomizePawn_Patch
{
static void Prefix(ref ProgramState __state)
{
+ // todo is this compatible with 1.5's "Create new wanderers?"
__state = Current.ProgramState;
Current.programStateInt = ProgramState.Entry;
}
diff --git a/Source/Client/Factions/MultifactionPatches.cs b/Source/Client/Factions/MultifactionPatches.cs
index 75e62376..fa89ed29 100644
--- a/Source/Client/Factions/MultifactionPatches.cs
+++ b/Source/Client/Factions/MultifactionPatches.cs
@@ -322,7 +322,7 @@ static void Postfix(IAttackTarget target, ref bool __result)
}
}
-[HarmonyPatch(typeof(LetterStack), nameof(LetterStack.ReceiveLetter), typeof(Letter), typeof(string))]
+[HarmonyPatch(typeof(LetterStack), nameof(LetterStack.ReceiveLetter), typeof(Letter), typeof(string), typeof(int), typeof(bool))]
static class LetterStackReceiveOnlyMyFaction
{
// todo the letter might get culled from the archive if it isn't in the stack and Sync depends on the archive
@@ -333,7 +333,7 @@ static void Postfix(LetterStack __instance, Letter let)
}
}
-[HarmonyPatch(typeof(LetterStack), nameof(LetterStack.ReceiveLetter), typeof(Letter), typeof(string))]
+[HarmonyPatch(typeof(LetterStack), nameof(LetterStack.ReceiveLetter), typeof(Letter), typeof(string), typeof(int), typeof(bool))]
static class LetterStackReceiveSoundOnlyMyFaction
{
private static MethodInfo PlayOneShotOnCamera =
diff --git a/Source/Client/Multiplayer.csproj b/Source/Client/Multiplayer.csproj
index a964b3a9..56b59b42 100644
--- a/Source/Client/Multiplayer.csproj
+++ b/Source/Client/Multiplayer.csproj
@@ -3,7 +3,7 @@
net472
true
- 11
+ 12
false
bin
false
@@ -29,7 +29,7 @@
-
+
diff --git a/Source/Client/MultiplayerData.cs b/Source/Client/MultiplayerData.cs
index 4ac9cd54..7233fd50 100644
--- a/Source/Client/MultiplayerData.cs
+++ b/Source/Client/MultiplayerData.cs
@@ -120,20 +120,22 @@ internal static void CollectDefInfos()
int TypeHash(Type type) => GenText.StableStringHash(type.FullName);
- dict["ThingComp"] = GetDefInfo(RwImplSerialization.thingCompTypes, TypeHash);
- dict["AbilityComp"] = GetDefInfo(RwImplSerialization.abilityCompTypes, TypeHash);
- dict["Designator"] = GetDefInfo(RwImplSerialization.designatorTypes, TypeHash);
- dict["WorldObjectComp"] = GetDefInfo(RwImplSerialization.worldObjectCompTypes, TypeHash);
- dict["HediffComp"] = GetDefInfo(RwImplSerialization.hediffCompTypes, TypeHash);
- dict["IStoreSettingsParent"] = GetDefInfo(RwImplSerialization.storageParents, TypeHash);
+ dict["ThingComp"] = GetDefInfo(CompSerialization.thingCompTypes, TypeHash);
+ dict["AbilityComp"] = GetDefInfo(CompSerialization.abilityCompTypes, TypeHash);
+ dict["WorldObjectComp"] = GetDefInfo(CompSerialization.worldObjectCompTypes, TypeHash);
+ dict["HediffComp"] = GetDefInfo(CompSerialization.hediffCompTypes, TypeHash);
+ dict["IStoreSettingsParent"] = GetDefInfo(RwImplSerialization.storageSettingsParent, TypeHash);
dict["IPlantToGrowSettable"] = GetDefInfo(RwImplSerialization.plantToGrowSettables, TypeHash);
+ dict["ISlotGroup"] = GetDefInfo(RwImplSerialization.slotGroupTypes, TypeHash);
+ dict["ISlotGroupParent"] = GetDefInfo(RwImplSerialization.slotGroupParents, TypeHash);
+ dict["Designator"] = GetDefInfo(RwImplSerialization.designatorTypes, TypeHash);
dict["DefTypes"] = GetDefInfo(DefSerialization.DefTypes, TypeHash);
- dict["GameComponent"] = GetDefInfo(RwImplSerialization.gameCompTypes, TypeHash);
- dict["WorldComponent"] = GetDefInfo(RwImplSerialization.worldCompTypes, TypeHash);
- dict["MapComponent"] = GetDefInfo(RwImplSerialization.mapCompTypes, TypeHash);
- dict["ISyncSimple"] = GetDefInfo(ImplSerialization.syncSimples, TypeHash);
- dict["ISession"] = GetDefInfo(ImplSerialization.sessions, TypeHash);
+ dict["GameComponent"] = GetDefInfo(CompSerialization.gameCompTypes, TypeHash);
+ dict["WorldComponent"] = GetDefInfo(CompSerialization.worldCompTypes, TypeHash);
+ dict["MapComponent"] = GetDefInfo(CompSerialization.mapCompTypes, TypeHash);
+ dict["ISyncSimple"] = GetDefInfo(ApiSerialization.syncSimples, TypeHash);
+ dict["ISession"] = GetDefInfo(ApiSerialization.sessions, TypeHash);
dict["PawnBio"] = GetDefInfo(SolidBioDatabase.allBios, b => b.name.GetHashCode());
diff --git a/Source/Client/MultiplayerGame.cs b/Source/Client/MultiplayerGame.cs
index 3e2ea1b0..ad9a1780 100644
--- a/Source/Client/MultiplayerGame.cs
+++ b/Source/Client/MultiplayerGame.cs
@@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
+using LudeonTK;
using Multiplayer.API;
using Multiplayer.Client.AsyncTime;
using Multiplayer.Client.Comp;
diff --git a/Source/Client/MultiplayerStatic.cs b/Source/Client/MultiplayerStatic.cs
index 12c63686..40b2b69d 100644
--- a/Source/Client/MultiplayerStatic.cs
+++ b/Source/Client/MultiplayerStatic.cs
@@ -348,17 +348,18 @@ void TryPatch(MethodBase original, HarmonyMethod prefix = null, HarmonyMethod po
var randomBoltMesh = typeof(LightningBoltMeshPool).GetProperty(nameof(LightningBoltMeshPool.RandomBoltMesh))!.GetGetMethod();
var drawTrackerCtor = typeof(Pawn_DrawTracker).GetConstructor(new[] { typeof(Pawn) });
var randomHair = typeof(PawnStyleItemChooser).GetMethod(nameof(PawnStyleItemChooser.RandomHairFor));
- var cannotAssignReason = typeof(Dialog_BeginRitual).GetMethod(nameof(Dialog_BeginRitual.CannotAssignReason), BindingFlags.NonPublic | BindingFlags.Instance);
+ // todo for 1.5
+ // var cannotAssignReason = typeof(Dialog_BeginRitual).GetMethod(nameof(Dialog_BeginRitual.CannotAssignReason), BindingFlags.NonPublic | BindingFlags.Instance);
var canEverSpectate = typeof(RitualRoleAssignments).GetMethod(nameof(RitualRoleAssignments.CanEverSpectate));
var effectMethods = new MethodBase[] { subSustainerStart, sampleCtor, subSoundPlay, effecterTick, effecterTrigger, effecterCleanup, randomBoltMesh, drawTrackerCtor, randomHair };
var moteMethods = typeof(MoteMaker).GetMethods(BindingFlags.Static | BindingFlags.Public)
- .Where(m => m.Name != "MakeBombardmentMote"); // Special case, just calls MakeBombardmentMote_NewTmp, prevents Hugslib complains
+ .Where(m => m.Name != "MakeBombardmentMote"); // Special case, just calls MakeBombardmentMote_NewTmp, prevents Hugslib complaints
var fleckMethods = typeof(FleckMaker).GetMethods(BindingFlags.Static | BindingFlags.Public)
.Where(m => m.ReturnType == typeof(void))
.Concat(typeof(FleckManager).GetMethods() // FleckStatic uses Rand in Setup method, FleckThrown uses RandomInRange in TimeInterval. May as well catch all in case mods do the same.
.Where(m => m.ReturnType == typeof(void)));
- var ritualMethods = new[] { cannotAssignReason, canEverSpectate };
+ var ritualMethods = new[] { canEverSpectate };
foreach (MethodBase m in effectMethods.Concat(moteMethods).Concat(fleckMethods).Concat(ritualMethods))
TryPatch(m, randPatchPrefix, randPatchPostfix);
diff --git a/Source/Client/Patches/ArbiterPatches.cs b/Source/Client/Patches/ArbiterPatches.cs
index 0787fea2..328ae75e 100644
--- a/Source/Client/Patches/ArbiterPatches.cs
+++ b/Source/Client/Patches/ArbiterPatches.cs
@@ -62,7 +62,7 @@ static IEnumerable TargetMethods()
yield return AccessTools.Method(typeof(Prefs), nameof(Prefs.Save));
yield return AccessTools.Method(typeof(FloatMenuOption), nameof(FloatMenuOption.SetSizeMode));
yield return AccessTools.Method(typeof(Section), nameof(Section.RegenerateAllLayers));
- yield return AccessTools.Method(typeof(Section), nameof(Section.RegenerateLayers));
+ yield return AccessTools.Method(typeof(Section), nameof(Section.RegenerateDirtyLayers));
yield return AccessTools.Method(typeof(SectionLayer), nameof(SectionLayer.DrawLayer));
yield return AccessTools.Method(typeof(Map), nameof(Map.MapUpdate));
yield return AccessTools.Method(typeof(GUIStyle), nameof(GUIStyle.CalcSize));
diff --git a/Source/Client/Patches/Determinism.cs b/Source/Client/Patches/Determinism.cs
index b860fb85..849171dd 100644
--- a/Source/Client/Patches/Determinism.cs
+++ b/Source/Client/Patches/Determinism.cs
@@ -277,36 +277,6 @@ static bool Prefix()
}
}
- [HarmonyPatch(typeof(QuestNode_Root_PollutionRetaliation), nameof(QuestNode_Root_PollutionRetaliation.RunInt))]
- static class ReplaceUnityRngPollutionRetaliation
- {
- // Simplified transpiler from MP Compat.
- // Source: https://github.com/rwmt/Multiplayer-Compatibility/blob/2e82e71aef64c5a5a4fc879db6f49d3c20da25cb/Source/PatchingUtilities.cs#L226
- static IEnumerable Transpiler(IEnumerable insts, MethodBase original)
- {
- var anythingPatched = false;
-
- var parameters = new[] { typeof(int), typeof(int) };
- var unityRandomRangeInt = AccessTools.DeclaredMethod(typeof(Random), nameof(Random.Range), parameters);
- var verseRandomRangeInt = AccessTools.DeclaredMethod(typeof(Rand), nameof(Rand.Range), parameters);
-
- foreach (var inst in insts)
- {
- if ((inst.opcode == OpCodes.Call || inst.opcode == OpCodes.Callvirt) && inst.operand is MethodInfo method && method == unityRandomRangeInt)
- {
- inst.opcode = OpCodes.Call;
- inst.operand = verseRandomRangeInt;
-
- anythingPatched = true;
- }
-
- yield return inst;
- }
-
- if (!anythingPatched) Log.Warning($"No Unity RNG was patched for method: {original?.FullDescription() ?? "(unknown method)"}");
- }
- }
-
[HarmonyPatch(typeof(Pawn_RecordsTracker), nameof(Pawn_RecordsTracker.ExposeData))]
static class RecordsTrackerExposePatch
{
@@ -376,7 +346,7 @@ private static int NewQueryTick(int ticks, SituationalThoughtHandler thoughtHand
}
}
- [HarmonyPatch(typeof(SituationalThoughtHandler), nameof(SituationalThoughtHandler.CheckRecalculateMoodThoughts))]
+ [HarmonyPatch(typeof(SituationalThoughtHandler), nameof(SituationalThoughtHandler.UpdateAllMoodThoughts))]
static class DontRecalculateMoodThoughtsInInterface
{
static bool Prefix(SituationalThoughtHandler __instance)
@@ -384,7 +354,7 @@ static bool Prefix(SituationalThoughtHandler __instance)
if (Multiplayer.Client != null && !Multiplayer.Ticking && !Multiplayer.ExecutingCmds) return false;
// Notify_SituationalThoughtsDirty was called
- if (__instance.lastMoodThoughtsRecalculationTick == -99999)
+ if (__instance.thoughtsDirty)
__instance.cachedThoughts.Clear();
return true;
@@ -521,30 +491,4 @@ private static int NewCacheStatus(int gameTick)
}
}
- [HarmonyPatch(typeof(CompPollutionPump), nameof(CompPollutionPump.CompTick))]
- static class PollutionPumpRemoveCurrentMap
- {
- private static MethodInfo currentMapGetter = AccessTools.PropertyGetter(typeof(Find), nameof(Find.CurrentMap));
-
- static IEnumerable Transpiler(IEnumerable insts)
- {
- foreach (var inst in insts)
- {
- if (inst.operand == currentMapGetter)
- {
- yield return new CodeInstruction(OpCodes.Ldarg_0);
- yield return new CodeInstruction(OpCodes.Call, MethodOf.Lambda(CompMap));
- continue;
- }
-
- yield return inst;
- }
- }
-
- static Map CompMap(CompPollutionPump pump)
- {
- return pump.parent.Map;
- }
- }
-
}
diff --git a/Source/Client/Patches/Feedback.cs b/Source/Client/Patches/Feedback.cs
index b5dfdddc..ed0425fb 100644
--- a/Source/Client/Patches/Feedback.cs
+++ b/Source/Client/Patches/Feedback.cs
@@ -30,7 +30,7 @@ static IEnumerable TargetMethods()
static bool Prefix() => !Cancel;
}
- [HarmonyPatch(typeof(Targeter), nameof(Targeter.BeginTargeting), typeof(TargetingParameters), typeof(Action), typeof(Pawn), typeof(Action), typeof(Texture2D))]
+ [HarmonyPatch(typeof(Targeter), nameof(Targeter.BeginTargeting), typeof(TargetingParameters), typeof(Action), typeof(Pawn), typeof(Action), typeof(Texture2D), typeof(bool))]
static class CancelBeginTargeting
{
static bool Prefix()
@@ -57,7 +57,7 @@ static class CancelMotesNotTargetedAtMe
static IEnumerable TargetMethods()
{
yield return AccessTools.Method(typeof(MoteMaker), nameof(MoteMaker.MakeStaticMote), new[] { typeof(IntVec3), typeof(Map), typeof(ThingDef), typeof(float) });
- yield return AccessTools.Method(typeof(MoteMaker), nameof(MoteMaker.MakeStaticMote), new[] { typeof(Vector3), typeof(Map), typeof(ThingDef), typeof(float), typeof(bool) });
+ yield return AccessTools.Method(typeof(MoteMaker), nameof(MoteMaker.MakeStaticMote), new[] { typeof(Vector3), typeof(Map), typeof(ThingDef), typeof(float), typeof(bool), typeof(float) });
}
static bool Prefix(ThingDef moteDef)
diff --git a/Source/Client/Patches/LongEvents.cs b/Source/Client/Patches/LongEvents.cs
index 40e99255..b07b4e40 100644
--- a/Source/Client/Patches/LongEvents.cs
+++ b/Source/Client/Patches/LongEvents.cs
@@ -7,7 +7,7 @@
namespace Multiplayer.Client.Patches
{
- [HarmonyPatch(typeof(LongEventHandler), nameof(LongEventHandler.QueueLongEvent), typeof(Action), typeof(string), typeof(bool), typeof(Action), typeof(bool))]
+ [HarmonyPatch(typeof(LongEventHandler), nameof(LongEventHandler.QueueLongEvent), typeof(Action), typeof(string), typeof(bool), typeof(Action), typeof(bool), typeof(Action))]
static class MarkLongEvents
{
private static MethodInfo MarkerMethod = AccessTools.Method(typeof(MarkLongEvents), nameof(Marker));
@@ -62,7 +62,7 @@ static void Postfix()
}
}
- [HarmonyPatch(typeof(LongEventHandler), nameof(LongEventHandler.QueueLongEvent), new[] { typeof(Action), typeof(string), typeof(bool), typeof(Action), typeof(bool) })]
+ [HarmonyPatch(typeof(LongEventHandler), nameof(LongEventHandler.QueueLongEvent), new[] { typeof(Action), typeof(string), typeof(bool), typeof(Action), typeof(bool), typeof(Action) })]
static class LongEventAlwaysSync
{
static void Prefix(ref bool doAsynchronously)
diff --git a/Source/Client/Patches/Patches.cs b/Source/Client/Patches/Patches.cs
index 7d8e76ab..5fbe2999 100644
--- a/Source/Client/Patches/Patches.cs
+++ b/Source/Client/Patches/Patches.cs
@@ -245,7 +245,7 @@ static class RootPlayStartMarker
static void Finalizer() => starting = false;
}
- [HarmonyPatch(typeof(LongEventHandler), nameof(LongEventHandler.QueueLongEvent), new[] { typeof(Action), typeof(string), typeof(bool), typeof(Action), typeof(bool) })]
+ [HarmonyPatch(typeof(LongEventHandler), nameof(LongEventHandler.QueueLongEvent), new[] { typeof(Action), typeof(string), typeof(bool), typeof(Action), typeof(bool), typeof(Action) })]
static class CancelRootPlayStartLongEvents
{
public static bool cancel;
@@ -263,7 +263,7 @@ static class DisableScreenFade1
static bool Prefix() => LongEventHandler.eventQueue.All(e => e.eventTextKey == "MpLoading");
}
- [HarmonyPatch(typeof(ScreenFader), nameof(ScreenFader.StartFade))]
+ [HarmonyPatch(typeof(ScreenFader), nameof(ScreenFader.StartFade), typeof(Color), typeof(float), typeof(float))]
static class DisableScreenFade2
{
static bool Prefix() => LongEventHandler.eventQueue.All(e => e.eventTextKey == "MpLoading");
@@ -381,11 +381,11 @@ static class WorkPrioritySameValue
static bool Prefix(Pawn_WorkSettings __instance, WorkTypeDef w, int priority) => __instance.GetPriority(w) != priority;
}
- [HarmonyPatch(typeof(Pawn_PlayerSettings), nameof(Pawn_PlayerSettings.AreaRestriction), MethodType.Setter)]
+ [HarmonyPatch(typeof(Pawn_PlayerSettings), nameof(Pawn_PlayerSettings.AreaRestrictionInPawnCurrentMap), MethodType.Setter)]
static class AreaRestrictionSameValue
{
[HarmonyPriority(MpPriority.MpFirst + 1)]
- static bool Prefix(Pawn_PlayerSettings __instance, Area value) => __instance.AreaRestriction != value;
+ static bool Prefix(Pawn_PlayerSettings __instance, Area value) => __instance.AreaRestrictionInPawnCurrentMap != value;
}
[HarmonyPatch]
@@ -426,7 +426,7 @@ internal static void Choose(QuestPart_Choice part, int index)
}
[HarmonyPatch(typeof(MoteMaker), nameof(MoteMaker.MakeStaticMote))]
- [HarmonyPatch(new[] {typeof(Vector3), typeof(Map), typeof(ThingDef), typeof(float), typeof(bool)})]
+ [HarmonyPatch(new[] {typeof(Vector3), typeof(Map), typeof(ThingDef), typeof(float), typeof(bool), typeof(float)})]
static class FixNullMotes
{
static Dictionary cache = new();
diff --git a/Source/Client/Patches/Seeds.cs b/Source/Client/Patches/Seeds.cs
index ede7b2f5..188b6d70 100644
--- a/Source/Client/Patches/Seeds.cs
+++ b/Source/Client/Patches/Seeds.cs
@@ -91,7 +91,7 @@ static void Postfix(Map map, bool __state)
}
}
- [HarmonyPatch(typeof(LongEventHandler), nameof(LongEventHandler.QueueLongEvent), new[] { typeof(Action), typeof(string), typeof(bool), typeof(Action), typeof(bool) })]
+ [HarmonyPatch(typeof(LongEventHandler), nameof(LongEventHandler.QueueLongEvent), typeof(Action), typeof(string), typeof(bool), typeof(Action), typeof(bool), typeof(Action))]
static class SeedLongEvents
{
static void Prefix(ref Action action)
@@ -106,7 +106,7 @@ static void Prefix(ref Action action)
}
// Seed the rotation random
- [HarmonyPatch(typeof(GenSpawn), nameof(GenSpawn.Spawn), new[] { typeof(Thing), typeof(IntVec3), typeof(Map), typeof(Rot4), typeof(WipeMode), typeof(bool) })]
+ [HarmonyPatch(typeof(GenSpawn), nameof(GenSpawn.Spawn), new[] { typeof(Thing), typeof(IntVec3), typeof(Map), typeof(Rot4), typeof(WipeMode), typeof(bool), typeof(bool) })]
static class GenSpawnRotatePatch
{
static MethodInfo Rot4GetRandom = AccessTools.Property(typeof(Rot4), nameof(Rot4.Random)).GetGetMethod();
@@ -154,7 +154,7 @@ static IEnumerable TargetMethods()
{
yield return AccessTools.Method(typeof(GrammarResolver), nameof(GrammarResolver.Resolve));
yield return AccessTools.Method(typeof(PawnBioAndNameGenerator), nameof(PawnBioAndNameGenerator.GeneratePawnName));
- yield return AccessTools.Method(typeof(NameGenerator), nameof(NameGenerator.GenerateName), new[] { typeof(RulePackDef), typeof(Predicate), typeof(bool), typeof(string), typeof(string) });
+ yield return AccessTools.Method(typeof(NameGenerator), nameof(NameGenerator.GenerateName), new[] { typeof(RulePackDef), typeof(Predicate), typeof(bool), typeof(string), typeof(string), typeof(List) });
}
[HarmonyPriority(MpPriority.MpFirst)]
@@ -178,12 +178,11 @@ static class SeedPawnGraphics
{
static IEnumerable TargetMethods()
{
- yield return AccessTools.Method(typeof(PawnGraphicSet), nameof(PawnGraphicSet.ResolveAllGraphics));
- yield return AccessTools.Method(typeof(PawnGraphicSet), nameof(PawnGraphicSet.ResolveApparelGraphics));
+ yield return AccessTools.Method(typeof(PawnRenderer), nameof(PawnRenderer.SetAllGraphicsDirty));
}
[HarmonyPriority(MpPriority.MpFirst)]
- static void Prefix(PawnGraphicSet __instance, ref bool __state)
+ static void Prefix(PawnRenderer __instance, ref bool __state)
{
Rand.PushState(__instance.pawn.thingIDNumber);
__state = true;
diff --git a/Source/Client/Patches/ThingMethodPatches.cs b/Source/Client/Patches/ThingMethodPatches.cs
index 8ce42dbc..a3457f68 100644
--- a/Source/Client/Patches/ThingMethodPatches.cs
+++ b/Source/Client/Patches/ThingMethodPatches.cs
@@ -92,7 +92,7 @@ static void Finalizer(Container