diff --git a/1.4/Assemblies/PerformanceFish.dll b/1.4/Assemblies/PerformanceFish.dll index 82634fa..b6dcb27 100644 Binary files a/1.4/Assemblies/PerformanceFish.dll and b/1.4/Assemblies/PerformanceFish.dll differ diff --git a/1.4/Assemblies/PerformanceFish.pdb b/1.4/Assemblies/PerformanceFish.pdb index b4896ba..85b3b04 100644 Binary files a/1.4/Assemblies/PerformanceFish.pdb and b/1.4/Assemblies/PerformanceFish.pdb differ diff --git a/1.5/Assemblies/PerformanceFish.dll b/1.5/Assemblies/PerformanceFish.dll index 6a61750..b38a742 100644 Binary files a/1.5/Assemblies/PerformanceFish.dll and b/1.5/Assemblies/PerformanceFish.dll differ diff --git a/1.5/Assemblies/PerformanceFish.pdb b/1.5/Assemblies/PerformanceFish.pdb index 4b168e9..182a5d5 100644 Binary files a/1.5/Assemblies/PerformanceFish.pdb and b/1.5/Assemblies/PerformanceFish.pdb differ diff --git a/DubsAnalyzer.xml b/DubsAnalyzer.xml index 8a6fa9d..fe2f7b9 100644 --- a/DubsAnalyzer.xml +++ b/DubsAnalyzer.xml @@ -86,6 +86,9 @@
  • RimWorld.JobGiver_Haul:TryGiveJob
  • + +
  • RimWorld.Toils_Bed:BedNoLongerUsable
  • +
  • RimWorld.IdeoUtility:GetStyleDominance
  • diff --git a/Source/PerformanceFish/JobSystem/Toils_BedOptimization.cs b/Source/PerformanceFish/JobSystem/Toils_BedOptimization.cs new file mode 100644 index 0000000..8d631af --- /dev/null +++ b/Source/PerformanceFish/JobSystem/Toils_BedOptimization.cs @@ -0,0 +1,61 @@ +// Copyright (c) 2024 bradson, missionz3r0 +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +using System.Linq; +using System.Reflection.Emit; +using Verse.AI; + +namespace PerformanceFish.JobSystem; + +public sealed class Toils_BedOptimization : ClassWithFishPatches +{ + public sealed class FailOnBedNoLongerUsable_Patch : FishPatch + { + public override string Description { get; } + = "Adds a HashOffset to skip BedNoLongerUsable calls every tick."; + + public override MethodBase TargetMethodInfo { get; } + = FindDelegateMethod( + AccessTools.Method(typeof(Toils_Bed), nameof(Toils_Bed.FailOnBedNoLongerUsable), [typeof(Toil), typeof(TargetIndex), typeof(TargetIndex)]), + "FailOn" + ); + + public static bool Prefix(ref bool __result) + { + if (TickHelper.MatchesModulo(64)) + return true; + + return __result = false; + } + } + + private static MethodBase FindDelegateMethod( + MethodBase containingMethod, + string secondOrderMethod + ) + { + var body = PatchProcessor.ReadMethodBody(containingMethod).ToList(); + + for (var i = 0; i < body.Count; i++) + { + var (opcode, operand) = body[i]; + if (operand is not MethodInfo info || info.Name != secondOrderMethod) + continue; + + while (--i >= 0) + { + (opcode, operand) = body[i]; + if (opcode == OpCodes.Ldftn) + return (MethodBase)operand; + } + + break; + } + + throw new InvalidOperationException( + $"Performance Fish failed to find a delegate called from method {secondOrderMethod} within method {containingMethod}" + ); + } +}