using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("WhereIsMyAmulet")]
[assembly: AssemblyDescription("Shows the distance to dropped amulet fragments in PEAK.")]
[assembly: AssemblyProduct("WhereIsMyAmulet")]
[assembly: ComVisible(false)]
[assembly: Guid("ce0f5e2c-08a1-4f5f-8da4-a91c5c43a5a7")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[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 WhereIsMyAmulet
{
[BepInPlugin("com.wuyachiyu.WhereIsMyAmulet", "WhereIsMyAmulet", "1.0.0")]
public sealed class WhereIsMyAmuletPlugin : BaseUnityPlugin
{
public const string PluginGuid = "com.wuyachiyu.WhereIsMyAmulet";
public const string PluginName = "WhereIsMyAmulet";
public const string PluginVersion = "1.0.0";
private readonly Dictionary<int, AmuletLabel> _labels = new Dictionary<int, AmuletLabel>();
private ManualLogSource _log;
private Canvas _canvas;
private TMP_FontAsset _font;
private bool _loggedDiscovery;
private ConfigEntry<bool> _enabled;
private ConfigEntry<KeyCode> _scanKey;
private ConfigEntry<float> _maxDistance;
private ConfigEntry<float> _fontSize;
private ConfigEntry<bool> _showOffscreen;
private void Awake()
{
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
_log = ((BaseUnityPlugin)this).Logger;
_enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Show labels for dropped amulet fragments.");
_scanKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "ScanKey", (KeyCode)99, "Press this key to scan for dropped amulet fragments.");
_maxDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "MaxDistance", 500f, "Maximum distance in metres for a label. Set to 0 for unlimited.");
_fontSize = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "FontSize", 22f, "Distance label font size.");
_showOffscreen = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "ShowOffscreenDirection", true, "Show a direction marker on the screen edge for offscreen fragments.");
CreateCanvas();
_log.LogInfo((object)("WhereIsMyAmulet v1.0.0 loaded. Press " + ((object)_scanKey.Value/*cast due to .constrained prefix*/).ToString() + " to scan for dropped fragments."));
}
private void Update()
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
if (!_enabled.Value)
{
ClearLabels();
return;
}
if (Input.GetKeyDown(_scanKey.Value))
{
ScanItems();
}
foreach (AmuletLabel item in _labels.Values.ToList())
{
if (item.IsValid)
{
item.Update(Camera.main, _maxDistance.Value, _showOffscreen.Value);
}
else
{
RemoveLabel(item.InstanceId);
}
}
}
private void OnDestroy()
{
ClearLabels();
if ((Object)(object)_canvas != (Object)null)
{
Object.Destroy((Object)(object)((Component)_canvas).gameObject);
}
}
private void CreateCanvas()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Expected O, but got Unknown
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("WhereIsMyAmuletCanvas");
Object.DontDestroyOnLoad((Object)(object)val);
val.layer = 5;
_canvas = val.AddComponent<Canvas>();
_canvas.renderMode = (RenderMode)0;
_canvas.sortingOrder = 32700;
CanvasScaler obj = val.AddComponent<CanvasScaler>();
obj.uiScaleMode = (ScaleMode)1;
obj.referenceResolution = new Vector2(1920f, 1080f);
val.AddComponent<GraphicRaycaster>();
_font = FindFont();
}
private void ScanItems()
{
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_font == (Object)null)
{
_font = FindFont();
}
Item[] array = Object.FindObjectsByType<Item>((FindObjectsSortMode)0);
HashSet<int> hashSet = new HashSet<int>();
Item[] array2 = array;
Backpack backpack = default(Backpack);
foreach (Item item in array2)
{
if ((Object)(object)item == (Object)null || !((Component)item).gameObject.activeInHierarchy || (int)item.itemState != 0)
{
continue;
}
if (Matches(item))
{
int instanceID = ((Object)((Component)item).gameObject).GetInstanceID();
hashSet.Add(instanceID);
AddLabel(instanceID, ((Component)item).transform, "Amulet", () => (Object)(object)item != (Object)null && ((Component)item).gameObject.activeInHierarchy && (int)item.itemState == 0);
}
ref Backpack reference = ref backpack;
Item obj = item;
reference = (Backpack)(object)((obj is Backpack) ? obj : null);
if ((Object)(object)backpack != (Object)null && HasAmulet(((Item)backpack).data))
{
int instanceID2 = ((Object)((Component)backpack).gameObject).GetInstanceID();
hashSet.Add(instanceID2);
AddLabel(instanceID2, ((Component)backpack).transform, "Backpack\nAmulet", () => (Object)(object)backpack != (Object)null && ((Component)backpack).gameObject.activeInHierarchy && (int)((Item)backpack).itemState == 0 && HasAmulet(((Item)backpack).data));
}
}
foreach (int item2 in _labels.Keys.ToList())
{
if (!hashSet.Contains(item2))
{
RemoveLabel(item2);
}
}
}
private static bool Matches(Item item)
{
return ((Object)((Component)item).gameObject).name.IndexOf("amulet", StringComparison.OrdinalIgnoreCase) >= 0;
}
private void AddLabel(int id, Transform target, string title, Func<bool> isValid)
{
if (!_labels.ContainsKey(id))
{
_labels.Add(id, new AmuletLabel(((Component)_canvas).transform, target, title, isValid, _font, _fontSize));
if (!_loggedDiscovery)
{
_log.LogInfo((object)("Found amulet target: " + title));
_loggedDiscovery = true;
}
}
}
private static bool HasAmulet(ItemInstanceData instanceData)
{
BackpackData val = default(BackpackData);
if (instanceData == null || !instanceData.TryGetDataEntry<BackpackData>((DataEntryKey)7, ref val) || val == null || val.itemSlots == null)
{
return false;
}
ItemSlot[] itemSlots = val.itemSlots;
foreach (ItemSlot val2 in itemSlots)
{
if (val2 != null && !val2.IsEmpty() && (Object)(object)val2.prefab != (Object)null && Matches(val2.prefab))
{
return true;
}
}
return false;
}
private void RemoveLabel(int id)
{
if (_labels.TryGetValue(id, out var value))
{
value.Dispose();
_labels.Remove(id);
}
}
private void ClearLabels()
{
foreach (AmuletLabel value in _labels.Values)
{
value.Dispose();
}
_labels.Clear();
}
private static TMP_FontAsset FindFont()
{
try
{
if ((Object)(object)GUIManager.instance != (Object)null)
{
AscentUI componentInChildren = ((Component)GUIManager.instance).GetComponentInChildren<AscentUI>(true);
if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.text != (Object)null && (Object)(object)((TMP_Text)componentInChildren.text).font != (Object)null)
{
return ((TMP_Text)componentInChildren.text).font;
}
if ((Object)(object)GUIManager.instance.heroDayText != (Object)null && (Object)(object)((TMP_Text)GUIManager.instance.heroDayText).font != (Object)null)
{
return ((TMP_Text)GUIManager.instance.heroDayText).font;
}
}
TextMeshProUGUI val = Object.FindAnyObjectByType<TextMeshProUGUI>();
if ((Object)(object)val != (Object)null && (Object)(object)((TMP_Text)val).font != (Object)null)
{
return ((TMP_Text)val).font;
}
if ((Object)(object)TMP_Settings.defaultFontAsset != (Object)null)
{
return TMP_Settings.defaultFontAsset;
}
}
catch (Exception ex)
{
Debug.LogWarning((object)("WhereIsMyAmulet: failed to find a game font: " + ex.Message));
}
return null;
}
}
internal sealed class AmuletLabel
{
private readonly int _instanceId;
private readonly Transform _target;
private readonly Func<bool> _isValid;
private readonly string _title;
private readonly GameObject _root;
private readonly CanvasGroup _group;
private readonly List<TextMeshProUGUI> _shadowTexts = new List<TextMeshProUGUI>();
private readonly TextMeshProUGUI _mainText;
private readonly TextMeshProUGUI _arrow;
private static readonly Vector2[] ShadowOffsets = (Vector2[])(object)new Vector2[8]
{
new Vector2(0f, 1f),
new Vector2(0f, -1f),
new Vector2(-1f, 0f),
new Vector2(1f, 0f),
new Vector2(-1f, 1f),
new Vector2(1f, 1f),
new Vector2(-1f, -1f),
new Vector2(1f, -1f)
};
public int InstanceId => _instanceId;
public bool IsValid
{
get
{
if ((Object)(object)_target != (Object)null && _isValid != null)
{
return _isValid();
}
return false;
}
}
public AmuletLabel(Transform canvas, Transform target, string title, Func<bool> isValid, TMP_FontAsset font, ConfigEntry<float> fontSize)
{
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Expected O, but got Unknown
//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
//IL_0147: Unknown result type (might be due to invalid IL or missing references)
//IL_0156: Unknown result type (might be due to invalid IL or missing references)
//IL_015c: Expected O, but got Unknown
//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
//IL_0208: Unknown result type (might be due to invalid IL or missing references)
//IL_0227: Unknown result type (might be due to invalid IL or missing references)
_instanceId = ((!((Object)(object)target == (Object)null)) ? ((Object)((Component)target).gameObject).GetInstanceID() : 0);
_target = target;
_title = title;
_isValid = isValid;
_root = new GameObject("AmuletDistanceLabel");
_root.transform.SetParent(canvas, false);
_root.layer = 5;
_group = _root.AddComponent<CanvasGroup>();
_group.blocksRaycasts = false;
_group.interactable = false;
for (int i = 0; i < 8; i++)
{
TextMeshProUGUI val = CreateText("Shadow_" + i, font, fontSize.Value);
((Graphic)val).color = new Color(0f, 0f, 0f, 0.9f);
((TMP_Text)val).rectTransform.anchoredPosition = ShadowOffsets[i] * 1.5f;
_shadowTexts.Add(val);
}
_mainText = CreateText("MainText", font, fontSize.Value);
((Graphic)_mainText).color = new Color(0.875f, 0.855f, 0.761f, 1f);
GameObject val2 = new GameObject("OffscreenDirection");
val2.transform.SetParent(_root.transform, false);
_arrow = val2.AddComponent<TextMeshProUGUI>();
val2.layer = 5;
((TMP_Text)_arrow).font = font;
((TMP_Text)_arrow).text = "^";
((TMP_Text)_arrow).alignment = (TextAlignmentOptions)514;
((TMP_Text)_arrow).fontSize = 22f;
((Graphic)_arrow).color = new Color(1f, 0.85f, 0.2f, 1f);
((Graphic)_arrow).raycastTarget = false;
((TMP_Text)_arrow).rectTransform.sizeDelta = new Vector2(18f, 18f);
((TMP_Text)_arrow).rectTransform.anchoredPosition = new Vector2(0f, -28f);
((Behaviour)_arrow).enabled = false;
}
private TextMeshProUGUI CreateText(string name, TMP_FontAsset font, float size)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: 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_0076: 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)
GameObject val = new GameObject(name);
val.transform.SetParent(_root.transform, false);
val.layer = 5;
TextMeshProUGUI obj = val.AddComponent<TextMeshProUGUI>();
((TMP_Text)obj).alignment = (TextAlignmentOptions)514;
((Graphic)obj).raycastTarget = false;
((TMP_Text)obj).overflowMode = (TextOverflowModes)0;
((TMP_Text)obj).richText = true;
((TMP_Text)obj).font = font;
((TMP_Text)obj).fontSize = Mathf.Clamp(size, 10f, 64f);
((TMP_Text)obj).rectTransform.sizeDelta = new Vector2(260f, 90f);
((TMP_Text)obj).rectTransform.anchoredPosition = Vector2.zero;
return obj;
}
public void Update(Camera camera, float maxDistance, bool showOffscreen)
{
//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_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: 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_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: 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_0131: 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)
//IL_0138: Unknown result type (might be due to invalid IL or missing references)
//IL_0198: Unknown result type (might be due to invalid IL or missing references)
//IL_019a: Unknown result type (might be due to invalid IL or missing references)
//IL_019e: Unknown result type (might be due to invalid IL or missing references)
//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
//IL_01e9: 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_0208: Unknown result type (might be due to invalid IL or missing references)
//IL_0148: 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)
if ((Object)(object)camera == (Object)null)
{
SetVisible(visible: false);
return;
}
Vector3 val = _target.position + Vector3.up * 0.8f;
Vector3 val2 = camera.WorldToViewportPoint(val);
float num = Vector3.Distance(((Component)camera).transform.position, _target.position);
bool flag = maxDistance <= 0f || num <= maxDistance;
bool flag2 = val2.z > 0f;
if (flag2 && val2.x >= 0f && val2.x <= 1f && val2.y >= 0f && val2.y <= 1f && flag)
{
_root.transform.position = camera.WorldToScreenPoint(val);
SetText($"<b>{_title}</b>\n<size=18>{num:F0}m</size>");
((Behaviour)_arrow).enabled = false;
SetVisible(visible: true);
return;
}
if (!showOffscreen || !flag)
{
SetVisible(visible: false);
return;
}
Vector2 val3 = default(Vector2);
((Vector2)(ref val3))..ctor(val2.x - 0.5f, val2.y - 0.5f);
if (!flag2)
{
val3 = -val3;
}
if (((Vector2)(ref val3)).sqrMagnitude < 0.001f)
{
val3 = Vector2.up;
}
((Vector2)(ref val3)).Normalize();
Vector2 val4 = default(Vector2);
((Vector2)(ref val4))..ctor((float)Screen.width * 0.5f, (float)Screen.height * 0.5f);
float num2 = (float)Mathf.Min(Screen.width, Screen.height) * 0.42f;
_root.transform.position = Vector2.op_Implicit(val4 + val3 * num2);
SetText($"{num:F0}m");
((Behaviour)_arrow).enabled = true;
((Transform)((TMP_Text)_arrow).rectTransform).localRotation = Quaternion.Euler(0f, 0f, Mathf.Atan2(val3.y, val3.x) * 57.29578f - 90f);
SetVisible(visible: true);
}
public void Dispose()
{
if ((Object)(object)_root != (Object)null)
{
Object.Destroy((Object)(object)_root);
}
}
private void SetVisible(bool visible)
{
_group.alpha = (visible ? 1f : 0f);
}
private void SetText(string value)
{
((TMP_Text)_mainText).text = value;
foreach (TextMeshProUGUI shadowText in _shadowTexts)
{
((TMP_Text)shadowText).text = value;
}
}
}
}