Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of S1FuelMod Il2Cpp v1.1.0
S1FuelMod-IL2CPP.dll
Decompiled 5 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using HarmonyLib; using Il2Cpp; using Il2CppFishNet.Object; using Il2CppInterop.Runtime.Attributes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppNewtonsoft.Json; using Il2CppNewtonsoft.Json.Linq; using Il2CppScheduleOne.DevUtilities; using Il2CppScheduleOne.GameTime; using Il2CppScheduleOne.Interaction; using Il2CppScheduleOne.Law; using Il2CppScheduleOne.Levelling; using Il2CppScheduleOne.Money; using Il2CppScheduleOne.NPCs.CharacterClasses; using Il2CppScheduleOne.Networking; using Il2CppScheduleOne.Persistence.Datas; using Il2CppScheduleOne.Persistence.Loaders; using Il2CppScheduleOne.PlayerScripts; using Il2CppScheduleOne.UI; using Il2CppScheduleOne.Vehicles; using Il2CppScheduleOne.Vehicles.Modification; using Il2CppSteamworks; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Il2CppTMPro; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using S1FuelMod; using S1FuelMod.Integrations; using S1FuelMod.Networking; using S1FuelMod.Systems; using S1FuelMod.UI; using S1FuelMod.Utils; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(Core), "S1FuelMod", "1.0.0", "Bars & SirTidez", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("S1FuelMod-IL2CPP")] [assembly: AssemblyConfiguration("Release IL2CPP")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+799f187b4f5c0b96006ec63cbf7ed85a4512971a")] [assembly: AssemblyProduct("S1FuelMod-IL2CPP")] [assembly: AssemblyTitle("S1FuelMod-IL2CPP")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] 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; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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 S1FuelMod { public class Core : MelonMod { private MelonPreferences_Category? _preferencesCategory; private MelonPreferences_Category? _capacityCategory; private MelonPreferences_Entry<bool>? _enableFuelSystem; private MelonPreferences_Entry<float>? _fuelConsumptionMultiplier; private MelonPreferences_Entry<float>? _defaultFuelCapacity; private MelonPreferences_Entry<float>? _shitboxFuelCapacity; private MelonPreferences_Entry<float>? _veeperFuelCapacity; private MelonPreferences_Entry<float>? _bruiserFuelCapacity; private MelonPreferences_Entry<float>? _dinklerFuelCapacity; private MelonPreferences_Entry<float>? _hounddogFuelCapacity; private MelonPreferences_Entry<float>? _cheetahFuelCapacity; private MelonPreferences_Entry<float>? _hotboxFuelCapacity; private MelonPreferences_Entry<float>? _bugattiTourbillonFuelCapacity; private MelonPreferences_Entry<float>? _canofsoupcarFuelCapacity; private MelonPreferences_Entry<float>? _cyberTruckFuelCapacity; private MelonPreferences_Entry<float>? _demonFuelCapacity; private MelonPreferences_Entry<float>? _driftcarFuelCapacity; private MelonPreferences_Entry<float>? _gtrR34FuelCapacity; private MelonPreferences_Entry<float>? _gtrR35FuelCapacity; private MelonPreferences_Entry<float>? _lamborghiniVenenoFuelCapacity; private MelonPreferences_Entry<float>? _rollsRoyceGhostFuelCapacity; private MelonPreferences_Entry<float>? _supercarFuelCapacity; private MelonPreferences_Entry<float>? _koenigseggCc850FuelCapacity; private MelonPreferences_Entry<bool>? _showFuelGauge; private MelonPreferences_Entry<bool>? _enableDynamicPricing; private MelonPreferences_Entry<bool>? _enablePricingOnTier; private MelonPreferences_Entry<bool>? _enableDebugLogging; private MelonPreferences_Entry<float>? _baseFuelPricePerLiter; private MelonPreferences_Entry<bool>? _enableCurfewFuelTax; private MelonPreferences_Entry<bool>? _swapGaugeDirection; private MelonPreferences_Entry<bool>? _useNewGaugeUI; private FuelSystemManager? _fuelSystemManager; private FuelUIManager? _fuelUIManager; private FuelStationManager? _fuelStationManager; public static Core? Instance { get; private set; } public bool EnableFuelSystem => _enableFuelSystem?.Value ?? true; public float FuelConsumptionMultiplier => _fuelConsumptionMultiplier?.Value ?? 1f; public float DefaultFuelCapacity => _defaultFuelCapacity?.Value ?? 40f; public float ShitboxFuelCapacity => _shitboxFuelCapacity?.Value ?? 30f; public float VeeperFuelCapacity => _veeperFuelCapacity?.Value ?? 40f; public float BruiserFuelCapacity => _bruiserFuelCapacity?.Value ?? 40f; public float DinklerFuelCapacity => _dinklerFuelCapacity?.Value ?? 55f; public float HounddogFuelCapacity => _hounddogFuelCapacity?.Value ?? 35f; public float CheetahFuelCapacity => _cheetahFuelCapacity?.Value ?? 35f; public float HotboxFuelCapacity => _hotboxFuelCapacity?.Value ?? 50f; public float BugattiTourbillonFuelCapacity => _bugattiTourbillonFuelCapacity?.Value ?? 40f; public float CanofsoupcarFuelCapacity => _canofsoupcarFuelCapacity?.Value ?? 30f; public float CyberTruckFuelCapacity => _cyberTruckFuelCapacity?.Value ?? 50f; public float DemonFuelCapacity => _demonFuelCapacity?.Value ?? 40f; public float DriftcarFuelCapacity => _driftcarFuelCapacity?.Value ?? 25f; public float GtrR34FuelCapacity => _gtrR34FuelCapacity?.Value ?? 30f; public float GtrR35FuelCapacity => _gtrR35FuelCapacity?.Value ?? 35f; public float LamborghiniVenenoFuelCapacity => _lamborghiniVenenoFuelCapacity?.Value ?? 35f; public float RollsRoyceGhostFuelCapacity => _rollsRoyceGhostFuelCapacity?.Value ?? 45f; public float SupercarFuelCapacity => _supercarFuelCapacity?.Value ?? 30f; public float KoenigseggCc850FuelCapacity => _koenigseggCc850FuelCapacity?.Value ?? 45f; public bool ShowFuelGauge => _showFuelGauge?.Value ?? true; public bool EnableDynamicPricing => _enableDynamicPricing?.Value ?? true; public bool EnablePricingOnTier => _enablePricingOnTier?.Value ?? true; public bool EnableDebugLogging => _enableDebugLogging?.Value ?? false; public float BaseFuelPricePerLiter => _baseFuelPricePerLiter?.Value ?? 4f; public bool EnableCurfewFuelTax => _enableCurfewFuelTax?.Value ?? false; public bool SwapGaugeDirection => _swapGaugeDirection?.Value ?? false; public bool UseNewGaugeUI => _useNewGaugeUI?.Value ?? true; public override void OnInitializeMelon() { Instance = this; ModLogger.LogInitialization(); try { InitializePreferences(); HarmonyPatches.SetModInstance(this); ModLogger.Info("S1FuelMod initialized successfully"); ModLogger.Info($"Fuel System Enabled: {EnableFuelSystem}"); ModLogger.Info($"Show Fuel Gauge: {ShowFuelGauge}"); ModLogger.Info("Gauge Direction: " + (SwapGaugeDirection ? "Left to Right" : "Right to Left")); ModLogger.Info($"Use New Gauge UI: {UseNewGaugeUI} ({(UseNewGaugeUI ? "Circular" : "Slider")})"); ModLogger.Info("Debug logging can be toggled in the mod preferences"); } catch (Exception exception) { ModLogger.Error("Failed to initialize S1FuelMod", exception); } } public override void OnSceneWasInitialized(int buildIndex, string sceneName) { try { ModLogger.Debug($"Scene initialized: {sceneName} (index: {buildIndex})"); if (sceneName.Contains("Main")) { ModLogger.Debug("Main game scene detected, initializing fuel systems..."); InitializeSystems(); } else { ModLogger.Debug("Scene '" + sceneName + "' is not a main game scene, skipping system initialization"); } } catch (Exception exception) { ModLogger.Error("Error during scene initialization", exception); } } public override void OnUpdate() { try { _fuelSystemManager?.Update(); _fuelUIManager?.Update(); _fuelStationManager?.Update(); } catch (Exception exception) { ModLogger.Error("Error during update", exception); } } private void InitializePreferences() { try { _preferencesCategory = MelonPreferences.CreateCategory("S1FuelMod"); _capacityCategory = MelonPreferences.CreateCategory("S1FuelMod_Capacity", "Fuel Tank Capacity"); _enableFuelSystem = _preferencesCategory.CreateEntry<bool>("EnableFuelSystem", true, "Enable Fuel System", "If enabled, vehicles will consume fuel and require refueling", false, false, (ValueValidator)null, (string)null); _fuelConsumptionMultiplier = _preferencesCategory.CreateEntry<float>("FuelConsumptionMultiplier", 1f, "Fuel Consumption Multiplier", "Multiplier for fuel consumption rate (1.0 = normal, 0.5 = half consumption, 2.0 = double consumption)", false, false, (ValueValidator)(object)new ValueRange<float>(0.1f, 5f), (string)null); _baseFuelPricePerLiter = _preferencesCategory.CreateEntry<float>("BaseFuelPricePerLiter", 4f, "Fuel Price Per Liter ($)", "Base price per liter of fuel in dollars", false, false, (ValueValidator)(object)new ValueRange<float>(0.1f, 1000f), (string)null); _defaultFuelCapacity = _preferencesCategory.CreateEntry<float>("DefaultFuelCapacity", 40f, "Default Fuel Capacity (L)", "Default fuel tank capacity for vehicles in liters", false, false, (ValueValidator)(object)new ValueRange<float>(10f, 200f), (string)null); _shitboxFuelCapacity = _capacityCategory.CreateEntry<float>("ShitboxFuelCapacity", 30f, "Shitbox Fuel Capacity (L)", "Fuel capacity for the Shitbox vehicle in liters", false, false, (ValueValidator)(object)new ValueRange<float>(10f, 200f), (string)null); _veeperFuelCapacity = _capacityCategory.CreateEntry<float>("VeeperFuelCapacity", 40f, "Veeper Fuel Capacity (L)", "Fuel capacity for the Veeper vehicle in liters", false, false, (ValueValidator)(object)new ValueRange<float>(10f, 200f), (string)null); _bruiserFuelCapacity = _capacityCategory.CreateEntry<float>("BruiserFuelCapacity", 40f, "Bruiser Fuel Capacity (L)", "Fuel capacity for the Bruiser vehicle in liters", false, false, (ValueValidator)(object)new ValueRange<float>(10f, 200f), (string)null); _dinklerFuelCapacity = _capacityCategory.CreateEntry<float>("DinklerFuelCapacity", 55f, "Dinkler Fuel Capacity (L)", "Fuel capacity for the Dinkler vehicle in liters", false, false, (ValueValidator)(object)new ValueRange<float>(10f, 200f), (string)null); _hounddogFuelCapacity = _capacityCategory.CreateEntry<float>("HounddogFuelCapacity", 35f, "Hounddog Fuel Capacity (L)", "Fuel capacity for the Hounddog vehicle in liters", false, false, (ValueValidator)(object)new ValueRange<float>(10f, 200f), (string)null); _cheetahFuelCapacity = _capacityCategory.CreateEntry<float>("CheetahFuelCapacity", 35f, "Cheetah Fuel Capacity (L)", "Fuel capacity for the Cheetah vehicle in liters", false, false, (ValueValidator)(object)new ValueRange<float>(10f, 200f), (string)null); _hotboxFuelCapacity = _capacityCategory.CreateEntry<float>("HotboxFuelCapacity", 50f, "Hotbox Fuel Capacity (L)", "Fuel capacity for the Hotbox vehicle in liters", false, false, (ValueValidator)(object)new ValueRange<float>(10f, 200f), (string)null); _bugattiTourbillonFuelCapacity = _capacityCategory.CreateEntry<float>("Bugatti_TourbillonFuelCapacity", 40f, "Bugatti Tourbillon Fuel Capacity (L)", "Fuel capacity for the Bugatti Tourbillon vehicle in liters", false, false, (ValueValidator)(object)new ValueRange<float>(10f, 200f), (string)null); _canofsoupcarFuelCapacity = _capacityCategory.CreateEntry<float>("canofsoupcarFuelCapacity", 30f, "canofsoupcar Fuel Capacity (L)", "Fuel capacity for the canofsoupcar vehicle in liters", false, false, (ValueValidator)(object)new ValueRange<float>(10f, 200f), (string)null); _cyberTruckFuelCapacity = _capacityCategory.CreateEntry<float>("Cyber_TruckFuelCapacity", 50f, "Cyber Truck Fuel Capacity (L)", "Fuel capacity for the Cyber Truck vehicle in liters", false, false, (ValueValidator)(object)new ValueRange<float>(10f, 200f), (string)null); _demonFuelCapacity = _capacityCategory.CreateEntry<float>("DemonFuelCapacity", 40f, "Demon Fuel Capacity (L)", "Fuel capacity for the Demon vehicle in liters", false, false, (ValueValidator)(object)new ValueRange<float>(10f, 200f), (string)null); _driftcarFuelCapacity = _capacityCategory.CreateEntry<float>("driftcarFuelCapacity", 25f, "driftcar Fuel Capacity (L)", "Fuel capacity for the driftcar vehicle in liters", false, false, (ValueValidator)(object)new ValueRange<float>(10f, 200f), (string)null); _gtrR34FuelCapacity = _capacityCategory.CreateEntry<float>("GTR_R34FuelCapacity", 30f, "GTR R34 Fuel Capacity (L)", "Fuel capacity for the GTR R34 vehicle in liters", false, false, (ValueValidator)(object)new ValueRange<float>(10f, 200f), (string)null); _gtrR35FuelCapacity = _capacityCategory.CreateEntry<float>("GTR_R35FuelCapacity", 35f, "GTR R35 Fuel Capacity (L)", "Fuel capacity for the GTR R35 vehicle in liters", false, false, (ValueValidator)(object)new ValueRange<float>(10f, 200f), (string)null); _lamborghiniVenenoFuelCapacity = _capacityCategory.CreateEntry<float>("Lamborghini_VenenoFuelCapacity", 35f, "Lamborghini Veneno Fuel Capacity (L)", "Fuel capacity for the Lamborghini Veneno vehicle in liters", false, false, (ValueValidator)(object)new ValueRange<float>(10f, 200f), (string)null); _rollsRoyceGhostFuelCapacity = _capacityCategory.CreateEntry<float>("Rolls_Royce_GhostFuelCapacity", 45f, "Rolls Royce Ghost Fuel Capacity (L)", "Fuel capacity for the Rolls Royce Ghost vehicle in liters", false, false, (ValueValidator)(object)new ValueRange<float>(10f, 200f), (string)null); _supercarFuelCapacity = _capacityCategory.CreateEntry<float>("supercarFuelCapacity", 30f, "Supercar Fuel Capacity (L)", "Fuel capacity for the Supercar vehicle in liters", false, false, (ValueValidator)(object)new ValueRange<float>(10f, 200f), (string)null); _koenigseggCc850FuelCapacity = _capacityCategory.CreateEntry<float>("Koenigsegg_CC850FuelCapacity", 45f, "Koenigsegg CC850 Fuel Capacity (L)", "Fuel capacity for the Koenigsegg CC850 vehicle in liters", false, false, (ValueValidator)(object)new ValueRange<float>(10f, 200f), (string)null); _showFuelGauge = _preferencesCategory.CreateEntry<bool>("ShowFuelGauge", true, "Show Fuel Gauge", "If enabled, shows fuel gauge UI when driving vehicles", false, false, (ValueValidator)null, (string)null); _enableDynamicPricing = _preferencesCategory.CreateEntry<bool>("EnableDynamicPricing", true, "Enable Dynamic Pricing", "If enabled, fuel prices will vary based on which day it is", false, false, (ValueValidator)null, (string)null); _enablePricingOnTier = _preferencesCategory.CreateEntry<bool>("EnablePricingOnTier", true, "Enable Pricing on Tier", "If enabled, fuel prices will be inflated based on the player's current tier", false, false, (ValueValidator)null, (string)null); _enableCurfewFuelTax = _preferencesCategory.CreateEntry<bool>("EnableCurfewFuelTax", true, "Enable Curfew Fuel Tax", "If enabled, fuel price is doubled during curfew hours", false, false, (ValueValidator)null, (string)null); _enableDebugLogging = _preferencesCategory.CreateEntry<bool>("EnableDebugLogging", false, "Enable Debug Logging", "If enabled, shows detailed debug information in console", false, false, (ValueValidator)null, (string)null); _swapGaugeDirection = _preferencesCategory.CreateEntry<bool>("SwapGaugeDirection", false, "Swap Gauge Direction", "If enabled, fuel gauge fills from left to right instead of right to left", false, false, (ValueValidator)null, (string)null); _useNewGaugeUI = _preferencesCategory.CreateEntry<bool>("UseNewGaugeUI", true, "Use New Gauge UI", "If enabled, uses the new circular fuel gauge instead of the old slider-based gauge. Change requires vehicle re-entry to take effect.", false, false, (ValueValidator)null, (string)null); ModLogger.Debug("MelonPreferences initialized successfully"); } catch (Exception exception) { ModLogger.Error("Failed to initialize MelonPreferences", exception); } } private void InitializeSystems() { try { if (!EnableFuelSystem) { ModLogger.Debug("Fuel system disabled via preferences"); return; } _fuelSystemManager = new FuelSystemManager(); ModLogger.Debug("Fuel system manager initialized"); HarmonyPatches.SetModInstance(this); ModLogger.Debug("Harmony patches updated with fuel systems"); _fuelUIManager = new FuelUIManager(); ModLogger.Debug("Fuel UI manager initialized"); _fuelStationManager = new FuelStationManager(); ModLogger.Debug("Fuel station manager initialized"); ModLogger.Debug("All fuel systems initialized successfully"); } catch (Exception exception) { ModLogger.Error("Failed to initialize fuel systems", exception); } } public void ToggleDebugLogging() { try { if (_enableDebugLogging != null) { _enableDebugLogging.Value = !_enableDebugLogging.Value; ModLogger.Info("Debug logging " + (_enableDebugLogging.Value ? "enabled" : "disabled")); if (_enableDebugLogging.Value) { ModLogger.Info("Debug logging is now ON - you should see [FUEL] and [UI] messages"); } else { ModLogger.Info("Debug logging is now OFF"); } } } catch (Exception exception) { ModLogger.Error("Error toggling debug logging", exception); } } public override void OnApplicationQuit() { try { ModLogger.Info("S1FuelMod shutting down..."); _fuelSystemManager?.Dispose(); _fuelUIManager?.Dispose(); _fuelStationManager?.Dispose(); Instance = null; } catch (Exception exception) { ModLogger.Error("Error during mod shutdown", exception); } } public void SavePreferences() { try { MelonPreferences_Category? preferencesCategory = _preferencesCategory; if (preferencesCategory != null) { preferencesCategory.SaveToFile(true); } ModLogger.Debug("Preferences saved successfully"); } catch (Exception exception) { ModLogger.Error("Failed to save preferences", exception); } } public FuelSystemManager? GetFuelSystemManager() { return _fuelSystemManager; } public FuelUIManager? GetFuelUIManager() { return _fuelUIManager; } public FuelStationManager? GetFuelStationManager() { return _fuelStationManager; } public void RefreshFuelGauges() { try { _fuelUIManager?.RefreshAllGauges(); ModLogger.Debug("Fuel gauges refreshed to apply preference changes"); } catch (Exception exception) { ModLogger.Error("Error refreshing fuel gauges", exception); } } public void OnNewGaugeUIPreferenceChanged() { try { ModLogger.Info($"New Gauge UI preference changed to: {UseNewGaugeUI}"); RefreshFuelGauges(); } catch (Exception exception) { ModLogger.Error("Error handling new gauge UI preference change", exception); } } } } namespace S1FuelMod.Utils { public static class Constants { public static class Defaults { public const bool ENABLE_FUEL_SYSTEM = true; public const float FUEL_CONSUMPTION_MULTIPLIER = 1f; public const float DEFAULT_FUEL_CAPACITY = 40f; public const float SHITBOX_FUEL_CAPACITY = 30f; public const float VEEPER_FUEL_CAPACITY = 40f; public const float BRUISER_FUEL_CAPACITY = 40f; public const float DINKLER_FUEL_CAPACITY = 55f; public const float HOUNDDOG_FUEL_CAPACITY = 35f; public const float CHEETAH_FUEL_CAPACITY = 35f; public const float HOTBOX_FUEL_CAPACITY = 50f; public const float BUGATTI_TOURBILLON_FUEL_CAPACITY = 40f; public const float CANOFSOUPCAR_FUEL_CAPACITY = 30f; public const float CYBER_TRUCK_FUEL_CAPACITY = 50f; public const float DEMON_FUEL_CAPACITY = 40f; public const float DRIFTCAR_FUEL_CAPACITY = 25f; public const float GTR_R34_FUEL_CAPACITY = 30f; public const float GTR_R35_FUEL_CAPACITY = 35f; public const float LAMBORGHINI_VENENO_FUEL_CAPACITY = 35f; public const float ROLLS_ROYCE_GHOST_FUEL_CAPACITY = 45f; public const float SUPERCAR_FUEL_CAPACITY = 30f; public const float KOENIGSEGG_CC850_FUEL_CAPACITY = 45f; public const bool SHOW_FUEL_GAUGE = true; public const bool ENABLE_DEBUG_LOGGING = false; } public static class Constraints { public const float MIN_CONSUMPTION_MULTIPLIER = 0.1f; public const float MAX_CONSUMPTION_MULTIPLIER = 5f; public const float MIN_FUEL_CAPACITY = 10f; public const float MAX_FUEL_CAPACITY = 200f; public const float MIN_FUEL_PRICE_PER_LITER = 0.1f; public const float MAX_FUEL_PRICE_PER_LITER = 1000f; } public static class Fuel { public const float BASE_CONSUMPTION_RATE = 360f; public const float IDLE_CONSUMPTION_RATE = 30f; public const float LOW_FUEL_WARNING_THRESHOLD = 20f; public const float CRITICAL_FUEL_WARNING_THRESHOLD = 5f; public const float REFUEL_RATE = 4f; public const float FUEL_PRICE_PER_LITER = 4f; public const float ENGINE_CUTOFF_FUEL_LEVEL = 0f; public const float ENGINE_SPUTTER_FUEL_LEVEL = 4f; } public static class UI { public static class Colors { public static readonly Color FUEL_NORMAL = new Color(0.2f, 0.8f, 0.2f, 0.8f); public static readonly Color FUEL_LOW = new Color(1f, 0.8f, 0f, 0.8f); public static readonly Color FUEL_CRITICAL = new Color(1f, 0.2f, 0.2f, 0.8f); public static readonly Color GAUGE_BACKGROUND = new Color(0.1f, 0.1f, 0.1f, 0.6f); public static readonly Color GAUGE_BORDER = new Color(0.8f, 0.8f, 0.8f, 0.8f); } public const float GAUGE_UPDATE_INTERVAL = 0.1f; public const float GAUGE_WIDTH = 200f; public const float GAUGE_HEIGHT = 20f; } public static class Game { public const string GAME_STUDIO = "TVGS"; public const string GAME_NAME = "Schedule I"; public const string VEHICLE_LAYER = "Vehicle"; public const string UI_LAYER = "UI"; public const string MAIN_SCENE = "Main"; public const string MENU_SCENE = "Menu"; } public static class Network { public const string FUEL_UPDATE_MESSAGE_TYPE = "fuel_update"; public const string FUEL_SYNC_MESSAGE_TYPE = "fuel_sync"; public const float SYNC_INTERVAL = 1f; } public static class SaveSystem { public const string FUEL_DATA_KEY_PREFIX = "fuel_"; public const string FUEL_LEVEL_KEY = "fuel_level"; public const string MAX_CAPACITY_KEY = "max_capacity"; public const string CONSUMPTION_RATE_KEY = "consumption_rate"; } public const string MOD_NAME = "S1FuelMod"; public const string MOD_VERSION = "1.0.0"; public const string MOD_AUTHORS = "Bars & SirTidez"; public const string MOD_DESCRIPTION = "Adds a comprehensive fuel system to LandVehicles in Schedule I"; public const string PREFERENCES_CATEGORY = "S1FuelMod"; public const string PREFERENCES_FILE_PATH = "UserData/S1FuelMod.cfg"; } public static class ModLogger { public static void Info(string message) { MelonLogger.Msg(message); } public static void Warning(string message) { MelonLogger.Warning(message); } public static void Error(string message) { MelonLogger.Error(message); } public static void Error(string message, Exception exception) { MelonLogger.Error(message + ": " + exception.Message); MelonLogger.Error("Stack trace: " + exception.StackTrace); } public static void Debug(string message) { Core? instance = Core.Instance; if (instance != null && instance.EnableDebugLogging) { MelonLogger.Msg("[DEBUG] " + message); } } public static void FuelDebug(string message) { Core? instance = Core.Instance; if (instance != null && instance.EnableDebugLogging) { MelonLogger.Msg("[FUEL] " + message); } } public static void UIDebug(string message) { Core? instance = Core.Instance; if (instance != null && instance.EnableDebugLogging) { MelonLogger.Msg("[UI] " + message); } } public static void LogInitialization() { Info("Initializing S1FuelMod v1.0.0 by Bars & SirTidez"); Info("Adds a comprehensive fuel system to LandVehicles in Schedule I"); } public static void LogVehicleFuel(string vehicleCode, string vehicleGUID, float currentFuel, float maxCapacity) { Core? instance = Core.Instance; if (instance != null && instance.EnableDebugLogging) { MelonLogger.Msg($"[FUEL] {vehicleCode} ({vehicleGUID.Substring(0, 8)}...): {currentFuel:F1}L / {maxCapacity:F1}L ({currentFuel / maxCapacity * 100f:F1}%)"); } } public static void LogFuelConsumption(string vehicleGUID, float consumed, float remaining) { Core? instance = Core.Instance; if (instance != null && instance.EnableDebugLogging) { MelonLogger.Msg($"[FUEL] Vehicle {vehicleGUID.Substring(0, 8)}... consumed {consumed:F3}L, remaining: {remaining:F1}L"); } } public static void LogFuelWarning(string vehicleGUID, float fuelLevel, string warningType) { MelonLogger.Warning($"[FUEL] Vehicle {vehicleGUID.Substring(0, 8)}... {warningType} fuel warning: {fuelLevel:F1}L"); } } } namespace S1FuelMod.UI { public class FuelGauge : IDisposable { private readonly VehicleFuelSystem _fuelSystem; private GameObject? _gaugeContainer; private RectTransform? _gaugeContainerRect; private RectTransform? _gaugeNeedleRect; private Image? _gaugeBackground; private TextMeshProUGUI? _gaugeText; private Canvas? _parentCanvas; private CanvasGroup? _gaugeTextGroup; private bool _isVisible; private float _lastUpdateTime; public bool IsVisible => _isVisible && (Object)(object)_gaugeContainer != (Object)null && _gaugeContainer.activeInHierarchy; public FuelGauge(VehicleFuelSystem fuelSystem) { _fuelSystem = fuelSystem ?? throw new ArgumentNullException("fuelSystem"); CreateGauge(); } private void CreateGauge() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: 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) _parentCanvas = FindUICanvas(); if ((Object)(object)_parentCanvas == (Object)null) { ModLogger.Error("FuelGaugeUI: No suitable UI canvas found. Cannot create gauge."); return; } _gaugeContainer = new GameObject("FuelGauge"); _gaugeContainer.transform.SetParent(((Component)_parentCanvas).transform, false); _gaugeContainerRect = _gaugeContainer.AddComponent<RectTransform>(); _gaugeContainerRect.anchorMin = new Vector2(0.42f, 0.1f); _gaugeContainerRect.anchorMax = new Vector2(0.42f, 0.1f); _gaugeContainerRect.pivot = new Vector2(0f, 1f); _gaugeContainerRect.sizeDelta = new Vector2(200f, 75f); _gaugeContainerRect.anchoredPosition = Vector2.zero; SetupEventListeners(); CreateGaugeBackground(); CreateFillElements(); CreateGaugeNeedle(); _gaugeContainer.SetActive(true); } private void SetupEventListeners() { try { _fuelSystem.OnFuelLevelChanged.AddListener(UnityAction<float>.op_Implicit((Action<float>)OnFuelLevelChanged)); _fuelSystem.OnFuelPercentageChanged.AddListener(UnityAction<float>.op_Implicit((Action<float>)OnFuelPercentageChanged)); _fuelSystem.OnLowFuelWarning.AddListener(UnityAction<bool>.op_Implicit((Action<bool>)OnLowFuelWarning)); _fuelSystem.OnCriticalFuelWarning.AddListener(UnityAction<bool>.op_Implicit((Action<bool>)OnCriticalFuelWarning)); _fuelSystem.OnFuelEmpty.AddListener(UnityAction<bool>.op_Implicit((Action<bool>)OnFuelEmpty)); } catch (Exception exception) { ModLogger.Error("Error setting up event listeners", exception); } } private void CreateGaugeBackground() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_002d: 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_0045: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) try { GameObject val = new GameObject("FuelGaugeBackground"); val.transform.SetParent(_gaugeContainer.transform, false); RectTransform val2 = val.AddComponent<RectTransform>(); val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.one; val2.offsetMin = Vector2.zero; val2.offsetMax = Vector2.zero; _gaugeBackground = val.AddComponent<Image>(); ((Graphic)_gaugeBackground).color = new Color(0.8f, 0.8f, 0.8f, 0.5f); _gaugeBackground.type = (Type)0; Outline val3 = val.AddComponent<Outline>(); ((Shadow)val3).effectColor = new Color(0f, 0f, 0f, 0.8f); ((Shadow)val3).effectDistance = new Vector2(1f, 1f); } catch (Exception exception) { ModLogger.Error("Error creating gauge background", exception); } } private void CreateFillElements() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: 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_0101: Expected O, but got Unknown //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_0206: 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_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Expected O, but got Unknown //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Expected O, but got Unknown //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Unknown result type (might be due to invalid IL or missing references) //IL_03f8: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Empty"); val.transform.SetParent(_gaugeContainer.transform, false); CanvasGroup val2 = val.AddComponent<CanvasGroup>(); RectTransform val3 = val.AddComponent<RectTransform>(); val3.anchorMin = new Vector2(0.13f, 0.75f); val3.anchorMax = new Vector2(0.23f, 0.85f); val3.anchoredPosition = new Vector2(-5f, -2f); val3.sizeDelta = new Vector2(40f, 20f); TextMeshProUGUI val4 = val.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val4).alignment = (TextAlignmentOptions)513; ((TMP_Text)val4).fontSize = 18f; ((TMP_Text)val4).fontStyle = (FontStyles)1; ((Graphic)val4).color = Color.red; ((TMP_Text)val4).text = "E"; Shadow val5 = val.AddComponent<Shadow>(); val5.effectColor = Color.black; val5.effectDistance = new Vector2(1f, -1f); GameObject val6 = new GameObject("Full"); val6.transform.SetParent(_gaugeContainer.transform, false); CanvasGroup val7 = val6.AddComponent<CanvasGroup>(); RectTransform val8 = val6.AddComponent<RectTransform>(); val8.anchorMin = new Vector2(0.77f, 0.75f); val8.anchorMax = new Vector2(0.87f, 0.85f); val8.anchoredPosition = new Vector2(5f, 0f); val8.sizeDelta = new Vector2(40f, 20f); TextMeshProUGUI val9 = val6.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val9).alignment = (TextAlignmentOptions)516; ((TMP_Text)val9).fontSize = 18f; ((TMP_Text)val9).fontStyle = (FontStyles)1; ((Graphic)val9).color = Color.white; ((TMP_Text)val9).text = "F"; Shadow val10 = val6.AddComponent<Shadow>(); val10.effectColor = Color.black; val10.effectDistance = new Vector2(1f, -1f); val3.pivot = new Vector2(0.5f, 0.5f); ((Transform)val3).localRotation = Quaternion.Euler(0f, 0f, 40f); val8.pivot = new Vector2(0.5f, 0.5f); ((Transform)val8).localRotation = Quaternion.Euler(0f, 0f, -43f); List<GameObject> list = new List<GameObject>(); int num = 0; while (list.Count < 5) { GameObject val11 = new GameObject($"Fuel Gauge Tick {num + 1}"); val11.transform.SetParent(_gaugeContainer.transform, false); RectTransform val12 = val11.AddComponent<RectTransform>(); CreateTick(num, val11); list.Add(val11); num++; } GameObject val13 = new GameObject("Fuel Readout"); val13.transform.SetParent(_gaugeContainer.transform, false); _gaugeTextGroup = val13.AddComponent<CanvasGroup>(); RectTransform val14 = val13.AddComponent<RectTransform>(); val14.anchorMin = new Vector2(0f, 0.1f); val14.anchorMax = new Vector2(0.3f, 0.25f); val14.pivot = new Vector2(0f, 1f); val14.anchoredPosition = Vector2.zero; val14.sizeDelta = new Vector2(50f, 40f); _gaugeText = val13.AddComponent<TextMeshProUGUI>(); ((TMP_Text)_gaugeText).alignment = (TextAlignmentOptions)513; ((TMP_Text)_gaugeText).fontSize = 12f; ((TMP_Text)_gaugeText).fontStyle = (FontStyles)1; ((Graphic)_gaugeText).color = Color.white; ((TMP_Text)_gaugeText).text = "50.0L (100%)"; Shadow val15 = val13.AddComponent<Shadow>(); val15.effectColor = Color.black; val15.effectDistance = new Vector2(1f, -1f); } private void CreateGaugeNeedle() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_0091: 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_00bf: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("FuelGaugeNeedle"); val.transform.SetParent(_gaugeContainer.transform, false); _gaugeNeedleRect = val.AddComponent<RectTransform>(); _gaugeNeedleRect.anchorMin = new Vector2(0.5f, 0.01f); _gaugeNeedleRect.anchorMax = new Vector2(0.5f, 0.01f); _gaugeNeedleRect.sizeDelta = new Vector2(1f, 70f); _gaugeNeedleRect.pivot = new Vector2(0.5f, 0f); _gaugeNeedleRect.anchoredPosition = new Vector2(0f, 0f); Image val2 = val.AddComponent<Image>(); ((Graphic)val2).color = Color.red; val2.type = (Type)0; } private void CreateTick(int index, GameObject tickObject) { //IL_0036: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: 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_00da: 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) //IL_0106: 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_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0168: 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_0194: 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_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0253: 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_0284: 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_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) RectTransform component = tickObject.GetComponent<RectTransform>(); switch (index) { case 0: component.anchorMin = new Vector2(0.5f, 0.75f); component.anchorMax = new Vector2(0.5f, 0.75f); component.anchoredPosition = new Vector2(-77f, -25f); component.sizeDelta = new Vector2(3f, 15f); component.pivot = new Vector2(0.5f, 0.5f); ((Transform)component).localRotation = Quaternion.Euler(0f, 0f, 55f); break; case 1: component.anchorMin = new Vector2(0.5f, 0.75f); component.anchorMax = new Vector2(0.5f, 0.75f); component.anchoredPosition = new Vector2(-40f, -5f); component.sizeDelta = new Vector2(3f, 10f); component.pivot = new Vector2(0.5f, 0.5f); ((Transform)component).localRotation = Quaternion.Euler(0f, 0f, 30f); break; case 2: component.anchorMin = new Vector2(0.5f, 0.75f); component.anchorMax = new Vector2(0.5f, 0.75f); component.anchoredPosition = new Vector2(0f, 0f); component.sizeDelta = new Vector2(3f, 15f); component.pivot = new Vector2(0.5f, 0.5f); ((Transform)component).localRotation = Quaternion.Euler(0f, 0f, 0f); break; case 3: component.anchorMin = new Vector2(0.5f, 0.75f); component.anchorMax = new Vector2(0.5f, 0.75f); component.anchoredPosition = new Vector2(40f, -5f); component.sizeDelta = new Vector2(3f, 10f); component.pivot = new Vector2(0.5f, 0.5f); ((Transform)component).localRotation = Quaternion.Euler(0f, 0f, -30f); break; case 4: component.anchorMin = new Vector2(0.5f, 0.75f); component.anchorMax = new Vector2(0.5f, 0.75f); component.anchoredPosition = new Vector2(77f, -25f); component.sizeDelta = new Vector2(3f, 15f); component.pivot = new Vector2(0.5f, 0.5f); ((Transform)component).localRotation = Quaternion.Euler(0f, 0f, -55f); break; default: ModLogger.Error($"FuelGaugeUI: Invalid tick index {index}. Must be between 0 and 4."); return; } Image val = tickObject.AddComponent<Image>(); val.type = (Type)0; ((Graphic)val).color = new Color(0.15f, 0.15f, 0.15f, (index == 0 || index == 2 || index == 4) ? 1f : 0.75f); tickObject.SetActive(true); } private Canvas? FindUICanvas() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) try { Scene activeScene = SceneManager.GetActiveScene(); string name = ((Scene)(ref activeScene)).name; ModLogger.UIDebug("FuelGaugeUI: Current scene: " + name); if (name.Contains("Menu")) { ModLogger.UIDebug("FuelGaugeUI: Skipping UI creation in scene: " + name); return null; } if (Singleton<HUD>.InstanceExists) { Canvas canvas = Singleton<HUD>.Instance.canvas; if ((Object)(object)canvas != (Object)null) { ModLogger.UIDebug("FuelGaugeUI: Found HUD Singleton canvas in scene: " + name); return canvas; } } GameObject val = GameObject.Find("HUD"); if ((Object)(object)val != (Object)null) { Canvas component = val.GetComponent<Canvas>(); if ((Object)(object)component != (Object)null) { ModLogger.UIDebug("FuelGaugeUI: Found HUD GameObject canvas in scene: " + name); return component; } } Canvas[] array = Il2CppArrayBase<Canvas>.op_Implicit(Object.FindObjectsOfType<Canvas>()); Canvas[] array2 = array; foreach (Canvas val2 in array2) { if ((int)val2.renderMode == 0 && !((Object)val2).name.Contains("Menu")) { ModLogger.UIDebug("FuelGaugeUI: Found suitable overlay canvas: " + ((Object)val2).name + " in scene: " + name); return val2; } } ModLogger.Warning("FuelGaugeUI: No suitable UI canvas found in scene: " + name); return null; } catch (Exception exception) { ModLogger.Error("Error finding UI canvas", exception); return null; } } public void Update() { try { if (!_isVisible && !((Object)(object)_gaugeContainer == (Object)null) && !(Time.time - _lastUpdateTime < 0.1f)) { UpdateDisplay(); _lastUpdateTime = Time.time; } } catch (Exception exception) { ModLogger.Error("Error in updating the fuel gauge", exception); } } private void UpdateDisplay() { try { if ((Object)(object)_fuelSystem == (Object)null) { ModLogger.UIDebug("FuelGauge: UpdateDisplay called but fuel system is null"); } float currentFuelLevel = _fuelSystem.CurrentFuelLevel; float maxFuelCapacity = _fuelSystem.MaxFuelCapacity; float fuelPercentage = _fuelSystem.FuelPercentage; if ((Object)(object)_gaugeNeedleRect != (Object)null) { RotateNeedle(); } if ((Object)(object)_gaugeText != (Object)null) { string text = $"{currentFuelLevel:F1}L ({fuelPercentage:F1}%)"; ((TMP_Text)_gaugeText).text = text; } } catch (Exception exception) { ModLogger.Error("Error updating gauge display", exception); } } public void RotateNeedle() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) float currentFuelLevel = _fuelSystem.CurrentFuelLevel; float maxFuelCapacity = _fuelSystem.MaxFuelCapacity; float num = currentFuelLevel / maxFuelCapacity; float num2 = Mathf.Lerp(70f, -70f, num); ((Transform)_gaugeNeedleRect).localRotation = Quaternion.Euler(0f, 0f, num2); } private void OnFuelLevelChanged(float fuelLevel) { if (_isVisible) { UpdateDisplay(); } } private void OnFuelPercentageChanged(float percentage) { if (_isVisible) { UpdateDisplay(); } } public void Show() { try { if ((Object)(object)_gaugeContainer != (Object)null) { _gaugeContainer.SetActive(true); _isVisible = true; UpdateDisplay(); ModLogger.UIDebug("FuelGauge: Shown for vehicle " + _fuelSystem.VehicleGUID.Substring(0, 8) + "..."); } } catch (Exception exception) { ModLogger.Error("Error showing fuel gauge", exception); } } public void Hide() { try { if ((Object)(object)_gaugeContainer != (Object)null) { _gaugeContainer.SetActive(false); _isVisible = false; ModLogger.UIDebug("FuelGauge: Hidden for vehicle " + _fuelSystem.VehicleGUID.Substring(0, 8) + "..."); } } catch (Exception exception) { ModLogger.Error("Error hiding fuel gauge", exception); } } public void Dispose() { try { if ((Object)(object)_fuelSystem != (Object)null) { _fuelSystem.OnFuelLevelChanged.RemoveListener(UnityAction<float>.op_Implicit((Action<float>)OnFuelLevelChanged)); _fuelSystem.OnFuelPercentageChanged.RemoveListener(UnityAction<float>.op_Implicit((Action<float>)OnFuelPercentageChanged)); _fuelSystem.OnLowFuelWarning.RemoveListener(UnityAction<bool>.op_Implicit((Action<bool>)OnLowFuelWarning)); _fuelSystem.OnCriticalFuelWarning.RemoveListener(UnityAction<bool>.op_Implicit((Action<bool>)OnCriticalFuelWarning)); _fuelSystem.OnFuelEmpty.RemoveListener(UnityAction<bool>.op_Implicit((Action<bool>)OnFuelEmpty)); } if ((Object)(object)_gaugeContainer != (Object)null) { Object.Destroy((Object)(object)_gaugeContainer); _gaugeContainer = null; } _gaugeNeedleRect = null; _gaugeText = null; _isVisible = false; } catch (Exception exception) { ModLogger.Error("Error disposing FuelGauge", exception); } } private void OnLowFuelWarning(bool isActive) { ModLogger.UIDebug("FuelGauge: Low fuel warning " + (isActive ? "activated" : "deactivated")); } private void OnCriticalFuelWarning(bool isActive) { ModLogger.UIDebug("FuelGauge: Critical fuel warning " + (isActive ? "activated" : "deactivated")); } private void OnFuelEmpty(bool isEmpty) { ModLogger.UIDebug("FuelGauge: Fuel empty state " + (isEmpty ? "activated" : "deactivated")); } } public class FuelGaugeUI : IDisposable { private readonly VehicleFuelSystem _fuelSystem; private GameObject? _gaugeContainer; private RectTransform? _gaugeRect; private Image? _gaugeBackground; private Slider? _gaugeSlider; private TextMeshProUGUI? _fuelText; private Image? _warningIcon; private Image? _gaugeSliderImage; private bool _isVisible = false; private float _lastUpdateTime = 0f; private Canvas? _parentCanvas; private CanvasGroup? _fuelTextParentGroup; public bool IsVisible => _isVisible && (Object)(object)_gaugeContainer != (Object)null && _gaugeContainer.activeInHierarchy; public FuelGaugeUI(VehicleFuelSystem fuelSystem) { _fuelSystem = fuelSystem ?? throw new ArgumentNullException("fuelSystem"); try { CreateGaugeUI(); SetupEventListeners(); UpdateDisplay(); ModLogger.UIDebug("FuelGaugeUI: Created for vehicle " + _fuelSystem.VehicleGUID.Substring(0, 8) + "..."); } catch (Exception exception) { ModLogger.Error("Error creating FuelGaugeUI", exception); } } private void CreateGaugeUI() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) try { _parentCanvas = FindUICanvas(); if ((Object)(object)_parentCanvas == (Object)null) { ModLogger.Error("FuelGaugeUI: Could not find UI canvas"); return; } _gaugeContainer = new GameObject("FuelGauge"); _gaugeContainer.transform.SetParent(((Component)_parentCanvas).transform, false); _gaugeRect = _gaugeContainer.AddComponent<RectTransform>(); _gaugeRect.anchorMin = new Vector2(0.02f, 0.95f); _gaugeRect.anchorMax = new Vector2(0.02f, 0.95f); _gaugeRect.pivot = new Vector2(0f, 1f); _gaugeRect.sizeDelta = new Vector2(200f, 45f); _gaugeRect.anchoredPosition = Vector2.zero; CreateGaugeBackground(); CreateGaugeFill(); CreateFuelText(); CreateWarningIcon(); _gaugeContainer.SetActive(false); ModLogger.UIDebug("FuelGaugeUI: UI elements created successfully"); } catch (Exception exception) { ModLogger.Error("Error creating gauge UI elements", exception); } } private Canvas? FindUICanvas() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) try { Scene activeScene = SceneManager.GetActiveScene(); string name = ((Scene)(ref activeScene)).name; ModLogger.UIDebug("FuelGaugeUI: Current scene: " + name); if (name.Contains("Menu")) { ModLogger.UIDebug("FuelGaugeUI: Skipping UI creation in scene: " + name); return null; } if (Singleton<HUD>.InstanceExists) { Canvas canvas = Singleton<HUD>.Instance.canvas; if ((Object)(object)canvas != (Object)null) { ModLogger.UIDebug("FuelGaugeUI: Found HUD Singleton canvas in scene: " + name); return canvas; } } GameObject val = GameObject.Find("HUD"); if ((Object)(object)val != (Object)null) { Canvas component = val.GetComponent<Canvas>(); if ((Object)(object)component != (Object)null) { ModLogger.UIDebug("FuelGaugeUI: Found HUD GameObject canvas in scene: " + name); return component; } } Canvas[] array = Il2CppArrayBase<Canvas>.op_Implicit(Object.FindObjectsOfType<Canvas>()); Canvas[] array2 = array; foreach (Canvas val2 in array2) { if ((int)val2.renderMode == 0 && !((Object)val2).name.Contains("Menu")) { ModLogger.UIDebug("FuelGaugeUI: Found suitable overlay canvas: " + ((Object)val2).name + " in scene: " + name); return val2; } } ModLogger.Warning("FuelGaugeUI: No suitable UI canvas found in scene: " + name); return null; } catch (Exception exception) { ModLogger.Error("Error finding UI canvas", exception); return null; } } private void CreateGaugeBackground() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_002d: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) try { GameObject val = new GameObject("Background"); val.transform.SetParent(_gaugeContainer.transform, false); RectTransform val2 = val.AddComponent<RectTransform>(); val2.anchorMin = Vector2.zero; val2.anchorMax = new Vector2(1f, 0.8f); val2.offsetMin = Vector2.zero; val2.offsetMax = Vector2.zero; _gaugeBackground = val.AddComponent<Image>(); ((Graphic)_gaugeBackground).color = Constants.UI.Colors.GAUGE_BACKGROUND; _gaugeBackground.type = (Type)0; Outline val3 = val.AddComponent<Outline>(); ((Shadow)val3).effectColor = Constants.UI.Colors.GAUGE_BORDER; ((Shadow)val3).effectDistance = new Vector2(1f, 1f); } catch (Exception exception) { ModLogger.Error("Error creating gauge background", exception); } } private void CreateGaugeFill() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0037: 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_0059: 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_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Expected O, but got Unknown //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0108: 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_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) try { GameObject val = new GameObject("Fill"); val.transform.SetParent(_gaugeContainer.transform, false); RectTransform val2 = val.AddComponent<RectTransform>(); val2.anchorMin = new Vector2(0.05f, 0.1f); val2.anchorMax = new Vector2(0.95f, 0.7f); val2.offsetMin = Vector2.zero; val2.offsetMax = Vector2.zero; _gaugeSlider = val.AddComponent<Slider>(); bool flag = Core.Instance?.SwapGaugeDirection ?? false; _gaugeSlider.direction = (Direction)((!flag) ? 1 : 0); _gaugeSlider.minValue = 0f; _gaugeSlider.maxValue = 100f; GameObject val3 = new GameObject("SliderFill"); val3.transform.SetParent(val.transform, false); RectTransform val4 = val3.AddComponent<RectTransform>(); _gaugeSliderImage = val3.AddComponent<Image>(); ((Graphic)_gaugeSliderImage).color = Constants.UI.Colors.FUEL_NORMAL; val4.anchorMin = Vector2.zero; val4.anchorMax = Vector2.one; val4.offsetMin = Vector2.zero; val4.offsetMax = Vector2.zero; _gaugeSlider.fillRect = val4; } catch (Exception exception) { ModLogger.Error("Error creating gauge fill", exception); } } private void CreateFuelText() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0043: 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_006f: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) try { GameObject val = new GameObject("FuelText"); val.transform.SetParent(_gaugeContainer.transform, false); _fuelTextParentGroup = val.AddComponent<CanvasGroup>(); RectTransform val2 = val.AddComponent<RectTransform>(); val2.anchorMin = new Vector2(0f, 0.8f); val2.anchorMax = new Vector2(1f, 1f); val2.pivot = new Vector2(0f, 1f); val2.anchoredPosition = new Vector2(0f, -50f); val2.sizeDelta = new Vector2(400f, 20f); _fuelText = val.AddComponent<TextMeshProUGUI>(); ((TMP_Text)_fuelText).alignment = (TextAlignmentOptions)513; ((TMP_Text)_fuelText).fontSize = 12f; ((TMP_Text)_fuelText).fontStyle = (FontStyles)1; ((Graphic)_fuelText).color = Color.white; ((TMP_Text)_fuelText).text = "50.0L (100%)"; Shadow val3 = val.AddComponent<Shadow>(); val3.effectColor = Color.black; val3.effectDistance = new Vector2(1f, -1f); } catch (Exception exception) { ModLogger.Error("Error creating fuel text", exception); } } private void CreateWarningIcon() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) try { GameObject val = new GameObject("WarningIcon"); val.transform.SetParent(_gaugeContainer.transform, false); RectTransform val2 = val.AddComponent<RectTransform>(); Core? instance = Core.Instance; if (instance != null && instance.SwapGaugeDirection) { val2.anchorMin = new Vector2(0.05f, 0.15f); val2.anchorMax = new Vector2(0.15f, 0.65f); } else { val2.anchorMin = new Vector2(0.85f, 0.15f); val2.anchorMax = new Vector2(0.95f, 0.65f); } val2.offsetMin = Vector2.zero; val2.offsetMax = Vector2.zero; _warningIcon = val.AddComponent<Image>(); ((Graphic)_warningIcon).color = Constants.UI.Colors.FUEL_CRITICAL; _warningIcon.type = (Type)0; val.SetActive(false); } catch (Exception exception) { ModLogger.Error("Error creating warning icon", exception); } } private void SetupEventListeners() { try { if ((Object)(object)_fuelSystem != (Object)null) { ModLogger.UIDebug("FuelGaugeUI: Setting up event listeners for vehicle " + _fuelSystem.VehicleGUID.Substring(0, 8) + "..."); _fuelSystem.OnFuelLevelChanged.AddListener(UnityAction<float>.op_Implicit((Action<float>)OnFuelLevelChanged)); _fuelSystem.OnFuelPercentageChanged.AddListener(UnityAction<float>.op_Implicit((Action<float>)OnFuelPercentageChanged)); _fuelSystem.OnLowFuelWarning.AddListener(UnityAction<bool>.op_Implicit((Action<bool>)OnLowFuelWarning)); _fuelSystem.OnCriticalFuelWarning.AddListener(UnityAction<bool>.op_Implicit((Action<bool>)OnCriticalFuelWarning)); _fuelSystem.OnFuelEmpty.AddListener(UnityAction<bool>.op_Implicit((Action<bool>)OnFuelEmpty)); ModLogger.UIDebug("FuelGaugeUI: Event listeners set up successfully for vehicle " + _fuelSystem.VehicleGUID.Substring(0, 8) + "..."); } else { ModLogger.Warning("FuelGaugeUI: Cannot setup event listeners - fuel system is null"); } } catch (Exception exception) { ModLogger.Error("Error setting up event listeners", exception); } } public void Update() { try { if (_isVisible && !((Object)(object)_gaugeContainer == (Object)null) && !(Time.time - _lastUpdateTime < 0.1f)) { UpdateDisplay(); _lastUpdateTime = Time.time; } } catch (Exception exception) { ModLogger.Error("Error updating fuel gauge display", exception); } } private void UpdateDisplay() { try { if ((Object)(object)_fuelSystem == (Object)null) { ModLogger.UIDebug("FuelGaugeUI: UpdateDisplay called but fuel system is null"); return; } float currentFuelLevel = _fuelSystem.CurrentFuelLevel; float maxFuelCapacity = _fuelSystem.MaxFuelCapacity; float fuelPercentage = _fuelSystem.FuelPercentage; if ((Object)(object)_gaugeSlider != (Object)null && (Object)(object)_gaugeSliderImage != (Object)null) { _gaugeSlider.value = fuelPercentage; } ModLogger.UIDebug($"FuelGaugeUI: Percentage shown: {fuelPercentage}"); if ((Object)(object)_fuelText != (Object)null) { string text = $"{currentFuelLevel:F1}L ({fuelPercentage:F1}%)"; ((TMP_Text)_fuelText).text = text; } UpdateGaugeColors(); UpdateWarningIcon(); } catch (Exception exception) { ModLogger.Error("Error updating gauge display", exception); } } private void UpdateGaugeColors() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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_0071: 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_0082: 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) try { if (!((Object)(object)_fuelText == (Object)null)) { Color color = Color.white; Color val; if (_fuelSystem.IsCriticalFuel) { val = Constants.UI.Colors.FUEL_CRITICAL; color = Constants.UI.Colors.FUEL_CRITICAL; } else if (_fuelSystem.IsLowFuel) { val = Constants.UI.Colors.FUEL_LOW; color = Constants.UI.Colors.FUEL_LOW; } else { val = Constants.UI.Colors.FUEL_NORMAL; } ((Graphic)_gaugeSliderImage).color = Color.Lerp(((Graphic)_gaugeSliderImage).color, val, Time.deltaTime * 5f); ((Graphic)_fuelText).color = color; } } catch (Exception exception) { ModLogger.Error("Error updating gauge colors", exception); } } public void UpdateGaugeDirection() { //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: 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_009c: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)_gaugeSlider == (Object)null || (Object)(object)_warningIcon == (Object)null || (Object)(object)_gaugeRect == (Object)null) { return; } bool flag = Core.Instance?.SwapGaugeDirection ?? false; _gaugeSlider.direction = (Direction)((!flag) ? 1 : 0); RectTransform component = ((Component)_warningIcon).GetComponent<RectTransform>(); if ((Object)(object)component != (Object)null) { if (flag) { component.anchorMin = new Vector2(0.05f, 0.15f); component.anchorMax = new Vector2(0.15f, 0.65f); } else { component.anchorMin = new Vector2(0.85f, 0.15f); component.anchorMax = new Vector2(0.95f, 0.65f); } } ModLogger.UIDebug("FuelGaugeUI: Gauge updated - Direction: " + (flag ? "LeftToRight" : "RightToLeft")); } catch (Exception exception) { ModLogger.Error("Error updating gauge direction", exception); } } private void UpdateWarningIcon() { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)_warningIcon == (Object)null) { return; } bool flag = _fuelSystem.IsLowFuel || _fuelSystem.IsCriticalFuel || _fuelSystem.IsOutOfFuel; ((Component)_warningIcon).gameObject.SetActive(flag); if (flag) { if (_fuelSystem.IsLowFuel) { float a = 0.5f + 0.5f * Mathf.Sin(Time.time * 2f); Color color = ((Graphic)_gaugeSliderImage).color; color.a = a; ((Graphic)_gaugeSliderImage).color = color; } else if (_fuelSystem.IsCriticalFuel || _fuelSystem.IsOutOfFuel) { float a2 = 0.5f + 0.5f * Mathf.Sin(Time.time * 3f); Color color2 = ((Graphic)_warningIcon).color; Color color3 = ((Graphic)_gaugeSliderImage).color; color2.a = a2; color3.a = a2; ((Graphic)_warningIcon).color = color2; ((Graphic)_gaugeSliderImage).color = color3; } else { Color color4 = ((Graphic)_warningIcon).color; color4.a = 1f; ((Graphic)_warningIcon).color = color4; } } } catch (Exception exception) { ModLogger.Error("Error updating warning icon", exception); } } public void Show() { //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_0052: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)_gaugeContainer != (Object)null) { _gaugeContainer.SetActive(true); if ((Object)(object)_gaugeSliderImage != (Object)null) { Color color = ((Graphic)_gaugeSliderImage).color; color.a = 1f; ((Graphic)_gaugeSliderImage).color = color; } _isVisible = true; UpdateGaugeDirection(); UpdateDisplay(); ModLogger.UIDebug("FuelGaugeUI: Shown for vehicle " + _fuelSystem.VehicleGUID.Substring(0, 8) + "..."); } } catch (Exception exception) { ModLogger.Error("Error showing fuel gauge", exception); } } public void Hide() { //IL_002a: 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_0042: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)_gaugeContainer != (Object)null) { if ((Object)(object)_gaugeSliderImage != (Object)null) { Color color = ((Graphic)_gaugeSliderImage).color; color.a = 0f; ((Graphic)_gaugeSliderImage).color = color; } _gaugeContainer.SetActive(false); _isVisible = false; ModLogger.UIDebug("FuelGaugeUI: Hidden for vehicle " + _fuelSystem.VehicleGUID.Substring(0, 8) + "..."); } } catch (Exception exception) { ModLogger.Error("Error hiding fuel gauge", exception); } } private void OnFuelLevelChanged(float fuelLevel) { if (_isVisible) { UpdateDisplay(); } } private void OnFuelPercentageChanged(float percentage) { if (_isVisible) { UpdateDisplay(); } } private void OnLowFuelWarning(bool isActive) { ModLogger.UIDebug("FuelGaugeUI: Low fuel warning " + (isActive ? "activated" : "deactivated")); } private void OnCriticalFuelWarning(bool isActive) { ModLogger.UIDebug("FuelGaugeUI: Critical fuel warning " + (isActive ? "activated" : "deactivated")); } private void OnFuelEmpty(bool isEmpty) { ModLogger.UIDebug("FuelGaugeUI: Fuel empty state " + (isEmpty ? "activated" : "deactivated")); } public void Dispose() { try { if ((Object)(object)_fuelSystem != (Object)null) { _fuelSystem.OnFuelLevelChanged.RemoveListener(UnityAction<float>.op_Implicit((Action<float>)OnFuelLevelChanged)); _fuelSystem.OnFuelPercentageChanged.RemoveListener(UnityAction<float>.op_Implicit((Action<float>)OnFuelPercentageChanged)); _fuelSystem.OnLowFuelWarning.RemoveListener(UnityAction<bool>.op_Implicit((Action<bool>)OnLowFuelWarning)); _fuelSystem.OnCriticalFuelWarning.RemoveListener(UnityAction<bool>.op_Implicit((Action<bool>)OnCriticalFuelWarning)); _fuelSystem.OnFuelEmpty.RemoveListener(UnityAction<bool>.op_Implicit((Action<bool>)OnFuelEmpty)); } if ((Object)(object)_gaugeContainer != (Object)null) { Object.Destroy((Object)(object)_gaugeContainer); _gaugeContainer = null; } _gaugeRect = null; _gaugeBackground = null; _gaugeSliderImage = null; _fuelText = null; _warningIcon = null; _isVisible = false; ModLogger.UIDebug("FuelGaugeUI: Disposed for vehicle " + _fuelSystem.VehicleGUID.Substring(0, 8) + "..."); } catch (Exception exception) { ModLogger.Error("Error disposing FuelGaugeUI", exception); } } } public class FuelUIManager : IDisposable { private readonly Dictionary<string, FuelGaugeUI> _activeFuelGauges = new Dictionary<string, FuelGaugeUI>(); private readonly Dictionary<string, FuelGauge> _activeNewGauges = new Dictionary<string, FuelGauge>(); private Player? _localPlayer; private LandVehicle? _currentVehicle; private string _currentVehicleGUID = string.Empty; private FuelGaugeUI? _currentGauge; private FuelGauge? _currentNewGauge; public FuelUIManager() { ModLogger.UIDebug("FuelUIManager: Initializing..."); SceneManager.sceneLoaded += UnityAction<Scene, LoadSceneMode>.op_Implicit((Action<Scene, LoadSceneMode>)OnSceneLoaded); SceneManager.sceneUnloaded += UnityAction<Scene>.op_Implicit((Action<Scene>)OnSceneUnloaded); FindLocalPlayer(); ModLogger.UIDebug("FuelUIManager: Initialized"); } public void Update() { try { Core? instance = Core.Instance; if ((instance == null || instance.ShowFuelGauge) && IsInGameScene()) { if ((Object)(object)_localPlayer == (Object)null) { FindLocalPlayer(); return; } CheckVehicleChange(); _currentGauge?.Update(); _currentNewGauge?.Update(); } } catch (Exception exception) { ModLogger.Error("Error in FuelUIManager.Update", exception); } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { try { ModLogger.UIDebug("FuelUIManager: Scene loaded: " + ((Scene)(ref scene)).name); _localPlayer = null; _currentVehicle = null; _currentVehicleGUID = string.Empty; if (_currentGauge != null) { _currentGauge.Hide(); _currentGauge = null; } if (_currentNewGauge != null) { _currentNewGauge.Hide(); _currentNewGauge = null; } } catch (Exception exception) { ModLogger.Error("Error handling scene loaded event", exception); } } private void OnSceneUnloaded(Scene scene) { try { ModLogger.UIDebug("FuelUIManager: Scene unloaded: " + ((Scene)(ref scene)).name); List<string> list = new List<string>(); foreach (KeyValuePair<string, FuelGaugeUI> activeFuelGauge in _activeFuelGauges) { if (activeFuelGauge.Value != null && !activeFuelGauge.Value.IsVisible) { list.Add(activeFuelGauge.Key); } } foreach (string item in list) { RemoveFuelGaugeForVehicle(item); } list.Clear(); foreach (KeyValuePair<string, FuelGauge> activeNewGauge in _activeNewGauges) { if (activeNewGauge.Value != null && !activeNewGauge.Value.IsVisible) { list.Add(activeNewGauge.Key); } } foreach (string item2 in list) { RemoveNewFuelGaugeForVehicle(item2); } } catch (Exception exception) { ModLogger.Error("Error handling scene unloaded event", exception); } } private bool IsInGameScene() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) try { Scene activeScene = SceneManager.GetActiveScene(); string name = ((Scene)(ref activeScene)).name; if (name.Contains("Menu")) { return false; } return true; } catch (Exception exception) { ModLogger.Error("Error checking game scene", exception); return false; } } private void FindLocalPlayer() { try { if ((Object)(object)Player.Local != (Object)null) { _localPlayer = Player.Local; ModLogger.UIDebug("FuelUIManager: Found local player"); } else { ModLogger.UIDebug("FuelUIManager: Local player not found"); } } catch (Exception exception) { ModLogger.Error("Error finding local player", exception); } } private void CheckVehicleChange() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)_localPlayer == (Object)null) { return; } LandVehicle val = null; string text = string.Empty; if ((Object)(object)_localPlayer.CurrentVehicle != (Object)null) { NetworkObject currentVehicle = _localPlayer.CurrentVehicle; val = ((Component)currentVehicle).GetComponent<LandVehicle>(); if ((Object)(object)val != (Object)null) { Guid gUID = val.GUID; text = ((object)(Guid)(ref gUID)).ToString(); } } if (!(text != _currentVehicleGUID)) { return; } if (_currentGauge != null) { _currentGauge.Hide(); _currentGauge = null; } if (_currentNewGauge != null) { _currentNewGauge.Hide(); _currentNewGauge = null; } _currentVehicle = val; _currentVehicleGUID = text; if ((Object)(object)_currentVehicle != (Object)null) { Core? instance = Core.Instance; if (instance != null && instance.UseNewGaugeUI) { ShowNewFuelGaugeForVehicle(_currentVehicle); } else { ShowFuelGaugeForVehicle(_currentVehicle); } } LandVehicle? currentVehicle2 = _currentVehicle; ModLogger.UIDebug("FuelUIManager: Vehicle changed to " + (((currentVehicle2 != null) ? currentVehicle2.VehicleName : null) ?? "none")); } catch (Exception exception) { ModLogger.Error("Error checking vehicle change", exception); } } public void ShowFuelGaugeForVehicle(LandVehicle vehicle) { //IL_0013: 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_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) try { if ((Object)(object)vehicle == (Object)null) { return; } Guid gUID = vehicle.GUID; string text = ((object)(Guid)(ref gUID)).ToString(); if (!_activeFuelGauges.ContainsKey(text)) { Core? instance = Core.Instance; object obj; if (instance == null) { obj = null; } else { FuelSystemManager? fuelSystemManager = instance.GetFuelSystemManager(); if (fuelSystemManager == null) { obj = null; } else { gUID = vehicle.GUID; obj = fuelSystemManager.GetFuelSystem(((object)(Guid)(ref gUID)).ToString()); } } VehicleFuelSystem vehicleFuelSystem = (VehicleFuelSystem)obj; if ((Object)(object)vehicleFuelSystem == (Object)null) { ModLogger.Warning("FuelUIManager: No fuel system found for vehicle " + text.Substring(0, 8) + "..."); return; } FuelGaugeUI value = new FuelGaugeUI(vehicleFuelSystem); _activeFuelGauges[text] = value; ModLogger.UIDebug("FuelUIManager: Created fuel gauge for vehicle " + text.Substring(0, 8) + "..."); } _currentGauge = _activeFuelGauges[text]; _currentGauge.Show(); ModLogger.UIDebug("FuelUIManager: Showing fuel gauge for " + vehicle.VehicleName); } catch (Exception exception) { ModLogger.Error("Error showing fuel gauge for vehicle", exception); } } public void HideFuelGaugeForVehicle(string vehicleGUID) { try { if (_activeFuelGauges.TryGetValue(vehicleGUID, out var value)) { value.Hide(); ModLogger.UIDebug("FuelUIManager: Hidden fuel gauge for vehicle " + vehicleGUID.Substring(0, 8) + "..."); } } catch (Exception exception) { ModLogger.Error("Error hiding fuel gauge for vehicle", exception); } } public void RemoveFuelGaugeForVehicle(string vehicleGUID) { try { if (_activeFuelGauges.TryGetValue(vehicleGUID, out var value)) { value.Dispose(); _activeFuelGauges.Remove(vehicleGUID); if (_currentGauge == value) { _currentGauge = null; } ModLogger.UIDebug("FuelUIManager: Removed fuel gauge for vehicle " + vehicleGUID.Substring(0, 8) + "..."); } } catch (Exception exception) { ModLogger.Error("Error removing fuel gauge for vehicle", exception); } } public void ShowNewFuelGaugeForVehicle(LandVehicle vehicle) { //IL_0013: 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_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) try { if ((Object)(object)vehicle == (Object)null) { return; } Guid gUID = vehicle.GUID; string text = ((object)(Guid)(ref gUID)).ToString(); if (!_activeNewGauges.ContainsKey(text)) { Core? instance = Core.Instance; object obj; if (instance == null) { obj = null; } else { FuelSystemManager? fuelSystemManager = instance.GetFuelSystemManager(); if (fuelSystemManager == null) { obj = null; } else { gUID = vehicle.GUID; obj = fuelSystemManager.GetFuelSystem(((object)(Guid)(ref gUID)).ToString()); } } VehicleFuelSystem vehicleFuelSystem = (VehicleFuelSystem)obj; if ((Object)(object)vehicleFuelSystem == (Object)null) { ModLogger.Warning("FuelUIManager: No fuel system found for vehicle " + text.Substring(0, 8) + "..."); return; } FuelGauge value = new FuelGauge(vehicleFuelSystem); _activeNewGauges[text] = value; ModLogger.UIDebug("FuelUIManager: Created new fuel gauge for vehicle " + text.Substring(0, 8) + "..."); } _currentNewGauge = _activeNewGauges[text]; _currentNewGauge.Show(); ModLogger.UIDebug("FuelUIManager: Showing new fuel gauge for " + vehicle.VehicleName); } catch (Exception exception) { ModLogger.Error("Error showing new fuel gauge for vehicle", exception); } } public void HideNewFuelGaugeForVehicle(string vehicleGUID) { try { if (_activeNewGauges.TryGetValue(vehicleGUID, out var value)) { value.Hide(); ModLogger.UIDebug("FuelUIManager: Hidden new fuel gauge for vehicle " + vehicleGUID.Substring(0, 8) + "..."); } } catch (Exception exception) { ModLogger.Error("Error hiding new fuel gauge for vehicle", exception); } } public void RemoveNewFuelGaugeForVehicle(string vehicleGUID) { try { if (_activeNewGauges.TryGetValue(vehicleGUID, out var value)) { value.Dispose(); _activeNewGauges.Remove(vehicleGUID); if (_currentNewGauge == value) { _currentNewGauge = null; } ModLogger.UIDebug("FuelUIManager: Removed new fuel gauge for vehicle " + vehicleGUID.Substring(0, 8) + "..."); } } catch (Exception exception) { ModLogger.Error("Error removing new fuel gauge for vehicle", exception); } } public void HideAllGauges() { try { foreach (FuelGaugeUI value in _activeFuelGauges.Values) { value?.Hide(); } foreach (FuelGauge value2 in _activeNewGauges.Values) { value2?.Hide(); } _currentGauge = null; _currentNewGauge = null; ModLogger.UIDebug("FuelUIManager: Hidden all fuel gauges"); } catch (Exception exception) { ModLogger.Error("Error hiding all fuel gauges", exception); } } public void ShowAllGauges() { try { foreach (FuelGaugeUI value in _activeFuelGauges.Values) { value?.Show(); } foreach (FuelGauge value2 in _activeNewGauges.Values) { value2?.Show(); } ModLogger.UIDebug("FuelUIManager: Shown all fuel gauges (debug mode)"); } catch (Exception exception) { ModLogger.Error("Error showing all fuel gauges", exception); } } public FuelUIStats GetStatistics() { FuelUIStats fuelUIStats = new FuelUIStats(); try { fuelUIStats.TotalGauges = _activeFuelGauges.Count + _activeNewGauges.Count; fuelUIStats.HasCurrentGauge = _currentGauge != null || _currentNewGauge != null; LandVehicle? currentVehicle = _currentVehicle; fuelUIStats.CurrentVehicleName = ((currentVehicle != null) ? currentVehicle.VehicleName : null) ?? "None"; Player? localPlayer = _localPlayer; fuelUIStats.LocalPlayerInVehicle = (Object)(object)((localPlayer != null) ? localPlayer.CurrentVehicle : null) != (Object)null; foreach (FuelGaugeUI value in _activeFuelGauges.Values) { if (value != null) { if (value.IsVisible) { fuelUIStats.VisibleGauges++; } else { fuelUIStats.HiddenGauges++; } } else { fuelUIStats.InvalidGauges++; } } foreach (FuelGauge value2 in _activeNewGauges.Values) { if (value2 != null) { if (value2.IsVisible) { fuelUIStats.VisibleGauges++; } else { fuelUIStats.HiddenGauges++; } } else { fuelUIStats.InvalidGauges++; } } } catch (Exception exception) { ModLogger.Error("Error calculating fuel UI statistics", exception); } return fuelUIStats; } public void RefreshAllGauges() { try { ModLogger.UIDebug("FuelUIManager: Refreshing all gauges..."); if (_currentGauge != null) { _currentGauge.Hide(); _currentGauge = null; } if (_currentNewGauge != null) { _currentNewGauge.Hide(); _currentNewGauge = null; } if ((Object)(object)_currentVehicle != (Object)null) { Core? instance = Core.Instance; if (instance != null && instance.UseNewGaugeUI) { ShowNewFuelGaugeForVehicle(_currentVehicle); } else { ShowFuelGaugeForVehicle(_currentVehicle); } } ModLogger.UIDebug("FuelUIManager: All gauges refreshed"); } catch (Exception exception) { ModLogger.Error("Error refreshing fuel gauges", exception); } } public void Dispose() { try { ModLogger.UIDebug("FuelUIManager: Disposing..."); SceneManager.sceneLoaded -= UnityAction<Scene, LoadSceneMode>.op_Implicit((Action<Scene, LoadSceneMode>)OnSceneLoaded); SceneManager.sceneUnloaded -= UnityAction<Scene>.op_Implicit((Action<Scene>)OnSceneUnloaded); foreach (FuelGaugeUI value in _activeFuelGauges.Values) { value?.Dispose(); } foreach (FuelGauge value2 in _activeNewGauges.Values) { value2?.Dispose(); } _activeFuelGauges.Clear(); _activeNewGauges.Clear(); _currentGauge = null; _currentNewGauge = null; _currentVehicle = null; _localPlayer = null; ModLogger.Info("FuelUIManager: Disposed"); } catch (Exception exception) { ModLogger.Error("Error disposing FuelUIManager", exception); } } } public class FuelUIStats { public int TotalGauges { get; set; } public int VisibleGauges { get; set; } public int HiddenGauges { get; set; } public int InvalidGauges { get; set; } public bool HasCurrentGauge { get; set; } public string CurrentVehicleName { get; set; } = string.Empty; public bool LocalPlayerInVehicle { get; set; } } } namespace S1FuelMod.Systems { [RegisterTypeInIl2Cpp] public class FuelStation : InteractableObject { private enum MessageType { Info, Warning, Error, Success } private float refuelRate = 40f; private float pricePerLiter = 1f; private float maxInteractionDistance = 4f; private float vehicleDetectionRadius = 6f; private AudioSource refuelAudioSource; private AudioClip refuelStartSound; private AudioClip refuelLoopSound; private AudioClip refuelEndSound; private bool _isRefueling = false; private LandVehicle _targetVehicle; private VehicleFuelSystem _targetFuelSystem; private float _refuelStartTime; private float _totalFuelAdded; private float _totalCost; private MoneyManager _moneyManager; private FuelSystemManager _fuelSystemManager; public FuelStation(IntPtr ptr) : base(ptr) { } private void Start() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) try { InitializeFuelStation(); ModLogger.Debug($"FuelStation initialized at {((Component)this).transform.position}"); } catch (Exception exception) { ModLogger.Error("Error initializing FuelStation", exception); } } private void InitializeFuelStation() { ((InteractableObject)this).SetMessage("Refuel Vehicle - Hold to refuel"); ((InteractableObject)this).SetInteractionType((EInteractionType)0); ((InteractableObject)this).MaxInteractionRange = maxInteractionDistance; ((InteractableObject)this).RequiresUniqueClick = false; if (NetworkSingleton<MoneyManager>.InstanceExists) { _moneyManager = NetworkSingleton<MoneyManager>.Instance; } if (Core.Instance?.GetFuelSystemManager() != null) { _fuelSystemManager = Core.Instance.GetFuelSystemManager(); } if ((Object)(object)refuelAudioSource == (Object)null) { refuelAudioSource = ((Component)this).GetComponent<AudioSource>(); if ((Object)(object)refuelAudioSource == (Object)null) { refuelAudioSource = ((Component)this).gameObject.AddComponent<AudioSource>(); } } if ((Object)(object)refuelAudioSource != (Object)null) { refuelAudioSource.playOnAwake = false; refuelAudioSource.loop = false; refuelAudioSource.volume = 0.7f; refuelAudioSource.spatialBlend = 1f; refuelAudioSource.maxDistance = 20f; } refuelRate = 4f; pricePerLiter = 4f; } public override void Hovered() { //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Invalid comparison between Unknown and I4 //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) try { LandVehicle nearestOwnedVehicle = GetNearestOwnedVehicle(); if ((Object)(object)nearestOwnedVehicle != (Object)null && (Object)(object)((Component)nearestOwnedVehicle).gameObject != (Object)null) { try { FuelSystemManager fuelSystemManager = _fuelSystemManager; object obj; if (fuelSystemManager == null) { obj = null; } else { Guid gUID = nearestOwnedVehicle.GUID; obj = fuelSystemManager.GetFuelSystem(((object)(Guid)(ref gUID)).ToString()); } VehicleFuelSystem vehicleFuelSystem = (VehicleFuelSystem)obj; if ((Object)(object)vehicleFuelSystem != (Object)null) { SetFuelPrice(); float num = vehicleFuelSystem.MaxFuelCapacity - vehicleFuelSystem.CurrentFuelLevel; float num2 = num * pricePerLiter; if (num > 0.1f) { ((InteractableObject)this).SetMessage($"Refuel {nearestOwnedVehicle.VehicleName} - {MoneyManager.FormatAmount(num2, false, false)} | ${pricePerLiter:F2}/L"); ((InteractableObject)this).SetInteractableState((EInteractableState)0); } else { ((InteractableObject)this).SetMessage(nearestOwnedVehicle.VehicleName + " - Tank Full"); ((InteractableObject)this).SetInteractableState((EInteractableState)1); } } else { ((InteractableObject)this).SetMessage("Vehicle has no fuel system"); ((InteractableObject)this).SetInteractableState((EInteractableState)1); } } catch (Exception ex) { ModLogger.Debug("Error accessing vehicle properties in Hovered: " + ex.Message); ((InteractableObject)this).SetMessage("Vehicle not accessible"); ((InteractableObject)this).SetInteractableState((EInteractableState)1); } } else { ((InteractableObject)this).SetMessage("No owned vehicle nearby"); ((InteractableObject)this).SetInteractableState((EInteractableState)1); } if (((InteractableObject)this).onHovered != null) { ((InteractableObject)this).onHovered.Invoke(); } if ((int)((InteractableObject)this).interactionState != 2) { ((InteractableObject)this).ShowMessage(); } } catch (Exception exception) { ModLogger.Error("Error in FuelStation.Hovered", exception); ((InteractableObject)this).SetMessage("Error"); ((InteractableObject)this).SetInteractableState((EInteractableState)1); } } public override void StartInteract() { //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_01e9: Invalid comparison between Unknown and I4 if (_isRefueling) { return; } try { _targetVehicle = GetNearestOwnedVehicle(); if ((Object)(object)_targetVehicle == (Object)null || (Object)(object)((Component)_targetVehicle).gameObject == (Object)null) { ShowMessage("No owned vehicle nearby!", MessageType.Error); return; } try { FuelUIManager fuelUIManager = Core.Instance?.GetFuelUIManager(); if (fuelUIManager != null) { Core? instance = Core.Instance; if (instance != null && instance.UseNewGaugeUI) { fuelUIManager.ShowNewFuelGaugeForVehicle(_targetVehicle); } else { fuelUIManager.ShowFuelGaugeForVehicle(_targetVehicle); } } } catch (Exception ex) { ModLogger.Debug("Error showing fuel gauge UI: " + ex.Message); } try { FuelSystemManager fuelSystemManager = _fuelSystemManager; object targetFuelSystem; if (fuelSystemManager == null) { targetFuelSystem = null; } else { Guid gUID = _targetVehicle.GUID; targetFuelSystem = fuelSystemManager.GetFuelSystem(((object)(Guid)(ref gUID)).ToString()); } _targetFuelSystem = (VehicleFuelSystem)targetFuelSystem; } catch (Exception ex2) { ModLogger.Debug("Error getting fuel system: " + ex2.Message); _targetFuelSystem = null; } if ((Object)(object)_targetFuelSystem == (Object)null) { ShowMessage("Vehicle has no fuel system!", MessageType.Error); return; } float num = _targetFuelSystem.MaxFuelCapacity - _targetFuelSystem.CurrentFuelLevel; if (num <= 0.1f) { ShowMessage("Vehicle tank is already full!", MessageType.Warning); return; } if ((Object)(object)_moneyManager != (Object)null && _moneyManager.onlineBalance < pricePerLiter) { ShowMessage("Insufficient funds! Need " + MoneyManager.FormatAmount(pricePerLiter, false, false) + " minimum", MessageType.Error); return; } if ((int)((InteractableObject)this).interactionState != 1) { if (((InteractableObject)this).onInteractStart != null) { ((InteractableObject)this).onInteractStart.Invoke(); } try { InteractionManager instance2 = Singleton<InteractionManager>.Instance; if ((Object)(object)instance2 != (Object)null) { Singleton<InteractionCanvas>.Instance.LerpDisplayScale(0.9f); } } catch (Exception ex3) { ModLogger.Debug("Error accessing InteractionManager: " + ex3.Message); } } StartRefueling(); } catch (Exception exception) { ModLogger.Error("Error starting fuel station interaction", exception); ShowMessage("Error starting refuel process", MessageType.Error); } } public override void EndInteract() { //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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) try { try { FuelUIManager fuelUIManager = Core.Instance?.GetFuelUIManager(); if (fuelUIManager != null && (Object)(object)_targetVehicle != (Object)null) { Core? instance = Core.Instance; Guid gUID; if (instance != null && instance.UseNewGaugeUI) { gUID = _targetVehicle.GUID; fuelUIManager.HideNewFuelGaugeForVehicle(((object)(Guid)(ref gUID)).ToString()); } else { gUID = _targetVehicle.GUID; fuelUIManager.HideFuelGaugeForVehicle(((object)(Guid)(ref gUID)).ToString()); } } } catch (Exception ex) { ModLogger.Debug("Error hiding fuel gauge UI: " + ex.Message); } if (_isRefueling) { StopRefueling(); } if (((InteractableObject)this).onInteractEnd != null) { ((InteractableObject)this).onInteractEnd.Invoke(); } try { InteractionCanvas instance2 = Singleton<InteractionCanvas>.Instance; if ((Object)(object)instance2 != (Object)null) { Singleton<InteractionCanvas>.Instance.LerpDisplayScale(1f); } } catch (Exception ex2) { ModLogger.Debug("Error accessing InteractionCanvas in EndInteract: " + ex2.Message); } } catch (Exception exception) { ModLogger.Error("Error in FuelStation.EndInteract", exception); } } private void StartRefueling() { _isRefueling = true; _refuelStartTime = Time.time; _totalFuelAdded = 0f; _totalCost = 0f; PlayRefuelSound(refuelStartSound); ModLogger.Debug("Started refueling " + _targetVehicle.VehicleName + " at fuel station"); ShowMessage("Refueling " + _targetVehicle.VehicleName + "...", MessageType.Info); } private void StopRefueling() { if (_isRefueling) { _isRefueling = false; PlayRefuelSound(refuelEndSound); if (_totalFuelAdded > 0.01f) { ProcessPayment(); ShowMessage($"Refueled {_totalFuelAdded:F1}L for {MoneyManager.FormatAmount(_totalCost, false, false)}", MessageType.Success); ModLogger.Debug($"Completed refueling: {_totalFuelAdded:F1}L for {MoneyManager.FormatAmount(_totalCost, false, false)}"); } else { ShowMessage("No fuel added", MessageType.Warning); } _targetVehicle = null; _targetFuelSystem = null; _totalFuelAdded = 0f; _totalCost = 0f; } } private void Update() { if (_isRefueling && (Object)(object)_targetFuelSystem != (Object)null) { UpdateRefueling(); } } private void UpdateRefueling() { //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) float deltaTime = Time.deltaTime; float num = refuelRate * deltaTime; float num2 = num * pricePerLiter; if ((Object)(object)_targetVehicle == (Object)null || (Object)(object)_targetFuelSystem == (Object)null) { return; } if ((Object)(object)_moneyManager != (Object)null && _moneyManager.onlineBalance < num2) { StopRefueling(); ShowMessage("Insufficient funds to continue refueling!", MessageType.Error); return; } float num3 = _targetFuelSystem.AddFuel(num); if (num3 > 0f) { _totalFuelAdded += num3; _totalCost += num3 * pricePerLiter; if ((Object)(object)refuelLoopSound != (Object)null && !refuelAudioSource.isPlaying) { PlayRefuelSound(refuelLoopSound); } } else { StopRefueling(); ShowMessage("Vehicle tank is now full!", MessageType.Success); } if (!((Object)(object)_targetVehicle == (Object)null) && !((Object)(object)((Component)_targetVehicle).transform == (Object)null) && Vector3.Distance(((Component)this).transform.position, ((Component)_targetVehicle).transform.position) > vehicleDetectionRadius) { StopRefueling(); ShowMessage("Vehicle moved too far away!", MessageType.Warning); } } private void ProcessPayment() { if ((Object)(object)_moneyManager != (Object)null && _totalCost > 0f) { string text = "Fuel Station"; string text2 = $"Refueled {_targetVehicle.VehicleName} with {_totalFuelAdded:F1}L"; _moneyManager.CreateOnlineTransaction(text, 0f - _totalCost, 1f, text2); ModLogger.Debug($"Processed fuel payment: {MoneyManager.FormatAmount(_totalCost, false, false)} for {_totalFuelAdded:F1}L"); } } private LandVehicle GetNearestOwnedVehicle() { //IL_000b: 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_016e: Unknown result type (might be due to invalid IL or missing references) try { Collider[] array = null; try { array = Il2CppArrayBase<Collider>.op_Implicit((Il2CppArrayBase<Collider>)(object)Physics.OverlapSphere(((Component)this).transform.position, vehicleDetectionRadius)); } catch (Exception exception) { ModLogger.Error("Error calling Physics.OverlapSphere", exception); return null; } if (array == null) { return null; } List<LandVehicle> list = new List<LandVehicle>(); Collider[] array2 = array; foreach (Collider val in array2) { if ((Object)(object)val == (Object)null || (Object)(object)((Compon