Decompiled source of Overheat Meter v1.0.0

Distance.OverheatMeter.dll

Decompiled 3 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Distance.Overheatmeter.Enums;
using Distance.Overheatmeter.Scripts;
using Events;
using Events.Game;
using Events.GameMode;
using Events.Level;
using Events.LevelEditor;
using Events.RaceEnd;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Distance.ModTemplate")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Distance.ModTemplate")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("7bcb2908-b003-45d9-be68-50cba5217603")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Distance.Overheatmeter
{
	[BepInPlugin("Distance.OverheatMeter", "Overheat Meter", "1.0.0")]
	public sealed class Mod : BaseUnityPlugin
	{
		private const string modGUID = "Distance.OverheatMeter";

		private const string modName = "Overheat Meter";

		private const string modVersion = "1.0.0";

		private static readonly Harmony harmony = new Harmony("Distance.OverheatMeter");

		public static ManualLogSource Log = new ManualLogSource("Overheat Meter");

		public static Mod Instance;

		public static ConfigEntry<KeyboardShortcut> ToggleHotkey { get; set; }

		public static ConfigEntry<ActivationMode> ActivationModeConfig { get; set; }

		public static ConfigEntry<DisplayMode> DisplayModeConfig { get; set; }

		public static ConfigEntry<float> WarningThreshold { get; set; }

		public bool DisplayCondition => ActivationModeConfig.Value == ActivationMode.Always || (ActivationModeConfig.Value == ActivationMode.Warning && Vehicle.HeatLevel >= WarningThreshold.Value) || (ActivationModeConfig.Value == ActivationMode.Toggle && Toggled);

		public bool Toggled { get; set; }

		public string Text => GetHeatLevel() + "\n" + GetSpeed();

		private void Awake()
		{
			//IL_0065: 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_0080: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Expected O, but got Unknown
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Expected O, but got Unknown
			Object.DontDestroyOnLoad((Object)(object)this);
			Flags.SubscribeEvents();
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			Log = Logger.CreateLogSource("Distance.OverheatMeter");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Initializing Overheat Meter...");
			ToggleHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "SET TOGGLE HOTKEY", new KeyboardShortcut((KeyCode)104, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), new ConfigDescription("Set the shortcut to toggle the Overheat Meter UI", (AcceptableValueBase)null, new object[0]));
			ActivationModeConfig = ((BaseUnityPlugin)this).Config.Bind<ActivationMode>("General", "ACTIVATION MODE", ActivationMode.Always, new ConfigDescription("Control how the UI activates", (AcceptableValueBase)null, new object[0]));
			DisplayModeConfig = ((BaseUnityPlugin)this).Config.Bind<DisplayMode>("General", "DISPLAY MODE", DisplayMode.Hud, new ConfigDescription("Control how the UI displays", (AcceptableValueBase)null, new object[0]));
			WarningThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("General", "WARNING THRESHOLD", 0.8f, new ConfigDescription("Adjust the warning threshold", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[0]));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Loading...");
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded!");
		}

		private Dictionary<string, T> MapEnumToListBox<T>() where T : Enum
		{
			Dictionary<string, T> dictionary = new Dictionary<string, T>();
			string[] names = Enum.GetNames(typeof(T));
			T[] array = (T[])Enum.GetValues(typeof(T));
			for (int i = 0; i < names.Length; i++)
			{
				dictionary.Add(SplitCamelCase(names[i]), array[i]);
			}
			return dictionary;
		}

		private string SplitCamelCase(string str)
		{
			return Regex.Replace(Regex.Replace(str, "(\\P{Ll})(\\P{Ll}\\p{Ll})", "$1 $2"), "(\\p{Ll})(\\P{Ll})", "$1 $2");
		}

		public string GetHeatLevel()
		{
			if (G.Sys.GameManager_.IsModeStarted_)
			{
				string text = Mathf.RoundToInt(100f * Mathf.Clamp(Vehicle.HeatLevel, 0f, 1f)).ToString();
				while (text.Length < 3)
				{
					text = "0" + text;
				}
				return text + " %";
			}
			return "0%";
		}

		private string GetSpeed()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			if (G.Sys.GameManager_.IsModeStarted_)
			{
				Units units = Options.General.Units;
				Units val = units;
				if ((int)val != 0)
				{
					if ((int)val == 1)
					{
						return $"{Mathf.RoundToInt(Vehicle.VelocityKPH)} KM/H";
					}
					return string.Empty;
				}
				return $"{Mathf.RoundToInt(Vehicle.VelocityMPH)} MPH";
			}
			return string.Empty;
		}

		public void OnConfigChanged(object sender, EventArgs e)
		{
			SettingChangedEventArgs val = (SettingChangedEventArgs)(object)((e is SettingChangedEventArgs) ? e : null);
			if (val == null || sender != ToggleHotkey)
			{
				return;
			}
			Toggled = !Toggled;
			if (!Toggled)
			{
				TrickyTextLogic[] array = Object.FindObjectsOfType<TrickyTextLogic>();
				foreach (TrickyTextLogic val2 in array)
				{
					val2.Clear();
				}
			}
		}
	}
	public static class Flags
	{
		public static bool IsModeStarted { get; private set; }

		public static bool IsPaused { get; private set; }

		public static bool IsMenuOpen
		{
			get
			{
				MenuPanelManager menuPanelManager_ = G.Sys.MenuPanelManager_;
				return menuPanelManager_ != null && menuPanelManager_.panelStack_?.Count > 0;
			}
		}

		public static bool IsLoading => (int)G.Sys.GameManager_.BlackFade_.currentState_ != 0 && !G.Sys.GameManager_.IsLevelLoaded_;

		public static bool IsReplayMode => G.Sys.ReplayManager_.IsReplayMode_;

		public static GameModeID[] NonPlayModeIDS { get; }

		public static bool CurrentModeIsPlayable => !NonPlayModeIDS.Contains(G.Sys.GameManager_.ModeID_);

		public static bool CanDisplayHudElements => IsModeStarted && !IsLoading && CurrentModeIsPlayable && !IsPaused && !IsMenuOpen && !IsReplayMode;

		static Flags()
		{
			NonPlayModeIDS = (GameModeID[])(object)new GameModeID[3]
			{
				(GameModeID)17,
				(GameModeID)13,
				default(GameModeID)
			};
		}

		internal static void SubscribeEvents()
		{
			StaticEvent<Data>.Subscribe((Delegate<Data>)OnGamePauseToggled);
			StaticEvent<Data>.Subscribe((Delegate<Data>)OnGameModeInitialized);
			StaticEvent<Data>.Subscribe((Delegate<Data>)OnGameModeModeStarted);
			StaticEvent<Data>.Subscribe((Delegate<Data>)OnRaceEndLocalCarHitFinish);
			StaticEvent<Data>.Subscribe((Delegate<Data>)OnLevelEditorEnterPlayMode);
			StaticEvent<Data>.Subscribe((Delegate<Data>)OnLevelEditorEnterEditorMode);
			StaticEvent<Data>.Subscribe((Delegate<Data>)OnLevelUninitializeOptimizations);
		}

		private static void OnLevelUninitializeOptimizations(Data data)
		{
			IsModeStarted = false;
		}

		private static void OnGameModeModeStarted(Data data)
		{
			IsPaused = false;
			IsModeStarted = true;
		}

		private static void OnLevelEditorEnterEditorMode(Data data)
		{
			IsPaused = false;
			IsModeStarted = false;
		}

		private static void OnLevelEditorEnterPlayMode(Data data)
		{
			IsModeStarted = true;
		}

		private static void OnRaceEndLocalCarHitFinish(Data data)
		{
			IsModeStarted = false;
		}

		private static void OnGameModeInitialized(Data data)
		{
			IsPaused = false;
		}

		private static void OnGamePauseToggled(Data data)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			IsPaused = data.paused_;
		}
	}
	public static class Options
	{
		public static class General
		{
			public static GeneralSettings Manager => OptionsManager.General_;

			public static bool MenuAnimations
			{
				get
				{
					return Manager.menuAnimations_;
				}
				set
				{
					Manager.menuAnimations_ = value;
				}
			}

			public static Units Units
			{
				get
				{
					//IL_0005: Unknown result type (might be due to invalid IL or missing references)
					return Manager.Units_;
				}
				set
				{
					//IL_0005: Unknown result type (might be due to invalid IL or missing references)
					Manager.Units_ = value;
				}
			}
		}

		public static GameManager Game => G.Sys.GameManager_;

		public static OptionsManager OptionsManager => G.Sys.OptionsManager_;
	}
	internal static class Utilities
	{
		internal static class MathUtil
		{
			public static float Map(float s, float a1, float a2, float b1, float b2)
			{
				return b1 + (s - a1) * (b2 - b1) / (a2 - a1);
			}
		}

		internal static GameObject FindLocalCar()
		{
			PlayerManager playerManager_ = G.Sys.PlayerManager_;
			object result;
			if (playerManager_ == null)
			{
				result = null;
			}
			else
			{
				LocalPlayer current_ = playerManager_.Current_;
				if (current_ == null)
				{
					result = null;
				}
				else
				{
					PlayerDataLocal playerData_ = current_.playerData_;
					result = ((playerData_ != null) ? ((PlayerDataBase)playerData_).Car_ : null);
				}
			}
			return (GameObject)result;
		}

		internal static CarLogic FindLocalCarLogic()
		{
			PlayerManager playerManager_ = G.Sys.PlayerManager_;
			object result;
			if (playerManager_ == null)
			{
				result = null;
			}
			else
			{
				LocalPlayer current_ = playerManager_.Current_;
				if (current_ == null)
				{
					result = null;
				}
				else
				{
					PlayerDataLocal playerData_ = current_.playerData_;
					result = ((playerData_ != null) ? ((PlayerDataBase)playerData_).CarLogic_ : null);
				}
			}
			return (CarLogic)result;
		}
	}
	public static class Vehicle
	{
		private static CarLogic CarLogic { get; set; }

		public static float HeatLevel
		{
			get
			{
				UpdateObjectReferences();
				if (Object.op_Implicit((Object)(object)CarLogic))
				{
					return CarLogic.Heat_;
				}
				return 0f;
			}
		}

		public static float VelocityKPH
		{
			get
			{
				UpdateObjectReferences();
				if (Object.op_Implicit((Object)(object)CarLogic))
				{
					return CarLogic.CarStats_.GetKilometersPerHour();
				}
				return 0f;
			}
		}

		public static float VelocityMPH
		{
			get
			{
				UpdateObjectReferences();
				if (Object.op_Implicit((Object)(object)CarLogic))
				{
					return CarLogic.CarStats_.GetMilesPerHour();
				}
				return 0f;
			}
		}

		private static void UpdateObjectReferences()
		{
			GameObject obj = Utilities.FindLocalCar();
			CarLogic = ((obj != null) ? obj.GetComponent<CarLogic>() : null) ?? Utilities.FindLocalCarLogic();
		}
	}
}
namespace Distance.Overheatmeter.Scripts
{
	public class HeatTextLogic : MonoBehaviour
	{
		internal const float MaximumOpacity = 0.7f;

		internal static bool creatingInstance;

		internal UILabel label;

		internal UIWidget widget;

		internal UIPanel panel;

		private Coroutine _transitionCoroutine = null;

		private bool _visible = true;

		internal static HeatTextLogic Instance { get; set; }

		internal bool Visible
		{
			get
			{
				return _visible;
			}
			set
			{
				if (value != _visible)
				{
					if (_transitionCoroutine != null)
					{
						((MonoBehaviour)this).StopCoroutine(_transitionCoroutine);
					}
					_transitionCoroutine = ((MonoBehaviour)this).StartCoroutine(Transition(value));
				}
				_visible = value;
			}
		}

		internal bool CanDisplay => Mod.Instance.DisplayCondition && Flags.CanDisplayHudElements && Mod.DisplayModeConfig.Value == DisplayMode.Watermark;

		internal static void Create(GameObject speedrunTimerLogic = null)
		{
			if (Object.op_Implicit((Object)(object)Instance) || creatingInstance)
			{
				return;
			}
			creatingInstance = true;
			GameObject val = null;
			val = ((!Object.op_Implicit((Object)(object)speedrunTimerLogic)) ? GameObject.Find("Anchor : Speedrun Timer") : GameObjectEx.Parent(speedrunTimerLogic));
			if (Object.op_Implicit((Object)(object)val))
			{
				GameObject val2 = Object.Instantiate<GameObject>(val, val.transform.parent);
				val2.SetActive(true);
				((Object)val2).name = "Anchor : Heat Display";
				GameObjectEx.ForEachChildObjectDepthFirstRecursive(val2, (Action<GameObject>)delegate(GameObject obj)
				{
					obj.SetActive(true);
					GameObjectEx.RemoveComponents<SpeedrunTimerLogic>(obj);
				});
				UILabel componentInChildren = val2.GetComponentInChildren<UILabel>();
				Instance = ((Component)componentInChildren).gameObject.AddComponent<HeatTextLogic>();
			}
			creatingInstance = false;
		}

		internal void Start()
		{
			GameObject val = GameObjectEx.Parent(((Component)this).gameObject);
			GameObject val2 = GameObjectEx.Parent(val);
			label = ((Component)this).GetComponent<UILabel>();
			widget = val.GetComponent<UIWidget>();
			panel = val2.GetComponent<UIPanel>();
			((UIRect)widget).alpha = 0f;
			AdjustPosition();
		}

		internal void Update()
		{
			label.text = Mod.Instance.Text;
			Visible = CanDisplay;
		}

		internal void AdjustPosition()
		{
			((UIRect)label).SetAnchor(((Component)panel).gameObject, 21, 19, -19, -17);
			((UIWidget)label).pivot = (Pivot)0;
		}

		internal IEnumerator Transition(bool visible, float duration = 0.2f)
		{
			float target = (visible ? 0.7f : 0f);
			float current = ((UIRect)widget).alpha;
			for (float time = 0f; time < duration; time += Timex.deltaTime_)
			{
				if (!Options.General.MenuAnimations)
				{
					break;
				}
				float value = Utilities.MathUtil.Map(time, 0f, duration, current, target);
				((UIRect)widget).alpha = value;
				yield return null;
			}
			((UIRect)widget).alpha = target;
		}
	}
}
namespace Distance.Overheatmeter.Patches
{
	[HarmonyPatch(typeof(SpeedrunTimerLogic), "OnEnable")]
	internal static class SpeedrunTimerLogic__OnEnable
	{
		[HarmonyPostfix]
		internal static void Postfix(SpeedrunTimerLogic __instance)
		{
			try
			{
				HeatTextLogic.Create(((Component)__instance).gameObject);
			}
			catch (Exception ex)
			{
				Mod.Log.LogError((object)ex.ToString());
			}
		}
	}
	[HarmonyPatch(typeof(TrickyTextLogic), "Update")]
	internal static class TrickyTextLogic__Update
	{
		[HarmonyPostfix]
		internal static void Postfix(TrickyTextLogic __instance)
		{
			if (Mod.Instance.DisplayCondition && Mod.DisplayModeConfig.Value == DisplayMode.Hud)
			{
				__instance.SetAlpha(1f);
				__instance.textMesh_.text = Mod.Instance.Text;
			}
		}
	}
}
namespace Distance.Overheatmeter.Enums
{
	public enum ActivationMode
	{
		Always,
		Warning,
		Toggle
	}
	public enum DisplayMode
	{
		Watermark,
		Hud
	}
	public enum DisplayUnits
	{
		Automatic,
		Kph,
		Mph
	}
}