Files

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}"
);
}
}