using System.Reflection; using EFT; using HarmonyLib; using SPT.Reflection.Patching; namespace SmartAction.Patch; /// /// Lets you walk while healing a leg. /// /// Vanilla MovementContext.CanWalk (EFT 0.16.9.0.40087): /// if (PhysicalConditionIs(HealingLegs)) return false; /// if (!ObstacleCollisionFacade_1.CanMove()) return false; /// return true; /// /// Upstream SmartAction replaced this body with a transpiler, which rewrote the method for /// every MovementContext in the raid — bots included — and dropped the obstacle check along /// with the HealingLegs check. A postfix that only ever flips false -> true is per-instance, /// composes with other movement mods, needs no IL matching, and keeps CanMove() intact. /// public class CanWalkPatch : ModulePatch { protected override MethodBase GetTargetMethod() { return AccessTools.PropertyGetter(typeof(MovementContext), nameof(MovementContext.CanWalk)); } [PatchPostfix] private static void Postfix(MovementContext __instance, ref bool __result) { // Never grant movement vanilla already allows, and never take it away. if (__result) return; if (!MovementPatchUtil.IsLocalPlayer(__instance)) return; // Only intervene when healing is the reason we were blocked. if (!__instance.PhysicalConditionIs(EPhysicalCondition.HealingLegs)) return; // The other vanilla blocker still applies: if something is physically in the way, // leave the false alone. (Null facade -> treat as blocked.) if (__instance.ObstacleCollisionFacade_1?.CanMove() != true) { if (Diagnostics.Enabled) { Diagnostics.WalkHeldByObstacle++; Diagnostics.OnceWalkHeldByObstacle(); } return; } __result = true; if (Diagnostics.Enabled) { Diagnostics.WalkLifted++; Diagnostics.OnceWalkLifted(); } } }