Decompiled source of FarSightSpyglass v1.0.1

FarSightSpyglass.dll

Decompiled a day ago
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("FarSightSpyglass")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("FarSightSpyglass")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("47f3bb4a-5ef4-435e-a981-04a768c765fe")]
[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")]
namespace FarSightSpyglass;

[BepInPlugin("com.shaya.farsightspyglass", "Far Sight Spyglass", "1.0.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
public class FarSightSpyglassMod : BaseUnityPlugin
{
	public const string PluginGUID = "com.shaya.farsightspyglass";

	public const string PluginName = "Far Sight Spyglass";

	public const string PluginVersion = "1.0.1";

	private GameObject spyglassUI;

	private Text topText;

	private RectTransform healthBarFill;

	private Text healthBarText;

	private Text bottomText;

	private GameObject iconContainer;

	public static bool IsSpyglassToggled = true;

	private void Awake()
	{
		Harmony.CreateAndPatchAll(typeof(FarSightSpyglassMod), (string)null);
		PrefabManager.OnVanillaPrefabsAvailable += AddSpyglassItem;
		GUIManager.OnCustomGUIAvailable += CreateCustomUI;
	}

	[HarmonyPatch(typeof(Humanoid), "UseItem")]
	[HarmonyPrefix]
	public static bool UseItemPatch(Humanoid __instance, ItemData item)
	{
		if (item != null && (Object)(object)item.m_dropPrefab != (Object)null && ((Object)item.m_dropPrefab).name == "FarSightSpyglass")
		{
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if ((Object)(object)val != (Object)null && (Object)(object)val == (Object)(object)Player.m_localPlayer)
			{
				IsSpyglassToggled = !IsSpyglassToggled;
				((Character)val).Message((MessageType)2, IsSpyglassToggled ? "Far Sight: ON" : "Far Sight: OFF", 0, (Sprite)null, false);
			}
			return false;
		}
		return true;
	}

	private void AddSpyglassItem()
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Expected O, but got Unknown
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Expected O, but got Unknown
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Expected O, but got Unknown
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Expected O, but got Unknown
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Expected O, but got Unknown
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Expected O, but got Unknown
		//IL_00ee: 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_017a: Expected O, but got Unknown
		PrefabManager.OnVanillaPrefabsAvailable -= AddSpyglassItem;
		CustomLocalization val = new CustomLocalization();
		string text = "English";
		val.AddTranslation(ref text, new Dictionary<string, string>
		{
			{ "item_farsightspyglass", "Far Sight Spyglass" },
			{ "item_farsightspyglass_desc", "Reveals health, information and stats about creatures from a distance." }
		});
		LocalizationManager.Instance.AddLocalization(val);
		RecipeConfig val2 = new RecipeConfig();
		val2.Item = "FarSightSpyglass";
		val2.AddRequirement(new RequirementConfig("Stone", 4, 0, true));
		val2.AddRequirement(new RequirementConfig("Flint", 4, 0, true));
		val2.CraftingStation = string.Empty;
		ItemConfig val3 = new ItemConfig();
		val3.Name = "$item_farsightspyglass";
		val3.Description = "$item_farsightspyglass_desc";
		CustomItem val4 = new CustomItem("FarSightSpyglass", "Wishbone", val3);
		val4.ItemDrop.m_itemData.m_shared.m_equipStatusEffect = null;
		val4.ItemDrop.m_itemData.m_shared.m_itemType = (ItemType)19;
		val4.ItemDrop.m_itemData.m_shared.m_maxStackSize = 1;
		GameObject prefab = PrefabManager.Instance.GetPrefab("DvergrExtractor");
		if ((Object)(object)prefab != (Object)null)
		{
			Sprite val5 = prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_icons[0];
			val4.ItemDrop.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { val5 };
		}
		ItemManager.Instance.AddItem(val4);
		ItemManager.Instance.AddRecipe(new CustomRecipe(val2));
	}

	private void CreateCustomUI()
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Expected O, but got Unknown
		//IL_005b: 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_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Expected O, but got Unknown
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0115: Expected O, but got Unknown
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_018d: Expected O, but got Unknown
		//IL_01be: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ed: Expected O, but got Unknown
		//IL_0219: Unknown result type (might be due to invalid IL or missing references)
		//IL_023f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0259: Unknown result type (might be due to invalid IL or missing references)
		//IL_0269: Unknown result type (might be due to invalid IL or missing references)
		//IL_0279: Unknown result type (might be due to invalid IL or missing references)
		//IL_0288: Unknown result type (might be due to invalid IL or missing references)
		//IL_028f: Expected O, but got Unknown
		//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0314: Unknown result type (might be due to invalid IL or missing references)
		//IL_031f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0329: Unknown result type (might be due to invalid IL or missing references)
		//IL_0338: Unknown result type (might be due to invalid IL or missing references)
		//IL_033f: Expected O, but got Unknown
		//IL_038c: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_03bf: Expected O, but got Unknown
		//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)spyglassUI != (Object)null))
		{
			GameObject customGUIFront = GUIManager.CustomGUIFront;
			spyglassUI = new GameObject("SpyglassPanel");
			spyglassUI.transform.SetParent(customGUIFront.transform, false);
			((Graphic)spyglassUI.AddComponent<Image>()).color = new Color(0.05f, 0.05f, 0.05f, 0.85f);
			RectTransform component = spyglassUI.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.anchoredPosition = new Vector2(200f, 0f);
			component.sizeDelta = new Vector2(250f, 0f);
			VerticalLayoutGroup obj = spyglassUI.AddComponent<VerticalLayoutGroup>();
			((LayoutGroup)obj).padding = new RectOffset(10, 10, 10, 10);
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 8f;
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = false;
			spyglassUI.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			GameObject val = new GameObject("TopText");
			val.transform.SetParent(spyglassUI.transform, false);
			topText = val.AddComponent<Text>();
			topText.font = GUIManager.Instance.AveriaSerifBold;
			topText.fontSize = 16;
			((Graphic)topText).color = Color.white;
			topText.alignment = (TextAnchor)0;
			val.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			GameObject val2 = new GameObject("HealthBarBG");
			val2.transform.SetParent(spyglassUI.transform, false);
			((Graphic)val2.AddComponent<Image>()).color = new Color(0.15f, 0.05f, 0.05f, 1f);
			val2.GetComponent<RectTransform>().sizeDelta = new Vector2(0f, 20f);
			GameObject val3 = new GameObject("HealthBarFill");
			val3.transform.SetParent(val2.transform, false);
			((Graphic)val3.AddComponent<Image>()).color = new Color(0.8f, 0.1f, 0.1f, 1f);
			healthBarFill = val3.GetComponent<RectTransform>();
			healthBarFill.anchorMin = new Vector2(0f, 0f);
			healthBarFill.anchorMax = new Vector2(1f, 1f);
			healthBarFill.sizeDelta = Vector2.zero;
			healthBarFill.anchoredPosition = Vector2.zero;
			GameObject val4 = new GameObject("HealthBarText");
			val4.transform.SetParent(val2.transform, false);
			healthBarText = val4.AddComponent<Text>();
			healthBarText.font = GUIManager.Instance.AveriaSerifBold;
			healthBarText.fontSize = 14;
			((Graphic)healthBarText).color = Color.white;
			healthBarText.alignment = (TextAnchor)4;
			RectTransform component2 = val4.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0f, 0f);
			component2.anchorMax = new Vector2(1f, 1f);
			component2.sizeDelta = Vector2.zero;
			component2.anchoredPosition = Vector2.zero;
			GameObject val5 = new GameObject("BottomText");
			val5.transform.SetParent(spyglassUI.transform, false);
			bottomText = val5.AddComponent<Text>();
			bottomText.font = GUIManager.Instance.AveriaSerifBold;
			bottomText.fontSize = 14;
			((Graphic)bottomText).color = Color.white;
			bottomText.alignment = (TextAnchor)0;
			val5.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			iconContainer = new GameObject("IconContainer");
			iconContainer.transform.SetParent(spyglassUI.transform, false);
			iconContainer.AddComponent<RectTransform>().sizeDelta = new Vector2(0f, 30f);
			HorizontalLayoutGroup obj2 = iconContainer.AddComponent<HorizontalLayoutGroup>();
			((LayoutGroup)obj2).childAlignment = (TextAnchor)3;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj2).spacing = 8f;
			spyglassUI.SetActive(false);
		}
	}

	private void Update()
	{
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)spyglassUI == (Object)null)
		{
			return;
		}
		if (!IsSpyglassToggled)
		{
			spyglassUI.SetActive(false);
			return;
		}
		bool flag = false;
		foreach (ItemData allItem in ((Humanoid)Player.m_localPlayer).GetInventory().GetAllItems())
		{
			if ((Object)(object)allItem.m_dropPrefab != (Object)null && ((Object)allItem.m_dropPrefab).name == "FarSightSpyglass")
			{
				flag = true;
				break;
			}
		}
		if (!flag)
		{
			spyglassUI.SetActive(false);
			return;
		}
		GameCamera instance = GameCamera.instance;
		Camera val = ((instance != null) ? ((Component)((Component)instance).transform).GetComponent<Camera>() : null);
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		Ray val2 = default(Ray);
		((Ray)(ref val2))..ctor(((Component)val).transform.position, ((Component)val).transform.forward);
		int mask = LayerMask.GetMask(new string[3] { "character", "character_net", "character_ghost" });
		RaycastHit val3 = default(RaycastHit);
		if (Physics.Raycast(val2, ref val3, 150f, mask))
		{
			Character componentInParent = ((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent<Character>();
			if ((Object)(object)componentInParent != (Object)null && !componentInParent.IsPlayer())
			{
				UpdateUI(componentInParent);
				spyglassUI.SetActive(true);
				return;
			}
		}
		spyglassUI.SetActive(false);
	}

	private void UpdateUI(Character character)
	{
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01df: Unknown result type (might be due to invalid IL or missing references)
		//IL_0200: Unknown result type (might be due to invalid IL or missing references)
		string text = Localization.instance.Localize(character.m_name);
		int level = character.GetLevel();
		float health = character.GetHealth();
		float maxHealth = character.GetMaxHealth();
		string text2 = ((object)Unsafe.As<Faction, Faction>(ref character.m_faction)/*cast due to .constrained prefix*/).ToString();
		string text3 = "";
		if (level > 1)
		{
			text3 = new string('★', level - 1);
			text3 = "<color=#FFFF00>" + text3 + "</color> ";
		}
		topText.text = "<b><color=#00FF00>" + text + "</color></b> " + text3 + "\nFaction: " + text2;
		health = Mathf.Clamp(health, 0f, maxHealth);
		float num = ((maxHealth > 0f) ? (health / maxHealth) : 0f);
		healthBarFill.anchorMax = new Vector2(num, 1f);
		healthBarText.text = $"{Mathf.RoundToInt(health)} / {Mathf.RoundToInt(maxHealth)}";
		foreach (Transform item in iconContainer.transform)
		{
			Object.Destroy((Object)(object)((Component)item).gameObject);
		}
		string text4 = "";
		bool active = false;
		SEMan sEMan = character.GetSEMan();
		if (sEMan != null)
		{
			foreach (StatusEffect statusEffect in sEMan.GetStatusEffects())
			{
				string text5 = Localization.instance.Localize(statusEffect.m_name);
				text4 = text4 + "<color=#FF8800>• " + text5 + "</color>\n";
				if ((Object)(object)statusEffect.m_icon != (Object)null)
				{
					active = true;
					GameObject val = new GameObject("StatusIcon");
					val.transform.SetParent(iconContainer.transform, false);
					val.AddComponent<Image>().sprite = statusEffect.m_icon;
					val.GetComponent<RectTransform>().sizeDelta = new Vector2(24f, 24f);
				}
			}
		}
		string text6 = "";
		Tameable component = ((Component)character).GetComponent<Tameable>();
		if ((Object)(object)component != (Object)null)
		{
			text6 = ((!component.IsTamed()) ? "<color=#FFA500>Status: Wild / Tameable</color>\n" : "<color=#00FFFF>Status: Tamed</color>\n");
		}
		bottomText.text = text6 + text4.TrimEnd(new char[1] { '\n' });
		((Component)bottomText).gameObject.SetActive(!string.IsNullOrEmpty(bottomText.text));
		iconContainer.gameObject.SetActive(active);
	}
}