62 lines
1.6 KiB
C#
62 lines
1.6 KiB
C#
// 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}"
|
|
);
|
|
}
|
|
}
|