using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("EasyManual")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("EasyManual")] [assembly: AssemblyTitle("EasyManual")] [assembly: AssemblyVersion("1.0.0.0")] namespace EasyManual; [HarmonyPatch(typeof(sHUD), "FrameUpdate")] public static class GearboxHud { private const float X = 70f; private static readonly FieldRef getRenderer = AccessTools.FieldRefAccess("R"); [HarmonyPostfix] public static void Postfix(sHUD __instance) { //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.ShowHud.Value || (Object)(object)__instance.navigation == (Object)null || (Object)(object)__instance.navigation.car == (Object)null) { return; } sCarController car = __instance.navigation.car; if (car.GuyActive) { return; } MiniRenderer val = getRenderer.Invoke(__instance); if (!((Object)(object)val == (Object)null)) { Gearbox.State state = Gearbox.Get(car); bool showActive = !(state.Rpm01 > 0.95f) || !(Time.time % 0.3f > 0.15f); float num = (float)val.height / 2f + 10f; val.fontOptions.alignment = (Alignment)0; val.fput(GearRow(state, showActive), 70f, num - 27f, 0f, 13f, 0f, -1); int num2; if (!((Object)(object)car.rb != (Object)null)) { num2 = 0; } else { Vector3 linearVelocity = car.rb.linearVelocity; num2 = Mathf.FloorToInt(((Vector3)(ref linearVelocity)).magnitude * 3.6f); } int num3 = num2; val.fput(num3 + "km/h", 70f, num - 14f, 0f, 13f, 0f, -1); } } private static string GearRow(Gearbox.State g, bool showActive) { string text = ((g.Reverse && showActive) ? "[R]" : "R"); for (int i = 1; i <= Gearbox.Count; i++) { bool flag = !g.Reverse && i - 1 == g.Index && showActive; text += (flag ? ("[" + i + "]") : (" " + i)); } return text; } } public static class Gearbox { public class State { public int Index; public float Rpm01; public bool Reverse; public void ShiftUp() { if (Index < Count - 1) { Index++; } } } private struct Stock { public float Scale; public float Power; } [HarmonyPatch(typeof(sCarController), "Move")] public static class MovePatch { [HarmonyPrefix] public static void Prefix(sCarController __instance, out State __state) { //IL_003d: 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) __state = null; if (__instance.player < 0 || (Object)(object)__instance.rb == (Object)null) { return; } Stock stock = GetStock(__instance); State state = Get(__instance); float num = __instance.maxSpeed * stock.Scale; float num2 = Vector3.Dot(__instance.rb.linearVelocity, ((Component)__instance).transform.forward); bool flag = __instance.input.y < -0.01f && num2 < 0.5f; if (!__instance.GuyActive) { if (Plugin.UpPressed()) { state.ShiftUp(); } if (Plugin.DownPressed()) { TryShiftDown(state, num, num2); } } float num3 = (flag ? Ratio[0] : Ratio[state.Index]); float num4 = (flag ? 1f : Torque[state.Index]); state.Reverse = flag; state.Rpm01 = ((num > 0.01f) ? (Mathf.Abs(num2) / (num * num3)) : 0f); __instance.maxSpeedScale = stock.Scale * num3; __instance.maxDrivePower = stock.Power * num4; __state = state; } [HarmonyPostfix] public static void Postfix(sCarController __instance, State __state) { if (__state != null) { Stock stock = GetStock(__instance); __instance.maxSpeedScale = stock.Scale; __instance.maxDrivePower = stock.Power; } } private static void TryShiftDown(State g, float baseTop, float forwardSpeed) { if (g.Index > 0) { int num = g.Index - 1; if (((baseTop > 0.01f) ? (Mathf.Abs(forwardSpeed) / (baseTop * Ratio[num])) : 0f) <= 1.1f) { g.Index = num; } } } } public static readonly float[] Ratio = new float[4] { 0.3f, 0.55f, 0.78f, 1f }; public static readonly float[] Torque = new float[4] { 2.2f, 1.5f, 1.15f, 1f }; private const float DownshiftRedline = 1.1f; private static readonly Dictionary states = new Dictionary(); private static readonly Dictionary stocks = new Dictionary(); public static int Count => Ratio.Length; public static State Get(sCarController car) { if (!states.TryGetValue(car, out var value)) { value = (states[car] = new State()); } return value; } private static Stock GetStock(sCarController car) { if (!stocks.TryGetValue(car, out var value)) { value = (stocks[car] = new Stock { Scale = car.maxSpeedScale, Power = car.maxDrivePower }); } return value; } } [BepInPlugin("com.jxpitwr.easydelivery.manualmod", "EasyManual", "1.0.0")] public class Plugin : BaseUnityPlugin { private readonly Harmony harmony = new Harmony("com.jxpitwr.easydelivery.manualmod"); internal static ConfigEntry ShiftUpKey; internal static ConfigEntry ShiftDownKey; internal static ConfigEntry UseGamepad; internal static ConfigEntry ShowHud; private void Awake() { ShiftUpKey = ((BaseUnityPlugin)this).Config.Bind("Controls", "ShiftUpKey", (Key)38, "Keyboard key to shift up a gear."); ShiftDownKey = ((BaseUnityPlugin)this).Config.Bind("Controls", "ShiftDownKey", (Key)40, "Keyboard key to shift down a gear."); UseGamepad = ((BaseUnityPlugin)this).Config.Bind("Controls", "UseGamepad", true, "Also shift with the gamepad bumpers (RB = up, LB = down)."); ShowHud = ((BaseUnityPlugin)this).Config.Bind("HUD", "ShowGearDisplay", true, "Show the gear + RPM indicator on the in-game HUD."); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin EasyManual is loaded!"); harmony.PatchAll(); } internal static bool UpPressed() { //IL_000e: 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) Keyboard current = Keyboard.current; if (current != null && (int)ShiftUpKey.Value != 0 && ((ButtonControl)current[ShiftUpKey.Value]).wasPressedThisFrame) { return true; } if (UseGamepad.Value) { Gamepad current2 = Gamepad.current; if (current2 != null && current2.rightShoulder.wasPressedThisFrame) { return true; } } return false; } internal static bool DownPressed() { //IL_000e: 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) Keyboard current = Keyboard.current; if (current != null && (int)ShiftDownKey.Value != 0 && ((ButtonControl)current[ShiftDownKey.Value]).wasPressedThisFrame) { return true; } if (UseGamepad.Value) { Gamepad current2 = Gamepad.current; if (current2 != null && current2.leftShoulder.wasPressedThisFrame) { return true; } } return false; } } public static class PluginInfo { public const string PLUGIN_GUID = "com.jxpitwr.easydelivery.manualmod"; public const string PLUGIN_NAME = "EasyManual"; public const string PLUGIN_VERSION = "1.0.0"; }