Files
Performance-Fish/Source/PerformanceFish/MeditationUtilityCaching.cs
T

66 lines
2.1 KiB
C#

// Copyright (c) 2023 bradson
// 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 PsyfocusGainCache
= PerformanceFish.Cache.ByInt<Verse.Pawn, Verse.Thing,
PerformanceFish.MeditationUtilityCaching.PsyfocusCacheValue>;
namespace PerformanceFish;
// Suggested by https://github.com/notfood
public sealed class MeditationUtilityCaching : ClassWithFishPatches
{
public sealed class PsyfocusGainPerTick : FirstPriorityFishPatch
{
public override string? Description { get; } = "Caches psyfocus gain per tick while the target remains "
+ "constant. Impactful in psycasting focused playthroughs";
public override Delegate TargetMethodGroup { get; } = MeditationUtility.PsyfocusGainPerTick;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool Prefix(Pawn pawn, Thing? focus, ref float __result, out bool __state)
{
ref var cache = ref PsyfocusGainCache.GetOrAddReference(pawn.thingIDNumber, focus?.thingIDNumber ?? 0);
if (cache.Dirty)
return __state = true;
__result = cache.PsyfocusGain;
return __state = false;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Postfix(Pawn pawn, Thing? focus, float __result, bool __state)
{
if (!__state)
return;
UpdateCache(pawn, focus, __result);
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void UpdateCache(Pawn pawn, Thing? focus, float __result)
=> PsyfocusGainCache.GetExistingReference(pawn.thingIDNumber, focus?.thingIDNumber ?? 0)
.Update(__result, pawn);
}
public record struct PsyfocusCacheValue
{
private int _nextRefreshTick;
public float PsyfocusGain;
public void Update(float psyfocusGain, Pawn pawn)
{
PsyfocusGain = psyfocusGain;
_nextRefreshTick = TickHelper.Add(GenTicks.TickRareInterval, pawn.thingIDNumber);
}
public bool Dirty
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => TickHelper.Past(_nextRefreshTick);
}
}
}