Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of VNitro v1.0.1
FoafNitroMod.dll
Decompiled a week agousing System; using System.Collections; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using FoafNitroMod; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes.Arrays; using MelonLoader; using MelonLoader.Utils; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(VNitroLiteMod), "VNitro", "0.4.2", "foaf", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("FoafNitroMod")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("FoafNitroMod")] [assembly: AssemblyTitle("FoafNitroMod")] [assembly: AssemblyVersion("1.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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; } } } namespace FoafNitroMod { internal static class VNitroAudio { private static GameObject? _go; private static AudioSource? _src; private static AudioClip? _clip; private static bool _active; private static bool _boosting; internal static void Initialize() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown if (!((Object)(object)_go != (Object)null)) { _go = new GameObject("[VNitroAudio]"); Object.DontDestroyOnLoad((Object)(object)_go); _src = _go.AddComponent<AudioSource>(); _src.playOnAwake = false; _src.loop = true; _src.volume = 0.75f; MelonCoroutines.Start(CoLoadClip()); } } internal static void SetActive(bool on) { _active = on; if (!on) { _boosting = false; if ((Object)(object)_src != (Object)null && _src.isPlaying) { _src.Stop(); } } } internal static void SetBoosting(bool on) { _boosting = on && _active && (Object)(object)_clip != (Object)null; if ((Object)(object)_src == (Object)null) { return; } if (_boosting) { if (!_src.isPlaying && (Object)(object)_clip != (Object)null) { _src.clip = _clip; _src.Play(); } } else if (_src.isPlaying) { _src.Stop(); } } internal static void AttachToVehicle(GameObject? vehicleRoot) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)_go == (Object)null) { Initialize(); } if (!((Object)(object)_go == (Object)null) && !((Object)(object)vehicleRoot == (Object)null) && !((Object)(object)_src == (Object)null)) { _go.transform.SetParent(vehicleRoot.transform, false); _go.transform.localPosition = Vector3.zero; if (!TryCopyFromVehicleSound(vehicleRoot)) { _src.spatialBlend = 0f; _src.dopplerLevel = 0f; } } } catch (Exception ex) { MelonLogger.Warning("[VNitro] AttachToVehicle failed: " + ex.Message); } } internal static void Detach() { try { if ((Object)(object)_go != (Object)null) { _go.transform.SetParent((Transform)null, false); } if ((Object)(object)_src != (Object)null && _src.isPlaying) { _src.Stop(); } } catch (Exception ex) { MelonLogger.Warning("[VNitro] Detach failed: " + ex.Message); } } private static IEnumerator CoLoadClip() { string baseDir = MelonEnvironment.MelonBaseDirectory; string audioDir = Path.Combine(baseDir, "Mods", "VNitro", "Audio"); string audioDirAlt = Path.Combine(baseDir, "Mods", "VNitro", "audio"); string chosen = null; string candidate1 = Path.Combine(audioDir, "nitro.wav"); string candidate2 = Path.Combine(audioDirAlt, "nitro.wav"); if (File.Exists(candidate1)) { chosen = candidate1; } else if (File.Exists(candidate2)) { chosen = candidate2; } else if (Directory.Exists(audioDir)) { string[] wavs2 = Directory.GetFiles(audioDir, "*.wav", SearchOption.TopDirectoryOnly); if (wavs2.Length != 0) { chosen = wavs2[0]; } } else if (Directory.Exists(audioDirAlt)) { string[] wavs = Directory.GetFiles(audioDirAlt, "*.wav", SearchOption.TopDirectoryOnly); if (wavs.Length != 0) { chosen = wavs[0]; } } if (string.IsNullOrEmpty(chosen)) { MelonLogger.Warning("[VNitro] No WAV found. Place nitro.wav in: " + audioDir); yield break; } try { _clip = LoadWavClip(chosen); if ((Object)(object)_clip != (Object)null) { MelonLogger.Msg("[VNitro] Loaded hiss WAV: " + chosen); } else { MelonLogger.Warning("[VNitro] WAV load returned null: " + chosen); } } catch (Exception ex) { MelonLogger.Warning("[VNitro] WAV load failed: " + chosen + "\n" + ex.Message); } } private static AudioClip LoadWavClip(string path) { byte[] array = File.ReadAllBytes(path); int p = 0; string text = ReadString(array, ref p, 4); int num = ReadInt(array, ref p); string text2 = ReadString(array, ref p, 4); if (text != "RIFF" || text2 != "WAVE") { throw new Exception("Not a WAVE/RIFF file."); } short num2 = 0; int num3 = 0; short num4 = 0; ushort num5 = 0; byte[] array2 = null; while (p + 8 <= array.Length) { string text3 = ReadString(array, ref p, 4); int num6 = ReadInt(array, ref p); if (p + num6 > array.Length) { break; } if (text3 == "fmt ") { num5 = (ushort)ReadShort(array, ref p); num2 = ReadShort(array, ref p); num3 = ReadInt(array, ref p); int num7 = ReadInt(array, ref p); short num8 = ReadShort(array, ref p); num4 = ReadShort(array, ref p); int num9 = num6 - 16; if (num9 > 0) { p += num9; } } else if (text3 == "data") { array2 = new byte[num6]; Buffer.BlockCopy(array, p, array2, 0, num6); p += num6; } else { p += num6; } if (array2 != null && num2 > 0 && num3 > 0 && (num5 == 1 || num5 == 3)) { break; } } if (array2 == null) { throw new Exception("Missing data chunk."); } if (num2 < 1 || num2 > 2) { throw new Exception("Unsupported channel count: " + num2); } if (num3 <= 0) { throw new Exception("Invalid sample rate."); } if (num5 != 1 && num5 != 3) { throw new Exception("Unsupported WAV format tag: " + num5 + " (use PCM or float)."); } float[] array3; if (num5 == 1) { switch (num4) { case 16: { int num13 = array2.Length / 2; array3 = new float[num13]; int num14 = 0; for (int j = 0; j < num13; j++) { short num15 = (short)(array2[num14] | (array2[num14 + 1] << 8)); array3[j] = (float)num15 / 32768f; num14 += 2; } break; } case 24: { int num16 = array2.Length / 3; array3 = new float[num16]; int num17 = 0; for (int k = 0; k < num16; k++) { int num18 = array2[num17]; int num19 = array2[num17 + 1] << 8; int num20 = array2[num17 + 2] << 16; int num21 = num18 | num19 | num20; if (((uint)num21 & 0x800000u) != 0) { num21 |= -16777216; } array3[k] = Mathf.Clamp((float)num21 / 8388608f, -1f, 1f); num17 += 3; } break; } case 32: { int num10 = array2.Length / 4; array3 = new float[num10]; int num11 = 0; for (int i = 0; i < num10; i++) { int num12 = BitConverter.ToInt32(array2, num11); array3[i] = Mathf.Clamp((float)num12 / 2.1474836E+09f, -1f, 1f); num11 += 4; } break; } default: throw new Exception("Unsupported PCM bit depth: " + num4 + " (use 16/24/32-bit PCM or 32-bit float)."); } } else { if (num4 != 32) { throw new Exception("Unsupported float bit depth: " + num4); } int num22 = array2.Length / 4; array3 = new float[num22]; Buffer.BlockCopy(array2, 0, array3, 0, array2.Length); } int num23 = array3.Length / num2; AudioClip val = AudioClip.Create("VNitro_Hiss", num23, (int)num2, num3, false); val.SetData(Il2CppStructArray<float>.op_Implicit(array3), 0); return val; } private static bool TryCopyFromVehicleSound(GameObject? vehicleRoot) { //IL_0161: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)vehicleRoot == (Object)null || (Object)(object)_src == (Object)null) { return false; } Component val = null; Il2CppArrayBase<Component> componentsInChildren = vehicleRoot.GetComponentsInChildren<Component>(true); for (int i = 0; i < componentsInChildren.Count; i++) { Component val2 = componentsInChildren[i]; if (!((Object)(object)val2 == (Object)null)) { string fullName = ((object)val2).GetType().FullName; if (fullName != null && fullName.IndexOf("VehicleSound", StringComparison.OrdinalIgnoreCase) >= 0) { val = val2; break; } } } if ((Object)(object)val != (Object)null) { Type type = ((object)val).GetType(); FieldInfo fieldInfo = AccessTools.Field(type, "EngineLoopSource") ?? AccessTools.Field(type, "EngineIdleSource"); object obj = ((fieldInfo != null) ? fieldInfo.GetValue(val) : null); AudioSource val3 = null; Component val4 = (Component)((obj is Component) ? obj : null); if (val4 != null) { val3 = val4.GetComponent<AudioSource>() ?? val4.GetComponentInChildren<AudioSource>(true); } if ((Object)(object)val3 != (Object)null) { _src.outputAudioMixerGroup = val3.outputAudioMixerGroup; _src.spatialBlend = val3.spatialBlend; _src.dopplerLevel = val3.dopplerLevel; _src.rolloffMode = val3.rolloffMode; _src.minDistance = val3.minDistance; _src.maxDistance = val3.maxDistance; MelonLogger.Msg("[VNitro] Hiss copied VehicleSound mixer/3D settings."); return true; } } } catch (Exception ex) { MelonLogger.Warning("[VNitro] Copy VehicleSound settings failed: " + ex.Message); } return false; } private static string ReadString(byte[] b, ref int p, int len) { string @string = Encoding.ASCII.GetString(b, p, len); p += len; return @string; } private static int ReadInt(byte[] b, ref int p) { int result = b[p] | (b[p + 1] << 8) | (b[p + 2] << 16) | (b[p + 3] << 24); p += 4; return result; } private static short ReadShort(byte[] b, ref int p) { short result = (short)(b[p] | (b[p + 1] << 8)); p += 2; return result; } } internal static class VNitroHud { private static bool _inVehicle; private static bool _visible = true; private static bool _dockBottom = true; private static float _scale = 1f; private static float _panelOpacity = 0.9f; private static float _nitro = 1f; private static bool _boosting = false; private const float _minBoostPct = 0.2f; private static float _sheenOffset = 0f; private static readonly Color _accentA = new Color(0.18f, 0.9f, 1f, 1f); private static readonly Color _accentB = new Color(0.67f, 0.41f, 1f, 1f); private static GUIStyle _titleStyle = null; private static GUIStyle _hintStyle = null; private static Texture2D _whiteTex = null; private static Texture2D _panelGradTex = null; private static Texture2D _roundedPanelTex = null; private static Texture2D _roundedBarTex = null; private static Texture2D _roundedBarBorderTex = null; private static Texture2D _barGradTex = null; private static Texture2D _sheenGradTex = null; private static Texture2D _icon = null; internal static void SetActive(bool isInVehicle) { _inVehicle = isInVehicle; VNitroAudio.SetActive(isInVehicle); if (!isInVehicle) { VNitroAudio.SetBoosting(on: false); _sheenOffset = 0f; } } internal static void SetFill01(float pct) { _nitro = Mathf.Clamp01(pct); } internal static void SetBoosting(bool boosting) { _boosting = boosting; } internal static void OnUpdate() { if (Input.GetKeyDown((KeyCode)290)) { _visible = !_visible; } if (Input.GetKeyDown((KeyCode)289)) { _dockBottom = !_dockBottom; } float num = (Input.GetKey((KeyCode)304) ? 0.02f : 0.05f); if (Input.GetKeyDown((KeyCode)61) || Input.GetKeyDown((KeyCode)270)) { _scale = Mathf.Clamp(_scale + num, 0.6f, 1.6f); } if (Input.GetKeyDown((KeyCode)45) || Input.GetKeyDown((KeyCode)269)) { _scale = Mathf.Clamp(_scale - num, 0.6f, 1.6f); } if (Input.GetKeyDown((KeyCode)93)) { _panelOpacity = Mathf.Clamp01(_panelOpacity + 0.05f); } if (Input.GetKeyDown((KeyCode)91)) { _panelOpacity = Mathf.Clamp01(_panelOpacity - 0.05f); } if (_inVehicle) { if (_boosting) { _sheenOffset = (_sheenOffset + Time.deltaTime * 0.7f) % 1f; } else { _sheenOffset = Mathf.MoveTowards(_sheenOffset, 0f, Time.deltaTime * 0.8f); } } } internal static void Draw() { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Unknown result type (might be due to invalid IL or missing references) if (_visible && _inVehicle) { EnsureAssets(); float num = 420f; float num2 = 94f; float num3 = num * _scale; float num4 = num2 * _scale; float num5 = 32f * _scale; float num6 = ((float)Screen.width - num3) * 0.5f; float num7 = (_dockBottom ? ((float)Screen.height - num4 - num5) : num5); Rect val = default(Rect); ((Rect)(ref val))..ctor(num6, num7 + 4f * _scale, num3, num4); GUI.color = new Color(0f, 0f, 0f, 0.25f * _panelOpacity); GUI.DrawTexture(val, (Texture)(object)_roundedPanelTex, (ScaleMode)0, true); GUI.color = Color.white; GUI.color = new Color(1f, 1f, 1f, _panelOpacity); GUI.DrawTexture(new Rect(num6, num7, num3, num4), (Texture)(object)_panelGradTex, (ScaleMode)0, true); GUI.DrawTexture(new Rect(num6, num7, num3, num4), (Texture)(object)_roundedPanelTex, (ScaleMode)0, true); GUI.color = new Color(1f, 1f, 1f, 0.12f * _panelOpacity); GUI.DrawTexture(new Rect(num6, num7, num3, 1.5f * _scale), (Texture)(object)_whiteTex); GUI.color = Color.white; float num8 = 56f * _scale; float num9 = num6 + 14f * _scale; float num10 = num7 + (num4 - num8) * 0.5f; if ((Object)(object)_icon != (Object)null) { GUI.color = new Color(1f, 1f, 1f, 0.95f); GUI.DrawTexture(new Rect(num9, num10, num8, num8), (Texture)(object)_icon, (ScaleMode)2, true); GUI.color = Color.white; } float num11 = num9 + (((Object)(object)_icon != (Object)null) ? (num8 + 16f * _scale) : (8f * _scale)); float num12 = num7 + 10f * _scale; int value = Mathf.RoundToInt(_nitro * 100f); string text = $"NITRO {value}%"; ShadowLabel(new Rect(num11, num12, num3 - (num11 - num6) - 12f, 28f * _scale), text, _titleStyle); string text2 = ((!_boosting && _nitro < 0.2f) ? "LOW NITRO" : "Hold Left Shift to boost"); ShadowLabel(new Rect(num11, num12 + 26f * _scale, num3 - (num11 - num6) - 12f, 22f * _scale), text2, _hintStyle); float num13 = num11; float num14 = num7 + num4 - 26f * _scale; float num15 = num3 - (num13 - num6) - 12f * _scale; float num16 = 12f * _scale; DrawModernBar(new Rect(num13, num14, num15, num16), _nitro); } } private static void DrawModernBar(Rect r, float pct) { //IL_0015: 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_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: 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_024c: 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_0263: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: 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_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) GUI.color = new Color(1f, 1f, 1f, 0.28f); GUI.DrawTexture(r, (Texture)(object)_roundedBarTex, (ScaleMode)0, true); float num = Mathf.Round(pct * ((Rect)(ref r)).width); if (num > 1f) { Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref r)).x, ((Rect)(ref r)).y, num, ((Rect)(ref r)).height); float num2 = ((pct < 0.2f) ? 0.65f : 1f); GUI.color = new Color(1f, 1f, 1f, num2); GUI.DrawTexture(val, (Texture)(object)_barGradTex, (ScaleMode)0, true); GUI.color = new Color(1f, 1f, 1f, 0.18f * num2); GUI.DrawTexture(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y, ((Rect)(ref val)).width, ((Rect)(ref val)).height * 0.45f), (Texture)(object)_whiteTex); GUI.color = Color.white; if (_sheenOffset > 0f && pct > 0.1f && _boosting) { float num3 = Mathf.Min(80f * _scale, ((Rect)(ref val)).width * 0.6f); float num4 = ((Rect)(ref val)).x + (((Rect)(ref val)).width - num3) * _sheenOffset; Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(num4, ((Rect)(ref val)).y, num3, ((Rect)(ref val)).height); GUI.color = new Color(1f, 1f, 1f, 0.22f); GUI.DrawTexture(val2, (Texture)(object)_sheenGradTex, (ScaleMode)0, true); GUI.color = Color.white; } } GUI.color = new Color(1f, 1f, 1f, 0.1f); GUI.DrawTexture(r, (Texture)(object)_roundedBarBorderTex, (ScaleMode)0, true); GUI.color = Color.white; float num5 = ((Rect)(ref r)).x + ((Rect)(ref r)).width * 0.2f; Rect val3 = default(Rect); ((Rect)(ref val3))..ctor(num5 - 1f, ((Rect)(ref r)).y - 2f, 2f, ((Rect)(ref r)).height + 4f); GUI.color = new Color(1f, 1f, 1f, 0.25f); GUI.DrawTexture(val3, (Texture)(object)_whiteTex); GUI.color = Color.white; } private static void ShadowLabel(Rect r, string text, GUIStyle style) { //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_004e: 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_0062: 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) float num = 1f * _scale; Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref r)).x + num, ((Rect)(ref r)).y + num, ((Rect)(ref r)).width, ((Rect)(ref r)).height); Color color = GUI.color; GUI.color = new Color(0f, 0f, 0f, 0.55f); GUI.Label(val, text, style); GUI.color = color; GUI.Label(r, text, style); } private static void EnsureAssets() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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_009a: Expected O, but got Unknown //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0184: 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_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_0223: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Expected O, but got Unknown if (_titleStyle == null) { _titleStyle = new GUIStyle(GUI.skin.label) { fontSize = Mathf.RoundToInt(18f * _scale), fontStyle = (FontStyle)1, alignment = (TextAnchor)0, richText = false }; } if (_hintStyle == null) { _hintStyle = new GUIStyle(GUI.skin.label) { fontSize = Mathf.RoundToInt(12f * _scale), alignment = (TextAnchor)0, richText = false }; } if ((Object)(object)_whiteTex == (Object)null) { _whiteTex = MakeTex(new Color(1f, 1f, 1f, 1f)); } if ((Object)(object)_panelGradTex == (Object)null) { _panelGradTex = MakeVerticalGradientTex(new Color(0.06f, 0.08f, 0.1f, 0.7f * _panelOpacity), new Color(0.06f, 0.08f, 0.1f, 0.55f * _panelOpacity)); } if ((Object)(object)_roundedPanelTex == (Object)null) { _roundedPanelTex = MakeRoundedBoxTex(32, new Color(1f, 1f, 1f, 0.14f)); } if ((Object)(object)_roundedBarTex == (Object)null) { _roundedBarTex = MakeRoundedBoxTex(16, new Color(0f, 0f, 0f, 0.55f)); } if ((Object)(object)_roundedBarBorderTex == (Object)null) { _roundedBarBorderTex = MakeRoundedBoxBorderTex(16, new Color(1f, 1f, 1f, 0.35f)); } if ((Object)(object)_barGradTex == (Object)null) { _barGradTex = MakeHorizontalGradientTex(_accentA, _accentB); } if ((Object)(object)_sheenGradTex == (Object)null) { _sheenGradTex = MakeHorizontalGradientTex(new Color(1f, 1f, 1f, 0f), new Color(1f, 1f, 1f, 1f), (Color?)new Color(1f, 1f, 1f, 0f), 256, 2); } if (!((Object)(object)_icon == (Object)null)) { return; } string melonBaseDirectory = MelonEnvironment.MelonBaseDirectory; string text = Path.Combine(melonBaseDirectory, "Mods", "VNitro", "UI", "nitro.png"); string text2 = Path.Combine(melonBaseDirectory, "Mods", "VNitro", "ui", "nitro.png"); string text3 = (File.Exists(text) ? text : (File.Exists(text2) ? text2 : null)); if (string.IsNullOrEmpty(text3)) { return; } try { byte[] array = File.ReadAllBytes(text3); Texture2D val = new Texture2D(2, 2, (TextureFormat)5, false); if (ImageConversion.LoadImage(val, Il2CppStructArray<byte>.op_Implicit(array))) { ((Texture)val).wrapMode = (TextureWrapMode)1; _icon = val; } } catch (Exception ex) { MelonLogger.Warning("[VNitroHUD] Icon load failed: " + ex.Message); } } private static Texture2D MakeTex(Color c) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_000e: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(1, 1, (TextureFormat)5, false); val.SetPixel(0, 0, c); val.Apply(); return val; } private static Texture2D MakeVerticalGradientTex(Color top, Color bottom, int h = 64, int w = 2) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(w, h, (TextureFormat)5, false); for (int i = 0; i < h; i++) { float num = (float)i / (float)(h - 1); Color val2 = Color.Lerp(top, bottom, num); for (int j = 0; j < w; j++) { val.SetPixel(j, i, val2); } } val.Apply(); return val; } private static Texture2D MakeHorizontalGradientTex(Color left, Color right, Color? mid = null, int w = 256, int h = 2) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_004c: 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) Texture2D val = new Texture2D(w, h, (TextureFormat)5, false); for (int i = 0; i < w; i++) { float num = (float)i / (float)(w - 1); Color val2 = ((!mid.HasValue) ? Color.Lerp(left, right, num) : ((!(num < 0.5f)) ? Color.Lerp(mid.Value, right, (num - 0.5f) / 0.5f) : Color.Lerp(left, mid.Value, num / 0.5f))); for (int j = 0; j < h; j++) { val.SetPixel(i, j, val2); } } val.Apply(); return val; } private static Texture2D MakeRoundedBoxTex(int radius, Color fill) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_007e: Unknown result type (might be due to invalid IL or missing references) int num = radius * 2; Texture2D val = new Texture2D(num, num, (TextureFormat)5, false); for (int i = 0; i < num; i++) { for (int j = 0; j < num; j++) { float num2 = (float)(j - radius) + 0.5f; float num3 = (float)(i - radius) + 0.5f; float num4 = Mathf.Sqrt(num2 * num2 + num3 * num3); float num5 = Mathf.Clamp01((float)radius - num4); float num6 = Mathf.Clamp01(num5 / 1.5f) * fill.a; val.SetPixel(j, i, new Color(fill.r, fill.g, fill.b, num6)); } } val.Apply(); return val; } private static Texture2D MakeRoundedBoxBorderTex(int radius, Color border) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown //IL_0071: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008a: 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) int num = radius * 2; Texture2D val = new Texture2D(num, num, (TextureFormat)5, false); float num2 = 1.25f; for (int i = 0; i < num; i++) { for (int j = 0; j < num; j++) { float num3 = (float)(j - radius) + 0.5f; float num4 = (float)(i - radius) + 0.5f; float num5 = Mathf.Sqrt(num3 * num3 + num4 * num4); float num6 = Mathf.Abs(num5 - (float)radius + 1f); float num7 = Mathf.Clamp01(1f - num6 / num2) * border.a; val.SetPixel(j, i, new Color(border.r, border.g, border.b, num7)); } } val.Apply(); return val; } } public class VNitroLiteMod : MelonMod { private Harmony? _harmony; private object? _current; private Rigidbody? _rb; private const float RbAccelBoost = 9f; private const float RbVelNudgePerSec = 5f; private const float MaxAssistSpeed = 25f; private float _nitro01 = 1f; private const float DrainPerSec = 0.7f; private const float RechargePerSec = 0.18f; internal const float MinBoostPct = 0.3f; private const float RegenDelaySeconds = 3f; private float _regenDelayTimer = 0f; private bool _isBoosting = false; private bool _loggedFallback; private readonly KeyCode _boostKey = (KeyCode)304; public static VNitroLiteMod? Instance { get; private set; } public override void OnInitializeMelon() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown Instance = this; ((MelonBase)this).LoggerInstance.Msg("[VNitro] initializing"); _harmony = new Harmony("com.foaf.vnitrolite"); PatchByName("Il2CppScheduleOne.Vehicles.LandVehicle", "EnterVehicle", "EnterVehicle_Postfix"); PatchByName("Il2CppScheduleOne.Vehicles.LandVehicle", "ExitVehicle", "ExitVehicle_Postfix"); PatchByName("Il2CppScheduleOne.Vehicles.LandVehicle", "FixedUpdate", "FixedUpdate_Postfix"); ((MelonBase)this).LoggerInstance.Msg("[VNitro] Loaded. Hold LeftShift to boost."); } public override void OnUpdate() { //IL_006f: Unknown result type (might be due to invalid IL or missing references) bool flag = _current != null; VNitroHud.SetActive(flag); VNitroAudio.SetActive(flag); VNitroVFX.SetActive(flag); VNitroVFX.OnUpdate(); if (!flag) { if (_isBoosting) { _isBoosting = false; } VNitroAudio.SetBoosting(on: false); VNitroVFX.SetBoosting(boosting: false); VNitroHud.SetBoosting(boosting: false); VNitroHud.SetFill01(_nitro01); return; } float deltaTime = Time.deltaTime; bool key = Input.GetKey(_boostKey); if (!_isBoosting && key && _nitro01 >= 0.3f) { _isBoosting = true; } if (_isBoosting && (!key || _nitro01 <= 0f)) { _isBoosting = false; } if (_isBoosting) { _nitro01 = Mathf.Max(0f, _nitro01 - 0.7f * deltaTime); if (_nitro01 <= 0f) { _isBoosting = false; _regenDelayTimer = 3f; } } else if (_nitro01 <= 0f && _regenDelayTimer > 0f) { _regenDelayTimer -= deltaTime; if (_regenDelayTimer < 0f) { _regenDelayTimer = 0f; } } else { _nitro01 = Mathf.Min(1f, _nitro01 + 0.18f * deltaTime); } VNitroAudio.SetBoosting(_isBoosting); VNitroVFX.SetBoosting(_isBoosting); VNitroHud.SetBoosting(_isBoosting); VNitroHud.SetFill01(_nitro01); } public override void OnGUI() { VNitroHud.Draw(); } private void PatchByName(string typeName, string methodName, string postfixName) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown Type type = AccessTools.TypeByName(typeName); if (type == null) { ((MelonBase)this).LoggerInstance.Warning("[VNitro] Type not found: " + typeName); return; } MethodInfo methodInfo = AccessTools.Method(type, methodName, (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(VNitroLiteMod), postfixName, (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { ((MelonBase)this).LoggerInstance.Warning("[VNitro] Could not patch " + typeName + "." + methodName); } else { _harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } public static void EnterVehicle_Postfix(object __instance) { VNitroLiteMod instance = Instance; if (instance != null && __instance != null) { instance._current = __instance; Component val = (Component)((__instance is Component) ? __instance : null); instance._rb = (((Object)(object)val != (Object)null) ? val.gameObject.GetComponentInParent<Rigidbody>() : null); if ((Object)(object)val != (Object)null) { GameObject gameObject = val.gameObject; VNitroAudio.AttachToVehicle(gameObject); VNitroVFX.AttachToVehicle(gameObject); VNitroVFX.SetActive(enable: true); } VNitroHud.SetActive(isInVehicle: true); VNitroAudio.SetActive(on: true); } } public static void ExitVehicle_Postfix(object __instance) { VNitroLiteMod instance = Instance; if (instance != null) { instance._isBoosting = false; instance._regenDelayTimer = 0f; VNitroAudio.SetBoosting(on: false); VNitroAudio.SetActive(on: false); VNitroAudio.Detach(); VNitroVFX.SetBoosting(boosting: false); VNitroVFX.SetActive(enable: false); VNitroVFX.Detach(); VNitroVFX.ResetFov(); VNitroHud.SetActive(isInVehicle: false); instance._current = null; instance._rb = null; instance._loggedFallback = false; } } public static void FixedUpdate_Postfix(object __instance) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: 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_00be: 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_00cb: Unknown result type (might be due to invalid IL or missing references) VNitroLiteMod instance = Instance; if (instance == null || instance._current == null || instance._current != __instance || !instance._isBoosting) { return; } Rigidbody rb = instance._rb; if (!((Object)(object)rb == (Object)null)) { if (!instance._loggedFallback) { instance._loggedFallback = true; } Vector3 forward = ((Component)rb).transform.forward; rb.AddForce(forward * 9f, (ForceMode)5); float fixedDeltaTime = Time.fixedDeltaTime; Vector3 velocity = rb.velocity; if (((Vector3)(ref velocity)).magnitude < 25f) { rb.velocity = velocity + forward * (5f * fixedDeltaTime); } } } } internal static class VNitroVFX { private const string LogTag = "[VNitroVFX]"; private static Camera? _cam; private static float _baseFov = -1f; private static Quaternion _baseLocalRot; private static Vector3 _baseLocalPos; private static bool _haveBaseRot; private static bool _haveBasePos; private static bool _active; private static bool _boosting; private static float _boostIntensity; private static float _fovVel; private static float _rollDeg; private static float _rollVelDeg; private static Vector3 _shakeOffset; private static Vector3 _shakeVel; internal static void SetActive(bool enable) { _active = enable; if (!enable) { Reset(); } } internal static void AttachToVehicle(GameObject go) { AttachToVehicle(((Object)(object)go != (Object)null) ? go.transform : null); } internal static void AttachToVehicle(Transform? _) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) _cam = Camera.main; if ((Object)(object)_cam == (Object)null) { MelonLogger.Msg("[VNitroVFX] No Camera.main found."); return; } if (_baseFov < 0f) { _baseFov = _cam.fieldOfView; } if (!_haveBaseRot) { _baseLocalRot = ((Component)_cam).transform.localRotation; _haveBaseRot = true; } if (!_haveBasePos) { _baseLocalPos = ((Component)_cam).transform.localPosition; _haveBasePos = true; } } internal static void Detach() { Reset(); } internal static void ResetFov() { try { if ((Object)(object)_cam != (Object)null && _baseFov > 0f) { _cam.fieldOfView = _baseFov; } } catch { } } internal static void SetBoosting(bool boosting) { OnBoost(boosting, boosting ? 1f : 0f); } internal static void OnBoost(bool pressed, float intensity01) { if (_active) { _boosting = pressed; _boostIntensity = Mathf.Clamp01(intensity01); } } internal static void OnUpdate() { OnUpdate(Time.deltaTime); } internal static void OnUpdate(float dt) { //IL_01ea: 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_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_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_0167: Unknown result type (might be due to invalid IL or missing references) if (!_active) { return; } if ((Object)(object)_cam == (Object)null) { _cam = Camera.main; } if ((Object)(object)_cam == (Object)null) { return; } if (_baseFov > 0f) { float num = Mathf.Lerp(8f, 14f, _boostIntensity); float num2 = (_boosting ? (_baseFov + num) : _baseFov); _cam.fieldOfView = Mathf.SmoothDamp(_cam.fieldOfView, num2, ref _fovVel, 0.1f); } if (_haveBaseRot) { float num3 = (_boosting ? Mathf.Lerp(0f, 3f, _boostIntensity) : 0f); if (_boosting) { float unscaledTime = Time.unscaledTime; float num4 = Mathf.Sin(unscaledTime * 13f) * 0.35f * _boostIntensity + Mathf.Sin(unscaledTime * 7.7f + 1.1f) * 0.25f * _boostIntensity; num3 += num4; } _rollDeg = Mathf.SmoothDampAngle(_rollDeg, num3, ref _rollVelDeg, 0.16f); ((Component)_cam).transform.localRotation = _baseLocalRot * Quaternion.AngleAxis(_rollDeg, Vector3.forward); } if (_haveBasePos) { float num5 = (_boosting ? Mathf.Lerp(0f, 0.025f, _boostIntensity) : 0f); float unscaledTime2 = Time.unscaledTime; float num6 = Mathf.PerlinNoise(unscaledTime2 * 12.7f, 0.123f) - 0.5f; float num7 = Mathf.PerlinNoise(0.987f, unscaledTime2 * 10.9f) - 0.5f; Vector3 val = new Vector3(num6, num7, 0f) * (num5 * 2f); _shakeOffset = Vector3.SmoothDamp(_shakeOffset, val, ref _shakeVel, 0.08f, float.PositiveInfinity, dt); ((Component)_cam).transform.localPosition = _baseLocalPos + _shakeOffset; } } private static void Reset() { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)_cam != (Object)null) { if (_baseFov > 0f) { _cam.fieldOfView = _baseFov; } if (_haveBaseRot) { ((Component)_cam).transform.localRotation = _baseLocalRot; } if (_haveBasePos) { ((Component)_cam).transform.localPosition = _baseLocalPos; } } } catch { } _boosting = false; _boostIntensity = 0f; _fovVel = 0f; _rollVelDeg = 0f; _rollDeg = 0f; _shakeOffset = Vector3.zero; _shakeVel = Vector3.zero; } } }