using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("ShotSpeedometer")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ShotSpeedometer")]
[assembly: AssemblyTitle("ShotSpeedometer")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 ShotSpeedometer
{
[BepInPlugin("sbg.shotspeedometer", "ShotSpeedometer", "0.1.0")]
public sealed class Plugin : BaseUnityPlugin
{
[HarmonyPatch(typeof(WorldspaceIconUi), "Initialize")]
private static class Patch_WorldspaceIconUi_Initialize
{
private static void Postfix(WorldspaceIconUi __instance, Transform parent)
{
if (!((Object)(object)__instance == (Object)null))
{
BallSpeedLabel.AttachOrUpdate(__instance, parent);
}
}
}
public const string ModGuid = "sbg.shotspeedometer";
public const string ModName = "ShotSpeedometer";
public const string ModVersion = "0.1.0";
internal static ManualLogSource Log;
internal static Plugin Instance;
internal ConfigEntry<bool> hideAtRestConfig;
internal ConfigEntry<float> minSpeedToShowConfig;
internal ConfigEntry<float> verticalOffsetConfig;
private void Awake()
{
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
hideAtRestConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "HideAtRest", true, "Hide the speed line when the ball is below MinSpeedToShow. Disable to keep it visible whenever the ball icon is on screen.");
minSpeedToShowConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "MinSpeedToShow", 0.3f, "Speed threshold (m/s) below which the label hides when HideAtRest is true.");
verticalOffsetConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "VerticalOffset", -22f, "Vertical offset in pixels of the speed line relative to the distance label. Negative values place it below.");
new Harmony("sbg.shotspeedometer").PatchAll();
Log.LogInfo((object)"ShotSpeedometer v0.1.0 loaded.");
}
}
internal sealed class BallSpeedLabel : MonoBehaviour
{
private static readonly FieldInfo distanceLabelField = AccessTools.Field(typeof(WorldspaceIconUi), "distanceLabel");
private WorldspaceIconUi host;
private TextMeshProUGUI distanceLabel;
private TextMeshProUGUI speedLabel;
private Rigidbody ballRigidbody;
private int lastDisplayed = int.MinValue;
private bool unitListenerHooked;
public static void AttachOrUpdate(WorldspaceIconUi icon, Transform parent)
{
BallSpeedLabel ballSpeedLabel = ((Component)icon).GetComponent<BallSpeedLabel>();
GolfBall val = (((Object)(object)parent != (Object)null) ? ((Component)parent).GetComponent<GolfBall>() : null);
if ((Object)(object)val == (Object)null)
{
if ((Object)(object)ballSpeedLabel != (Object)null)
{
ballSpeedLabel.Detach();
}
return;
}
if ((Object)(object)ballSpeedLabel == (Object)null)
{
ballSpeedLabel = ((Component)icon).gameObject.AddComponent<BallSpeedLabel>();
}
ballSpeedLabel.Bind(icon, val);
}
private void Bind(WorldspaceIconUi icon, GolfBall ball)
{
host = icon;
ballRigidbody = (((Object)(object)ball != (Object)null) ? ((Component)ball).GetComponent<Rigidbody>() : null);
if ((Object)(object)distanceLabel == (Object)null)
{
ref TextMeshProUGUI reference = ref distanceLabel;
object? obj = distanceLabelField?.GetValue(icon);
reference = (TextMeshProUGUI)((obj is TextMeshProUGUI) ? obj : null);
if ((Object)(object)distanceLabel == (Object)null)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)"WorldspaceIconUi.distanceLabel was null; cannot mount speed label.");
}
((Behaviour)this).enabled = false;
return;
}
}
if ((Object)(object)speedLabel == (Object)null)
{
BuildSpeedLabel();
}
if ((Object)(object)speedLabel != (Object)null)
{
((Component)speedLabel).gameObject.SetActive(true);
}
if (!unitListenerHooked)
{
GeneralSettings.DistanceUnitChanged = (Action)Delegate.Combine(GeneralSettings.DistanceUnitChanged, new Action(OnUnitChanged));
unitListenerHooked = true;
}
lastDisplayed = int.MinValue;
}
private void Detach()
{
if ((Object)(object)speedLabel != (Object)null)
{
((Component)speedLabel).gameObject.SetActive(false);
}
ballRigidbody = null;
}
private void BuildSpeedLabel()
{
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Expected O, but got Unknown
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: 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_008f: 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_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: 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_00b4: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
GameObject val = Object.Instantiate<GameObject>(((Component)distanceLabel).gameObject, ((TMP_Text)distanceLabel).transform.parent);
((Object)val).name = "ShotSpeedometer-SpeedLabel";
speedLabel = val.GetComponent<TextMeshProUGUI>();
if ((Object)(object)speedLabel == (Object)null)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)"Cloned distance label is missing TMP component.");
}
Object.Destroy((Object)(object)val);
}
else
{
RectTransform val2 = (RectTransform)((TMP_Text)distanceLabel).transform;
RectTransform val3 = (RectTransform)((TMP_Text)speedLabel).transform;
val3.anchorMin = val2.anchorMin;
val3.anchorMax = val2.anchorMax;
val3.pivot = val2.pivot;
val3.sizeDelta = val2.sizeDelta;
val3.anchoredPosition = val2.anchoredPosition + new Vector2(0f, Plugin.Instance.verticalOffsetConfig.Value);
((TMP_Text)speedLabel).text = string.Empty;
}
}
private void LateUpdate()
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)host == (Object)null) && !((Object)(object)speedLabel == (Object)null) && !((Object)(object)ballRigidbody == (Object)null))
{
Vector3 linearVelocity = ballRigidbody.linearVelocity;
float magnitude = ((Vector3)(ref linearVelocity)).magnitude;
bool flag = !Plugin.Instance.hideAtRestConfig.Value || magnitude >= Plugin.Instance.minSpeedToShowConfig.Value;
if (((Component)speedLabel).gameObject.activeSelf != flag)
{
((Component)speedLabel).gameObject.SetActive(flag);
}
if (flag)
{
UpdateText(magnitude);
}
}
}
private void UpdateText(float speedMps)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Invalid comparison between Unknown and I4
float num = speedMps * 3.6f;
int num2;
string format;
if ((int)GameSettings.All.General.DistanceUnits == 1)
{
num2 = Mathf.RoundToInt(num * 0.621371f);
format = "{0} mph";
}
else
{
num2 = Mathf.RoundToInt(num);
format = "{0} kph";
}
if (num2 != lastDisplayed)
{
lastDisplayed = num2;
((TMP_Text)speedLabel).text = string.Format(format, num2);
}
}
private void OnUnitChanged()
{
lastDisplayed = int.MinValue;
}
private void OnDestroy()
{
if (unitListenerHooked)
{
GeneralSettings.DistanceUnitChanged = (Action)Delegate.Remove(GeneralSettings.DistanceUnitChanged, new Action(OnUnitChanged));
unitListenerHooked = false;
}
}
}
}