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
}
}