Decompiled source of BigChoppa v1.0.2
BigChoppa.dll
Decompiled 4 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.IO; using System.Linq; using System.Net.Http; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.Json; using System.Threading.Tasks; using BepInEx; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Il2CppSystem.Reflection; using Microsoft.CodeAnalysis; using Mirror; using Rewired; using UnityEngine; using UnityEngine.Audio; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("BigChoppa")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+4e223f5a2725ed08cb9ce3d84465d45f259c5bc5")] [assembly: AssemblyProduct("BigChoppa")] [assembly: AssemblyTitle("BigChoppa")] [assembly: AssemblyVersion("1.0.0.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 BigChoppa { internal static class ChoppaAudio { private const int Rate = 44100; private static AudioClip rotorClip; private static AudioClip turbineClip; private static AudioClip[] bonkClips; private static AudioMixerGroup mixerGroup; private static bool mixerSearched; public static void Attach(Helicopter heli) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_003a: 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) if (EnsureClips()) { GameObject val = new GameObject("Audio"); val.transform.SetParent(((Component)heli).transform, false); val.transform.localPosition = new Vector3(0f, 2.5f, 0f) * ChoppaConfig.HeliScale.Value; heli.RotorAudio = Loop(val, rotorClip, 12f); heli.TurbineAudio = Loop(val, turbineClip, 6f); } } private static AudioSource Loop(GameObject go, AudioClip clip, float minDistance) { AudioSource obj = go.AddComponent<AudioSource>(); Setup(obj, minDistance); obj.clip = clip; obj.loop = true; obj.volume = 0f; return obj; } private static void Setup(AudioSource s, float minDistance) { s.playOnAwake = false; s.spatialBlend = 1f; s.rolloffMode = (AudioRolloffMode)0; s.minDistance = minDistance * ChoppaConfig.HeliScale.Value; s.maxDistance = ChoppaConfig.AudioMaxDistance.Value; s.dopplerLevel = 0.6f; s.spread = 60f; s.priority = 64; AudioMixerGroup val = MixerGroup(); if ((Object)(object)val != (Object)null) { s.outputAudioMixerGroup = val; } } public static void Drive(Helicopter h) { if ((Object)(object)h.RotorAudio == (Object)null || (Object)(object)h.TurbineAudio == (Object)null) { return; } float value = ChoppaConfig.AudioVolume.Value; float num = (h.Broken ? 0f : h.RotorSpin); float collective = h.Collective; bool flag = num > 0.005f && value > 0f; AudioSource[] array = (AudioSource[])(object)new AudioSource[2] { h.RotorAudio, h.TurbineAudio }; foreach (AudioSource val in array) { if (flag && !val.isPlaying) { val.time = Random.value * val.clip.length * 0.99f; val.Play(); } else if (!flag && val.isPlaying) { val.Stop(); } } if (flag) { h.RotorAudio.volume = value * Mathf.Pow(num, 1.3f) * (0.55f + 0.45f * collective); h.RotorAudio.pitch = 0.35f + 0.65f * num + 0.1f * (collective - 0.5f) * num; h.TurbineAudio.volume = value * 0.12f * Mathf.Pow(num, 0.7f); h.TurbineAudio.pitch = 0.4f + 0.6f * num + 0.1f * collective; } } public static void Bonk(AudioSource src, float impactSpeed, float size) { float value = ChoppaConfig.AudioVolume.Value; if (!(value <= 0f) && !((Object)(object)src == (Object)null) && EnsureClips()) { float num = Mathf.Clamp01((impactSpeed - 0.5f) / 8f); if (!(num <= 0.02f)) { src.pitch = Mathf.Lerp(1.35f, 0.55f, size) * Random.Range(0.9f, 1.1f); src.PlayOneShot(bonkClips[Random.Range(0, bonkClips.Length)], value * num * Mathf.Lerp(0.6f, 1f, size)); } } } public static AudioSource OneShotSource(GameObject go, float minDistance) { AudioSource obj = go.AddComponent<AudioSource>(); Setup(obj, minDistance); obj.loop = false; return obj; } public static void PlayCrash(Vector3 position) { //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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_0053: Expected O, but got Unknown if (!(ChoppaConfig.AudioVolume.Value <= 0f) && EnsureClips()) { GameObject val = new GameObject("ChoppaCrashSound"); val.transform.position = position; Bonk(OneShotSource(val, 15f), 20f, 1f); Object.Destroy((Object)val, 2f); } } private static AudioMixerGroup MixerGroup() { //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Expected O, but got Unknown //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Expected O, but got Unknown if ((Object)(object)mixerGroup != (Object)null && !((Il2CppObjectBase)mixerGroup).WasCollected) { return mixerGroup; } if (mixerSearched) { return null; } mixerSearched = true; bool flag = default(bool); try { Dictionary<string, (AudioMixerGroup, int)> dictionary = new Dictionary<string, (AudioMixerGroup, int)>(); foreach (AudioSource item in Object.FindObjectsByType<AudioSource>((FindObjectsInactive)1, (FindObjectsSortMode)0)) { AudioMixerGroup outputAudioMixerGroup = item.outputAudioMixerGroup; if (!((Object)(object)outputAudioMixerGroup == (Object)null)) { dictionary[((Object)outputAudioMixerGroup).name] = (dictionary.TryGetValue(((Object)outputAudioMixerGroup).name, out var value) ? (outputAudioMixerGroup, value.Item2 + 1) : (outputAudioMixerGroup, 1)); } } Plugin.Verbose("Game mixer groups: " + string.Join(", ", dictionary.Select<KeyValuePair<string, (AudioMixerGroup, int)>, string>((KeyValuePair<string, (AudioMixerGroup g, int n)> kv) => $"{kv.Key}x{kv.Value.n}"))); string text = null; foreach (KeyValuePair<string, (AudioMixerGroup, int)> item2 in dictionary) { if (Score(item2.Key) >= 0 && (text == null || Score(item2.Key) > Score(text) || (Score(item2.Key) == Score(text) && item2.Value.Item2 > dictionary[text].Item2))) { text = item2.Key; } } if (text != null) { mixerGroup = dictionary[text].Item1; ManualLogSource l = Plugin.L; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(38, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Choppa audio routed to mixer group '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'."); } l.LogInfo(val); } else { Plugin.L.LogInfo((object)"No game mixer group found; choppa audio plays direct."); } } catch (Exception ex) { ManualLogSource l2 = Plugin.L; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(27, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Mixer group search failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message); } l2.LogWarning(val2); } return mixerGroup; static int Score(string name) { string text2 = name.ToLowerInvariant(); if (text2.Contains("music") || text2.Contains("ui") || text2.Contains("voice") || text2.Contains("amb")) { return -1; } if (text2.Contains("sfx") || text2.Contains("effect")) { return 3; } if (text2.Contains("world") || text2.Contains("game") || text2.Contains("prop")) { return 2; } return 1; } } private static bool EnsureClips() { //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Expected O, but got Unknown try { if (Dead(rotorClip)) { rotorClip = MakeClip("ChoppaRotor", SynthRotor()); } if (Dead(turbineClip)) { turbineClip = MakeClip("ChoppaTurbine", SynthTurbine()); } if (bonkClips == null || Array.Exists(bonkClips, Dead)) { bonkClips = (AudioClip[])(object)new AudioClip[4]; for (int i = 0; i < bonkClips.Length; i++) { bonkClips[i] = MakeClip($"ChoppaBonk{i}", SynthBonk(i)); } } return true; } catch (Exception ex) { ManualLogSource l = Plugin.L; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(31, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Choppa audio synthesis failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex); } l.LogError(val); return false; } } private static bool Dead(AudioClip c) { if (!((Object)(object)c == (Object)null)) { return ((Il2CppObjectBase)c).WasCollected; } return true; } private static AudioClip MakeClip(string name, float[] data) { Normalize(data, 0.9f); AudioClip obj = AudioClip.Create(name, data.Length, 1, 44100, false); obj.SetData(Il2CppStructArray<float>.op_Implicit(data), 0); ((Object)obj).hideFlags = (HideFlags)32; return obj; } private static float[] SynthRotor() { int num = 44100; Random rng = new Random(1234); float[] array = LowPassLoop(WhiteNoise(num, rng), 420f); float[] array2 = LowPassLoop(WhiteNoise(num, rng), 120f); float[] array3 = new float[num]; int num2 = num / 10; for (int i = 0; i < num; i++) { float num3 = (float)(i % num2) / 44100f; float num4 = Mathf.Exp((0f - num3) / 0.035f) * Mathf.Clamp01(num3 / 0.003f); float num5 = Mathf.Sin((float)Math.PI * 140f * num3) * Mathf.Exp((0f - num3) / 0.05f); array3[i] = num4 * array[i] * 2.2f + num5 * 0.7f + array2[i] * 1.2f; } return array3; } private static float[] SynthTurbine() { int num = 44100; float[] array = new float[num]; for (int i = 0; i < num; i++) { float num2 = (float)i / 44100f; float num3 = 0.5f + 0.5f * Mathf.Sin((float)Math.PI * 68f * num2); array[i] = Mathf.Sin((float)Math.PI * 1240f * num2) * num3; } return array; } private static float[] SynthBonk(int variant) { int num = 15435; Random rng = new Random(500 + variant); float num2 = 260f + (float)variant * 70f; float[] array = LowPass(WhiteNoise(num, rng), 3000f); float[] array2 = new float[num]; double num3 = 0.0; double num4 = 0.0; for (int i = 0; i < num; i++) { float num5 = (float)i / 44100f; float num6 = num2 * (1f + 0.6f * Mathf.Exp((0f - num5) / 0.012f)); num3 += Math.PI * 2.0 * (double)num6 / 44100.0; num4 += Math.PI * 2.0 * (double)num6 * 2.31 / 44100.0; float num7 = Mathf.Exp((0f - num5) / 0.07f) * Mathf.Clamp01(num5 / 0.001f); array2[i] = num7 * ((float)Math.Sin(num3) + 0.35f * (float)Math.Sin(num4) * Mathf.Exp((0f - num5) / 0.03f)) + array[i] * 1.5f * Mathf.Exp((0f - num5) / 0.004f); } return array2; } private static float[] WhiteNoise(int n, Random rng) { float[] array = new float[n]; for (int i = 0; i < n; i++) { array[i] = (float)(rng.NextDouble() * 2.0 - 1.0); } return array; } private static float[] LowPass(float[] x, float cutoff) { float num = 1f - Mathf.Exp((float)Math.PI * -2f * cutoff / 44100f); float[] array = new float[x.Length]; float num2 = 0f; for (int i = 0; i < x.Length; i++) { num2 = (array[i] = num2 + num * (x[i] - num2)); } return array; } private static float[] LowPassLoop(float[] x, float cutoff) { float num = 1f - Mathf.Exp((float)Math.PI * -2f * cutoff / 44100f); float[] array = new float[x.Length]; float num2 = 0f; for (int i = 0; i < 2; i++) { for (int j = 0; j < x.Length; j++) { num2 = (array[j] = num2 + num * (x[j] - num2)); } } return array; } private static void Normalize(float[] d, float peak) { float num = 1E-06f; foreach (float num2 in d) { num = Mathf.Max(num, Mathf.Abs(num2)); } float num3 = peak / num; for (int j = 0; j < d.Length; j++) { d[j] *= num3; } } } public class ChoppaBonker : MonoBehaviour { public AudioSource Source; public float Size = 0.5f; public float MinSpeed = 1f; private float nextAllowed; private static float windowStart; private static int windowCount; public ChoppaBonker(IntPtr ptr) : base(ptr) { } public static ChoppaBonker Add(GameObject go, float size, float minSpeed) { ChoppaBonker choppaBonker = go.AddComponent<ChoppaBonker>(); choppaBonker.Size = size; choppaBonker.MinSpeed = minSpeed; choppaBonker.Source = ChoppaAudio.OneShotSource(go, 4f + 6f * size); return choppaBonker; } private void OnCollisionEnter(Collision c) { //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) Vector3 relativeVelocity = c.relativeVelocity; float magnitude = ((Vector3)(ref relativeVelocity)).magnitude; if (!(magnitude < MinSpeed) && !(Time.time < nextAllowed)) { nextAllowed = Time.time + 0.08f; if (Time.time - windowStart > 0.1f) { windowStart = Time.time; windowCount = 0; } if (++windowCount <= 12) { ChoppaAudio.Bonk(Source, magnitude, Size); } } } } internal enum InputBackend { Auto, Rewired, Unity } internal static class ChoppaConfig { public static ConfigEntry<KeyCode> CollectiveUpKey; public static ConfigEntry<KeyCode> CollectiveDownKey; public static ConfigEntry<KeyCode> PedalLeftKey; public static ConfigEntry<KeyCode> PedalRightKey; public static ConfigEntry<KeyCode> SpawnKey; public static ConfigEntry<KeyCode> EnterExitKey; public static ConfigEntry<KeyCode> ResetKey; public static ConfigEntry<KeyCode> CameraKey; public static ConfigEntry<KeyCode> FreeLookKey; public static ConfigEntry<KeyCode> HudKey; public static ConfigEntry<float> MouseSensitivity; public static ConfigEntry<bool> InvertPitch; public static ConfigEntry<bool> InvertRoll; public static ConfigEntry<InputBackend> Backend; public static ConfigEntry<bool> RequireCursorLock; public static ConfigEntry<float> MaxLiftG; public static ConfigEntry<float> CollectiveRate; public static ConfigEntry<float> MaxPitchRollRate; public static ConfigEntry<float> YawRate; public static ConfigEntry<float> ControlResponse; public static ConfigEntry<float> MouseSmoothing; public static ConfigEntry<float> AutoLevel; public static ConfigEntry<float> Weathervane; public static ConfigEntry<float> SpinUpSeconds; public static ConfigEntry<float> ForwardDrag; public static ConfigEntry<float> SideDrag; public static ConfigEntry<float> VerticalDrag; public static ConfigEntry<float> LinearDrag; public static ConfigEntry<float> Mass; public static ConfigEntry<float> CenterOfMassHeight; public static ConfigEntry<bool> CollectiveSpringBack; public static ConfigEntry<bool> HoverTiltCompensation; public static ConfigEntry<float> CollectiveReturnRate; public static ConfigEntry<bool> BreakApart; public static ConfigEntry<float> CrashDeltaV; public static ConfigEntry<float> CrashBlast; public static ConfigEntry<float> DebrisSeconds; public static ConfigEntry<float> CrashStunRadius; public static ConfigEntry<float> HeliScale; public static ConfigEntry<float> SeatHeightOffset; public static ConfigEntry<float> SeatForwardOffset; public static ConfigEntry<float> EnterDistance; public static ConfigEntry<float> ChaseDistance; public static ConfigEntry<float> ChaseHeight; public static ConfigEntry<float> CockpitEyeHeight; public static ConfigEntry<bool> SitWhileFlying; public static ConfigEntry<int> ChoppaLayer; public static ConfigEntry<float> AudioVolume; public static ConfigEntry<float> AudioMaxDistance; public static ConfigEntry<bool> LogbookEnabled; public static ConfigEntry<string> LogbookInstallId; public static ConfigEntry<bool> NetEnabled; public static ConfigEntry<float> NetSendRate; public static ConfigEntry<float> NetInterpDelay; public static ConfigEntry<bool> ShowHud; public static ConfigEntry<bool> VerboseLogging; public static void Bind(ConfigFile cfg) { CollectiveUpKey = cfg.Bind<KeyCode>("Controls", "CollectiveUp", (KeyCode)119, "Hold to raise collective (more lift)."); CollectiveDownKey = cfg.Bind<KeyCode>("Controls", "CollectiveDown", (KeyCode)115, "Hold to lower collective (less lift)."); PedalLeftKey = cfg.Bind<KeyCode>("Controls", "PedalLeft", (KeyCode)97, "Left anti-torque pedal (yaw left)."); PedalRightKey = cfg.Bind<KeyCode>("Controls", "PedalRight", (KeyCode)100, "Right anti-torque pedal (yaw right)."); SpawnKey = cfg.Bind<KeyCode>("Controls", "Spawn", (KeyCode)289, "Spawn a choppa in front of you (replaces your previous one if nobody is in it)."); EnterExitKey = cfg.Bind<KeyCode>("Controls", "EnterExit", (KeyCode)103, "Board or leave the choppa."); ResetKey = cfg.Bind<KeyCode>("Controls", "ResetUpright", (KeyCode)290, "Flip the choppa back upright where it is."); CameraKey = cfg.Bind<KeyCode>("Controls", "ToggleCamera", (KeyCode)118, "Switch between chase and cockpit camera."); FreeLookKey = cfg.Bind<KeyCode>("Controls", "FreeLook", (KeyCode)308, "Hold to look around with the mouse instead of flying with it."); HudKey = cfg.Bind<KeyCode>("Controls", "ToggleHud", (KeyCode)291, "Show/hide the flight HUD."); MouseSensitivity = cfg.Bind<float>("Controls", "MouseSensitivity", 0.3f, "Degrees of pitch/roll per unit of mouse movement. Mouse forward = nose down, mouse left = roll left."); InvertPitch = cfg.Bind<bool>("Controls", "InvertPitch", false, "Swap mouse forward/back for pitch."); InvertRoll = cfg.Bind<bool>("Controls", "InvertRoll", false, "Swap mouse left/right for roll."); Backend = cfg.Bind<InputBackend>("Controls", "InputBackend", InputBackend.Auto, "Where to read keys/mouse from. Auto tries the game's Rewired input first, then Unity's legacy Input."); RequireCursorLock = cfg.Bind<bool>("Controls", "RequireCursorLock", true, "Ignore flight inputs while the cursor is unlocked (menus open)."); MaxLiftG = cfg.Bind<float>("Flight", "MaxLiftG", 2f, "Lift at full collective as a multiple of gravity. 2.0 means hover at ~50% collective."); CollectiveRate = cfg.Bind<float>("Flight", "CollectiveRate", 0.45f, "How fast holding W/S moves the collective (fraction of full range per second)."); MaxPitchRollRate = cfg.Bind<float>("Flight", "MaxPitchRollRate", 90f, "Cap on pitch/roll rotation speed (deg/s)."); YawRate = cfg.Bind<float>("Flight", "YawRate", 65f, "Yaw speed with a pedal fully held (deg/s)."); ControlResponse = cfg.Bind<float>("Flight", "ControlResponse", 6f, "How snappily the airframe reaches the commanded rotation rate. Higher = twitchier."); MouseSmoothing = cfg.Bind<float>("Flight", "MouseSmoothing", 0.08f, "Seconds of smoothing on mouse cyclic input."); AutoLevel = cfg.Bind<float>("Flight", "AutoLevel", 0f, "Self-levelling tendency. 0 = none (Arma-like, holds whatever attitude you set). Try 0.3 for an easier ride."); Weathervane = cfg.Bind<float>("Flight", "Weathervane", 0.5f, "How strongly the tail swings the nose into the direction of travel at speed."); SpinUpSeconds = cfg.Bind<float>("Flight", "SpinUpSeconds", 3f, "Rotor spin up/down time when you board/leave."); ForwardDrag = cfg.Bind<float>("Flight", "ForwardDrag", 0.003f, "Quadratic drag along the nose. Lower = higher top speed."); SideDrag = cfg.Bind<float>("Flight", "SideDrag", 0.02f, "Quadratic drag sideways."); VerticalDrag = cfg.Bind<float>("Flight", "VerticalDrag", 0.04f, "Quadratic drag up/down."); LinearDrag = cfg.Bind<float>("Flight", "LinearDrag", 0.15f, "Low-speed drag in all directions (stops endless drifting)."); Mass = cfg.Bind<float>("Flight", "Mass", 600f, "Rigidbody mass. Mostly affects how it shoves things it bumps into."); CenterOfMassHeight = cfg.Bind<float>("Flight", "CenterOfMassHeight", 1.4f, "Height (m, before Scale) of the point the choppa pivots around. Higher = swings like it hangs from the rotor; lower = tips like a bottom-heavy toy."); CollectiveSpringBack = cfg.Bind<bool>("Flight", "CollectiveSpringBack", true, "Release W/S and the collective returns to hover (or to idle when sitting on the ground). Off = it stays where you leave it."); CollectiveReturnRate = cfg.Bind<float>("Flight", "CollectiveReturnRate", 1f, "How fast the collective springs back when released (fraction of full range per second)."); HoverTiltCompensation = cfg.Bind<bool>("Flight", "HoverTiltCompensation", true, "Spring-back point adds a bit of lift when tilted so forward flight roughly holds altitude."); BreakApart = cfg.Bind<bool>("Crashing", "BreakApart", true, "Hard impacts smash the choppa into pieces."); CrashDeltaV = cfg.Bind<float>("Crashing", "CrashSpeed", 10f, "Sudden speed change (m/s in one physics step) that counts as a crash. Higher = sturdier."); CrashBlast = cfg.Bind<float>("Crashing", "CrashBlast", 8f, "How hard the pieces fly apart."); DebrisSeconds = cfg.Bind<float>("Crashing", "DebrisSeconds", 30f, "How long wreckage lies around. 0 = forever."); CrashStunRadius = cfg.Bind<float>("Crashing", "StunRadius", 6f, "Your character gets knocked down if within this distance of a crash (pilot always is)."); HeliScale = cfg.Bind<float>("Model", "Scale", 1f, "Overall size of the choppa."); SeatHeightOffset = cfg.Bind<float>("Model", "SeatHeightOffset", 0f, "Raise/lower where you sit (metres, before Scale)."); SeatForwardOffset = cfg.Bind<float>("Model", "SeatForwardOffset", 0f, "Move where you sit forward/back (metres, before Scale)."); EnterDistance = cfg.Bind<float>("Model", "EnterDistance", 5f, "How close you need to be to the nearest part of the choppa to board."); ChaseDistance = cfg.Bind<float>("Model", "ChaseCameraDistance", 12f, "Chase camera distance behind the choppa."); ChaseHeight = cfg.Bind<float>("Model", "ChaseCameraHeight", 3.5f, "Chase camera height above the choppa."); CockpitEyeHeight = cfg.Bind<float>("Model", "CockpitEyeHeightOffset", 0f, "Nudge the cockpit camera up/down."); SitWhileFlying = cfg.Bind<bool>("Model", "SitWhileFlying", true, "Ask the game to put your character in its sitting pose while flying."); ChoppaLayer = cfg.Bind<int>("Model", "PhysicsLayer", -1, "Unity layer for the choppa's colliders. -1 = auto-detect one that collides with the ground (see LogOutput.log)."); AudioVolume = cfg.Bind<float>("Audio", "Volume", 0.8f, "Choppa sound volume (rotor, motor, bonks). 0 = silent."); AudioMaxDistance = cfg.Bind<float>("Audio", "MaxHearingDistance", 250f, "How far away you can hear a choppa (metres)."); LogbookEnabled = cfg.Bind<bool>("Pilot Logbook", "Enabled", true, "Send a few anonymous flight stats (spawns, boardings, flight time/height/speed) so the author can see how the choppa gets used. No names, Steam IDs or locations. Set to false to turn it off completely."); LogbookInstallId = cfg.Bind<string>("Pilot Logbook", "AnonymousId", "", "Random id generated on first use so your flights can be told apart from other people's. Not linked to you. Delete it to get a new one."); NetEnabled = cfg.Bind<bool>("Networking", "Enabled", true, "Share choppas with other players. Everyone in the lobby (host included) needs the mod; a host without it may kick you when you join."); NetSendRate = cfg.Bind<float>("Networking", "SendRate", 20f, "Position updates per second sent for a choppa you're flying."); NetInterpDelay = cfg.Bind<float>("Networking", "InterpolationDelay", 0.15f, "Seconds other players' choppas are shown in the past so their motion stays smooth. Raise if they stutter."); ShowHud = cfg.Bind<bool>("Debug", "ShowHud", true, "Show the flight HUD while flying."); VerboseLogging = cfg.Bind<bool>("Debug", "VerboseLogging", false, "Log extra detail to LogOutput.log and show a network status line on screen."); } } internal static class ChoppaCrash { public static void Break(Helicopter heli, int seed) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) State state = Random.state; Random.InitState(seed); try { BreakSeeded(heli); } finally { Random.state = state; } } private static void BreakSeeded(Helicopter heli) { //IL_0012: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0252: 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_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0272: 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_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) Transform val = ((Component)heli).transform.Find("Model"); Vector3 impactVelocity = heli.ImpactVelocity; heli.Body.isKinematic = true; Vector3 val2 = ((Component)heli).transform.TransformPoint(heli.Body.centerOfMass); float value = ChoppaConfig.HeliScale.Value; float value2 = ChoppaConfig.DebrisSeconds.Value; ChoppaAudio.PlayCrash(val2); List<Transform> list = new List<Transform>(); if ((Object)(object)heli.MainRotor != (Object)null) { list.Add(heli.MainRotor); } if ((Object)(object)heli.TailRotor != (Object)null) { list.Add(heli.TailRotor); } if ((Object)(object)val != (Object)null) { foreach (MeshRenderer componentsInChild in ((Component)val).GetComponentsInChildren<MeshRenderer>(true)) { Transform transform = ((Component)componentsInChild).transform; if ((!((Object)(object)heli.MainRotor != (Object)null) || !transform.IsChildOf(heli.MainRotor)) && (!((Object)(object)heli.TailRotor != (Object)null) || !transform.IsChildOf(heli.TailRotor))) { list.Add(transform); } } } foreach (Transform item in list) { item.SetParent((Transform)null, true); foreach (MeshRenderer componentsInChild2 in ((Component)item).GetComponentsInChildren<MeshRenderer>(true)) { if ((Object)(object)((Component)componentsInChild2).GetComponent<Collider>() == (Object)null) { ((Component)componentsInChild2).gameObject.AddComponent<BoxCollider>(); } } Rigidbody val3 = ((Component)item).gameObject.AddComponent<Rigidbody>(); bool flag = (Object)(object)item == (Object)(object)heli.MainRotor || (Object)(object)item == (Object)(object)heli.TailRotor; val3.mass = (flag ? 40f : 15f); val3.interpolation = (RigidbodyInterpolation)1; val3.maxAngularVelocity = 60f; val3.angularDamping = 0.3f; Vector3 val4 = item.position - val2; val4 = ((((Vector3)(ref val4)).sqrMagnitude < 0.01f) ? Random.onUnitSphere : ((Vector3)(ref val4)).normalized); float value3 = ChoppaConfig.CrashBlast.Value; val3.linearVelocity = impactVelocity * 0.5f + val4 * Random.Range(0.4f, 1f) * value3 * value + Vector3.up * Random.Range(0.3f, 0.8f) * value3 * value; val3.angularVelocity = Random.insideUnitSphere * 12f; ChoppaPhysics.CollideWithEverything(((Component)item).gameObject); ChoppaBonker.Add(((Component)item).gameObject, flag ? 0.8f : Random.Range(0.1f, 0.6f), 1.2f); if ((Object)(object)item == (Object)(object)heli.MainRotor) { val3.linearVelocity += ((Component)heli).transform.up * (value3 * 0.8f * value); val3.angularVelocity = ((Component)heli).transform.up * (heli.RotorSpin * 40f + 5f); } if (value2 > 0f) { Object.Destroy((Object)(object)((Component)item).gameObject, value2 + Random.Range(0f, 3f)); } } Object.Destroy((Object)(object)((Component)heli).gameObject); } } internal static class ChoppaInput { private static bool rewiredBroken; private static bool unityBroken; private static readonly Dictionary<KeyCode, bool> prev = new Dictionary<KeyCode, bool>(); private static readonly Dictionary<KeyCode, bool> cur = new Dictionary<KeyCode, bool>(); public static string ActiveBackend { get; private set; } = "none"; public static void Tick() { //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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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) foreach (KeyCode item in new List<KeyCode>(cur.Keys)) { prev[item] = cur[item]; cur[item] = RawKey(item); } } public static bool Held(KeyCode k) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_0017: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) if ((int)k == 0) { return false; } if (!cur.ContainsKey(k)) { cur[k] = RawKey(k); prev[k] = cur[k]; } return cur[k]; } public static bool Pressed(KeyCode k) { //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) if (Held(k)) { return !prev[k]; } return false; } public static float Axis(KeyCode negative, KeyCode positive) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) return (Held(positive) ? 1f : 0f) - (Held(negative) ? 1f : 0f); } public static Vector2 MouseDelta() { //IL_0076: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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) if (UseRewired()) { try { if (ReInput.isReady) { Mouse mouse = ReInput.controllers.Mouse; ActiveBackend = "Rewired"; return new Vector2(((ControllerWithAxes)mouse).GetAxisRaw(0), ((ControllerWithAxes)mouse).GetAxisRaw(1)); } } catch (Exception e) { MarkRewiredBroken(e); } } if (UseUnity()) { try { ActiveBackend = "Unity"; return new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y")); } catch (Exception e2) { MarkUnityBroken(e2); } } return Vector2.zero; } private static bool RawKey(KeyCode k) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (UseRewired()) { try { if (ReInput.isReady && ReInput.controllers.keyboardEnabled) { return ReInput.controllers.Keyboard.GetKey(k); } } catch (Exception e) { MarkRewiredBroken(e); } } if (UseUnity()) { try { return Input.GetKey(k); } catch (Exception e2) { MarkUnityBroken(e2); } } return false; } private static bool UseRewired() { if (!rewiredBroken) { return ChoppaConfig.Backend.Value != InputBackend.Unity; } return false; } private static bool UseUnity() { if (!unityBroken) { return ChoppaConfig.Backend.Value != InputBackend.Rewired; } return false; } private static void MarkRewiredBroken(Exception e) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown rewiredBroken = true; ManualLogSource l = Plugin.L; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(51, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Rewired input failed, falling back to Unity Input: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(e.Message); } l.LogWarning(val); } private static void MarkUnityBroken(Exception e) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown unityBroken = true; ManualLogSource l = Plugin.L; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(27, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Unity legacy Input failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(e.Message); } l.LogWarning(val); } } internal static class ChoppaLogbook { public struct Flight { public float Seconds; public float Distance; public float MaxAltitude; public float TopSpeedKmh; public float EndSpeedKmh; public float UpsideDownSeconds; public float CockpitPercent; public string How; public int Riders; public int Rolls; public int Loops; } private const string Endpoint = "https://us.i.posthog.com/batch/"; private const string ProjectKey = "phc_ubbcXrLXwRGBKUnLChUj6uzMQpCMNrcmjLALTKQMivbg"; private static readonly HttpClient http = new HttpClient { Timeout = TimeSpan.FromSeconds(10.0) }; private static readonly List<Dictionary<string, object>> queue = new List<Dictionary<string, object>>(); private static float nextFlush; private static bool sending; private static bool On => ChoppaConfig.LogbookEnabled.Value; public static void Spawned() { Log("choppa_spawned", null); } public static void Boarded(bool pilot) { Log("choppa_boarded", new Dictionary<string, object> { ["seat"] = (pilot ? "pilot" : "passenger") }); } public static void FlightEnded(Flight f) { Log("flight_ended", new Dictionary<string, object> { ["duration_s"] = Mathf.Round(f.Seconds), ["distance_m"] = Mathf.Round(f.Distance), ["max_altitude_m"] = Mathf.Round(f.MaxAltitude), ["top_speed_kmh"] = Mathf.Round(f.TopSpeedKmh), ["end_speed_kmh"] = Mathf.Round(f.EndSpeedKmh), ["how"] = f.How, ["riders"] = f.Riders, ["rolls"] = f.Rolls, ["loops"] = f.Loops, ["upside_down_s"] = Mathf.Round(f.UpsideDownSeconds), ["cockpit_view_pct"] = Mathf.Round(f.CockpitPercent) }); } public static void RideEnded(float seconds, string how) { Log("ride_ended", new Dictionary<string, object> { ["duration_s"] = Mathf.Round(seconds), ["how"] = how }); } public static void FlippedUpright(bool seated) { Log("flipped_upright", new Dictionary<string, object> { ["from"] = (seated ? "inside" : "outside") }); } public static void JumpedOut(bool pilot, float height, float speedKmh) { Log("jumped_out", new Dictionary<string, object> { ["seat"] = (pilot ? "pilot" : "passenger"), ["height_m"] = Mathf.Round(height), ["speed_kmh"] = Mathf.Round(speedKmh) }); } private static void Log(string evt, Dictionary<string, object> props) { if (!On) { return; } if (props == null) { props = new Dictionary<string, object>(); } props["distinct_id"] = InstallId(); props["mod_version"] = "1.0.2"; props["$process_person_profile"] = false; props["$geoip_disable"] = true; props["$ip"] = ""; lock (queue) { queue.Add(new Dictionary<string, object> { ["event"] = evt, ["properties"] = props, ["timestamp"] = DateTime.UtcNow.ToString("o") }); if (queue.Count > 200) { queue.RemoveAt(0); } } Plugin.Verbose("Logbook: " + evt); } private static string InstallId() { string text = ChoppaConfig.LogbookInstallId.Value; if (string.IsNullOrEmpty(text)) { text = Guid.NewGuid().ToString("N"); ChoppaConfig.LogbookInstallId.Value = text; } return text; } public static void Tick() { if (Time.unscaledTime < nextFlush) { return; } nextFlush = Time.unscaledTime + 30f; string json = TakeBatch(); if (json == null || sending) { return; } sending = true; Task.Run(async delegate { try { await http.PostAsync("https://us.i.posthog.com/batch/", new StringContent(json, Encoding.UTF8, "application/json")); } catch { } finally { sending = false; } }); } public static void FlushNow() { string text = TakeBatch(); if (text == null) { return; } try { http.PostAsync("https://us.i.posthog.com/batch/", new StringContent(text, Encoding.UTF8, "application/json")).Wait(TimeSpan.FromSeconds(2.0)); } catch { } } private static string TakeBatch() { lock (queue) { if (queue.Count == 0) { return null; } if (!On) { queue.Clear(); return null; } string result = JsonSerializer.Serialize(new Dictionary<string, object> { ["api_key"] = "phc_ubbcXrLXwRGBKUnLChUj6uzMQpCMNrcmjLALTKQMivbg", ["batch"] = queue }); queue.Clear(); return result; } } } public class ChoppaManager : MonoBehaviour { private enum CamMode { Chase, Cockpit } private PlayerCharacter local; private float nextPlayerSearch; private readonly Dictionary<uint, Helicopter> helis = new Dictionary<uint, Helicopter>(); private readonly Dictionary<uint, PlayerCharacter> players = new Dictionary<uint, PlayerCharacter>(); private readonly Dictionary<uint, float> sendTimers = new Dictionary<uint, float>(); private float nextPlayerScan; private int choppaLayer = -1; private bool seated; private Helicopter seatHeli; private int seatIndex; private uint pendingBoardId; private float pendingBoardUntil; private uint pendingSpawnId; private Rigidbody playerBody; private Transform playerRoot; private Collider[] playerColliders = Array.Empty<Collider>(); private bool savedKinematic; private bool savedDetect; private bool savedBypassUpdate; private bool savedBypassFixed; private bool savedBypassLate; private RigidbodyInterpolation savedInterp; private Transform kernal; private Quaternion savedKernalLocalRot; private Camera cam; private Transform camParent; private Vector3 camLocalPos; private Quaternion camLocalRot; private Vector3 eyeOffset; private CamMode camMode; private Vector2 smoothedCyclic; private float lookYaw; private float lookPitch; private Vector3 chaseVel; private bool showHud; private string lastHint; private Helicopter spawnHeli; private float spawnY; private float spawnCheckAt = -1f; private float flightStart = -1f; private float flightMaxAlt; private float flightTopSpeed; private float flightDistance; private float groundedSince = -1f; private float flightUpsideDown; private float flightCockpitTime; private float flightRollAccum; private float flightPitchAccum; private float rideStart = -1f; private int flightRolls; private int flightLoops; private Vector3 flightLastPos; private float hintUntil; private uint Me => ChoppaNet.LocalNetId; public ChoppaManager(IntPtr ptr) : base(ptr) { } private void Start() { showHud = ChoppaConfig.ShowHud.Value; Helicopter.Crashed += OnOwnCrash; ChoppaNet.ServerReceived = ChoppaServer.OnMessage; ChoppaNet.ClientReceived = OnClientMessage; ChoppaNet.ModeChanged = ClearWorld; } private void OnDestroy() { Helicopter.Crashed -= OnOwnCrash; } private void OnApplicationQuit() { ChoppaLogbook.FlushNow(); } private void Update() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown try { Tick(); } catch (Exception ex) { ManualLogSource l = Plugin.L; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(22, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ChoppaManager.Update: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex); } l.LogError(val); } } private void Tick() { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Invalid comparison between Unknown and I4 //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) ChoppaInput.Tick(); ChoppaNet.Tick(); if (!FindLocalPlayer()) { if (seated) { ForceUnseat("local player disappeared"); } return; } ChoppaNet.LocalNetId = ((((NetworkBehaviour)local).netId == 0) ? 1u : ((NetworkBehaviour)local).netId); PruneDead(); if (Time.unscaledTime >= nextPlayerScan) { ScanPlayers(); } bool flag = !ChoppaConfig.RequireCursorLock.Value || (int)Cursor.lockState == 1; if (flag && ChoppaInput.Pressed(ChoppaConfig.HudKey.Value)) { showHud = !showHud; } if (flag && ChoppaInput.Pressed(ChoppaConfig.SpawnKey.Value) && !seated) { RequestSpawn(); } if (flag && ChoppaInput.Pressed(ChoppaConfig.ResetKey.Value)) { ResetMine(); } if (flag && ChoppaInput.Pressed(ChoppaConfig.EnterExitKey.Value)) { if (seated) { Leave(); } else { TryBoard(); } } if (pendingBoardId != 0 && Time.time > pendingBoardUntil) { pendingBoardId = 0u; Hint("Couldn't board - the seat was taken or the host didn't answer."); } CheckSpawnSettled(); foreach (Helicopter value in helis.Values) { if (!value.IsProxy && (!seated || !((Object)(object)seatHeli == (Object)(object)value) || seatIndex != 0)) { value.CommandedRates = Vector3.zero; } } if (seated && seatIndex == 0 && !seatHeli.IsProxy) { FlyInput(flag); TrackFlight(seatHeli); } SendStates(); ChoppaLogbook.Tick(); } private void FixedUpdate() { if (seated) { PinPlayer(); } PinRemotePassengers(); } private void LateUpdate() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown try { PinRemotePassengers(); if (seated) { PinPlayer(); UpdateCamera(); } } catch (Exception ex) { ManualLogSource l = Plugin.L; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(26, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ChoppaManager.LateUpdate: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex); } l.LogError(val); } } private bool FindLocalPlayer() { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown if ((Object)(object)local != (Object)null && Alive((Object)(object)local)) { return true; } local = null; if (Time.unscaledTime < nextPlayerSearch) { return false; } nextPlayerSearch = Time.unscaledTime + 1f; bool flag = default(bool); foreach (PlayerCharacter item in Object.FindObjectsByType<PlayerCharacter>((FindObjectsSortMode)0)) { if (!((Object)(object)item == (Object)null) && ((NetworkBehaviour)item).isLocalPlayer) { local = item; ManualLogSource l = Plugin.L; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(29, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Found local player '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)((Component)item).gameObject).name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' netId "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<uint>(((NetworkBehaviour)item).netId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } l.LogInfo(val); return true; } } return false; } private void ScanPlayers() { nextPlayerScan = Time.unscaledTime + 1f; players.Clear(); foreach (PlayerCharacter item in Object.FindObjectsByType<PlayerCharacter>((FindObjectsSortMode)0)) { if ((Object)(object)item != (Object)null && ((NetworkBehaviour)item).netId != 0) { players[((NetworkBehaviour)item).netId] = item; } } if ((Object)(object)local != (Object)null) { players[Me] = local; } if (ChoppaNet.Mode == ChoppaNet.NetMode.Host) { ChoppaServer.Prune(ChoppaNet.ConnectedPlayers(), Me); } else if (ChoppaNet.Mode == ChoppaNet.NetMode.Offline) { ChoppaServer.Prune(new HashSet<uint> { Me }, Me); } } private PlayerCharacter Player(uint netId) { if (netId == 0) { return null; } if (players.TryGetValue(netId, out var value) && Alive((Object)(object)value)) { return value; } return null; } private string NameOf(uint netId) { if (netId == Me) { return "you"; } try { PlayerCharacter obj = Player(netId); object obj2; if (obj == null) { obj2 = null; } else { PlayerNetworking playerNetworking = obj.playerNetworking; obj2 = ((playerNetworking != null) ? playerNetworking.username : null); } string text = (string)obj2; if (!string.IsNullOrEmpty(text)) { return text; } } catch { } return $"player {netId}"; } private void OnClientMessage(Msg type, BinaryReader r) { //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_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) switch (type) { case Msg.Spawn: { uint id = r.ReadUInt32(); uint owner = r.ReadUInt32(); OnSpawned(id, owner, r.ReadVector3(), r.ReadQuaternion()); break; } case Msg.State: { if (helis.TryGetValue(r.ReadUInt32(), out var value4)) { value4.ReadState(r); } break; } case Msg.Seats: { uint key3 = r.ReadUInt32(); int num3 = r.ReadByte(); uint[] array = new uint[3]; for (int i = 0; i < num3; i++) { uint num4 = r.ReadUInt32(); if (i < array.Length) { array[i] = num4; } } if (helis.TryGetValue(key3, out var value5)) { OnSeats(value5, array); } break; } case Msg.Owner: { uint num = r.ReadUInt32(); uint num2 = r.ReadUInt32(); if (helis.TryGetValue(num, out var value3)) { value3.Owner = num2; value3.SetProxy(num2 != Me); Plugin.Verbose($"Choppa {num:X8} now simulated by {NameOf(num2)}."); } break; } case Msg.Crash: { uint key2 = r.ReadUInt32(); Vector3 impact = r.ReadVector3(); int seed = r.ReadInt32(); if (helis.TryGetValue(key2, out var value2)) { HandleCrash(value2, impact, seed); } break; } case Msg.Despawn: { uint key = r.ReadUInt32(); if (helis.TryGetValue(key, out var value)) { if (seated && (Object)(object)seatHeli == (Object)(object)value) { ForceUnseat("choppa removed"); } helis.Remove(key); if (Alive((Object)(object)value)) { Object.Destroy((Object)(object)((Component)value).gameObject); } } break; } case Msg.Board: case Msg.Leave: break; } } private void OnSpawned(uint id, uint owner, Vector3 pos, Quaternion rot) { //IL_0055: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_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_00d0: 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) if (!helis.ContainsKey(id) && !((Object)(object)local == (Object)null)) { if (choppaLayer < 0) { choppaLayer = PickLayer(GroundBelow(pos + Vector3.up * 2f, 10f, out var _)); } Helicopter helicopter = Helicopter.Build(id, pos, rot, choppaLayer, ((Component)local).gameObject.scene); helicopter.Owner = owner; helicopter.SetProxy(owner != Me); helis[id] = helicopter; ManualLogSource l = Plugin.L; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(24, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Choppa "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<uint>(id, "X8"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" spawned at "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Vector3>(pos); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" by "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(NameOf(owner)); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(helicopter.IsProxy ? " (remote)" : ""); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } l.LogInfo(val); if (id == pendingSpawnId) { pendingSpawnId = 0u; spawnHeli = helicopter; ChoppaLogbook.Spawned(); spawnY = pos.y; spawnCheckAt = Time.time + 2f; } } } private void OnSeats(Helicopter h, uint[] occ) { uint[] occupants = h.Occupants; for (int i = 0; i < occ.Length; i++) { if (occupants[i] != occ[i]) { if (occupants[i] != 0 && occupants[i] != Me) { IgnoreRemote(h, occupants[i], ignore: false); } if (occ[i] != 0 && occ[i] != Me) { IgnoreRemote(h, occ[i], ignore: true); } } } h.Occupants = occ; if (!h.IsProxy) { h.EngineOn = occ[0] != 0; } int num = Array.IndexOf(occ, Me); if (seated && (Object)(object)seatHeli == (Object)(object)h && num != seatIndex) { if (num < 0) { ForceUnseat("host removed us from the seat"); } else { seatIndex = num; } } else if (!seated && num >= 0 && pendingBoardId == h.Id) { pendingBoardId = 0u; Seat(h, num); } } private void IgnoreRemote(Helicopter h, uint netId, bool ignore) { PlayerCharacter val = Player(netId); if ((Object)(object)val == (Object)null) { return; } foreach (Collider componentsInChild in ((Component)h).GetComponentsInChildren<Collider>(true)) { foreach (Collider componentsInChild2 in ((Component)val).GetComponentsInChildren<Collider>(true)) { if ((Object)(object)componentsInChild != (Object)null && (Object)(object)componentsInChild2 != (Object)null) { Physics.IgnoreCollision(componentsInChild, componentsInChild2, ignore); } } } } private void PinRemotePassengers() { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) foreach (Helicopter value in helis.Values) { if ((Object)(object)value == (Object)null || value.Broken) { continue; } for (int i = 0; i < 3; i++) { uint num = value.Occupants[i]; if (num != 0 && num != Me) { PlayerCharacter val = Player(num); if (!((Object)(object)val == (Object)null)) { Transform val2 = value.Seats[i]; ((Component)val).transform.SetPositionAndRotation(val2.position, val2.rotation); } } } } } private void SendStates() { //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) ChoppaNet.NetMode mode = ChoppaNet.Mode; bool flag = (uint)(mode - 2) <= 1u; if (!flag || !ChoppaNet.Ready) { return; } foreach (Helicopter value2 in helis.Values) { if (value2.IsProxy || value2.Broken || value2.Owner != Me) { continue; } int num; if (!value2.Occupants.Any((uint o) => o != 0)) { Vector3 linearVelocity = value2.Body.linearVelocity; num = ((((Vector3)(ref linearVelocity)).sqrMagnitude > 0.01f) ? 1 : 0); } else { num = 1; } bool flag2 = (byte)num != 0; float num2 = 1f / Mathf.Max(1f, flag2 ? ChoppaConfig.NetSendRate.Value : 2f); sendTimers.TryGetValue(value2.Id, out var value); value -= Time.deltaTime; if (value <= 0f) { value += num2; if (value < 0f) { value = num2; } ChoppaNet.ToServer(ChoppaNet.Write(Msg.State, value2.WriteState), reliable: false); } sendTimers[value2.Id] = value; } } private void PruneDead() { List<uint> list = null; foreach (KeyValuePair<uint, Helicopter> heli in helis) { if (!Alive((Object)(object)heli.Value)) { (list ?? (list = new List<uint>())).Add(heli.Key); } } if (list == null) { return; } foreach (uint item in list) { if (seated && (Object)(object)seatHeli != (Object)null && !Alive((Object)(object)seatHeli)) { ForceUnseat("choppa destroyed"); } helis.Remove(item); sendTimers.Remove(item); } } private void ClearWorld() { if (seated) { ForceUnseat("network session changed"); } foreach (Helicopter value in helis.Values) { if (Alive((Object)(object)value)) { Object.Destroy((Object)(object)((Component)value).gameObject); } } helis.Clear(); sendTimers.Clear(); pendingBoardId = (pendingSpawnId = 0u); ChoppaServer.Reset(); } private void RequestSpawn() { //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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) if (!ChoppaNet.Ready) { Hint("Waiting for the host's Big Choppa to answer (does the host have the mod?)."); return; } Transform transform = ((Component)local).transform; Vector3 val = Vector3.ProjectOnPlane(transform.forward, Vector3.up); Vector3 val2 = ((Vector3)(ref val)).normalized; if (((Vector3)(ref val2)).sqrMagnitude < 0.01f) { val2 = Vector3.forward; } float value = ChoppaConfig.HeliScale.Value; Vector3 pos = transform.position + val2 * (6f * value); Vector3 point; Collider val3 = GroundBelow(pos + Vector3.up * 30f, 80f, out point); if ((Object)(object)val3 != (Object)null) { pos = point + Vector3.up * 0.15f; } if (choppaLayer < 0) { choppaLayer = PickLayer(val3); } Quaternion rot = Quaternion.LookRotation(Vector3.Cross(Vector3.up, val2), Vector3.up); foreach (Helicopter value2 in helis.Values) { if (value2.Owner == Me && value2.Occupants.All((uint o) => o == 0)) { uint oldId = value2.Id; ChoppaNet.ToServer(ChoppaNet.Write(Msg.Despawn, delegate(BinaryWriter w) { w.Write(oldId); }), reliable: true); } } uint id; do { id = (uint)(Random.Range(1, int.MaxValue) ^ (Random.Range(0, 2) << 31)); } while (id == 0 || helis.ContainsKey(id)); pendingSpawnId = id; ChoppaNet.ToServer(ChoppaNet.Write(Msg.Spawn, delegate(BinaryWriter w) { //IL_000e: 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) w.Write(id); w.Write(pos); w.Write(rot); }), reliable: true); } private void CheckSpawnSettled() { //IL_0053: 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: Expected O, but got Unknown if (spawnCheckAt < 0f || Time.time < spawnCheckAt) { return; } spawnCheckAt = -1f; if ((Object)(object)spawnHeli == (Object)null || !Alive((Object)(object)spawnHeli)) { return; } float num = spawnY - ((Component)spawnHeli).transform.position.y; if (num > 1f) { ManualLogSource l = Plugin.L; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(73, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Choppa fell "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(num, "0.0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("m in 2s after spawning - still not colliding with the ground."); } l.LogWarning(val); } else { Plugin.Verbose($"Choppa settled (moved {num:0.00}m vertically). Grounded={spawnHeli.Grounded}"); } } private void ResetMine() { Helicopter helicopter = null; if (seated && !seatHeli.IsProxy) { helicopter = seatHeli; } else { float num = ChoppaConfig.EnterDistance.Value * ChoppaConfig.HeliScale.Value * 3f; foreach (Helicopter value in helis.Values) { if (!value.IsProxy) { float num2 = DistanceTo(value); if (num2 < num) { num = num2; helicopter = value; } } } } if ((Object)(object)helicopter != (Object)null) { ChoppaLogbook.FlippedUpright(seated); helicopter.ResetUpright(); } else { Hint("Get in or next to a choppa you're flying to flip it upright."); } } private Collider GroundBelow(Vector3 origin, float distance, out Vector3 point) { //IL_0001: 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_0010: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) point = default(Vector3); Collider result = null; float num = float.MaxValue; foreach (RaycastHit item in (Il2CppArrayBase<RaycastHit>)(object)Physics.RaycastAll(origin, Vector3.down, distance, -1, (QueryTriggerInteraction)1)) { RaycastHit current = item; Collider collider = ((RaycastHit)(ref current)).collider; if (!((Object)(object)collider == (Object)null) && !(((RaycastHit)(ref current)).distance >= num) && !((Component)collider).transform.IsChildOf(((Component)local).transform) && !((Object)(object)((Component)collider).GetComponentInParent<Helicopter>() != (Object)null)) { result = collider; num = ((RaycastHit)(ref current)).distance; point = ((RaycastHit)(ref current)).point; } } return result; } private int PickLayer(Collider rayGround) { int value = ChoppaConfig.ChoppaLayer.Value; if (value >= 0 && value < 32) { return value; } int num = -1; try { PlayerGround ground = local.ground; Collider val = ((ground != null) ? ground.groundCollider : null); if ((Object)(object)val != (Object)null) { num = ((Component)val).gameObject.layer; } } catch (Exception ex) { Plugin.Verbose("PlayerGround lookup failed: " + ex.Message); } if (num < 0 && (Object)(object)rayGround != (Object)null) { num = ((Component)rayGround).gameObject.layer; } if (num < 0) { num = 0; } int[] array = new int[32]; foreach (Rigidbody item in Object.FindObjectsByType<Rigidbody>((FindObjectsSortMode)0)) { if (!((Object)(object)item == (Object)null) && !item.isKinematic && !((Object)(object)((Component)item).GetComponentInParent<PlayerCharacter>() != (Object)null) && !((Object)(object)((Component)item).GetComponentInParent<Helicopter>() != (Object)null)) { int layer = ((Component)item).gameObject.layer; if (!Physics.GetIgnoreLayerCollision(layer, num)) { array[layer]++; } } } int num2 = -1; for (int i = 0; i < 32; i++) { if (array[i] > 0 && (num2 < 0 || array[i] > array[num2])) { num2 = i; } } if (num2 >= 0) { return num2; } int layer2 = (((Object)(object)local.rb != (Object)null) ? ((Component)local.rb).gameObject : ((Component)local).gameObject).layer; if (!Physics.GetIgnoreLayerCollision(layer2, num)) { return layer2; } for (int j = 0; j < 32; j++) { if (!Physics.GetIgnoreLayerCollision(j, num)) { return j; } } return 0; } private float DistanceTo(Helicopter h) { //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_0011: 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_0039: 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_003c: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)local).transform.position; float num = Vector3.Distance(position, ((Component)h).transform.position); foreach (Collider componentsInChild in ((Component)h).GetComponentsInChildren<Collider>()) { num = Mathf.Min(num, Vector3.Distance(position, componentsInChild.ClosestPoint(position))); } return num; } private Helicopter NearestBoardable(out float dist) { Helicopter result = null; dist = float.MaxValue; float num = ChoppaConfig.EnterDistance.Value * ChoppaConfig.HeliScale.Value; foreach (Helicopter value in helis.Values) { if (!((Object)(object)value == (Object)null) && !value.Broken) { float num2 = DistanceTo(value); if (num2 < dist) { dist = num2; result = value; } } } if (!(dist <= num)) { return null; } return result; } private static int FreeSeat(Helicopter h) { for (int i = 0; i < 3; i++) { if (h.Occupants[i] == 0) { return i; } } return -1; } private void TryBoard() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (helis.Count == 0) { Hint($"No choppa yet - press {ChoppaConfig.SpawnKey.Value} to spawn one."); return; } float dist; Helicopter helicopter = NearestBoardable(out dist); if ((Object)(object)helicopter == (Object)null) { Hint($"Too far from a choppa ({dist:0.0}m, need {ChoppaConfig.EnterDistance.Value * ChoppaConfig.HeliScale.Value:0.0}m)."); return; } int num = FreeSeat(helicopter); if (num < 0) { Hint("That choppa is full."); return; } pendingBoardId = helicopter.Id; pendingBoardUntil = Time.time + 3f; byte s = (byte)num; uint id = helicopter.Id; ChoppaNet.ToServer(ChoppaNet.Write(Msg.Board, delegate(BinaryWriter w) { w.Write(id); w.Write(s); }), reliable: true); } private void Seat(Helicopter h, int index) { //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) seatHeli = h; seatIndex = index; playerBody = local.rb; playerRoot = (((Object)(object)playerBody != (Object)null) ? ((Component)playerBody).transform : ((Component)local).transform); savedBypassUpdate = local.bypassUpdate; savedBypassFixed = local.bypassFixedUpdate; savedBypassLate = local.bypassLateUpdate; local.bypassUpdate = true; local.bypassFixedUpdate = true; local.bypassLateUpdate = true; if ((Object)(object)playerBody != (Object)null) { savedKinematic = playerBody.isKinematic; savedDetect = playerBody.detectCollisions; savedInterp = playerBody.interpolation; playerBody.linearVelocity = Vector3.zero; playerBody.isKinematic = true; playerBody.detectCollisions = false; playerBody.interpolation = (RigidbodyInterpolation)0; } playerColliders = ((IEnumerable<Collider>)((Component)local).GetComponentsInChildren<Collider>(true)).ToArray(); foreach (Collider componentsInChild in ((Component)h).GetComponentsInChildren<Collider>(true)) { Collider[] array = playerColliders; foreach (Collider val in array) { Physics.IgnoreCollision(componentsInChild, val, true); } } if (ChoppaConfig.SitWhileFlying.Value) { SetSitting(sitting: true); } kernal = local.kernal; if ((Object)(object)kernal != (Object)null) { savedKernalLocalRot = kernal.localRotation; } cam = null; try { PlayerCameraMinder cameraMinder = local.cameraMinder; object obj; if (cameraMinder == null) { obj = null; } else { PlayerCameraReferences playerCameraReferences = cameraMinder.playerCameraReferences; obj = ((playerCameraReferences != null) ? playerCameraReferences.playerCamera : null); } cam = (Camera)obj; } catch (Exception ex) { Plugin.Verbose("cameraMinder lookup failed: " + ex.Message); } if ((Object)(object)cam == (Object)null) { cam = Camera.main; } if ((Object)(object)cam != (Object)null) { eyeOffset = playerRoot.InverseTransformPoint(((Component)cam).transform.position); camParent = ((Component)cam).transform.parent; camLocalPos = ((Component)cam).transform.localPosition; camLocalRot = ((Component)cam).transform.localRotation; ((Component)cam).transform.SetParent((Transform)null, true); } else { Plugin.L.LogWarning((object)"No camera found to take over; flying with whatever the game does."); } seated = true; flightStart = -1f; rideStart = ((index == 0) ? (-1f) : Time.time); ChoppaLogbook.Boarded(index == 0); if (index == 0 && !h.IsProxy) { h.EngineOn = true; h.Collective = 0f; } smoothedCyclic = Vector2.zero; lookYaw = (lookPitch = 0f); PinPlayer(); Plugin.L.LogInfo((object)((index == 0) ? "Boarded choppa as pilot. Engine starting." : $"Boarded choppa as passenger (seat {index}).")); } private void Leave() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_011b: 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_011e: Unknown result type (might be due to invalid IL or missing references) Helicopter helicopter = seatHeli; int num = seatIndex; Vector3 position = helicopter.Exits[num].position; Vector3 velocity = helicopter.Velocity; Vector3 val = Vector3.ProjectOnPlane(((Component)helicopter).transform.forward, Vector3.up); Quaternion rot = Quaternion.LookRotation(((Vector3)(ref val)).normalized + Vector3.forward * 0.0001f, Vector3.up); if (num == 0 && !helicopter.IsProxy) { helicopter.EngineOn = false; helicopter.CommandedRates = Vector3.zero; } float num2 = Altitude(helicopter); if (num2 > 1.5f) { ChoppaLogbook.JumpedOut(num == 0, num2, ((Vector3)(ref velocity)).magnitude * 3.6f); } if (num == 0) { EndFlight(helicopter, helicopter.Grounded ? "landed" : "bailed", ((Vector3)(ref velocity)).magnitude * 3.6f); } else { EndRide((num2 > 1.5f) ? "jumped out" : "got out"); } uint id = helicopter.Id; ChoppaNet.ToServer(ChoppaNet.Write(Msg.Leave, delegate(BinaryWriter w) { w.Write(id); }), reliable: true); Restore(position, rot, velocity); Plugin.L.LogInfo((object)"Left choppa."); } private void ForceUnseat(string why) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_004d: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) ManualLogSource l = Plugin.L; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(22, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Forced out of choppa: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(why); } l.LogWarning(val); try { if ((Object)(object)local != (Object)null && Alive((Object)(object)local)) { Restore(playerRoot.position, Quaternion.Euler(0f, playerRoot.eulerAngles.y, 0f), Vector3.zero); } else { RestoreCamera(); } } catch (Exception ex) { Plugin.L.LogError((object)ex); } seated = false; seatHeli = null; } private void Restore(Vector3 pos, Quaternion rot, Vector3 vel) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_0047: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) seated = false; if (ChoppaConfig.SitWhileFlying.Value) { SetSitting(sitting: false); } playerRoot.SetPositionAndRotation(pos, rot); if ((Object)(object)playerBody != (Object)null) { playerBody.position = pos; playerBody.rotation = rot; playerBody.isKinematic = savedKinematic; playerBody.detectCollisions = savedDetect; playerBody.interpolation = savedInterp; if (!playerBody.isKinematic) { playerBody.linearVelocity = vel; } } if ((Object)(object)kernal != (Object)null && Alive((Object)(object)kernal)) { kernal.localRotation = savedKernalLocalRot; } kernal = null; local.bypassUpdate = savedBypassUpdate; local.bypassFixedUpdate = savedBypassFixed; local.bypassLateUpdate = savedBypassLate; if ((Object)(object)seatHeli != (Object)null && Alive((Object)(object)seatHeli)) { foreach (Collider componentsInChild in ((Component)seatHeli).GetComponentsInChildren<Collider>(true)) { Collider[] array = playerColliders; foreach (Collider val in array) { if ((Object)(object)componentsInChild != (Object)null && (Object)(object)val != (Object)null) { Physics.IgnoreCollision(componentsInChild, val, false); } } } } seatHeli = null; RestoreCamera(); } private void RestoreCamera() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)cam == (Object)null) && Alive((Object)(object)cam)) { ((Component)cam).transform.SetParent(camParent, false); ((Component)cam).transform.localPosition = camLocalPos; ((Component)cam).transform.localRotation = camLocalRot; cam = null; } } private void SetSitting(bool sitting) { try { PlayerSitter sitter = local.sitter; if (sitter != null) { sitter.SetSittingLocal(sitting); } } catch (Exception ex) { Plugin.Verbose($"SetSittingLocal({sitting}) failed: {ex.Message}"); } try { PlayerNetworking playerNetworking = local.playerNetworking; if (playerNetworking != null) { playerNetworking.CmdSetSitting(sitting); } } catch (Exception ex2) { Plugin.Verbose($"CmdSetSitting({sitting}) failed: {ex2.Message}"); } } private void PinPlayer() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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_007a: 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) if (!((Object)(object)seatHeli == (Object)null) && Alive((Object)(object)seatHeli) && !((Object)(object)playerRoot == (Object)null)) { Transform val = seatHeli.Seats[seatIndex]; playerRoot.SetPositionAndRotation(val.position, val.rotation); if ((Object)(object)playerBody != (Object)null) { playerBody.position = val.position; playerBody.rotation = val.rotation; } if ((Object)(object)kernal != (Object)null) { kernal.rotation = val.rotation; } } } private void FlyInput(bool inputAllowed) { //IL_0021: 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) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: 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_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_0192: 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_0212: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) Helicopter helicopter = seatHeli; float num = Mathf.Max(Time.deltaTime, 0.0001f); Vector2 val = (inputAllowed ? ChoppaInput.MouseDelta() : Vector2.zero); bool num2 = inputAllowed && ChoppaInput.Held(ChoppaConfig.FreeLookKey.Value); if (inputAllowed && ChoppaInput.Pressed(ChoppaConfig.CameraKey.Value)) { camMode = ((camMode == CamMode.Chase) ? CamMode.Cockpit : CamMode.Chase); } float num3 = (inputAllowed ? ChoppaInput.Axis(ChoppaConfig.CollectiveDownKey.Value, ChoppaConfig.CollectiveUpKey.Value) : 0f); if (!ChoppaConfig.CollectiveSpringBack.Value) { helicopter.Collective = Mathf.Clamp01(helicopter.Collective + num3 * ChoppaConfig.CollectiveRate.Value * num); } else if (num3 != 0f) { helicopter.Collective = Mathf.MoveTowards(helicopter.Collective, (num3 > 0f) ? 1f : 0f, ChoppaConfig.CollectiveRate.Value * num); } else { float num4 = 0f; if (!helicopter.Grounded) { num4 = helicopter.HoverCollective; if (ChoppaConfig.HoverTiltCompensation.Value) { num4 /= Mathf.Max(0.75f, Vector3.Dot(((Component)helicopter).transform.up, Vector3.up)); } } helicopter.Collective = Mathf.MoveTowards(helicopter.Collective, Mathf.Clamp01(num4), ChoppaConfig.CollectiveReturnRate.Value * num); } float num5 = (inputAllowed ? ChoppaInput.Axis(ChoppaConfig.PedalLeftKey.Value, ChoppaConfig.PedalRightKey.Value) : 0f); Vector2 zero = Vector2.zero; if (num2) { lookYaw = Mathf.Clamp(lookYaw + val.x * 2f, -160f, 160f); lookPitch = Mathf.Clamp(lookPitch - val.y * 2f, -70f, 70f); } else { float num6 = ChoppaConfig.MouseSensitivity.Value / num; float num7 = val.y * num6 * (ChoppaConfig.InvertPitch.Value ? (-1f) : 1f); float num8 = (0f - val.x) * num6 * (ChoppaConfig.InvertRoll.Value ? (-1f) : 1f); float value = ChoppaConfig.MaxPitchRollRate.Value; ((Vector2)(ref zero))..ctor(Mathf.Clamp(num7, 0f - value, value), Mathf.Clamp(num8, 0f - value, value)); float num9 = 1f - Mathf.Exp((0f - num) * 8f); lookYaw = Mathf.Lerp(lookYaw, 0f, num9); lookPitch = Mathf.Lerp(lookPitch, 0f, num9); } float value2 = ChoppaConfig.MouseSmoothing.Value; float num10 = ((value2 <= 0f) ? 1f : (1f - Mathf.Exp((0f - num) / value2))); smoothedCyclic = Vector2.Lerp(smoothedCyclic, zero, num10); helicopter.CommandedRates = new Vector3(smoothedCyclic.x, num5 * ChoppaConfig.YawRate.Value, smoothedCyclic.y); } private void UpdateCamera() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Invalid comparison between Unknown and I4 //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: 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_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: 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_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0217: 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_0221: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0244: 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_0261: Unknown result type (might be due to invalid IL or missing references) //IL_026e: 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_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0295: 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_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: 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_0147: Unknown result type (might be due to invalid IL or missing references) //IL_015d: 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_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_00ac: 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) if ((Object)(object)cam == (Object)null || !Alive((Object)(object)cam) || (Object)(object)seatHeli == (Object)null || !Alive((Object)(object)seatHeli)) { return; } Transform transform = ((Component)seatHeli).transform; bool num = seatIndex == 0 && !seatHeli.IsProxy; bool flag = !ChoppaConfig.RequireCursorLock.Value || (int)Cursor.lockState == 1; if (!num && flag) { if (ChoppaInput.Pressed(ChoppaConfig.CameraKey.Value)) { camMode = ((camMode == CamMode.Chase) ? CamMode.Cockpit : CamMode.Chase); } Vector2 val = ChoppaInput.MouseDelta(); lookYaw = Mathf.Clamp(lookYaw + val.x * 2f, -170f, 170f); lookPitch = Mathf.Clamp(lookPitch - val.y * 2f, -70f, 70f); } if (camMode == CamMode.Cockpit) { Vector3 val2 = seatHeli.Seats[seatIndex].TransformPoint(eyeOffset) + transform.up * ChoppaConfig.CockpitEyeHeight.Value; ((Component)cam).transform.SetPositionAndRotation(val2, transform.rotation * Quaternion.Euler(lookPitch, lookYaw, 0f)); return; } float value = ChoppaConfig.HeliScale.Value; Vector3 val3 = Vector3.ProjectOnPlane(transform.forward, Vector3.up); Quaternion val4 = Quaternion.LookRotation(((Vector3)(ref val3)).normalized + Vector3.forward * 0.0001f); float y = ((Quaternion)(ref val4)).eulerAngles.y; Quaternion val5 = Quaternion.Euler(10f + lookPitch, y + lookYaw, 0f); Vector3 val6 = transform.position + Vector3.up * (2f * value); Vector3 val7 = val6 + val5 * new Vector3(0f, 0f, (0f - ChoppaConfig.ChaseDistance.Value) * value) + Vector3.up * (ChoppaConfig.ChaseHeight.Value * value - 2f * value); ((Component)cam).transform.position = Vector3.SmoothDamp(((Component)cam).transform.position, val7, ref chaseVel, 0.12f); ((Component)cam).transform.rotation = Quaternion.LookRotation(val6 - ((Component)cam).transform.position, Vector3.up); } private static float Altitude(Helicopter h) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) float num = -1f; foreach (RaycastHit item in (Il2CppArrayBase<RaycastHit>)(object)Physics.RaycastAll(((Component)h).transform.position + Vector3.up * 0.5f, Vector3.down, 2000f, -1, (QueryTriggerInteraction)1)) { RaycastHit current = item; if (!((Object)(object)((RaycastHit)(ref current)).collider == (Object)null) && !((Component)((RaycastHit)(ref current)).collider).transform.IsChildOf(((Component)h).transform) && !((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<PlayerCharacter>() != (Object)null) && (num < 0f || ((RaycastHit)(ref current)).distance < num)) { num = ((RaycastHit)(ref current)).distance; } } if (!(num < 0f)) { return Mathf.Max(0f, num - 0.5f); } return -1f; } private void TrackFlight(Helicopter h) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: 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_0107: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01af: 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_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) Vector3 val2; if (!h.Grounded) { groundedSince = -1f; Vector3 position = ((Component)h).transform.position; if (flightStart < 0f) { flightStart = Time.time; flightMaxAlt = (flightTopSpeed = (flightDistance = 0f)); flightUpsideDown = (flightCockpitTime = (flightRollAccum = (flightPitchAccum = 0f))); flightRolls = (flightLoops = 0); flightLastPos = position; } float deltaTime = Time.deltaTime; if (Vector3.Dot(((Component)h).transform.up, Vector3.up) < 0f) { flightUpsideDown += deltaTime; } if (camMode == CamMode.Cockpit) { flightCockpitTime += deltaTime; } Vector3 val = ((Component)h).transform.InverseTransformDirection(h.Body.angularVelocity) * (57.29578f * deltaTime); flightRollAccum += val.z; flightPitchAccum += val.x; while (Mathf.Abs(flightRollAccum) >= 360f) { flightRolls++; flightRollAccum -= Mathf.Sign(flightRollAccum) * 360f; } while (Mathf.Abs(flightPitchAccum) >= 360f) { flightLoops++; flightPitchAccum -= Mathf.Sign(flightPitchAccum) * 360f; } flightDistance += Vector3.Distance(position, flightLastPos); flightLastPos = position; flightMaxAlt = Mathf.Max(flightMaxAlt, Altitude(h)); float num = flightTopSpeed; val2 = h.Body.linearVelocity; flightTopSpeed = Mathf.Max(num, ((Vector3)(ref val2)).magnitude * 3.6f); } else if (flightStart >= 0f) { if (groundedSince < 0f) { groundedSince = Time.time; } else if (Time.time - groundedSince > 2f) { val2 = h.Velocity; EndFlight(h, "landed", ((Vector3)(ref val2)).magnitude * 3.6f); } } } private void EndFlight(Helicopter h, string how, float endSpeedKmh) { if (flightStart < 0f) { return; } float num = Time.time - flightStart; flightStart = -1f; groundedSince = -1f; if (!(num < 1f)) { ChoppaLogbook.FlightEnded(new ChoppaLogbook.Flight { Seconds = num, Distance = flightDistance, MaxAltitude = flightMaxAlt, TopSpeedKmh = flightTopSpeed, EndSpeedKmh = endSpeedKmh, How = how, Riders = h.Occupants.Count((uint o) => o != 0), Rolls = flightRolls, Loops = flightLoops, UpsideDownSeconds = flightUpsideDown, CockpitPercent = 100f * flightCockpitTime / num }); } } private void EndRide(string how) { if (!(rideStart < 0f)) { float seconds = Time.time - rideStart; rideStart = -1f; ChoppaLogbook.RideEnded(seconds, how); } } private void OnOwnCrash(Helicopter crashed, float deltaV) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) int seed = Random.Range(int.MinValue, int.MaxValue); uint id = crashed.Id; Vector3 impact = crashed.ImpactVelocity; try { ChoppaNet.ToServer(ChoppaNet.Write(Msg.Crash, delegate(BinaryWriter w) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) w.Write(id); w.Write(impact); w.Write(seed); }), reliable: true); } catch (Exception ex) { ManualLogSource l = Plugin.L; bool flag = default(bool)