Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of FroggosRagdoll v1.0.0
Mods/Froggos-Ragdoll.dll
Decompiled 11 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using FroggosRagdoll; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppScheduleOne.AvatarFramework; using Il2CppScheduleOne.DevUtilities; using Il2CppScheduleOne.Experimental; using Il2CppScheduleOne.Map; using Il2CppScheduleOne.PlayerScripts; using Il2CppScheduleOne.Skating; using Il2CppScheduleOne.Vehicles; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.Utilities; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: MelonInfo(typeof(RagdollMod), "Froggos-Ragdoll", "1.2.0", "froggonater", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("Froggos-Ragdoll")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.2.0.0")] [assembly: AssemblyInformationalVersion("1.2.0")] [assembly: AssemblyProduct("Froggos-Ragdoll")] [assembly: AssemblyTitle("Froggos-Ragdoll")] [assembly: AssemblyVersion("1.2.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace FroggosRagdoll { internal static class MotoBail { private struct Sample { public float Time; public Vector3 Vel; } private static readonly Queue<Sample> s_samples = new Queue<Sample>(); private const float Window = 0.25f; private const float ImpactDropKmh = 15f; private const float TippedUpDot = 0.42f; private const float MinFlingUp = 1.5f; private const float MaxFlingUp = 4f; private static LandVehicle s_bike; private static bool s_forceBail; private static bool s_packResolved; private static FieldInfo s_packStates; internal static bool IsBike(LandVehicle lv) { if ((Object)(object)lv != (Object)null && !string.IsNullOrEmpty(lv.vehicleCode)) { return lv.vehicleCode.EndsWith("_motorcycle", StringComparison.OrdinalIgnoreCase); } return false; } private static LandVehicle RiddenBike(Player player, bool driving = true) { try { if ((Object)(object)player == (Object)null || !player.IsInVehicle || (Object)(object)player.CurrentVehicle == (Object)null) { return null; } LandVehicle component = ((Component)player.CurrentVehicle).GetComponent<LandVehicle>(); return (IsBike(component) && (!driving || component.LocalPlayerIsDriver)) ? component : null; } catch { return null; } } public static void Tick() { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) LandVehicle val = RiddenBike(Player.Local); if ((Object)(object)val == (Object)null || (Object)(object)val.Rb == (Object)null || PlayerRagdoll.Active) { s_samples.Clear(); s_bike = null; return; } if ((Object)(object)s_bike == (Object)null || ((Il2CppObjectBase)s_bike).Pointer != ((Il2CppObjectBase)val).Pointer) { s_samples.Clear(); s_bike = val; } float time = Time.time; Vector3 velocity = val.Rb.velocity; s_samples.Enqueue(new Sample { Time = time, Vel = velocity }); while (s_samples.Count > 0 && time - s_samples.Peek().Time > 0.25f) { s_samples.Dequeue(); } if (!RagdollMod.Cfg.BikeBailOnCrash.Value) { return; } Fastest(velocity, out var kmh); float num = Flat(velocity) * 3.6f; if (!(kmh >= RagdollMod.Cfg.BikeBailSpeedKmh.Value) || !(num < kmh * 0.4f)) { return; } RagdollMod.Verbose($"Bike crash: {kmh:F0} -> {num:F0} km/h."); s_forceBail = true; try { val.ExitVehicle(); } catch (Exception ex) { RagdollMod.Log.Warning("Bike crash dismount failed: " + ex.Message); } finally { s_forceBail = false; } s_samples.Clear(); } internal static Vector3? CrashFling(LandVehicle exiting) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) if (!IsBike(exiting)) { return null; } LandVehicle val = RiddenBike(Player.Local, driving: false); if ((Object)(object)val == (Object)null || ((Il2CppObjectBase)val).Pointer != ((Il2CppObjectBase)exiting).Pointer) { RagdollMod.Verbose(exiting.vehicleCode + " exit ignored: the local player isn't on it."); return null; } if ((Object)(object)val.Rb == (Object)null || !RagdollMod.Cfg.BikeBailOnCrash.Value || PlayerRagdoll.Active) { return null; } Vector3 velocity = val.Rb.velocity; float kmh; Vector3 val2 = Fastest(velocity, out kmh); float num = kmh - Flat(velocity) * 3.6f; bool flag = Vector3.Dot(((Component)val).transform.up, Vector3.up) < 0.42f; bool flag2 = PackCrashPending(val); bool flag3 = s_forceBail || flag2 || num >= 15f || flag; RagdollMod.Log.Msg($"Leaving bike at {kmh:F0} km/h (now {Flat(velocity) * 3.6f:F0}): {(flag3 ? "crash, ragdolling" : "normal dismount")} [pack wipeout {flag2}, ours {s_forceBail}, tipped {flag}]."); if (!flag3) { return null; } float num2 = Math.Max(0f, RagdollMod.Cfg.BikeFlingLift.Value); float num3 = ((num2 > 0f) ? Mathf.Clamp(Flat(val2) * num2, 1.5f, 4f) : 0f); s_samples.Clear(); PlayerRagdoll.CaptureView(); return val2 * Math.Max(0f, RagdollMod.Cfg.BikeLaunchMultiplier.Value) + Vector3.up * num3; } private static bool PackCrashPending(LandVehicle bike) { try { if (!s_packResolved) { s_packResolved = true; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { if (!(assembly.GetName().Name != "ScheduleIBikePack")) { s_packStates = assembly.GetType("ScheduleIBikePack.BikeRecovery", throwOnError: false)?.GetField("states", BindingFlags.Static | BindingFlags.NonPublic); break; } } RagdollMod.Log.Msg((s_packStates != null) ? "Motorcycle_Pack found: its wipeouts throw you into a ragdoll." : "Motorcycle_Pack crash state not found; bike crashes are detected from speed only."); } if (s_packStates == null || !(s_packStates.GetValue(null) is IDictionary dictionary)) { return false; } object obj = (dictionary.Contains(((Object)bike).GetInstanceID()) ? dictionary[((Object)bike).GetInstanceID()] : null); object obj2 = obj?.GetType().GetField("Policy")?.GetValue(obj); object obj3 = obj2?.GetType().GetProperty("CrashPending")?.GetValue(obj2); bool flag = default(bool); int num; if (obj3 is bool) { flag = (bool)obj3; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } catch (Exception ex) { RagdollMod.Verbose("Reading Motorcycle_Pack crash state failed: " + ex.Message); return false; } } private static Vector3 Fastest(Vector3 current, out float kmh) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //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_005f: Unknown result type (might be due to invalid IL or missing references) Vector3 result = current; kmh = Flat(current) * 3.6f; foreach (Sample s_sample in s_samples) { float num = Flat(s_sample.Vel) * 3.6f; if (num > kmh) { kmh = num; result = s_sample.Vel; } } return result; } private static float Flat(Vector3 v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) return Mathf.Sqrt(v.x * v.x + v.z * v.z); } public static void Reset() { s_samples.Clear(); s_bike = null; s_forceBail = false; } } [HarmonyPatch(typeof(LandVehicle), "ExitVehicle")] internal static class ExitVehiclePatch { private static void Prefix(LandVehicle __instance, out Vector3? __state) { __state = null; try { __state = MotoBail.CrashFling(__instance); } catch (Exception ex) { RagdollMod.Log.Error("Checking for a bike crash failed: " + ex); } } private static void Postfix(Vector3? __state) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (!__state.HasValue) { return; } try { Player local = Player.Local; if ((Object)(object)local != (Object)null && !local.IsInVehicle) { PlayerRagdoll.StartAfterVehicle(__state.Value); } else { RagdollMod.Log.Msg("Still on the bike after the crash (no room to dismount), so no ragdoll."); } } catch (Exception ex) { RagdollMod.Log.Error("Ragdolling off the bike failed: " + ex); } } } [HarmonyPatch(typeof(Skateboard_Equippable), "Mount")] internal static class MountPatch { private static void Prefix() { try { PlayerRagdoll.OnMounting(); } catch (Exception ex) { RagdollMod.Log.Error("Standing up for skateboard mount failed: " + ex); } } } internal static class PlayerRagdoll { private const float DismountWait = 0.5f; private const int RelaunchSteps = 3; private static float s_startTime; private static bool s_meshesWereVisible; private static bool s_overlayWasEnabled; private static float s_yaw; private static float s_pitch; private static Vector3 s_camPos; private static float s_camDist; private static Vector3 s_launchVel; private static int s_fixedSteps; private static bool s_diagLogged; private const float FirstPersonRange = 0.6f; private const float FirstPersonNearClip = 0.05f; private static bool s_firstPerson; private static bool? s_startFirstPerson; private static Quaternion s_headToView = Quaternion.identity; private static float s_fpYaw; private static float s_fpPitch; private static float s_savedNearClip = -1f; private static readonly List<(Renderer, ShadowCastingMode)> s_hiddenHead = new List<(Renderer, ShadowCastingMode)>(); private const float LostFallDepth = 40f; private static Vector3 s_lastHips; private static Vector3 s_startFeet; private static bool s_pending; private static float s_pendingUntil; private static int s_pendingFrame; private static Vector3 s_pendingVel; private static Skateboard_Equippable s_mountAfterStand; private static readonly List<(Collider, Collider)> s_ignored = new List<(Collider, Collider)>(); private static readonly List<(Collider, int, bool, bool)> s_colliderStates = new List<(Collider, int, bool, bool)>(); private static readonly List<(Rigidbody, CollisionDetectionMode, RigidbodyInterpolation)> s_bodyModes = new List<(Rigidbody, CollisionDetectionMode, RigidbodyInterpolation)>(); public static bool Active { get; private set; } private static PlayerMovement Movement { get { if (!PlayerSingleton<PlayerMovement>.InstanceExists) { return null; } return PlayerSingleton<PlayerMovement>.Instance; } } private static PlayerCamera Cam { get { if (!PlayerSingleton<PlayerCamera>.InstanceExists) { return null; } return PlayerSingleton<PlayerCamera>.Instance; } } public static void Toggle() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) if (Active) { if (Time.time - s_startTime > 0.25f) { StandUp(); } } else if (!s_pending) { PlayerMovement movement = Movement; if (!((Object)(object)movement == (Object)null) && !((Object)(object)movement.Controller == (Object)null)) { Start((Vector3)(((??)SkateTuning.BoardVelocity) ?? movement.Controller.velocity)); } } } public static void Start(Vector3 velocity) { //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) if (Active || s_pending) { return; } Player local = Player.Local; if (!CanRagdoll(local)) { return; } PlayerMovement movement = Movement; try { if ((Object)(object)movement != (Object)null && (Object)(object)movement.CurrentLadder != (Object)null) { movement.DismountLadder(); } } catch { } CaptureView(); Skateboard activeSkateboard = local.ActiveSkateboard; if ((Object)(object)activeSkateboard != (Object)null) { try { if ((Object)(object)activeSkateboard.Equippable != (Object)null) { activeSkateboard.Equippable.Dismount(); } else { local.DismountSkateboard(); } } catch (Exception ex) { RagdollMod.Log.Warning("Skateboard dismount failed: " + ex.Message); } s_pending = true; s_pendingUntil = Time.time + 0.5f; s_pendingFrame = 0; s_pendingVel = velocity; } else { GoLimp(local, velocity); } } public static void StartAfterVehicle(Vector3 velocity) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (!Active && !s_pending) { s_pending = true; s_pendingUntil = Time.time + 0.5f; s_pendingFrame = Time.frameCount + 2; s_pendingVel = velocity; } } public static void CaptureView() { s_startFirstPerson = IsFirstPersonNow(Player.Local); } private static bool IsFirstPersonNow(Player player) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) PlayerCamera cam = Cam; Transform val = Head(player); if ((Object)(object)cam == (Object)null || (Object)(object)val == (Object)null) { return true; } return Vector3.Distance((((Object)(object)cam.Camera != (Object)null) ? ((Component)cam.Camera).transform : ((Component)cam).transform).position, val.position) < 0.6f; } private static Transform Head(Player player) { try { AvatarEffects val = (((Object)(object)player != (Object)null && (Object)(object)player.Avatar != (Object)null) ? player.Avatar.Effects : null); return ((Object)(object)val != (Object)null) ? val.HeadBone : null; } catch { return null; } } private static bool CanRagdoll(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)Movement == (Object)null || (Object)(object)Movement.Controller == (Object)null || (Object)(object)Cam == (Object)null || (Object)(object)player.Avatar == (Object)null) { return false; } if (player.IsInVehicle || player.IsArrested || player.IsTased || player.IsSleeping || player.IsRagdolled) { return false; } if (!((Object)(object)player.Health == (Object)null)) { return player.Health.IsAlive; } return true; } private static void GoLimp(Player player, Vector3 velocity) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) PlayerMovement movement = Movement; PlayerCamera cam = Cam; Avatar avatar = player.Avatar; CharacterController controller = movement.Controller; bool flag = s_startFirstPerson ?? IsFirstPersonNow(player); s_startFirstPerson = null; Transform val = Head(player); Quaternion rotation = ((Component)avatar).transform.rotation; Quaternion val2 = Quaternion.Euler(0f, ((Quaternion)(ref rotation)).eulerAngles.y, 0f); s_headToView = (((Object)(object)val != (Object)null) ? (Quaternion.Inverse(val.rotation) * val2) : Quaternion.identity); if (!avatar.Ragdolled) { avatar.EnableRagdoll(); } Ragdoll activeRagdoll = avatar.ActiveRagdoll; if (activeRagdoll == null || (Object)(object)activeRagdoll.RootRigidbody == (Object)null) { RagdollMod.Log.Warning("The avatar has no ragdoll; can't go limp."); return; } Active = true; s_startTime = Time.time; s_fixedSteps = 0; s_diagLogged = false; s_launchVel = velocity * Math.Max(0f, RagdollMod.Cfg.LaunchMultiplier.Value); movement.CanMove = false; movement.CanJump = false; movement.movementY = 0f; movement.residualVelocityTimeRemaining = 0f; ((Behaviour)movement).enabled = false; ((Collider)controller).enabled = false; MakeSolid(activeRagdoll, movement); IgnorePlayerColliders(player, activeRagdoll); Launch(activeRagdoll, tumble: true); s_startFeet = ((Component)controller).transform.TransformPoint(controller.center) - Vector3.up * controller.height * 0.5f; s_lastHips = activeRagdoll.RootRigidbody.position; s_meshesWereVisible = player.ThirdPersonMeshesVisibleToLocalPlayer; try { player.SetThirdPersonMeshesVisibility(true); } catch { } BeginCamera(cam); s_firstPerson = false; if (flag) { SetFirstPerson(on: true); } } private static void MakeSolid(Ragdoll rd, PlayerMovement pm) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) LayerMask groundDetectionMask = pm.GroundDetectionMask; int num = ((LayerMask)(ref groundDetectionMask)).value; RaycastHit val = default(RaycastHit); if (Physics.Raycast(((Component)pm.Controller).transform.position + Vector3.up * 0.5f, Vector3.down, ref val, 4f, num, (QueryTriggerInteraction)1)) { num |= 1 << ((Component)((RaycastHit)(ref val)).collider).gameObject.layer; } int num2 = -1; HashSet<string> hashSet = new HashSet<string>(); int num3 = 0; int num4 = 0; int num5 = 0; int num6 = 0; Il2CppReferenceArray<Rigidbody> rigidbodies = rd.Rigidbodies; for (int i = 0; i < ((Il2CppArrayBase<Rigidbody>)(object)rigidbodies).Length; i++) { if ((Object)(object)((Il2CppArrayBase<Rigidbody>)(object)rigidbodies)[i] == (Object)null) { continue; } Il2CppArrayBase<Collider> components = ((Component)((Il2CppArrayBase<Rigidbody>)(object)rigidbodies)[i]).GetComponents<Collider>(); for (int j = 0; j < components.Length; j++) { Collider val2 = components[j]; if ((Object)(object)val2 == (Object)null) { continue; } num6++; GameObject gameObject = ((Component)val2).gameObject; s_colliderStates.Add((val2, gameObject.layer, val2.enabled, val2.isTrigger)); hashSet.Add(LayerMask.LayerToName(gameObject.layer) + "(" + gameObject.layer + ")"); if (!val2.enabled) { val2.enabled = true; num5++; } if (val2.isTrigger) { val2.isTrigger = false; num4++; } if (!HitsAll(gameObject.layer, num)) { if (num2 < 0) { num2 = PickSolidLayer(num); } if (num2 >= 0) { gameObject.layer = num2; num3++; } } } } RagdollMod.Log.Msg($"Ragdoll colliders: {num6} on layers [{string.Join(", ", hashSet)}]; moved {num3} to {((num2 >= 0) ? (LayerMask.LayerToName(num2) + "(" + num2 + ")") : "-")}, un-triggered {num4}, enabled {num5}."); } private static bool HitsAll(int layer, int mask) { for (int i = 0; i < 32; i++) { if ((mask & (1 << i)) != 0 && Physics.GetIgnoreLayerCollision(layer, i)) { return false; } } return true; } private static int PickSolidLayer(int mask) { if (HitsAll(0, mask)) { return 0; } for (int i = 1; i < 32; i++) { if (!string.IsNullOrEmpty(LayerMask.LayerToName(i)) && HitsAll(i, mask)) { return i; } } return -1; } private static void RestoreSolid() { foreach (var (val, layer, enabled, isTrigger) in s_colliderStates) { try { if (!((Object)(object)val == (Object)null)) { ((Component)val).gameObject.layer = layer; val.isTrigger = isTrigger; val.enabled = enabled; } } catch { } } s_colliderStates.Clear(); } private static void IgnorePlayerColliders(Player player, Ragdoll rd) { List<Collider> list = new List<Collider>(); Il2CppReferenceArray<Rigidbody> rigidbodies = rd.Rigidbodies; for (int i = 0; i < ((Il2CppArrayBase<Rigidbody>)(object)rigidbodies).Length; i++) { if ((Object)(object)((Il2CppArrayBase<Rigidbody>)(object)rigidbodies)[i] == (Object)null) { continue; } Il2CppArrayBase<Collider> components = ((Component)((Il2CppArrayBase<Rigidbody>)(object)rigidbodies)[i]).GetComponents<Collider>(); for (int j = 0; j < components.Length; j++) { if ((Object)(object)components[j] != (Object)null) { list.Add(components[j]); } } } Il2CppArrayBase<Collider> componentsInChildren = ((Component)player).GetComponentsInChildren<Collider>(true); for (int k = 0; k < componentsInChildren.Length; k++) { Collider o = componentsInChildren[k]; if ((Object)(object)o == (Object)null || o.isTrigger || list.Exists((Collider r) => ((Il2CppObjectBase)r).Pointer == ((Il2CppObjectBase)o).Pointer)) { continue; } foreach (Collider item in list) { Physics.IgnoreCollision(o, item, true); s_ignored.Add((o, item)); } } } private static void RestorePlayerColliders() { foreach (var (val, val2) in s_ignored) { try { if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null) { Physics.IgnoreCollision(val, val2, false); } } catch { } } s_ignored.Clear(); } private static void Launch(Ragdoll rd, bool tumble) { //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) Il2CppReferenceArray<Rigidbody> rigidbodies = rd.Rigidbodies; for (int i = 0; i < ((Il2CppArrayBase<Rigidbody>)(object)rigidbodies).Length; i++) { Rigidbody rb = ((Il2CppArrayBase<Rigidbody>)(object)rigidbodies)[i]; if (!((Object)(object)rb == (Object)null)) { if (!s_bodyModes.Exists(((Rigidbody, CollisionDetectionMode, RigidbodyInterpolation) m) => ((Il2CppObjectBase)m.Item1).Pointer == ((Il2CppObjectBase)rb).Pointer)) { s_bodyModes.Add((rb, rb.collisionDetectionMode, rb.interpolation)); } rb.interpolation = (RigidbodyInterpolation)1; rb.collisionDetectionMode = (CollisionDetectionMode)(rb.isKinematic ? 3 : 2); rb.velocity = s_launchVel; } } if (tumble) { Vector3 val = s_launchVel; float num = Mathf.Min(((Vector3)(ref val)).magnitude * 0.25f, 10f) * Math.Max(0f, RagdollMod.Cfg.TumbleStrength.Value); if (num > 0.01f) { Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(val.x, 0f, val.z); Vector3 val3 = ((((Vector3)(ref val2)).sqrMagnitude > 0.01f) ? Vector3.Cross(Vector3.up, ((Vector3)(ref val2)).normalized) : Random.onUnitSphere); rd.RootRigidbody.angularVelocity = (val3 + Random.insideUnitSphere * 0.35f) * num; } } } public static void Tick() { //IL_00cd: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)s_mountAfterStand != (Object)null) { Skateboard_Equippable val = s_mountAfterStand; s_mountAfterStand = null; try { if (!val.IsRiding && (Object)(object)Player.Local != (Object)null && (Object)(object)Player.Local.ActiveSkateboard == (Object)null) { val.Mount(); } } catch (Exception ex) { RagdollMod.Verbose("Mount after standing failed: " + ex.Message); } } if (s_pending) { Player local = Player.Local; if ((Object)(object)local == (Object)null) { s_pending = false; } else if (((Object)(object)local.ActiveSkateboard == (Object)null && !local.IsInVehicle && Time.frameCount >= s_pendingFrame) || Time.time >= s_pendingUntil) { s_pending = false; if (CanRagdoll(local)) { GoLimp(local, s_pendingVel); return; } RagdollMod.Log.Warning($"Couldn't go limp after dismounting (in vehicle {local.IsInVehicle}, ragdolled {local.IsRagdolled})."); } } else { if (!Active) { return; } Player local2 = Player.Local; PlayerMovement movement = Movement; if ((Object)(object)local2 == (Object)null || (Object)(object)movement == (Object)null || (Object)(object)movement.Controller == (Object)null) { Reset(); return; } if (((Object)(object)local2.Health != (Object)null && !local2.Health.IsAlive) || local2.IsArrested) { Release(local2, movement, unragdoll: false); return; } Mouse current = Mouse.current; if (current != null && current.leftButton.wasPressedThisFrame && Time.time - s_startTime > 0.25f) { Skateboard_Equippable val2 = Object.FindObjectOfType<Skateboard_Equippable>(); if ((Object)(object)val2 != (Object)null) { StandUp(); s_mountAfterStand = val2; } } } } public static void FixedTick() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) if (!Active) { return; } Player local = Player.Local; Ragdoll val = (((Object)(object)local != (Object)null && (Object)(object)local.Avatar != (Object)null) ? local.Avatar.ActiveRagdoll : null); if (val == null || (Object)(object)val.RootRigidbody == (Object)null) { return; } Rigidbody rootRigidbody = val.RootRigidbody; if (!CheckWaterAndFall(rootRigidbody.position) && s_fixedSteps < 3) { s_fixedSteps++; Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(s_launchVel.x, 0f, s_launchVel.z); Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(rootRigidbody.velocity.x, 0f, rootRigidbody.velocity.z); if (!s_diagLogged) { s_diagLogged = true; RagdollMod.Log.Msg($"Launch: want {((Vector3)(ref val2)).magnitude * 3.6f:F0} km/h, root has {((Vector3)(ref val3)).magnitude * 3.6f:F0} km/h, kinematic {rootRigidbody.isKinematic}, parented to player {((Component)rootRigidbody).transform.IsChildOf(((Component)local).transform)}."); } if (((Vector3)(ref val2)).sqrMagnitude > 1f && ((Vector3)(ref val3)).magnitude < ((Vector3)(ref val2)).magnitude * 0.5f) { Launch(val, tumble: false); } } } private static bool CheckWaterAndFall(Vector3 hips) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) WaterCollider val = FindWater(s_lastHips, hips); s_lastHips = hips; if ((Object)(object)val != (Object)null) { RagdollMod.Log.Msg("Ragdoll hit water: standing up so the game can warp you out."); StandUp(); try { if (!val.localPlayerBeingWarped) { ((MonoBehaviour)val).StartCoroutine(val.WarpPlayer()); } } catch (Exception ex) { RagdollMod.Log.Warning("Water warp failed: " + ex.Message); } return true; } if (hips.y < s_startFeet.y - 40f) { RagdollMod.Log.Msg("Ragdoll fell out of the world: standing up where it started."); StandUp(s_startFeet); return true; } return false; } private static WaterCollider FindWater(Vector3 from, Vector3 to) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) foreach (Collider item in (Il2CppArrayBase<Collider>)(object)Physics.OverlapSphere(to, 0.4f, -1, (QueryTriggerInteraction)2)) { WaterCollider val = (((Object)(object)item != (Object)null && item.isTrigger) ? ((Component)item).GetComponent<WaterCollider>() : null); if ((Object)(object)val != (Object)null) { return val; } } Vector3 val2 = to - from; if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f) { return null; } foreach (RaycastHit item2 in (Il2CppArrayBase<RaycastHit>)(object)Physics.RaycastAll(from, ((Vector3)(ref val2)).normalized, ((Vector3)(ref val2)).magnitude, -1, (QueryTriggerInteraction)2)) { RaycastHit current2 = item2; WaterCollider val3 = (((Object)(object)((RaycastHit)(ref current2)).collider != (Object)null && ((RaycastHit)(ref current2)).collider.isTrigger) ? ((Component)((RaycastHit)(ref current2)).collider).GetComponent<WaterCollider>() : null); if ((Object)(object)val3 != (Object)null) { return val3; } } return null; } public static void LateTick() { //IL_0081: Unknown result type (might be due to invalid IL or missing references) if (!Active) { return; } Player local = Player.Local; PlayerCamera cam = Cam; if ((Object)(object)local == (Object)null || (Object)(object)cam == (Object)null || (Object)(object)local.Avatar == (Object)null) { return; } Ragdoll activeRagdoll = local.Avatar.ActiveRagdoll; if (activeRagdoll != null && !((Object)(object)activeRagdoll.RootRigidbody == (Object)null)) { Transform val = (s_firstPerson ? Head(local) : null); if ((Object)(object)val != (Object)null) { UpdateFirstPerson(cam, val); } else { UpdateCamera(cam, ((Component)activeRagdoll.RootRigidbody).transform.position); } } } public static void ToggleView() { if (Active) { SetFirstPerson(!s_firstPerson); } } private static void SetFirstPerson(bool on) { //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) if (on == s_firstPerson) { return; } PlayerCamera cam = Cam; Player local = Player.Local; if (on && (Object)(object)Head(local) == (Object)null) { return; } s_firstPerson = on; Camera val = (((Object)(object)cam != (Object)null) ? cam.Camera : null); if (on) { s_fpYaw = 0f; s_fpPitch = 0f; if ((Object)(object)val != (Object)null) { s_savedNearClip = val.nearClipPlane; val.nearClipPlane = Mathf.Min(val.nearClipPlane, 0.05f); } HideHead(local); return; } if ((Object)(object)val != (Object)null && s_savedNearClip > 0f) { val.nearClipPlane = s_savedNearClip; } s_savedNearClip = -1f; ShowHead(); if ((Object)(object)cam != (Object)null) { Quaternion rotation = ((Component)cam).transform.rotation; s_yaw = ((Quaternion)(ref rotation)).eulerAngles.y; } s_pitch = 20f; s_camDist = Math.Max(1.5f, RagdollMod.Cfg.CameraDistance.Value); } private static void UpdateFirstPerson(PlayerCamera cam, Transform head) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) Mouse current = Mouse.current; if (current != null) { Vector2 val = ((InputControl<Vector2>)(object)((Pointer)current).delta).ReadValue() * RagdollMod.Cfg.CameraSensitivity.Value; s_fpYaw = Mathf.Clamp(s_fpYaw + val.x, -110f, 110f); s_fpPitch = Mathf.Clamp(s_fpPitch - val.y, -80f, 80f); } Quaternion val2 = head.rotation * s_headToView; Quaternion val3 = val2 * Quaternion.Euler(s_fpPitch, s_fpYaw, 0f); Vector3 val4 = head.position + val2 * new Vector3(0f, 0.08f, 0.12f); Transform transform = ((Component)cam).transform; transform.SetPositionAndRotation(val4, val3); Transform val5 = (((Object)(object)cam.Camera != (Object)null) ? ((Component)cam.Camera).transform : transform); if ((Object)(object)val5 != (Object)(object)transform) { transform.rotation = val3 * Quaternion.Inverse(val5.rotation) * transform.rotation; transform.position += val4 - val5.position; } } private static void HideHead(Player player) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Invalid comparison between Unknown and I4 //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) Transform val = Head(player); if ((Object)(object)val == (Object)null || (Object)(object)player.Avatar == (Object)null) { return; } Vector3 position = val.position; foreach (Renderer componentsInChild in ((Component)player.Avatar).GetComponentsInChildren<Renderer>()) { if ((Object)(object)componentsInChild == (Object)null || !componentsInChild.enabled || (int)componentsInChild.shadowCastingMode == 3) { continue; } Bounds bounds = componentsInChild.bounds; if (!(Vector3.Distance(((Bounds)(ref bounds)).center, position) > 0.3f)) { Vector3 extents = ((Bounds)(ref bounds)).extents; if (!(((Vector3)(ref extents)).magnitude > 0.4f)) { s_hiddenHead.Add((componentsInChild, componentsInChild.shadowCastingMode)); componentsInChild.shadowCastingMode = (ShadowCastingMode)3; } } } } private static void ShowHead() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) foreach (var (val, shadowCastingMode) in s_hiddenHead) { try { if ((Object)(object)val != (Object)null) { val.shadowCastingMode = shadowCastingMode; } } catch { } } s_hiddenHead.Clear(); } private static void BeginCamera(PlayerCamera cam) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)cam).transform; Quaternion rotation = transform.rotation; s_yaw = ((Quaternion)(ref rotation)).eulerAngles.y; s_pitch = 20f; s_camDist = Math.Max(1.5f, RagdollMod.Cfg.CameraDistance.Value); s_camPos = transform.position; try { cam.OverrideTransform(transform.position, transform.rotation, 0f, false); } catch (Exception ex) { RagdollMod.Verbose("OverrideTransform failed: " + ex.Message); } try { cam.SetCanLook(false); } catch { } s_overlayWasEnabled = (Object)(object)cam.OverlayCamera != (Object)null && ((Behaviour)cam.OverlayCamera).enabled; if ((Object)(object)cam.OverlayCamera != (Object)null) { ((Behaviour)cam.OverlayCamera).enabled = false; } } private static void UpdateCamera(PlayerCamera cam, Vector3 hips) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) Mouse current = Mouse.current; if (current != null) { Vector2 val = ((InputControl<Vector2>)(object)((Pointer)current).delta).ReadValue() * RagdollMod.Cfg.CameraSensitivity.Value; s_yaw += val.x; s_pitch = Mathf.Clamp(s_pitch - val.y, -30f, 80f); } Quaternion val2 = Quaternion.Euler(s_pitch, s_yaw, 0f); Vector3 val3 = hips + Vector3.up * 0.3f; Vector3 val4 = val2 * Vector3.back; float num = s_camDist; PlayerMovement movement = Movement; int num2; if (!((Object)(object)movement != (Object)null)) { num2 = -5; } else { LayerMask groundDetectionMask = movement.GroundDetectionMask; num2 = ((LayerMask)(ref groundDetectionMask)).value; } int num3 = num2; RaycastHit val5 = default(RaycastHit); if (Physics.SphereCast(val3, 0.25f, val4, ref val5, num, num3, (QueryTriggerInteraction)1)) { num = Mathf.Max(0.4f, ((RaycastHit)(ref val5)).distance - 0.1f); } s_camDist = ((num < s_camDist) ? num : Mathf.MoveTowards(s_camDist, num, 6f * Time.unscaledDeltaTime)); s_camPos = val3 + val4 * s_camDist; ((Component)cam).transform.SetPositionAndRotation(s_camPos, val2); } public static void StandUp(Vector3? at = null) { //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0179: 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) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) if (!Active) { return; } Player local = Player.Local; PlayerMovement movement = Movement; if ((Object)(object)local == (Object)null || (Object)(object)movement == (Object)null || (Object)(object)movement.Controller == (Object)null) { Reset(); return; } CharacterController controller = movement.Controller; Vector3 val = ((Component)controller).transform.position; Avatar avatar = local.Avatar; if ((Object)(object)avatar != (Object)null && avatar.ActiveRagdoll != null && (Object)(object)avatar.ActiveRagdoll.RootRigidbody != (Object)null) { Vector3 position = avatar.ActiveRagdoll.RootRigidbody.position; Vector3 val2 = position + Vector3.up * 0.5f; Vector3 down = Vector3.down; LayerMask groundDetectionMask = movement.GroundDetectionMask; RaycastHit val3 = default(RaycastHit); val = (Physics.Raycast(val2, down, ref val3, 5f, ((LayerMask)(ref groundDetectionMask)).value, (QueryTriggerInteraction)1) ? ((RaycastHit)(ref val3)).point : (position - Vector3.up * 0.9f)); } if (at.HasValue) { val = at.Value; } Release(local, movement, unragdoll: true); Vector3 center = controller.center; Vector3 position2 = default(Vector3); ((Vector3)(ref position2))..ctor(val.x - center.x, val.y - center.y + controller.height * 0.5f + 0.05f, val.z - center.z); bool enabled = ((Collider)controller).enabled; ((Collider)controller).enabled = false; ((Component)controller).transform.position = position2; ((Collider)controller).enabled = enabled; try { movement.Teleport(val + Vector3.up * 0.05f, true); } catch (Exception ex) { RagdollMod.Log.Warning("Teleport to body failed: " + ex.Message); } try { movement.SetRotation(Quaternion.Euler(0f, s_yaw, 0f)); } catch { } } private static void Release(Player player, PlayerMovement pm, bool unragdoll) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) SetFirstPerson(on: false); Active = false; RestorePlayerColliders(); RestoreSolid(); foreach (var (val, collisionDetectionMode, interpolation) in s_bodyModes) { try { if (!((Object)(object)val == (Object)null)) { val.collisionDetectionMode = collisionDetectionMode; val.interpolation = interpolation; } } catch { } } s_bodyModes.Clear(); if (unragdoll) { try { if ((Object)(object)player.Avatar != (Object)null && player.Avatar.Ragdolled) { player.Avatar.DisableRagdoll(); } } catch (Exception ex) { RagdollMod.Log.Warning("DisableRagdoll failed: " + ex.Message); } } try { player.SetThirdPersonMeshesVisibility(s_meshesWereVisible); } catch { } ((Collider)pm.Controller).enabled = true; ((Behaviour)pm).enabled = true; pm.movementY = 0f; pm.CanMove = true; pm.CanJump = true; PlayerCamera cam = Cam; if ((Object)(object)cam != (Object)null) { if ((Object)(object)cam.OverlayCamera != (Object)null) { ((Behaviour)cam.OverlayCamera).enabled = s_overlayWasEnabled; } try { cam.StopTransformOverride(0.2f, true, false); } catch (Exception ex2) { RagdollMod.Verbose("StopTransformOverride failed: " + ex2.Message); } } } public static void OnMounting() { s_pending = false; if (Active) { StandUp(); } } public static void Reset() { Active = false; s_pending = false; s_mountAfterStand = null; s_ignored.Clear(); s_bodyModes.Clear(); s_colliderStates.Clear(); s_firstPerson = false; s_startFirstPerson = null; s_savedNearClip = -1f; s_hiddenHead.Clear(); } } internal class RagdollConfig { public readonly MelonPreferences_Entry<string> ToggleKey; public readonly MelonPreferences_Entry<float> LaunchMultiplier; public readonly MelonPreferences_Entry<float> TumbleStrength; public readonly MelonPreferences_Entry<float> SkateMaxSpeedMultiplier; public readonly MelonPreferences_Entry<float> SkateBuildUpRate; public readonly MelonPreferences_Entry<float> SkatePushMultiplier; public readonly MelonPreferences_Entry<bool> BailOnCrash; public readonly MelonPreferences_Entry<float> BailSpeedKmh; public readonly MelonPreferences_Entry<bool> BikeBailOnCrash; public readonly MelonPreferences_Entry<float> BikeBailSpeedKmh; public readonly MelonPreferences_Entry<float> BikeLaunchMultiplier; public readonly MelonPreferences_Entry<float> BikeFlingLift; public readonly MelonPreferences_Entry<string> ViewKey; public readonly MelonPreferences_Entry<float> CameraDistance; public readonly MelonPreferences_Entry<float> CameraSensitivity; public readonly MelonPreferences_Entry<bool> VerboseLogging; public RagdollConfig() { MelonPreferences_Category val = MelonPreferences.CreateCategory("Froggos-Ragdoll", "Froggos Ragdoll"); ToggleKey = val.CreateEntry<string>("ToggleKey", "R", "Toggle key", "Input System key name (R, G, F1, Backquote, ...). Press to go limp, press again to stand up.", false, false, (ValueValidator)null, (string)null); LaunchMultiplier = val.CreateEntry<float>("LaunchMultiplier", 1.15f, "Launch multiplier", "How much of your velocity carries into the ragdoll. 1 = exact, higher = you fly further.", false, false, (ValueValidator)null, (string)null); TumbleStrength = val.CreateEntry<float>("TumbleStrength", 1f, "Tumble strength", "Extra spin added when you ragdoll at speed. 0 = none.", false, false, (ValueValidator)null, (string)null); SkateMaxSpeedMultiplier = val.CreateEntry<float>("SkateMaxSpeedMultiplier", 3f, "Skate max speed multiplier", "How far above vanilla top speed you can build up by riding flat out. 1 = vanilla cap.", false, false, (ValueValidator)null, (string)null); SkateBuildUpRate = val.CreateEntry<float>("SkateBuildUpRate", 0.12f, "Skate build-up rate", "How fast the speed cap rises while you're at it (vanilla top speeds per second). 0.12 = ~17 s to reach 3x.", false, false, (ValueValidator)null, (string)null); SkatePushMultiplier = val.CreateEntry<float>("SkatePushForceMultiplier", 1f, "Skate push multiplier", "Scales each push's force. 1 = vanilla.", false, false, (ValueValidator)null, (string)null); BailOnCrash = val.CreateEntry<bool>("BailOnCrash", true, "Bail on crash", "Automatically ragdoll when you slam into something on a skateboard.", false, false, (ValueValidator)null, (string)null); BailSpeedKmh = val.CreateEntry<float>("BailSpeedKmh", 30f, "Bail speed (km/h)", "Minimum speed a sudden stop has to start from to throw you off the board.", false, false, (ValueValidator)null, (string)null); BikeBailOnCrash = val.CreateEntry<bool>("BikeBailOnCrash", true, "Bike bail on crash", "Motorcycle_Pack bikes: crashing throws you off and ragdolls you instead of the plain dismount.", false, false, (ValueValidator)null, (string)null); BikeBailSpeedKmh = val.CreateEntry<float>("BikeBailSpeedKmh", 30f, "Bike bail speed (km/h)", "A sudden stop from this speed throws you off a bike even when Motorcycle_Pack wouldn't dismount you.", false, false, (ValueValidator)null, (string)null); BikeLaunchMultiplier = val.CreateEntry<float>("BikeLaunchMultiplier", 0.6f, "Bike launch multiplier", "Share of the bike's speed you keep when thrown off (on top of Launch multiplier). Lower = you land closer.", false, false, (ValueValidator)null, (string)null); BikeFlingLift = val.CreateEntry<float>("BikeFlingLift", 0.12f, "Bike fling lift", "Upward kick when thrown off a bike, as a share of your speed (over the handlebars). 0 = none.", false, false, (ValueValidator)null, (string)null); ViewKey = val.CreateEntry<string>("ViewKey", "V", "View key", "Switches between first and third person while ragdolled. You start in whichever view you were in.", false, false, (ValueValidator)null, (string)null); CameraDistance = val.CreateEntry<float>("CameraDistance", 4f, "Camera distance", "Ragdoll camera distance (meters).", false, false, (ValueValidator)null, (string)null); CameraSensitivity = val.CreateEntry<float>("CameraSensitivity", 0.12f, "Camera sensitivity", "Mouse orbit speed while ragdolled.", false, false, (ValueValidator)null, (string)null); VerboseLogging = val.CreateEntry<bool>("VerboseLogging", false, "Verbose logging", (string)null, false, false, (ValueValidator)null, (string)null); } } public class RagdollMod : MelonMod { private sealed class KeyLookup { private readonly string _setting; private readonly Key _fallback; private string _name; private KeyControl _key; public KeyLookup(string setting, Key fallback) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) _setting = setting; _fallback = fallback; } public KeyControl Get(string name) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) Keyboard current = Keyboard.current; if (current == null) { return null; } name = name ?? ((object)_fallback/*cast due to .constrained prefix*/).ToString(); if (_key != null && _name == name && ((Il2CppObjectBase)((InputControl)_key).device).Pointer == ((Il2CppObjectBase)current).Pointer) { return _key; } _name = name; _key = null; if (!Enum.TryParse<Key>(name.Trim(), ignoreCase: true, out Key result)) { Log.Warning($"Unknown {_setting} '{name}', using {_fallback}."); result = _fallback; } Enumerator<KeyControl> enumerator = current.allKeys.GetEnumerator(); while (enumerator.MoveNext()) { KeyControl current2 = enumerator.Current; if (current2 != null && current2.keyCode == result) { _key = current2; break; } } return _key; } } internal static Instance Log; internal static RagdollConfig Cfg; private bool _inMain; private readonly KeyLookup _toggleKey = new KeyLookup("ToggleKey", (Key)32); private readonly KeyLookup _viewKey = new KeyLookup("ViewKey", (Key)36); public override void OnInitializeMelon() { Log = ((MelonBase)this).LoggerInstance; Cfg = new RagdollConfig(); Log.Msg("Froggos-Ragdoll loaded. Press " + Cfg.ToggleKey.Value + " to go limp, again to get up."); } public override void OnSceneWasInitialized(int buildIndex, string sceneName) { if (sceneName == "Main") { _inMain = true; } } public override void OnSceneWasUnloaded(int buildIndex, string sceneName) { if (!(sceneName != "Main")) { _inMain = false; PlayerRagdoll.Reset(); SkateTuning.Reset(); MotoBail.Reset(); } } public override void OnUpdate() { if (!_inMain) { return; } try { SkateTuning.Tick(); MotoBail.Tick(); KeyControl val = _toggleKey.Get(Cfg.ToggleKey.Value); if (val != null && ((ButtonControl)val).wasPressedThisFrame) { PlayerRagdoll.Toggle(); } KeyControl val2 = _viewKey.Get(Cfg.ViewKey.Value); if (val2 != null && ((ButtonControl)val2).wasPressedThisFrame) { PlayerRagdoll.ToggleView(); } PlayerRagdoll.Tick(); } catch (Exception ex) { Log.Error("Update failed: " + ex); } } public override void OnFixedUpdate() { if (!_inMain) { return; } try { PlayerRagdoll.FixedTick(); } catch (Exception ex) { Log.Error("FixedUpdate failed: " + ex); } } public override void OnLateUpdate() { if (!_inMain) { return; } try { PlayerRagdoll.LateTick(); } catch (Exception ex) { Log.Error("LateUpdate failed: " + ex); } } internal static void Verbose(string msg) { if (Cfg != null && Cfg.VerboseLogging.Value) { Log.Msg("[verbose] " + msg); } } } internal static class SkateTuning { private struct Sample { public float Time; public Vector3 Vel; } private static readonly Dictionary<IntPtr, (float top, float push)> s_base = new Dictionary<IntPtr, (float, float)>(); private static readonly Queue<Sample> s_samples = new Queue<Sample>(); private const float Window = 0.2f; private static float s_extra; public static Skateboard Board { get { try { Player local = Player.Local; return ((Object)(object)local != (Object)null) ? local.ActiveSkateboard : null; } catch { return null; } } } public static Vector3? BoardVelocity { get { //IL_002d: Unknown result type (might be due to invalid IL or missing references) Skateboard board = Board; if ((Object)(object)board == (Object)null || (Object)(object)board.Rb == (Object)null) { return null; } return board.Rb.velocity; } } public static void Tick() { Skateboard board = Board; if ((Object)(object)board == (Object)null || (Object)(object)board.Rb == (Object)null || PlayerRagdoll.Active) { s_samples.Clear(); s_extra = 0f; } else { Boost(board); WatchForCrash(board); } } private static void Boost(Skateboard board) { //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) SkateboardSettings defaultSettings = board.DefaultSettings; SkateboardSettings curentSettings = board.CurentSettings; if (defaultSettings != null && curentSettings != null) { if (!s_base.TryGetValue(((Il2CppObjectBase)defaultSettings).Pointer, out (float, float) value)) { value = (defaultSettings.TopSpeed_Kmh, defaultSettings.PushForceMultiplier); s_base[((Il2CppObjectBase)defaultSettings).Pointer] = value; RagdollMod.Verbose($"Board base: top {value.Item1} km/h, push x{value.Item2}."); } float num = Math.Max(0f, RagdollMod.Cfg.SkateMaxSpeedMultiplier.Value - 1f); float num2 = Math.Max(0f, RagdollMod.Cfg.SkateBuildUpRate.Value); Vector3 velocity = board.Rb.velocity; float num3 = ((Vector3)(ref velocity)).magnitude * 3.6f; float num4 = value.Item1 * (1f + s_extra); if (num3 >= num4 * 0.9f) { s_extra = Math.Min(num, s_extra + num2 * Time.deltaTime); } else if (num3 < num4 * 0.6f) { s_extra = Math.Max(0f, s_extra - num2 * 2f * Time.deltaTime); } s_extra = Math.Min(s_extra, num); float num5 = value.Item1 * (1f + s_extra); float num6 = value.Item2 * Math.Max(0f, RagdollMod.Cfg.SkatePushMultiplier.Value); if (curentSettings.TopSpeed_Kmh != num5) { curentSettings.TopSpeed_Kmh = num5; } if (curentSettings.PushForceMultiplier != num6) { curentSettings.PushForceMultiplier = num6; } } } private static void WatchForCrash(Skateboard board) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) float time = Time.time; Vector3 velocity = board.Rb.velocity; s_samples.Enqueue(new Sample { Time = time, Vel = velocity }); while (s_samples.Count > 0 && time - s_samples.Peek().Time > 0.2f) { s_samples.Dequeue(); } if (!RagdollMod.Cfg.BailOnCrash.Value) { return; } Vector3 velocity2 = Vector3.zero; float num = 0f; foreach (Sample s_sample in s_samples) { float num2 = Flat(s_sample.Vel) * 3.6f; if (num2 > num) { num = num2; velocity2 = s_sample.Vel; } } float num3 = Flat(velocity) * 3.6f; if (num >= RagdollMod.Cfg.BailSpeedKmh.Value && num3 < num * 0.4f) { RagdollMod.Verbose($"Crash: {num:F0} -> {num3:F0} km/h."); s_samples.Clear(); PlayerRagdoll.Start(velocity2); } } private static float Flat(Vector3 v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) return Mathf.Sqrt(v.x * v.x + v.z * v.z); } public static void Reset() { s_samples.Clear(); s_extra = 0f; } } }