diff --git a/Source/Client/Patches/Feedback.cs b/Source/Client/Patches/Feedback.cs index e2e18e1e3..bf6183b18 100644 --- a/Source/Client/Patches/Feedback.cs +++ b/Source/Client/Patches/Feedback.cs @@ -237,11 +237,15 @@ static class DraftedMove_GotoFeedbackPatch private static MethodInfo tryTakeOrderedJob = AccessTools.Method(typeof(Pawn_JobTracker), nameof(Pawn_JobTracker.TryTakeOrderedJob)); + private static MethodInfo endCurrentJob = + AccessTools.Method(typeof(Pawn_JobTracker), nameof(Pawn_JobTracker.EndCurrentJob)); + static IEnumerable Transpiler(IEnumerable instructions) { foreach (var inst in instructions) { if (inst.Calls(tryTakeOrderedJob)) inst.operand = ((Delegate)CustomTryTakeOrderedJob).Method; + else if (inst.Calls(endCurrentJob)) inst.operand = ((Delegate)CustomEndCurrentJob).Method; yield return inst; } } @@ -254,6 +258,17 @@ static bool CustomTryTakeOrderedJob(Pawn_JobTracker self, Job job, JobTag? tag = FleckMaker.Static(job.targetA.Cell, self.pawn.Map, FleckDefOf.FeedbackGoto); return false; } + + // PawnGotoAction can also stop a pawn without going through TryTakeOrderedJob: when the pawn is + // already standing on gotoLoc and its current job is Goto, it calls EndCurrentJob directly. That + // call isn't synced, so the pawn stops only for the player who issued the order while it keeps + // walking for everyone else, causing a desync. Sync it the same way as the TryTakeOrderedJob call. + [SyncMethod] + static void CustomEndCurrentJob(Pawn_JobTracker self, JobCondition condition, + bool startNewJob = true, bool canReturnToPool = true) + { + self.EndCurrentJob(condition, startNewJob, canReturnToPool); + } } }