Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of Motorcycle Pack v0.1.14
Mods/ScheduleIBikePack.dll
Decompiled 17 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Numerics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using HarmonyLib; using Il2CppFishNet.Object; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppRootMotion; using Il2CppRootMotion.FinalIK; using Il2CppScheduleOne; using Il2CppScheduleOne.AvatarFramework; using Il2CppScheduleOne.AvatarFramework.Animation; using Il2CppScheduleOne.DevUtilities; using Il2CppScheduleOne.Dialogue; using Il2CppScheduleOne.Graffiti; using Il2CppScheduleOne.Interaction; using Il2CppScheduleOne.Map; using Il2CppScheduleOne.Money; using Il2CppScheduleOne.NPCs; using Il2CppScheduleOne.NPCs.CharacterClasses; using Il2CppScheduleOne.Persistence; using Il2CppScheduleOne.PlayerScripts; using Il2CppScheduleOne.UI; using Il2CppScheduleOne.Vehicles; using Il2CppScheduleOne.Vehicles.Modification; using Il2CppScheduleOne.Vehicles.Sound; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Il2CppTMPro; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using ScheduleIBikePack; using UnityEngine; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: MelonInfo(typeof(BikePackMod), "Schedule I Motorcycle Pack", "0.1.14", "nacho", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: MelonPlatformDomain(/*Could not decode attribute arguments.*/)] [assembly: HarmonyDontPatchAll] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("ScheduleIBikePack")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.14.0")] [assembly: AssemblyInformationalVersion("0.1.14+c02009702c06e41397470955ed5c61813b6c6995")] [assembly: AssemblyProduct("ScheduleIBikePack")] [assembly: AssemblyTitle("ScheduleIBikePack")] [assembly: AssemblyVersion("0.1.14.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 ScheduleIBikePack { internal static class BikeArcadeHandling { private const double RadiansPerDegree = Math.PI / 180.0; internal const float UprightThreshold = 0.5736f; internal static float DesiredYawRate(float normalizedInput, float forwardSpeedMs, float wheelbase, float maxSteerDegrees = 32f) { if (!float.IsFinite(normalizedInput) || !ValidGeometry(forwardSpeedMs, wheelbase, maxSteerDegrees)) { return 0f; } double num = Math.Clamp(normalizedInput, -1.0, 1.0); num *= 1.35 - 0.35 * Math.Abs(num); double num2 = Math.Abs((double)forwardSpeedMs); double val = ((num2 <= 8.0) ? 1.65 : ((num2 <= 14.0) ? Lerp(1.65, 1.25, (num2 - 8.0) / 6.0) : ((num2 <= 22.0) ? Lerp(1.25, 0.7, (num2 - 14.0) / 8.0) : ((num2 <= 28.0) ? Lerp(0.7, 0.55, (num2 - 22.0) / 6.0) : 0.55)))); if (forwardSpeedMs < 0f) { val = Math.Min(val, 0.75); } double val2 = num2 * Math.Tan(Math.Clamp(maxSteerDegrees, 0.0, 60.0) * (Math.PI / 180.0)) / (double)wheelbase; return (float)(num * Math.Min(val, val2) * (double)Math.Sign(forwardSpeedMs)); } internal static float ApproachYaw(float currentYawRadians, float targetYawRadians, float deltaTime) { double num = (float.IsFinite(currentYawRadians) ? Math.Clamp(currentYawRadians, -1.65, 1.65) : 0.0); double num2 = (float.IsFinite(targetYawRadians) ? Math.Clamp(targetYawRadians, -1.65, 1.65) : 0.0); if (!float.IsFinite(deltaTime) || deltaTime <= 0f) { return (float)num; } double num3 = ((Math.Abs(num2) < 1E-06) ? 18.0 : 12.25) * Math.Min(deltaTime, 0.1); return (float)(num + Math.Clamp(num2 - num, 0.0 - num3, num3)); } internal static float WheelAngleDegrees(float desiredYawRadians, float normalizedInput, float forwardSpeedMs, float wheelbase, float maxSteerDegrees = 32f) { if (!float.IsFinite(desiredYawRadians) || !float.IsFinite(normalizedInput) || !ValidGeometry(forwardSpeedMs, wheelbase, maxSteerDegrees)) { return 0f; } double num = Math.Clamp(maxSteerDegrees, 0.0, 60.0); if (Math.Abs(forwardSpeedMs) <= 0.4f) { return (float)(Math.Clamp(normalizedInput, -1.0, 1.0) * num); } return (float)Math.Clamp(Math.Atan((double)desiredYawRadians * (double)wheelbase / (double)forwardSpeedMs) / (Math.PI / 180.0), 0.0 - num, num); } internal static float ApproachWheel(float currentDegrees, float targetDegrees, float deltaTime) { double num = (float.IsFinite(currentDegrees) ? Math.Clamp(currentDegrees, -60.0, 60.0) : 0.0); double num2 = (float.IsFinite(targetDegrees) ? Math.Clamp(targetDegrees, -60.0, 60.0) : 0.0); if (!float.IsFinite(deltaTime) || deltaTime <= 0f) { return (float)num; } double num3 = 240.0 * Math.Min(deltaTime, 0.1); return (float)(num + Math.Clamp(num2 - num, 0.0 - num3, num3)); } internal static float ApproachContact(float currentWeight, bool supported, float deltaTime) { if (!supported) { return 0f; } double num = (float.IsFinite(currentWeight) ? Math.Clamp(currentWeight, 0.0, 1.0) : 0.0); if (!float.IsFinite(deltaTime) || deltaTime <= 0f) { return (float)num; } return (float)Math.Min(1.0, num + Math.Min(deltaTime, 0.1) / 0.1); } internal static float SupportWeight(float forwardSpeedMs, float upDot, bool bothGrounded, bool inputActive, bool collisionBlocked, float contactWeight) { if (!bothGrounded || !inputActive || collisionBlocked || !float.IsFinite(forwardSpeedMs) || !float.IsFinite(upDot) || upDot <= 0.5736f || !float.IsFinite(contactWeight)) { return 0f; } double num = Math.Clamp((Math.Abs((double)forwardSpeedMs) - 0.4) / 1.1, 0.0, 1.0); num *= num * (3.0 - 2.0 * num); return (float)(num * Math.Clamp(contactWeight, 0.0, 1.0)); } internal static float YawAcceleration(float desiredYawRadians, float actualYawRadians, float normalizedInput, float supportWeight) { if (!float.IsFinite(desiredYawRadians) || !float.IsFinite(actualYawRadians) || !float.IsFinite(normalizedInput) || !float.IsFinite(supportWeight)) { return 0f; } bool num = Math.Abs(normalizedInput) < 1E-06f; double num2 = 22.0; double num3 = (num ? 16.0 : 12.0); return (float)(Math.Clamp(((double)desiredYawRadians - (double)actualYawRadians) * num2, 0.0 - num3, num3) * Math.Clamp(supportWeight, 0.0, 1.0)); } internal static float SideAcceleration(float sideSpeedMs, float supportWeight, float deltaTime) { if (!float.IsFinite(sideSpeedMs) || !float.IsFinite(supportWeight) || !float.IsFinite(deltaTime) || deltaTime <= 0f) { return 0f; } double value = Math.Clamp((0.0 - (double)sideSpeedMs) * 8.0, -10.0, 10.0) * Math.Clamp(supportWeight, 0.0, 1.0); double num = Math.Abs((double)sideSpeedMs) / (double)deltaTime; return (float)Math.Clamp(value, 0.0 - num, num); } internal static float TargetRollRadians(float forwardSpeedMs, float desiredYawRadians, float gravity = 9.81f) { if (!float.IsFinite(forwardSpeedMs) || !float.IsFinite(desiredYawRadians) || !float.IsFinite(gravity) || gravity <= 0.1f) { return 0f; } double num = Math.Clamp(((double)forwardSpeedMs - 0.75) / 2.25, 0.0, 1.0); num *= num * (3.0 - 2.0 * num); return (float)(Math.Clamp(0.0 - Math.Atan((double)forwardSpeedMs * (double)desiredYawRadians / (double)gravity), Math.PI * -2.0 / 9.0, Math.PI * 2.0 / 9.0) * num); } internal static bool HardCollision(float impulsePerMass) { if (float.IsFinite(impulsePerMass)) { return impulsePerMass > 2f; } return false; } private static bool ValidGeometry(float speedMs, float wheelbase, float maxSteerDegrees) { if (float.IsFinite(speedMs) && float.IsFinite(wheelbase) && wheelbase > 0.1f && float.IsFinite(maxSteerDegrees)) { return maxSteerDegrees > 0f; } return false; } private static double Lerp(double from, double to, double fraction) { return from + (to - from) * Math.Clamp(fraction, 0.0, 1.0); } } internal static class BikeBalance { private const double DegreesToRadians = Math.PI / 180.0; internal static float BodyCenterHeight(bool isMotorcycle) { if (!isMotorcycle) { return 0.63f; } return 0.74f; } internal static float TargetRollRadians(float forwardSpeedMs, float steerDegrees, float wheelbase, float maxLeanDegrees, bool riding, float gravity = 9.81f) { if (!riding || !float.IsFinite(forwardSpeedMs) || !float.IsFinite(steerDegrees) || !float.IsFinite(wheelbase) || wheelbase <= 0.1f || !float.IsFinite(maxLeanDegrees) || maxLeanDegrees <= 0f || !float.IsFinite(gravity) || gravity <= 0.1f) { return 0f; } double num = Math.Clamp(((double)forwardSpeedMs - 0.75) / 2.25, 0.0, 1.0); num *= num * (3.0 - 2.0 * num); if (num <= 0.0) { return 0f; } double a = Math.Clamp(steerDegrees, -60.0, 60.0) * (Math.PI / 180.0); double num2 = (double)forwardSpeedMs * (double)forwardSpeedMs * Math.Tan(a) / (double)wheelbase; double num3 = Math.Clamp(maxLeanDegrees, 0.0, 45.0) * (Math.PI / 180.0); return (float)(Math.Clamp(0.0 - Math.Atan(num2 / (double)gravity), 0.0 - num3, num3) * num); } internal static float ApproachRoll(float currentRadians, float targetRadians, float deltaTime) { if (!float.IsFinite(currentRadians)) { currentRadians = 0f; } if (!float.IsFinite(targetRadians)) { targetRadians = 0f; } if (!float.IsFinite(deltaTime) || deltaTime <= 0f) { return currentRadians; } float num = 1.8f * Math.Clamp(deltaTime, 0f, 0.1f); return currentRadians + Math.Clamp(targetRadians - currentRadians, 0f - num, num); } internal static float RollAcceleration(float errorRadians, float rollVelocityRadians) { if (!float.IsFinite(errorRadians) || !float.IsFinite(rollVelocityRadians)) { return 0f; } return (float)Math.Clamp((double)errorRadians * 85.0 - (double)rollVelocityRadians * 16.0, -100.0, 100.0); } internal static float WheelForcePointDistance(float wheelCenterHeight, float radius, float suspensionDistance, float springTarget, float massHeight = 0.48f, float belowMass = 0.08f) { if (!float.IsFinite(wheelCenterHeight) || !float.IsFinite(radius) || radius <= 0f || !float.IsFinite(suspensionDistance) || suspensionDistance < 0f || !float.IsFinite(springTarget) || !float.IsFinite(massHeight) || !float.IsFinite(belowMass) || belowMass < 0f) { return 0.4f; } float num = wheelCenterHeight - radius - suspensionDistance * (1f - Math.Clamp(springTarget, 0f, 1f)); return Math.Max(0f, massHeight - num - belowMass); } internal static float PitchAcceleration(float errorRadians, float pitchVelocityRadians, float forwardSpeedMs, float brakeEffort, bool groundSupported) { if (!groundSupported || !float.IsFinite(errorRadians) || !float.IsFinite(pitchVelocityRadians) || !float.IsFinite(forwardSpeedMs) || !float.IsFinite(brakeEffort)) { return 0f; } double num = Math.Clamp((3.0 - (double)Math.Abs(forwardSpeedMs)) / 2.0, 0.0, 1.0); num *= num * (3.0 - 2.0 * num); double num2 = Math.Max(Math.Clamp(brakeEffort, 0.0, 1.0), num); return (float)(Math.Clamp(Math.Clamp(errorRadians, -0.35, 0.35) * 45.0 - (double)pitchVelocityRadians * 10.0, -14.0, 14.0) * num2); } } internal sealed record BikeSpec(string Id, string Name, bool IsMotorcycle, bool IsOffroad, float Price, float TopSpeed, float Mass, float Acceleration, Color Color) { public bool IsCruiser => Id == "s1_cruiser_motorcycle"; public MotorcycleGeometry.Style MotorcycleStyle { get { if (!IsCruiser) { if (!IsOffroad) { return MotorcycleGeometry.Style.Sport; } return MotorcycleGeometry.Style.Enduro; } return MotorcycleGeometry.Style.Cruiser; } } public float WheelRadius { get { if (!IsMotorcycle) { return 0.34f; } return 0.33f; } } public float Wheelbase { get { if (!IsMotorcycle) { return 1.08f; } if (!IsCruiser) { if (!IsOffroad) { return 1.43f; } return 1.48f; } return 1.65f; } } public float Suspension { get { if (!IsOffroad) { return 0.12f; } return 0.24f; } } public float SeatHeight { get { if (!IsMotorcycle) { return 0.91f; } if (!IsCruiser) { if (!IsOffroad) { return 0.83f; } return 0.94f; } return 0.8f; } } public string Description { get { if (!IsCruiser) { if (!IsOffroad) { return "Firm suspension and higher speed for paved streets."; } return "Soft suspension and wide tires for rough ground."; } return "A relaxed chrome V-twin cruiser for the open road."; } } } internal static class BikeCatalog { public static readonly BikeSpec[] All = new BikeSpec[3] { new BikeSpec("s1_offroad_motorcycle", "Maduro", IsMotorcycle: true, IsOffroad: true, 6500f, 70f, 220f, 5.5f, new Color(0.93f, 0.39f, 0.08f)), new BikeSpec("s1_street_motorcycle", "Tucati", IsMotorcycle: true, IsOffroad: false, 11000f, 100f, 260f, 7f, new Color(0.72f, 0.12f, 0.16f)), new BikeSpec("s1_cruiser_motorcycle", "Marley Hutchinson", IsMotorcycle: true, IsOffroad: false, 9000f, 85f, 300f, 5.4f, new Color(0.035f, 0.04f, 0.045f)) }; private static readonly BikeSpec[] Legacy = new BikeSpec[2] { new BikeSpec("s1_offroad_bicycle", "Off-road Bicycle", IsMotorcycle: false, IsOffroad: true, 650f, 28f, 100f, 2.6f, new Color(0.19f, 0.56f, 0.27f)), new BikeSpec("s1_street_bicycle", "Street Bicycle", IsMotorcycle: false, IsOffroad: false, 900f, 36f, 95f, 2.9f, new Color(0.13f, 0.46f, 0.78f)) }; public static BikeSpec? Find(string? id) { return Array.Find(All, (BikeSpec x) => x.Id == id) ?? Array.Find(Legacy, (BikeSpec x) => x.Id == id); } } internal static class BikeCornering { private const double RadiansPerDegree = Math.PI / 180.0; private const double LeanReserveDegrees = 3.0; private const double LateralJerk = 24.0; private const double SteeringSlewDegrees = 90.0; internal static float MaxLeanDegrees(bool isMotorcycle) { if (!isMotorcycle) { return 25f; } return 45f; } internal static float SteeringLimit(float speedMs, float wheelbase, float maxSteerDegrees, float maxLeanDegrees, float gravity = 9.81f) { if (!ValidGeometry(speedMs, wheelbase, maxSteerDegrees, maxLeanDegrees) || !float.IsFinite(gravity) || gravity <= 0.1f) { return 0f; } double num = Math.Clamp(maxSteerDegrees, 0.0, 60.0); double num2 = (double)speedMs * (double)speedMs; if (num2 == 0.0) { return (float)num; } double a = (Math.Clamp(maxLeanDegrees, 0.0, 45.0) - 3.0) * (Math.PI / 180.0); double val = Math.Atan((double)gravity * Math.Tan(a) * (double)wheelbase / num2) / (Math.PI / 180.0); return (float)Math.Min(num, val); } internal static float TargetSteer(float nativeSteerDegrees, float maxSteerDegrees, float speedMs, float wheelbase, float maxLeanDegrees) { if (!float.IsFinite(nativeSteerDegrees) || !float.IsFinite(maxSteerDegrees) || maxSteerDegrees <= 0f) { return 0f; } return (float)(Math.Clamp((double)nativeSteerDegrees / (double)maxSteerDegrees, -1.0, 1.0) * (double)SteeringLimit(speedMs, wheelbase, maxSteerDegrees, maxLeanDegrees)); } internal static float ApproachSteer(float currentSteerDegrees, float targetSteerDegrees, float speedMs, float wheelbase, float maxSteerDegrees, float maxLeanDegrees, float deltaTime) { double num = SteeringLimit(speedMs, wheelbase, maxSteerDegrees, maxLeanDegrees); double num2 = (float.IsFinite(currentSteerDegrees) ? Math.Clamp(currentSteerDegrees, 0.0 - num, num) : 0.0); double num3 = (float.IsFinite(targetSteerDegrees) ? Math.Clamp(targetSteerDegrees, 0.0 - num, num) : 0.0); if (!float.IsFinite(deltaTime) || deltaTime <= 0f || num == 0.0) { return (float)num2; } double num4 = Math.Min(deltaTime, 0.1); double num5 = num3; double num6 = (double)speedMs * (double)speedMs; if (num6 > 0.0) { double num7 = num6 * Math.Tan(num2 * (Math.PI / 180.0)) / (double)wheelbase; double num8 = num6 * Math.Tan(num3 * (Math.PI / 180.0)) / (double)wheelbase; num5 = Math.Atan((num7 + Math.Clamp(num8 - num7, -24.0 * num4, 24.0 * num4)) * (double)wheelbase / num6) / (Math.PI / 180.0); } double num9 = 90.0 * num4; return (float)(num2 + Math.Clamp(num5 - num2, 0.0 - num9, num9)); } private static bool ValidGeometry(float speedMs, float wheelbase, float maxSteerDegrees, float maxLeanDegrees) { if (float.IsFinite(speedMs) && float.IsFinite(wheelbase) && wheelbase > 0.1f && float.IsFinite(maxSteerDegrees) && maxSteerDegrees > 0f && float.IsFinite(maxLeanDegrees)) { return (double)maxLeanDegrees > 3.0; } return false; } } internal sealed class BikeCrashPolicy { internal const float ImpactDeltaSpeed = 5f; internal const float MinimumImpactSpeed = 5f; internal const float FallRollDegrees = 65f; internal const float FallDuration = 0.3f; internal const float MountGraceDuration = 0.85f; internal const float RecoverySpeedSquared = 6.25f; public bool Fallen { get; private set; } public bool CrashPending { get; private set; } public bool ExitBlocked { get; private set; } public float GraceRemaining { get; private set; } public float SideFallTime { get; private set; } public void Mounted() { Fallen = false; CrashPending = false; ExitBlocked = false; SideFallTime = 0f; GraceRemaining = 0.85f; } public void Recovered() { Fallen = false; CrashPending = false; ExitBlocked = false; SideFallTime = 0f; GraceRemaining = 0.85f; } public void ObserveParked(float sideRollDegrees, bool owned, bool occupied) { if (owned && !occupied && float.IsFinite(sideRollDegrees) && MathF.Abs(sideRollDegrees) >= 65f) { Fallen = true; } } public bool ObserveImpact(float deltaSpeed, float impactSpeed, bool eligible) { if (!eligible || Fallen || CrashPending || ExitBlocked || GraceRemaining > 0f || !float.IsFinite(deltaSpeed) || !float.IsFinite(impactSpeed) || deltaSpeed < 5f || impactSpeed < 5f) { return false; } QueueCrash(); return true; } public bool ObserveSideFall(float sideRollDegrees, bool supported, bool eligible, float dt) { if (!float.IsFinite(dt) || dt <= 0f) { return false; } dt = MathF.Min(dt, 0.05f); GraceRemaining = MathF.Max(0f, GraceRemaining - dt); if (ExitBlocked && float.IsFinite(sideRollDegrees) && MathF.Abs(sideRollDegrees) < 45f) { ExitBlocked = false; } if (!eligible || Fallen || CrashPending || GraceRemaining > 0f || ExitBlocked || !float.IsFinite(sideRollDegrees) || MathF.Abs(sideRollDegrees) < 65f) { SideFallTime = 0f; return false; } SideFallTime += dt; if (SideFallTime < 0.29999f) { return false; } QueueCrash(); return true; } public void CompleteCrash(bool dismounted) { CrashPending = false; SideFallTime = 0f; Fallen = dismounted; ExitBlocked = !dismounted; if (!dismounted) { GraceRemaining = 0.85f; } } private void QueueCrash() { CrashPending = true; Fallen = true; SideFallTime = 0f; } public static bool CanRecover(float speedSquared) { if (float.IsFinite(speedSquared) && speedSquared >= 0f) { return speedSquared <= 6.25f; } return false; } public static bool CanPickUp(float speedSquared) { if (float.IsFinite(speedSquared) && speedSquared >= 0f) { return speedSquared <= 0.25f; } return false; } } internal static class BikeExitSafety { private sealed record CapsuleShape(Vector3 CenterOffset, float Height, float Radius, float Padding, float MinNormalY); private sealed record MountState(CapsuleShape Shape, Vector3? WalkingPosition, Quaternion WalkingRotation); private sealed record ExitState(GameObject Point, int PlayerId, int VehicleId, float CreatedAt) { public bool Cleaned; } private static readonly Dictionary<int, MountState> mounts = new Dictionary<int, MountState>(); private static readonly Dictionary<int, ExitState> preparedExits = new Dictionary<int, ExitState>(); private static bool preflighting; private static int failures; public static void Initialize(Harmony harmony) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_0068: 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_0088: 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_00a9: Expected O, but got Unknown //IL_00a9: Expected O, but got Unknown //IL_00a9: Expected O, but got Unknown //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Expected O, but got Unknown //IL_0112: Expected O, but got Unknown //IL_0112: Expected O, but got Unknown harmony.Patch((MethodBase)AccessTools.Method(typeof(Player), "EnterVehicle", (Type[])null, (Type[])null), new HarmonyMethod(typeof(BikeExitSafety), "BeforeEnter", (Type[])null) { priority = 800 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(LandVehicle), "ExitVehicle", (Type[])null, (Type[])null), new HarmonyMethod(typeof(BikeExitSafety), "BeforeExitRequest", (Type[])null) { priority = 800 }, new HarmonyMethod(typeof(BikeExitSafety), "AfterExitRequest", (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(BikeExitSafety), "FinalizeExitRequest", (Type[])null), (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(Player), "ExitVehicle", (Type[])null, (Type[])null), new HarmonyMethod(typeof(BikeExitSafety), "BeforeExit", (Type[])null) { priority = 800 }, new HarmonyMethod(typeof(BikeExitSafety), "AfterExit", (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(BikeExitSafety), "FinalizeExit", (Type[])null), (HarmonyMethod)null); } private static void BeforeEnter(Player __instance, LandVehicle vehicle) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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_0086: 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_0078: 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) if ((Object)(object)__instance == (Object)null || (Object)(object)vehicle == (Object)null || BikeCatalog.Find(vehicle.vehicleCode) == null) { return; } try { CapsuleShape shape = GetShape(__instance); Quaternion val = Upright(((Component)__instance).transform.rotation); ReleasePrepared(((Object)__instance).GetInstanceID()); Vector3? walkingPosition = null; Vector3 candidate = FeetReference(((Component)__instance).transform.position, val, shape, includesPadding: false); if (TryPlace(__instance, vehicle, candidate, val, shape, out var pivot) || TryPlace(__instance, vehicle, candidate, val, shape, out pivot, checkClearance: false)) { walkingPosition = pivot; } mounts[((Object)__instance).GetInstanceID()] = new MountState(shape, walkingPosition, val); } catch (Exception ex) { Report("Capturing the walking position", ex); } } private static bool BeforeExitRequest(LandVehicle __instance) { Player local = Player.Local; if ((Object)(object)__instance == (Object)null || BikeCatalog.Find(__instance.vehicleCode) == null || (Object)(object)local == (Object)null || (Object)(object)local.CurrentVehicle == (Object)null || (Object)(object)((Component)local.CurrentVehicle).GetComponent<LandVehicle>() != (Object)(object)__instance) { return true; } ReleasePrepared(((Object)local).GetInstanceID()); preflighting = true; try { Transform exitPoint = __instance.closestExitPoint ?? ((Component)__instance).transform; ExitState __state; bool num = BeforeExit(local, ref exitPoint, out __state); if (num && __state != null) { preparedExits[((Object)local).GetInstanceID()] = __state; } return num; } finally { preflighting = false; } } private static bool BeforeExit(Player __instance, ref Transform exitPoint, out ExitState? __state) { //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: 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_011c: 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_012b: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: 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_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0159: 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_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0144: 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_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0245: 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) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_04ca: Unknown result type (might be due to invalid IL or missing references) //IL_04d1: Expected O, but got Unknown //IL_04e3: Unknown result type (might be due to invalid IL or missing references) //IL_04f4: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_034c: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Unknown result type (might be due to invalid IL or missing references) //IL_0361: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_0381: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_03e9: Unknown result type (might be due to invalid IL or missing references) //IL_03ed: Unknown result type (might be due to invalid IL or missing references) //IL_03f5: Unknown result type (might be due to invalid IL or missing references) //IL_03fa: Unknown result type (might be due to invalid IL or missing references) //IL_040b: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_0414: Unknown result type (might be due to invalid IL or missing references) //IL_0416: Unknown result type (might be due to invalid IL or missing references) //IL_04a7: Unknown result type (might be due to invalid IL or missing references) //IL_0470: Unknown result type (might be due to invalid IL or missing references) //IL_0475: Unknown result type (might be due to invalid IL or missing references) //IL_047a: Unknown result type (might be due to invalid IL or missing references) //IL_047f: Unknown result type (might be due to invalid IL or missing references) //IL_0424: Unknown result type (might be due to invalid IL or missing references) //IL_048f: Unknown result type (might be due to invalid IL or missing references) __state = null; if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.CurrentVehicle == (Object)null) { return true; } LandVehicle component = ((Component)__instance.CurrentVehicle).GetComponent<LandVehicle>(); if ((Object)(object)component == (Object)null || BikeCatalog.Find(component.vehicleCode) == null) { return true; } try { int instanceID = ((Object)__instance).GetInstanceID(); if (preparedExits.TryGetValue(instanceID, out ExitState value)) { preparedExits.Remove(instanceID); if (!value.Cleaned && (Object)(object)value.Point != (Object)null && value.VehicleId == ((Object)component).GetInstanceID() && Time.unscaledTime - value.CreatedAt < 3f) { exitPoint = value.Point.transform; __state = value; return true; } ReleasePoint(value); } mounts.TryGetValue(instanceID, out MountState value2); CapsuleShape shape = value2?.Shape ?? GetShape(__instance); Quaternion val = Upright(((Object)(object)exitPoint != (Object)null) ? exitPoint.rotation : ((Component)component).transform.rotation); Vector3 position = ((Component)component).transform.position; Vector3 val2 = Vector3.ProjectOnPlane(((Component)component).transform.forward, Vector3.up); Vector3 val3 = ((Vector3)(ref val2)).normalized; if (((Vector3)(ref val3)).sqrMagnitude < 0.5f) { val3 = val * Vector3.forward; } val2 = Vector3.Cross(Vector3.up, val3); Vector3 normalized = ((Vector3)(ref val2)).normalized; List<Vector3> list = new List<Vector3>(); if ((Object)(object)exitPoint != (Object)null) { Vector3 position2 = exitPoint.position; position2.y = position.y; list.Add(position2); } float[] array = new float[4] { 1.05f, 1.6f, 2.3f, 3.1f }; foreach (float num in array) { list.Add(position + normalized * num); list.Add(position - normalized * num); list.Add(position + val3 * num); list.Add(position - val3 * num); val2 = normalized + val3; list.Add(position + ((Vector3)(ref val2)).normalized * num); val2 = normalized - val3; list.Add(position + ((Vector3)(ref val2)).normalized * num); val2 = -normalized + val3; list.Add(position + ((Vector3)(ref val2)).normalized * num); val2 = normalized + val3; list.Add(position - ((Vector3)(ref val2)).normalized * num); } Vector3? val4 = null; foreach (Vector3 item in list) { if (TryPlace(__instance, component, item, val, shape, out var pivot)) { val4 = pivot; break; } } if (!val4.HasValue) { Vector3? val5 = value2?.WalkingPosition; if (val5.HasValue) { Vector3 valueOrDefault = val5.GetValueOrDefault(); if (TryPlace(__instance, component, FeetReference(valueOrDefault, value2.WalkingRotation, shape, includesPadding: true), value2.WalkingRotation, shape, out var pivot2)) { val4 = pivot2; val = value2.WalkingRotation; MelonLogger.Msg("Bike dismount used the last safe walking position because nearby ground was unavailable."); } } } if (!val4.HasValue) { if (preflighting) { if (failures++ < 3) { MelonLogger.Warning("Bike dismount stayed mounted: no clear, supported standing position was found nearby."); } return false; } Vector3? val5 = value2?.WalkingPosition; if (val5.HasValue) { Vector3 valueOrDefault2 = val5.GetValueOrDefault(); val4 = valueOrDefault2; val = value2.WalkingRotation; } else { foreach (Vector3 item2 in list) { if (TryPlace(__instance, component, item2, val, shape, out var pivot3, checkClearance: false)) { val4 = pivot3; break; } } } if (!val4.HasValue) { GameObject val6 = GameObject.Find("/Map/Teleport Locations/Dealership"); if ((Object)(object)val6 != (Object)null && TryPlace(__instance, component, FeetReference(val6.transform.position, val, shape, includesPadding: false), val, shape, out var pivot4, checkClearance: false)) { val4 = pivot4; } } if (!val4.HasValue) { val4 = ((Component)__instance).transform.position; Report("Forced exit had no remaining map ground; native state restoration will complete", new InvalidOperationException("No ground colliders or captured walking position remain.")); } } GameObject val7 = new GameObject("BikePack_GroundedExit"); ((Object)val7).hideFlags = (HideFlags)61; val7.transform.position = val4.Value; val7.transform.rotation = val; exitPoint = val7.transform; __state = new ExitState(val7, instanceID, ((Object)component).GetInstanceID(), Time.unscaledTime); return true; } catch (Exception ex) { Report("Choosing safe dismount ground", ex); return !preflighting; } } private static CapsuleShape GetShape(Player player) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_002b: 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_003c: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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_0071: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: 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_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) CharacterController characterController = player.CharacterController; Vector3 centerOffset; float num3; float num4; float num2; float num; if ((Object)(object)characterController != (Object)null) { Vector3 lossyScale = ((Component)characterController).transform.lossyScale; centerOffset = Quaternion.Inverse(((Component)player).transform.rotation) * (((Component)characterController).transform.TransformPoint(characterController.center) - ((Component)player).transform.position); num = characterController.height * Mathf.Abs(lossyScale.y); num2 = characterController.radius * Mathf.Max(Mathf.Abs(lossyScale.x), Mathf.Abs(lossyScale.z)); num3 = characterController.skinWidth; num4 = characterController.slopeLimit; float num5 = Mathf.Max(num, PlayerMovement.DefaultCharacterControllerHeight * Mathf.Abs(lossyScale.y)); centerOffset.y += (num5 - num) * 0.5f; num = num5; } else if ((Object)(object)player.CapCol != (Object)null) { CapsuleCollider capCol = player.CapCol; Vector3 lossyScale2 = ((Component)capCol).transform.lossyScale; centerOffset = Quaternion.Inverse(((Component)player).transform.rotation) * (((Component)capCol).transform.TransformPoint(capCol.center) - ((Component)player).transform.position); num = capCol.height * Mathf.Abs(lossyScale2.y); num2 = capCol.radius * Mathf.Max(Mathf.Abs(lossyScale2.x), Mathf.Abs(lossyScale2.z)); num3 = 0.04f; num4 = 50f; } else { centerOffset = Vector3.zero; num = 1.85f; num2 = 0.35f; num3 = 0.04f; num4 = 55f; } num2 = Mathf.Clamp(num2, 0.15f, 0.7f); num = Mathf.Max(num, num2 * 2f); return new CapsuleShape(centerOffset, num, num2, Mathf.Max(0.025f, num3) + 0.025f, Mathf.Cos(Mathf.Clamp(num4, 10f, 55f) * ((float)Math.PI / 180f))); } private static bool TryPlace(Player player, LandVehicle bike, Vector3 candidate, Quaternion rotation, CapsuleShape shape, out Vector3 pivot, bool checkClearance = true) { //IL_0002: 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_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_0046: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_009c: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: 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_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014f: 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_0159: 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_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: 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_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019e: 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_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) pivot = candidate; if (!IsFinite(candidate) || !Ground(player, bike, candidate, shape.MinNormalY, out var ground)) { return false; } float num = shape.Radius * 0.55f; Vector3[] array = (Vector3[])(object)new Vector3[4] { Vector3.right * num, Vector3.left * num, Vector3.forward * num, Vector3.back * num }; foreach (Vector3 val in array) { if (!Ground(player, bike, ((RaycastHit)(ref ground)).point + val + Vector3.up * 0.15f, shape.MinNormalY, out var ground2) || Mathf.Abs(((RaycastHit)(ref ground2)).point.y - ((RaycastHit)(ref ground)).point.y) > 0.3f) { return false; } } Vector3 val2 = rotation * shape.CenterOffset; float num2 = shape.Radius * (1f / Mathf.Max(0.5f, ((RaycastHit)(ref ground)).normal.y) - 1f); pivot = ((RaycastHit)(ref ground)).point - new Vector3(val2.x, 0f, val2.z) + Vector3.up * (shape.Height * 0.5f - val2.y + shape.Padding + num2); if (!checkClearance) { return true; } Vector3 val3 = pivot + val2; Vector3 val4 = Vector3.up * (shape.Height * 0.5f - shape.Radius); foreach (Collider item in (Il2CppArrayBase<Collider>)(object)Physics.OverlapCapsule(val3 - val4, val3 + val4, shape.Radius * 0.98f, -1, (QueryTriggerInteraction)1)) { if ((Object)(object)item != (Object)null && !BelongsToPlayer(item, player)) { return false; } } return true; } private static bool Ground(Player player, LandVehicle bike, Vector3 approximate, float minNormalY, out RaycastHit ground) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //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) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_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_0067: 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00be: 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) ground = default(RaycastHit); float num = float.PositiveInfinity; foreach (RaycastHit item in (Il2CppArrayBase<RaycastHit>)(object)Physics.RaycastAll(approximate + Vector3.up * 2.5f, Vector3.down, 12f, -1, (QueryTriggerInteraction)1)) { RaycastHit current = item; Collider collider = ((RaycastHit)(ref current)).collider; if (!((Object)(object)collider == (Object)null) && !((Object)(object)collider.attachedRigidbody != (Object)null) && !(((RaycastHit)(ref current)).normal.y < minNormalY) && !(((RaycastHit)(ref current)).point.y > approximate.y + 0.4f) && !((Component)collider).transform.IsChildOf(((Component)bike).transform) && !BelongsToPlayer(collider, player) && !(((RaycastHit)(ref current)).distance >= num)) { num = ((RaycastHit)(ref current)).distance; ground = current; } } return !float.IsPositiveInfinity(num); } private static bool BelongsToPlayer(Collider collider, Player player) { if (!((Component)collider).transform.IsChildOf(((Component)player).transform) && (!((Object)(object)player.Avatar != (Object)null) || !((Component)collider).transform.IsChildOf(((Component)player.Avatar).transform)) && !((Object)(object)collider == (Object)(object)player.CharacterController)) { return (Object)(object)collider == (Object)(object)player.CapCol; } return true; } private static Quaternion Upright(Quaternion rotation) { //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_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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) //IL_0039: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Vector3.ProjectOnPlane(rotation * Vector3.forward, Vector3.up); Vector3 normalized = ((Vector3)(ref val)).normalized; return Quaternion.LookRotation((((Vector3)(ref normalized)).sqrMagnitude > 0.5f) ? normalized : Vector3.forward, Vector3.up); } private static bool IsFinite(Vector3 point) { //IL_0000: 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_001a: Unknown result type (might be due to invalid IL or missing references) if (float.IsFinite(point.x) && float.IsFinite(point.y)) { return float.IsFinite(point.z); } return false; } private static Vector3 FeetReference(Vector3 pivot, Quaternion rotation, CapsuleShape shape, bool includesPadding) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) pivot.y -= shape.Height * 0.5f - (rotation * shape.CenterOffset).y + (includesPadding ? shape.Padding : 0f); return pivot; } private static void AfterExitRequest(LandVehicle __instance) { KeyValuePair<int, ExitState>[] array = preparedExits.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair<int, ExitState> keyValuePair = array[i]; if (keyValuePair.Value.VehicleId == ((Object)__instance).GetInstanceID()) { ReleasePrepared(keyValuePair.Key); } } } private static Exception? FinalizeExitRequest(LandVehicle __instance, Exception? __exception) { AfterExitRequest(__instance); return __exception; } private static void ReleasePrepared(int id) { if (preparedExits.Remove(id, out ExitState value)) { ReleasePoint(value); } } private static void ReleasePoint(ExitState state) { if (!state.Cleaned) { state.Cleaned = true; if ((Object)(object)state.Point != (Object)null) { Object.Destroy((Object)(object)state.Point); } } } private static void AfterExit(ExitState? __state) { Cleanup(__state); } private static Exception? FinalizeExit(Exception? __exception, ExitState? __state) { Cleanup(__state); return __exception; } private static void Cleanup(ExitState? state) { if (!(state == null) && !state.Cleaned) { ReleasePoint(state); mounts.Remove(state.PlayerId); } } private static void Report(string context, Exception ex) { if (failures++ < 3) { MelonLogger.Warning($"Bike exit safety: {context}: {ex}"); } } public static void Reset() { foreach (ExitState value in preparedExits.Values) { ReleasePoint(value); } preparedExits.Clear(); mounts.Clear(); preflighting = false; failures = 0; } } internal static class BikeHandling { internal readonly record struct Drive(float Throttle, bool Brake); internal readonly record struct Brakes(float FrontTorque, float RearTorque); internal static Brakes BrakeTorques(float mass, float radius, float effort, bool motorcycle) { if (!float.IsFinite(mass) || mass <= 0f || !float.IsFinite(radius) || radius <= 0f || !float.IsFinite(effort)) { return default(Brakes); } float num = mass * (motorcycle ? 9.5f : 7f) * radius * Math.Clamp(effort, 0f, 1f); if (!float.IsFinite(num)) { return default(Brakes); } float num2 = num * (motorcycle ? 0.6f : 0.5f); return new Brakes(num2, num - num2); } internal static float LongitudinalSlipRetention(bool motorcycle) { if (!motorcycle) { return 0.6f; } return 0.75f; } internal static float ApproachBrake(float currentEffort, bool braking, float deltaTime) { if (!float.IsFinite(currentEffort)) { currentEffort = 0f; } currentEffort = Math.Clamp(currentEffort, 0f, 1f); if (!float.IsFinite(deltaTime) || deltaTime <= 0f) { return currentEffort; } float num = Math.Clamp(deltaTime, 0f, 0.1f) / (braking ? 0.18f : 0.075f); if (!braking) { return Math.Max(0f, currentEffort - num); } return Math.Min(1f, currentEffort + num); } public static Drive Calculate(float input, float forwardSpeedMs, float topSpeedKmh, bool occupied, bool handbrake) { input = Math.Clamp(input, -1f, 1f); bool flag = Math.Abs(forwardSpeedMs) > 0.5f && Math.Abs(input) > 0.05f && Math.Sign(forwardSpeedMs) != Math.Sign(input); if (!occupied || handbrake || flag) { return new Drive(0f, Brake: true); } float num = ((input < 0f) ? 7f : topSpeedKmh) / 3.6f; float num2 = forwardSpeedMs * (float)Math.Sign(input); return new Drive(input * Math.Clamp((num - num2) / 2f, 0f, 1f), Brake: false); } } internal static class BikeLightPolicy { internal readonly record struct Output(bool HeadOn, bool TailOn, float HeadEmission, float TailEmission, float RearIntensity); internal const float HeadlightDistance = 80f; internal const float TailLightDistance = 55f; internal const float HeadEmission = 2.2f; internal const float TailEmission = 0.7f; internal const float BrakeEmission = 3.2f; internal static Output Calculate(bool headlights, bool brakes, bool visible, bool rearInRange) { bool flag = headlights && visible; bool flag2 = (headlights || brakes) && visible; return new Output(flag, flag2 && rearInRange, flag ? 2.2f : 0f, (!flag2) ? 0f : (brakes ? 3.2f : 0.7f), (!flag2 || !rearInRange) ? 0f : (brakes ? 1.6f : 0.25f)); } internal static Vector3 HeadAnchor(IReadOnlyList<Vector3> vertices, int side) { return LensAnchor(vertices, side, forward: true); } internal static Vector3 RearAnchor(IReadOnlyList<Vector3> vertices) { return LensAnchor(vertices, 0, forward: false); } private static Vector3 LensAnchor(IReadOnlyList<Vector3> vertices, int side, bool forward) { if (vertices.Count == 0) { throw new ArgumentException("A bike light lens has no vertices."); } float num = (forward ? float.NegativeInfinity : float.PositiveInfinity); foreach (Vector3 vertex in vertices) { if (Finite(vertex) && OnSide(vertex, side)) { num = (forward ? MathF.Max(num, vertex.Z) : MathF.Min(num, vertex.Z)); } } if (!float.IsFinite(num)) { throw new ArgumentException("A bike light lens has no valid face."); } Vector3 vector = new Vector3(float.PositiveInfinity); Vector3 vector2 = new Vector3(float.NegativeInfinity); foreach (Vector3 vertex2 in vertices) { if (Finite(vertex2) && OnSide(vertex2, side) && (!forward || side != 0 || !(MathF.Abs(vertex2.Z - num) > 0.035f))) { vector = Vector3.Min(vector, vertex2); vector2 = Vector3.Max(vector2, vertex2); } } Vector3 result = (vector + vector2) * 0.5f; result.Z = num + (forward ? 0.025f : (-0.025f)); return result; } private static bool OnSide(Vector3 p, int side) { if (side != 0) { return p.X * (float)side > 0f; } return true; } private static bool Finite(Vector3 p) { if (float.IsFinite(p.X) && float.IsFinite(p.Y)) { return float.IsFinite(p.Z); } return false; } } internal static class BikeLights { private sealed class Lens { internal Renderer Renderer; internal Transform Assembly; internal Vector3[] Vertices = Array.Empty<Vector3>(); internal bool BaseColor; internal bool Color; internal bool Emission; } private sealed class State { internal LandVehicle Vehicle; internal VehicleLights Controller; internal Transform Model; internal Lens[] Heads = Array.Empty<Lens>(); internal Lens[] Tails = Array.Empty<Lens>(); internal OptimizedLight[] Beams = Array.Empty<OptimizedLight>(); internal Light? Rear; internal bool RearInRange; internal BikeLightPolicy.Output? Applied; internal readonly MaterialPropertyBlock Block = new MaterialPropertyBlock(); } private static readonly Dictionary<int, State> states = new Dictionary<int, State>(); private static readonly Dictionary<int, State> controllers = new Dictionary<int, State>(); private static readonly List<int> dead = new List<int>(); private static readonly int emissionId = Shader.PropertyToID("_EmissionColor"); private static readonly int baseColorId = Shader.PropertyToID("_BaseColor"); private static readonly int colorId = Shader.PropertyToID("_Color"); private static int failures; internal static void Initialize(Harmony harmony) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown harmony.Patch((MethodBase)AccessTools.Method(typeof(VehicleLights), "UpdateVisuals", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(BikeLights), "AfterNativeVisuals", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } internal static void Configure(LandVehicle vehicle, BikeSpec spec, Transform model) { //IL_0385: Unknown result type (might be due to invalid IL or missing references) //IL_0396: Unknown result type (might be due to invalid IL or missing references) //IL_03a7: Unknown result type (might be due to invalid IL or missing references) //IL_03ca: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)vehicle == (Object)null || (Object)(object)model == (Object)null || !spec.IsMotorcycle || (Object)(object)vehicle.lights == (Object)null) { return; } VehicleLights lights = vehicle.lights; Lens[] array = FindLenses(model, "Custom_Light"); Lens[] array2 = FindLenses(model, "Custom_TailLight"); if (array.Length == 0 || array2.Length == 0) { MelonLogger.Warning("Motorcycle lighting skipped: " + spec.Id + " has no fitted lens geometry."); return; } Il2CppReferenceArray<OptimizedLight> headLightSources = lights.headLightSources; List<OptimizedLight> list = new List<OptimizedLight>(); int num = ((spec.MotorcycleStyle != MotorcycleGeometry.Style.Sport) ? 1 : 2); if (headLightSources != null) { foreach (OptimizedLight item in (Il2CppArrayBase<OptimizedLight>)(object)headLightSources) { if ((Object)(object)item == (Object)null) { continue; } item.SetEnabled(false); Light val = item._Light; if ((Object)(object)val == (Object)null) { val = ((Component)item).GetComponent<Light>(); } if (!((Object)(object)val == (Object)null) && list.Count < num) { Lens lens = array[0]; int side = ((num == 2 && ((Il2CppArrayBase<OptimizedLight>)(object)headLightSources).Length >= 2) ? ((list.Count != 0) ? 1 : (-1)) : 0); Vector3 p = BikeLightPolicy.HeadAnchor(lens.Vertices, side); ((Component)item).transform.SetParent(lens.Assembly, false); ((Component)item).transform.localPosition = Convert(p); ((Component)item).transform.localRotation = Quaternion.Euler(5f, 0f, 0f); ((Component)item).transform.localScale = Vector3.one; if (((Il2CppObjectBase)((Component)val).transform).Pointer != ((Il2CppObjectBase)((Component)item).transform).Pointer) { ((Component)val).transform.SetParent(((Component)item).transform, false); ((Component)val).transform.localPosition = Vector3.zero; ((Component)val).transform.localRotation = Quaternion.identity; ((Component)val).transform.localScale = Vector3.one; } item._Light = val; item._transform = ((Component)item).transform; item.MaxDistance = 80f; item.maxDistanceSquared = item.MaxDistance * item.MaxDistance; ((Behaviour)item).enabled = true; val.type = (LightType)0; val.color = new Color(0.92f, 0.97f, 1f); val.range = 38f; val.spotAngle = 52f; val.intensity = ((num == 2) ? 1.7f : 2.4f); val.shadows = (LightShadows)0; item.UpdateLightState(); list.Add(item); } } } Light val2 = null; if (lights.brakeLightSources != null) { foreach (Light item2 in (Il2CppArrayBase<Light>)(object)lights.brakeLightSources) { if (!((Object)(object)item2 == (Object)null)) { ((Behaviour)item2).enabled = false; if ((Object)(object)val2 == (Object)null) { val2 = item2; } } } } if (lights.reverseLightSources != null) { foreach (Light item3 in (Il2CppArrayBase<Light>)(object)lights.reverseLightSources) { if ((Object)(object)item3 != (Object)null) { ((Behaviour)item3).enabled = false; } } } if ((Object)(object)val2 != (Object)null) { Lens lens2 = array2[0]; ((Component)val2).transform.SetParent(lens2.Assembly, false); ((Component)val2).transform.localPosition = Convert(BikeLightPolicy.RearAnchor(lens2.Vertices)); ((Component)val2).transform.localRotation = Quaternion.identity; ((Component)val2).transform.localScale = Vector3.one; val2.type = (LightType)2; val2.color = new Color(1f, 0.015f, 0.01f); val2.range = 2.8f; val2.shadows = (LightShadows)0; } lights.headLightMeshes = new Il2CppReferenceArray<MeshRenderer>(0L); lights.brakeLightMeshes = new Il2CppReferenceArray<MeshRenderer>(0L); lights.reverseLightMeshes = new Il2CppReferenceArray<MeshRenderer>(0L); lights.headLightSources = new Il2CppReferenceArray<OptimizedLight>(list.ToArray()); lights.brakeLightSources = new Il2CppReferenceArray<Light>((Light[])(((Object)(object)val2 == (Object)null) ? ((Array)Array.Empty<Light>()) : ((Array)new Light[1] { val2 }))); lights.reverseLightSources = new Il2CppReferenceArray<Light>(0L); lights.hasReverseLights = false; lights._debug = false; lights.vehicle = vehicle; ((Behaviour)lights).enabled = true; State state = new State { Vehicle = vehicle, Controller = lights, Model = model, Heads = array, Tails = array2, Beams = list.ToArray(), Rear = val2 }; states[((Object)vehicle).GetInstanceID()] = state; controllers[((Object)lights).GetInstanceID()] = state; UpdateDistance(state); Resync(vehicle); MelonLogger.Msg($"Motorcycle lights fitted: {spec.Id}, native beams={state.Beams.Length}, rear light={(Object)(object)val2 != (Object)null}, headlight control=native."); } private static Lens[] FindLenses(Transform model, string name) { //IL_00a2: 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_00be: Unknown result type (might be due to invalid IL or missing references) List<Lens> list = new List<Lens>(); foreach (MeshRenderer componentsInChild in ((Component)model).GetComponentsInChildren<MeshRenderer>(true)) { if ((Object)(object)componentsInChild == (Object)null || ((Object)((Component)componentsInChild).gameObject).name != name) { continue; } MeshFilter component = ((Component)componentsInChild).GetComponent<MeshFilter>(); Material sharedMaterial = ((Renderer)componentsInChild).sharedMaterial; if (!((Object)(object)component == (Object)null) && !((Object)(object)component.sharedMesh == (Object)null) && !((Object)(object)sharedMaterial == (Object)null)) { Il2CppStructArray<Vector3> vertices = component.sharedMesh.vertices; Vector3[] array = new Vector3[((Il2CppArrayBase<Vector3>)(object)vertices).Length]; for (int i = 0; i < ((Il2CppArrayBase<Vector3>)(object)vertices).Length; i++) { array[i] = new Vector3(((Il2CppArrayBase<Vector3>)(object)vertices)[i].x, ((Il2CppArrayBase<Vector3>)(object)vertices)[i].y, ((Il2CppArrayBase<Vector3>)(object)vertices)[i].z); } list.Add(new Lens { Renderer = (Renderer)(object)componentsInChild, Assembly = ((Component)componentsInChild).transform.parent, Vertices = array, BaseColor = sharedMaterial.HasProperty(baseColorId), Color = sharedMaterial.HasProperty(colorId), Emission = sharedMaterial.HasProperty(emissionId) }); } } return list.ToArray(); } private static void AfterNativeVisuals(VehicleLights __instance) { try { if ((Object)(object)__instance != (Object)null && controllers.TryGetValue(((Object)__instance).GetInstanceID(), out State value) && (Object)(object)value.Controller != (Object)null && ((Il2CppObjectBase)value.Controller).Pointer == ((Il2CppObjectBase)__instance).Pointer && (Object)(object)value.Vehicle != (Object)null) { Apply(value); } } catch (Exception ex) { Report(ex); } } internal static void Resync(LandVehicle vehicle) { try { if (!TryState(vehicle, out State state)) { return; } ((Behaviour)state.Controller).enabled = true; state.Applied = null; Apply(state); OptimizedLight[] beams = state.Beams; foreach (OptimizedLight val in beams) { if ((Object)(object)val != (Object)null) { val.UpdateLightState(); } } } catch (Exception ex) { Report(ex); } } internal static void Refresh() { dead.Clear(); foreach (KeyValuePair<int, State> state2 in states) { State value = state2.Value; if ((Object)(object)value.Vehicle == (Object)null || (Object)(object)value.Model == (Object)null || (Object)(object)value.Controller == (Object)null) { dead.Add(state2.Key); continue; } try { UpdateDistance(value); Apply(value); } catch (Exception ex) { Report(ex); } } foreach (int item in dead) { State state = states[item]; KeyValuePair<int, State>[] array = controllers.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair<int, State> keyValuePair = array[i]; if (keyValuePair.Value == state) { controllers.Remove(keyValuePair.Key); } } states.Remove(item); } } private static void UpdateDistance(State state) { //IL_0039: 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_0053: Unknown result type (might be due to invalid IL or missing references) PlayerCamera instance = PlayerSingleton<PlayerCamera>.Instance; if ((Object)(object)instance == (Object)null) { state.RearInRange = false; return; } float num = 55f + (state.RearInRange ? 3f : (-3f)); Vector3 val = ((Component)instance).transform.position - ((Component)state.Vehicle).transform.position; state.RearInRange = ((Vector3)(ref val)).sqrMagnitude <= num * num; } private static void Apply(State state) { //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) bool visible = state.Vehicle.IsVisible && ((Component)state.Model).gameObject.activeInHierarchy; BikeLightPolicy.Output value = BikeLightPolicy.Calculate(state.Controller.HeadlightsOn, state.Vehicle.BrakesApplied, visible, state.RearInRange); OptimizedLight[] beams = state.Beams; foreach (OptimizedLight val in beams) { if ((Object)(object)val != (Object)null && val.Enabled != value.HeadOn) { val.SetEnabled(value.HeadOn); } } if ((Object)(object)state.Rear != (Object)null) { if (((Behaviour)state.Rear).enabled != value.TailOn) { ((Behaviour)state.Rear).enabled = value.TailOn; } if (state.Rear.intensity != value.RearIntensity) { state.Rear.intensity = value.RearIntensity; } } if (!(state.Applied == value)) { state.Applied = value; SetLenses(state, state.Heads, value.HeadEmission, new Color(0.83f, 0.94f, 1f)); SetLenses(state, state.Tails, value.TailEmission, (value.TailEmission > 0f) ? new Color(1f, 0.025f, 0.025f) : new Color(0.21f, 0.005f, 0.005f)); } } private static void SetLenses(State state, Lens[] lenses, float emission, Color color) { //IL_004a: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) foreach (Lens lens in lenses) { if (!((Object)(object)lens.Renderer == (Object)null)) { state.Block.Clear(); lens.Renderer.GetPropertyBlock(state.Block); if (lens.BaseColor) { state.Block.SetColor(baseColorId, color); } if (lens.Color) { state.Block.SetColor(colorId, color); } if (lens.Emission) { state.Block.SetColor(emissionId, color * emission); } lens.Renderer.SetPropertyBlock(state.Block); } } } private static bool TryState(LandVehicle vehicle, out State state) { state = null; if ((Object)(object)vehicle != (Object)null && states.TryGetValue(((Object)vehicle).GetInstanceID(), out state) && (Object)(object)state.Vehicle != (Object)null && ((Il2CppObjectBase)state.Vehicle).Pointer == ((Il2CppObjectBase)vehicle).Pointer) { return (Object)(object)state.Controller != (Object)null; } return false; } private static Vector3 Convert(Vector3 p) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return new Vector3(p.X, p.Y, p.Z); } private static void Report(Exception ex) { if (failures++ < 3) { MelonLogger.Warning("Motorcycle lighting: " + ex.GetType().Name + ": " + ex.Message); } } internal static void Reset() { states.Clear(); controllers.Clear(); dead.Clear(); failures = 0; } } public sealed class BikePackMod : MelonMod { private Harmony? patches; private float nextAttempt; private int failures; private int showroomFailures; private bool announced; public override void OnInitializeMelon() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown patches = new Harmony("nacho.schedulei.bikepack"); BikeRig.Initialize(patches); BikeStuntControls.Initialize(); BikeLights.Initialize(patches); BikeRiderPose.Initialize(patches); BikeExitSafety.Initialize(patches); BikeRecovery.Initialize(patches); BikePaint.Initialize(patches); RegistryAndDealer.Initialize(patches); ((MelonBase)this).LoggerInstance.Msg("Motorcycle Pack 0.1.14 beta: native lights, rider leaning, wheelies/stoppies and safe wipeout/pickup. UpArrow leans forward while braking; DownArrow leans back while accelerating. Use the game's vehicle light control. P changes paint while stopped; R recovers a mounted bike. Interact once to pick up a fallen bike, again to ride."); } public override void OnUpdate() { BikeRig.Update(); if (Time.unscaledTime < nextAttempt) { return; } nextAttempt = Time.unscaledTime + 1f; try { LoadManager instance = Singleton<LoadManager>.Instance; if ((Object)(object)instance == (Object)null || !instance.IsGameLoaded || instance.IsLoading) { return; } BikePaint.Refresh(); BikeLights.Refresh(); BikeUiDiagnostics.TryInspect(); try { BikeShowroom.TryCreate(); } catch (Exception ex) { if (showroomFailures++ < 3) { ((MelonBase)this).LoggerInstance.Warning("Bike showroom setup will retry: " + ex.GetType().Name + ": " + ex.Message); } } if (!announced && RegistryAndDealer.TryRegister()) { if (RegistryAndDealer.TryAddToDealer() && !announced) { announced = true; ((MelonBase)this).LoggerInstance.Msg("Bike purchase choices linked into Jeremy's dialogue. This build supports single-player only."); } failures = 0; } } catch (Exception ex2) { nextAttempt = Time.unscaledTime + 5f; if (failures++ < 3) { ((MelonBase)this).LoggerInstance.Warning("Bike dealership setup will retry: " + ex2.GetType().Name + ": " + ex2.Message); } } } public override void OnLateUpdate() { BikeRecovery.Update(); BikeRecovery.LateUpdate(); BikePaint.UpdateInput(); } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { nextAttempt = 0f; announced = false; failures = 0; showroomFailures = 0; BikePaint.Refresh(); BikeUiDiagnostics.Reset(); } public override void OnDeinitializeMelon() { BikeRiderPose.Reset(); BikeShowroom.Reset(); BikeExitSafety.Reset(); BikeRecovery.Reset(); BikePaint.Reset(); BikeLights.Reset(); Harmony? obj = patches; if (obj != null) { obj.UnpatchSelf(); } } } internal static class BikePaint { private sealed class Surface { public Renderer Renderer; public int MaterialIndex; public bool BaseColor; public bool Color; } private sealed class PaintState { public LandVehicle Vehicle; public BikeSpec Spec; public Transform Model; public Surface[] Surfaces = Array.Empty<Surface>(); public readonly MaterialPropertyBlock Block = new MaterialPropertyBlock(); public int ObservedOwnedColor = -1; public int AppliedColor = -1; public bool HintShown; } internal const string PaintMaterialName = "BikePackCustomPaint"; private static readonly Dictionary<int, PaintState> states = new Dictionary<int, PaintState>(); private static readonly List<int> dead = new List<int>(); private static readonly int baseColorId = Shader.PropertyToID("_BaseColor"); private static readonly int colorId = Shader.PropertyToID("_Color"); private static float nextInput; private static int failures; public static void Initialize(Harmony harmony) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Expected O, but got Unknown //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Expected O, but got Unknown harmony.Patch((MethodBase)AccessTools.Method(typeof(LandVehicle), "ApplyColor", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(BikePaint), "AfterApplyColor", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(LandVehicle), "ApplyOwnedColor", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(BikePaint), "AfterOwnedColor", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(LandVehicle), "Load", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(BikePaint), "AfterOwnedColor", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(LandVehicle), "RpcLogic___SetOwnedColor_1679996372", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(BikePaint), "AfterOwnedColor", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(LandVehicle), "OnLocalPlayerEnter", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(BikePaint), "AfterMount", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } public static void Configure(LandVehicle vehicle, BikeSpec spec, Transform model) { if ((Object)(object)vehicle == (Object)null || (Object)(object)model == (Object)null || !spec.IsMotorcycle) { return; } List<Surface> list = new List<Surface>(); foreach (Renderer componentsInChild in ((Component)model).GetComponentsInChildren<Renderer>(true)) { Il2CppReferenceArray<Material> sharedMaterials = componentsInChild.sharedMaterials; for (int i = 0; i < ((Il2CppArrayBase<Material>)(object)sharedMaterials).Length; i++) { Material val = ((Il2CppArrayBase<Material>)(object)sharedMaterials)[i]; if (!((Object)(object)val == (Object)null) && !(((Object)val).name != "BikePackCustomPaint")) { list.Add(new Surface { Renderer = componentsInChild, MaterialIndex = i, BaseColor = val.HasProperty(baseColorId), Color = val.HasProperty(colorId) }); } } } if (list.Count != 0) { int instanceID = ((Object)vehicle).GetInstanceID(); if (!states.TryGetValue(instanceID, out PaintState value) || (Object)(object)value.Vehicle == (Object)null) { vehicle._OwnedColor_k__BackingField = (EVehicleColor)BikePaintPolicy.Default(spec.IsOffroad, spec.IsCruiser); } PaintState paintState = new PaintState { Vehicle = vehicle, Spec = spec, Model = model, Surfaces = list.ToArray(), HintShown = (value?.HintShown ?? false) }; states[instanceID] = paintState; CommitAppearance(paintState); } } private static void AfterApplyColor(LandVehicle __instance, EVehicleColor __0) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected I4, but got Unknown try { if (TryState(__instance, out PaintState state)) { Apply(state, (int)__0); } } catch (Exception ex) { Report(ex); } } private static void AfterOwnedColor(LandVehicle __instance) { try { if (TryState(__instance, out PaintState state)) { CommitAppearance(state); } } catch (Exception ex) { Report(ex); } } private static void AfterMount(LandVehicle __instance) { try { if (__instance.LocalPlayerIsDriver && TryState(__instance, out PaintState state)) { ShowHint(state); } } catch (Exception ex) { Report(ex); } } public static void Refresh() { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Invalid comparison between Unknown and I4 dead.Clear(); foreach (KeyValuePair<int, PaintState> state2 in states) { PaintState value = state2.Value; if ((Object)(object)value.Vehicle == (Object)null || (Object)(object)value.Model == (Object)null) { dead.Add(state2.Key); continue; } try { if ((int)value.Vehicle.OwnedColor != value.ObservedOwnedColor) { CommitAppearance(value); } } catch (Exception ex) { Report(ex); } } foreach (int item in dead) { states.Remove(item); } try { Player local = Player.Local; if (!((Object)(object)local == (Object)null) && GameplayInputAllowed(local)) { object obj; if (!local.IsInVehicle) { obj = HoveredBike(local); } else { NetworkObject currentVehicle = local.CurrentVehicle; obj = ((currentVehicle != null) ? ((Component)currentVehicle).GetComponent<LandVehicle>() : null); } LandVehicle val = (LandVehicle)obj; if ((!local.IsInVehicle || (!((Object)(object)val == (Object)null) && val.LocalPlayerIsDriver)) && (Object)(object)val != (Object)null && TryState(val, out PaintState state)) { ShowHint(state); } } } catch (Exception ex2) { Report(ex2); } } public static void UpdateInput() { //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_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Expected I4, but got Unknown Keyboard current = Keyboard.current; if (current == null || !((ButtonControl)current[(Key)30]).wasPressedThisFrame || Time.unscaledTime < nextInput) { return; } try { Player local = Player.Local; if ((Object)(object)local == (Object)null || !GameplayInputAllowed(local)) { return; } LandVehicle val; if (local.IsInVehicle) { NetworkObject currentVehicle = local.CurrentVehicle; val = ((currentVehicle != null) ? ((Component)currentVehicle).GetComponent<LandVehicle>() : null); if ((Object)(object)val == (Object)null || !val.LocalPlayerIsDriver || (Object)(object)val.State == (Object)null || !val.State.IsAcceptingInput) { return; } } else { if ((Object)(object)local.OnFootState == (Object)null || !local.OnFootState.IsAcceptingInput) { return; } val = HoveredBike(local); } if (!((Object)(object)val == (Object)null) && val.IsPlayerOwned && TryState(val, out PaintState state) && !((Object)(object)val.Rb == (Object)null)) { nextInput = Time.unscaledTime + 0.25f; Vector3 velocity = val.Rb.velocity; if (!BikePaintPolicy.Stopped(((Vector3)(ref velocity)).sqrMagnitude)) { Notify(state, "Stop the bike to change its paint."); return; } bool previous = ((ButtonControl)current[(Key)51]).isPressed || ((ButtonControl)current[(Key)52]).isPressed; int num = BikePaintPolicy.Cycle((int)val.OwnedColor, previous, state.Spec.IsOffroad, state.Spec.IsCruiser); val.SendOwnedColor((EVehicleColor)num); val.HasChanged = true; CommitAppearance(state); Notify(state, "Paint: " + BikePaintPolicy.Palette[num].Name + ". P: next, Shift+P: previous."); } } catch (Exception ex) { Report(ex); } } private static bool GameplayInputAllowed(Player local) { if (!Application.isFocused || Time.timeScale <= 0f || GameInput.IsTyping || local.IsArrested || local.IsTased || local.IsUnconscious || local.IsRagdolled || local.IsSleeping) { return false; } PlayerCamera instance = PlayerSingleton<PlayerCamera>.Instance; if ((Object)(object)instance == (Object)null || instance.ActiveUIElementCount > 0 || instance.FreeCamEnabled) { return false; } if (!((Object)(object)Singleton<PauseMenu>.Instance == (Object)null)) { return !Singleton<PauseMenu>.Instance.IsPaused; } return true; } private static LandVehicle? HoveredBike(Player local) { //IL_0089: 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) //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) InteractionManager instance = Singleton<InteractionManager>.Instance; if ((Object)(object)instance == (Object)null || instance.IsAnythingBlockingInteraction()) { return null; } InteractableObject hoveredValidInteractableObject = instance.HoveredValidInteractableObject; if ((Object)(object)hoveredValidInteractableObject == (Object)null) { return null; } LandVehicle componentInParent = ((Component)hoveredValidInteractableObject).GetComponentInParent<LandVehicle>(); if (!((Object)(object)componentInParent == (Object)null) && !((Object)(object)componentInParent.intObj == (Object)null) && !(((Il2CppObjectBase)hoveredValidInteractableObject).Pointer != ((Il2CppObjectBase)componentInParent.intObj).Pointer) && componentInParent.IsPlayerOwned && !componentInParent.IsOccupied && states.ContainsKey(((Object)componentInParent).GetInstanceID())) { Vector3 val = ((Component)componentInParent).transform.position - ((Component)local).transform.position; if (!(((Vector3)(ref val)).sqrMagnitude > 9f)) { return componentInParent; } } return null; } private static bool TryState(LandVehicle vehicle, out PaintState state) { state = null; if ((Object)(object)vehicle != (Object)null && states.TryGetValue(((Object)vehicle).GetInstanceID(), out state) && (Object)(object)state.Vehicle != (Object)null && ((Il2CppObjectBase)state.Vehicle).Pointer == ((Il2CppObjectBase)vehicle).Pointer) { return (Object)(object)state.Model != (Object)null; } return false; } private static void CommitAppearance(PaintState state) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected I4, but got Unknown state.ObservedOwnedColor = (int)state.Vehicle.OwnedColor; Apply(state, state.ObservedOwnedColor); } private static void Apply(PaintState state, int index) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Invalid comparison between Unknown and I4 //IL_00f9: 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_0113: Unknown result type (might be due to invalid IL or missing references) index = BikePaintPolicy.Normalize(index, state.Spec.IsOffroad, state.Spec.IsCruiser); if (state.AppliedColor == index) { return; } BikePaintPolicy.Paint paint = BikePaintPolicy.Palette[index]; Color materialColor = default(Color); ((Color)(ref materialColor))..ctor(paint.R, paint.G, paint.B, 1f); VehicleColors instance = Singleton<VehicleColors>.Instance; List<VehicleColorData> val = ((instance != null) ? instance.colorLibrary : null); if (val != null) { Enumerator<VehicleColorData> enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { VehicleColorData current = enumerator.Current; if (current != null && (int)current.color == index) { materialColor = current.MaterialColor; break; } } } Surface[] surfaces = state.Surfaces; foreach (Surface surface in surfaces) { if (!((Object)(object)surface.Renderer == (Object)null)) { state.Block.Clear(); surface.Renderer.GetPropertyBlock(state.Block, surface.MaterialIndex); if (surface.BaseColor) { state.Block.SetColor(baseColorId, materialColor); } if (surface.Color) { state.Block.SetColor(colorId, materialColor); } surface.Renderer.SetPropertyBlock(state.Block, surface.MaterialIndex); } } state.AppliedColor = index; } private static void ShowHint(PaintState state) { if (!state.HintShown && state.Vehicle.IsPlayerOwned && !((Object)(object)Singleton<NotificationsManager>.Instance == (Object)null)) { state.HintShown = true; Notify(state, "P: change paint. Shift+P: previous color. Stop or stand beside your bike."); } } private static void Notify(PaintState state, string message) { NotificationsManager instance = Singleton<NotificationsManager>.Instance; if ((Object)(object)instance != (Object)null) { instance.SendNotification("Motorcycle paint", message, BikeVisuals.Icon(state.Spec), 3f, false); } } private static void Report(Exception ex) { if (failures++ < 3) { MelonLogger.Warning("Motorcycle paint unavailable: " + ex.GetType().Name + ": " + ex.Message); } } public static void Reset() { states.Clear(); dead.Clear(); nextInput = 0f; failures = 0; } } internal static class BikePaintPolicy { internal readonly record struct Paint(string Name, float R, float G, float B); public const int ColorCount = 16; public static readonly Paint[] Palette = new Paint[16] { new Paint("Black", 0.035f, 0.04f, 0.045f), new Paint("Dark grey", 0.18f, 0.2f, 0.22f), new Paint("Light grey", 0.56f, 0.59f, 0.62f), new Paint("White", 0.91f, 0.93f, 0.95f), new Paint("Yellow", 0.97f, 0.73f, 0.045f), new Paint("Orange", 0.96f, 0.32f, 0.045f), new Paint("Red", 0.84f, 0.045f, 0.06f), new Paint("Dull red", 0.44f, 0.13f, 0.14f), new Paint("Pink", 0.94f, 0.31f, 0.54f), new Paint("Purple", 0.46f, 0.19f, 0.65f), new Paint("Navy", 0.045f, 0.095f, 0.24f), new Paint("Dark blue", 0.08f, 0.24f, 0.61f), new Paint("Light blue", 0.3f, 0.64f, 0.92f), new Paint("Cyan", 0.04f, 0.72f, 0.76f), new Paint("Light green", 0.39f, 0.76f, 0.13f), new Paint("Dark green", 0.045f, 0.29f, 0.15f) }; public static int Default(bool offroad, bool cruiser = false) { if (!cruiser) { if (!offroad) { return 6; } return 5; } return 0; } public static int Normalize(int savedColor, bool offroad, bool cruiser = false) { if (savedColor < 0 || savedColor >= 16) { return Default(offroad, cruiser); } return savedColor; } public static int Cycle(int savedColor, bool previous, bool offroad, bool cruiser = false) { return (Normalize(savedColor, offroad, cruiser) + ((!previous) ? 1 : 15)) % 16; } public static bool Stopped(float speedSquared) { if (float.IsFinite(speedSquared) && speedSquared >= 0f) { return speedSquared <= 0.25f; } return false; } } internal enum BikePaymentKind { Cash, Online } internal static class BikePurchasePolicy { public static bool CanAfford(float balance, float price) { if (float.IsFinite(balance) && float.IsFinite(price) && price > 0f) { return balance >= price; } return false; } public static bool TryGetPaymentKind(string label, out BikePaymentKind kind) { kind = BikePaymentKind.Online; if (string.Equals(label, "BUY_ONLINE", StringComparison.OrdinalIgnoreCase)) { return true; } if (!string.Equals(label, "BUY_CASH", StringComparison.OrdinalIgnoreCase)) { return false; } kind = BikePaymentKind.Cash; return true; } } internal static class BikeRecovery { private sealed class RecoveryState { public LandVehicle Vehicle; public readonly BikeCrashPolicy Policy = new BikeCrashPolicy(); public float LastPhysicsSpeed; public float NextPickup; } private static readonly Dictionary<int, RecoveryState> states = new Dictionary<int, RecoveryState>(); private static readonly List<int> dead = new List<int>(); private static float nextRecovery; private static int failures; public static void Initialize(Harmony harmony) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_0068: 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_0081: Expected O, but got Unknown //IL_00a9: 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_00c2: Expected O, but got Unknown //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Expected O, but got Unknown //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Expected O, but got Unknown harmony.Patch((MethodBase)AccessTools.Method(typeof(LandVehicle), "EnterVehicle", (Type[])null, (Type[])null), new HarmonyMethod(typeof(BikeRecovery), "BeforeMount", (Type[])null) { priority = 800 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(LandVehicle), "Interacted", (Type[])null, (Type[])null), new HarmonyMethod(typeof(BikeRecovery), "BeforeInteracted", (Type[])null) { priority = 800 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(LandVehicle), "Hovered", (Type[])null, (Type[])null), new HarmonyMethod(typeof(BikeRecovery), "BeforeHovered", (Type[])null) { priority = 800 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(LandVehicle), "OnLocalPlayerEnter", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(BikeRecovery), "AfterMount", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(LandVehicle), "Load", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(BikeRecovery), "AfterLoad", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } public static void Register(LandVehicle vehicle) { if ((Object)(object)vehicle == (Object)null) { return; } BikeSpec? bikeSpec = BikeCatalog.Find(vehicle.vehicleCode); if ((object)bikeSpec == null || !bikeSpec.IsMotorcycle) { return; } int instanceID = ((Object)vehicle).GetInstanceID(); if (!states.TryGetValue(instanceID, out RecoveryState value) || !((Object)(object)value.Vehicle != (Object)null) || !(((Il2CppObjectBase)value.Vehicle).Pointer == ((Il2CppObjectBase)vehicle).Pointer)) { RecoveryState recoveryState = new RecoveryState { Vehicle = vehicle }; recoveryState.Policy.Observ