using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("StumblingMod")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("StumblingMod")] [assembly: AssemblyTitle("StumblingMod")] [assembly: AssemblyVersion("1.0.0.0")] namespace FootRagdollMod; [BepInPlugin("yourname.footragdoll", "Foot Ragdoll", "1.0.0")] public class FootRagdollPlugin : BaseUnityPlugin { public const string PluginGuid = "yourname.footragdoll"; public const string PluginName = "Foot Ragdoll"; public const string PluginVersion = "1.0.0"; internal static ManualLogSource Log; internal static ConfigEntry SpeedThreshold; internal static ConfigEntry FallDuration; internal static ConfigEntry Cooldown; internal static ConfigEntry GroundNormalAngle; internal static ConfigEntry DebugLogAllFootHits; private void Awake() { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; SpeedThreshold = ((BaseUnityPlugin)this).Config.Bind("General", "SpeedThreshold", 4f, "Минимальная relativeVelocity столкновения ногой (м/с), при которой персонаж падает в регдолл."); FallDuration = ((BaseUnityPlugin)this).Config.Bind("General", "FallDuration", 2f, "Сколько секунд длится регдолл после срабатывания."); Cooldown = ((BaseUnityPlugin)this).Config.Bind("General", "Cooldown", 1f, "Минимальный интервал между срабатываниями (сек), чтобы не спамить регдоллом на одном ударе."); GroundNormalAngle = ((BaseUnityPlugin)this).Config.Bind("General", "GroundNormalAngle", 60f, "Если нормаль столкновения ближе к вертикали (угол к Vector3.up меньше этого значения, градусы) — считаем это полом/потолком и НЕ роняем игрока. Триггер срабатывает только на более 'боковых' нормалях."); DebugLogAllFootHits = ((BaseUnityPlugin)this).Config.Bind("Debug", "LogAllFootHits", false, "Если true — в лог пишется скорость и угол нормали КАЖДОГО столкновения ноги (для подбора порогов)."); new Harmony("yourname.footragdoll").PatchAll(); Log.LogInfo((object)string.Format("{0} v{1} загружен. Threshold={2}, FallDuration={3}", "Foot Ragdoll", "1.0.0", SpeedThreshold.Value, FallDuration.Value)); } } [HarmonyPatch(typeof(PlayerRagdoll), "BodyPartCollision")] internal static class PlayerRagdoll_BodyPartCollision_Patch { private static float lastTriggerTime = -999f; private static readonly MethodInfo RagdollMethod = AccessTools.Method(typeof(Player), "Ragdoll", (Type[])null, (Type[])null); private static readonly MethodInfo CallFallMethod = AccessTools.Method(typeof(Player), "CallTakeDamageAndAddForceAndFall", new Type[3] { typeof(float), typeof(Vector3), typeof(float) }, (Type[])null); [HarmonyPostfix] private static void Postfix(Collision collision, Bodypart bodypart, Player ___player) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) if (((int)bodypart.bodypartType == 13 || (int)bodypart.bodypartType == 16) && !((Object)(object)___player == (Object)null) && ___player.IsLocal && ___player.data.isSprinting && collision.contactCount != 0) { ContactPoint contact = collision.GetContact(0); float num = Vector3.Angle(((ContactPoint)(ref contact)).normal, Vector3.up); bool flag = num <= FootRagdollPlugin.GroundNormalAngle.Value || num >= 180f - FootRagdollPlugin.GroundNormalAngle.Value; Vector3 val = Vector3.ProjectOnPlane(collision.relativeVelocity, Vector3.up); float magnitude = ((Vector3)(ref val)).magnitude; if (FootRagdollPlugin.DebugLogAllFootHits.Value) { FootRagdollPlugin.Log.LogInfo((object)($"[FootHit] {bodypart.bodypartType} vs '{((Object)collision.collider).name}' " + $"horizSpeed={magnitude:F2} normalAngleToUp={num:F1} floorLike={flag}")); } if (!flag && !(bool)RagdollMethod.Invoke(___player, null) && !(magnitude < FootRagdollPlugin.SpeedThreshold.Value) && !(Time.time - lastTriggerTime < FootRagdollPlugin.Cooldown.Value)) { lastTriggerTime = Time.time; FootRagdollPlugin.Log.LogInfo((object)$"Регдолл: {bodypart.bodypartType} ударилась об '{((Object)collision.collider).name}' со скоростью {magnitude:F2} м/с"); CallFallMethod.Invoke(___player, new object[3] { 0f, Vector3.zero, FootRagdollPlugin.FallDuration.Value }); } } } }