using System.Reflection; using EFT; using HarmonyLib; using SPT.Reflection.Patching; namespace SmartAction.Patch; /// /// Lets you sprint while using meds / healing legs. /// /// Vanilla MovementContext.CanSprint (EFT 0.16.9.0.40087): /// if (PhysicalConditionIs(SprintDisabled)) return false; /// if (PhysicalConditionIs(UsingMeds)) return false; // lifted here /// if (PhysicalConditionIs(HealingLegs)) return false; // lifted here /// if (PhysicalConditionIs(OnPainkillers)) return true; /// if (PhysicalConditionIs(RightLegDamaged)) return false; /// if (PhysicalConditionIs(LeftLegDamaged)) return false; /// return true; /// /// Upstream SmartAction used a prefix that returned false outright, suppressing the original /// getter for every MovementContext in the raid. That is hard-incompatible with any other mod /// touching sprint or stamina. This lifts exactly the two med-related blocks and replays the /// rest of vanilla's chain, so leg damage and SprintDisabled keep their normal meaning. /// public class CanSprintPatch : ModulePatch { protected override MethodBase GetTargetMethod() { return AccessTools.PropertyGetter(typeof(MovementContext), nameof(MovementContext.CanSprint)); } [PatchPostfix] private static void Postfix(MovementContext __instance, ref bool __result) { if (__result) return; if (!MovementPatchUtil.IsLocalPlayer(__instance)) return; // Not ours to override — this is a deliberate game/quest/effect lockout. if (__instance.PhysicalConditionIs(EPhysicalCondition.SprintDisabled)) { if (Diagnostics.Enabled) Diagnostics.SprintHeldBySprintDisabled++; return; } // Only intervene when meds or leg-healing is what blocked us. var blockedByMeds = __instance.PhysicalConditionIs(EPhysicalCondition.UsingMeds) || __instance.PhysicalConditionIs(EPhysicalCondition.HealingLegs); if (!blockedByMeds) return; // Replay the remainder of vanilla's chain so a broken leg still stops you. if (__instance.PhysicalConditionIs(EPhysicalCondition.OnPainkillers)) { __result = true; if (Diagnostics.Enabled) { Diagnostics.SprintLifted++; Diagnostics.OnceSprintLifted(); } return; } if (__instance.PhysicalConditionIs(EPhysicalCondition.RightLegDamaged) || __instance.PhysicalConditionIs(EPhysicalCondition.LeftLegDamaged)) { if (Diagnostics.Enabled) { Diagnostics.SprintHeldByLeg++; Diagnostics.OnceSprintHeldByLeg(); } return; } __result = true; if (Diagnostics.Enabled) { Diagnostics.SprintLifted++; Diagnostics.OnceSprintLifted(); } } }