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 10 months 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; } } }