using System;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Reptile;
using TMPro;
using UnityEngine;
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: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("Speedometer")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Speedometer")]
[assembly: AssemblyFileVersion("1.2.3.0")]
[assembly: AssemblyInformationalVersion("1.2.3")]
[assembly: AssemblyProduct("Speedometer")]
[assembly: AssemblyTitle("Speedometer")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.3.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.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace Speedometer
{
[BepInPlugin("Speedometer", "Speedometer", "1.2.3")]
public class Plugin : BaseUnityPlugin
{
private enum DisplayMode
{
None,
MpS,
KmH,
MpH
}
private static Image _speedBar;
private static TextMeshProUGUI _speedLabel;
private static TextMeshProUGUI _zipLabel;
private static ConfigFile _config;
private static ConfigEntry<bool> _useTotalSpeed;
private static ConfigEntry<float> _customSpeedCap;
private static float _customSpeedCapKmh;
private static ConfigEntry<bool> _zipSpeedEnabled;
private static ConfigEntry<DisplayMode> _displayMode;
private static ConfigEntry<Color> _speedBarColor;
private static ConfigEntry<bool> _displayOverMaxColor;
private static ConfigEntry<Color> _overMaxColor;
private static ConfigEntry<bool> _outlineEnabled;
private static Material _outlineMaterial;
private static ConfigEntry<bool> _useMonoSpace;
private const float KmhFactor = 3.6f;
private const float MphFactor = 2.236936f;
private const string SpeedLabelFormat = "{0} {1}";
private const string CloseMonoTag = "</mspace>";
private const string StartMonoTag = "<mspace=1.133em>";
private const string SpeedLabelFormatMono = "<mspace=1.133em>{0}</mspace> {1}";
private const string MpsLabel = "M/S";
private const string KmhLabel = "KM/H";
private const string MphLabel = "MPH";
private static readonly CultureInfo _labelCulture = CultureInfo.InvariantCulture;
private static StringBuilder _labelBuilder;
private static bool _speedOverMax;
private const string SettingsHeader = "Settings";
private const string CosmeticHeader = "Cosmetic/Visual";
private const string TotalSpeedSetting = "Whether to use the lateral (forward) speed or the total speed of movement.";
private const string ZipSpeedSetting = "Whether to display the stored speed for a billboard zip glitch or not.";
private const string CustomCapSetting = "When set to above 0, the speed bar will use this value instead of the game's max speed value to calculate the fill percentage (in km/h).\nIf you use Movement Plus, a value of 400 is a good starting point.";
private const string DisplaySetting = "How to display the speed as text.";
private const string OverMaxSetting = "Whether to change the speedometers color when going over the maximum speed.";
private const string OutlineSetting = "Enables an outline around the speed and trick counter label, for better readability.";
private const string MonoSpaceSetting = "Makes it so numbers are mono-spaced, preventing jittery text when it changes frequently.";
private static Plugin _instance;
private void Awake()
{
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_0112: Unknown result type (might be due to invalid IL or missing references)
//IL_0192: Unknown result type (might be due to invalid IL or missing references)
//IL_0198: Expected O, but got Unknown
((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin Speedometer is loaded!");
_instance = this;
_config = ((BaseUnityPlugin)this).Config;
_useTotalSpeed = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Use Total Speed?", false, "Whether to use the lateral (forward) speed or the total speed of movement.");
_customSpeedCap = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "Custom Speed Cap", 67.5f, "When set to above 0, the speed bar will use this value instead of the game's max speed value to calculate the fill percentage (in km/h).\nIf you use Movement Plus, a value of 400 is a good starting point.");
_zipSpeedEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Display Stored Zip Speed?", false, "Whether to display the stored speed for a billboard zip glitch or not.");
_displayMode = ((BaseUnityPlugin)this).Config.Bind<DisplayMode>("Cosmetic/Visual", "Speed Display Mode", DisplayMode.KmH, "How to display the speed as text.");
_speedBarColor = _config.Bind<Color>("Cosmetic/Visual", "Speedometer Color", new Color(0.839f, 0.349f, 0.129f), (ConfigDescription)null);
_displayOverMaxColor = _config.Bind<bool>("Cosmetic/Visual", "Display Threshold Color?", true, "Whether to change the speedometers color when going over the maximum speed.");
_overMaxColor = _config.Bind<Color>("Cosmetic/Visual", "Threshold Color", new Color(0.898f, 0.098f, 0.443f), (ConfigDescription)null);
_outlineEnabled = _config.Bind<bool>("Cosmetic/Visual", "Enable Text Outline?", true, "Enables an outline around the speed and trick counter label, for better readability.");
_useMonoSpace = _config.Bind<bool>("Cosmetic/Visual", "Enable Monospace Numbers?", true, "Makes it so numbers are mono-spaced, preventing jittery text when it changes frequently.");
_customSpeedCapKmh = ((_customSpeedCap.Value > 0.001f) ? (_customSpeedCap.Value / 3.6f) : 0f);
Harmony val = new Harmony("sgiygas.speedometer");
val.PatchAll();
}
public static void InitializeUI(Transform speedBarBackground, Image speedBar, TextMeshProUGUI tricksLabel)
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: 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_015c: Unknown result type (might be due to invalid IL or missing references)
//IL_0161: Unknown result type (might be due to invalid IL or missing references)
//IL_016b: Unknown result type (might be due to invalid IL or missing references)
//IL_0170: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
//IL_01de: 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)
if (_useMonoSpace.Value)
{
_labelBuilder = new StringBuilder();
}
((Object)speedBarBackground).name = "speedBarBackground";
((Object)speedBar).name = "speedBar";
speedBarBackground.position += Vector3.down * 7.5f;
speedBarBackground.localScale = new Vector3(1.02f, 1.16f, 1f);
_speedBar = speedBar;
((Graphic)_speedBar).color = _speedBarColor.Value;
if (_outlineEnabled.Value)
{
TMProFontLocalizer component = ((Component)tricksLabel).GetComponent<TMProFontLocalizer>();
((Behaviour)component).enabled = false;
if ((Object)(object)_outlineMaterial == (Object)null)
{
_outlineMaterial = ((TMP_Text)tricksLabel).fontMaterial;
_outlineMaterial.EnableKeyword(ShaderUtilities.Keyword_Outline);
_outlineMaterial.SetColor(ShaderUtilities.ID_OutlineColor, Color.black);
_outlineMaterial.SetFloat(ShaderUtilities.ID_OutlineWidth, 0.075f);
}
((TMP_Text)tricksLabel).fontMaterial = _outlineMaterial;
}
if (_displayMode.Value != 0)
{
_speedLabel = Object.Instantiate<TextMeshProUGUI>(tricksLabel, ((TMP_Text)tricksLabel).transform.parent);
((TMP_Text)_speedLabel).transform.localPosition = ((TMP_Text)tricksLabel).transform.localPosition;
Transform transform = ((TMP_Text)tricksLabel).transform;
transform.localPosition += Vector3.up * 32f;
if (_zipSpeedEnabled.Value)
{
_zipLabel = Object.Instantiate<TextMeshProUGUI>(tricksLabel, ((TMP_Text)tricksLabel).transform.parent);
((TMP_Text)_zipLabel).transform.localPosition = ((TMP_Text)tricksLabel).transform.localPosition;
UpdateLastSpeed(0f);
Transform transform2 = ((TMP_Text)tricksLabel).transform;
transform2.localPosition += Vector3.up * 32f;
}
}
}
public static void UpdateSpeedBar(Player player)
{
//IL_00c3: 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)
float num = ((_customSpeedCapKmh > 0.001f) ? _customSpeedCapKmh : player.maxMoveSpeed);
float num2 = (_useTotalSpeed.Value ? player.GetTotalSpeed() : player.GetForwardSpeed());
num2 = Mathf.Max(0f, num2);
_speedBar.fillAmount = num2 / (num - 0.01f);
if (_displayOverMaxColor.Value)
{
if (num2 > num + 0.01f)
{
if (!_speedOverMax)
{
_speedOverMax = true;
((Graphic)_speedBar).color = _overMaxColor.Value;
}
}
else if (_speedOverMax)
{
_speedOverMax = false;
((Graphic)_speedBar).color = _speedBarColor.Value;
}
}
if (!((Object)(object)_speedLabel == (Object)null))
{
SetSpeedLabelFormatted(num2, _speedLabel);
}
}
public static void UpdateLastSpeed(float speed)
{
if (_zipSpeedEnabled.Value && !((Object)(object)_zipLabel == (Object)null))
{
SetSpeedLabelFormatted(speed, _zipLabel);
}
}
private static void SetSpeedLabelFormatted(float speed, TextMeshProUGUI label)
{
string format = (_useMonoSpace.Value ? "<mspace=1.133em>{0}</mspace> {1}" : "{0} {1}");
string arg = "M/S";
if (_displayMode.Value == DisplayMode.KmH)
{
speed *= 3.6f;
arg = "KM/H";
}
else if (_displayMode.Value == DisplayMode.MpH)
{
speed *= 2.236936f;
arg = "MPH";
}
string text = string.Format(_labelCulture, "{0:0.0}", speed);
if (_useMonoSpace.Value)
{
_labelBuilder.Clear();
int num = text.IndexOf(_labelCulture.NumberFormat.NumberDecimalSeparator);
_labelBuilder.Append(text);
_labelBuilder.Insert(num, "</mspace>");
_labelBuilder.Insert(num + "</mspace>".Length + 1, "<mspace=1.133em>");
text = _labelBuilder.ToString();
}
((TMP_Text)label).SetText(string.Format(_labelCulture, format, text, arg), true);
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "Speedometer";
public const string PLUGIN_NAME = "Speedometer";
public const string PLUGIN_VERSION = "1.2.3";
}
}
namespace Speedometer.Patches
{
[HarmonyPatch(typeof(GameplayUI), "Init")]
public class GameplayUIInit
{
public static void Postfix(Image ___chargeBar, TextMeshProUGUI ___tricksInComboLabel)
{
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Expected O, but got Unknown
GameObject gameObject = ((Component)((Component)___chargeBar).transform.parent).gameObject;
Image component = Object.Instantiate<GameObject>(gameObject, gameObject.transform.parent).GetComponent<Image>();
((Component)component).transform.SetSiblingIndex(gameObject.transform.GetSiblingIndex());
Object.DestroyImmediate((Object)(object)((Component)((Component)component).transform.GetChild(0)).gameObject);
Image val = null;
foreach (Transform item in ((Component)component).transform)
{
Transform val2 = item;
val = ((Component)val2).GetComponent<Image>();
if ((Object)(object)val != (Object)null)
{
break;
}
}
((Graphic)val).material = ((Graphic)component).material;
Plugin.InitializeUI(((Component)component).transform, val, ___tricksInComboLabel);
}
}
[HarmonyPatch(typeof(Player), "ChargeAndSpeedDisplayUpdate")]
public class ChargeAndSpeedDisplayUpdatePatch
{
public static void Postfix(Player __instance)
{
Plugin.UpdateSpeedBar(__instance);
}
}
[HarmonyPatch(typeof(WallrunLineAbility), "FixedUpdateAbility")]
public class WallrunLineAbilityFixedUpdate
{
public static void Postfix(float ___lastSpeed)
{
Plugin.UpdateLastSpeed(___lastSpeed);
}
}
[HarmonyPatch(typeof(WallrunLineAbility), "Jump")]
public class WallrunLineAbilityJump
{
public static void Postfix(float ___lastSpeed)
{
Plugin.UpdateLastSpeed(___lastSpeed);
}
}
}