Decompiled source of LuckHUD v0.1.0

Mods/LuckHUD.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using LuckHUD;
using MelonLoader;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: MelonInfo(typeof(Mod), "Luck HUD", "0.1.0", "Kospa", null)]
[assembly: MelonGame(null, "Backpack Hero")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace LuckHUD;

internal sealed class LuckHudView
{
	private RectTransform root;

	private RectTransform tooltip;

	private TextMeshProUGUI numbers;

	private TextMeshProUGUI description;

	private LuckValues values;

	internal bool Alive => Object.op_Implicit((Object)(object)root);

	internal void Create(TextMeshProUGUI gold)
	{
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: 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_016a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0179: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Unknown result type (might be due to invalid IL or missing references)
		//IL_0244: Unknown result type (might be due to invalid IL or missing references)
		//IL_026c: Unknown result type (might be due to invalid IL or missing references)
		//IL_027b: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = Resources.Load<GameObject>("items/standard/Unlucky Horseshoe Variant");
		SpriteRenderer val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<SpriteRenderer>() : null);
		if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)val2.sprite))
		{
			throw new InvalidOperationException("Нет спрайта подковы: Resources/items/standard/Unlucky Horseshoe Variant");
		}
		root = Rect("LuckHUD", ((TMP_Text)gold).transform, new Vector2(1f, 0.5f), new Vector2(14f, 0f), new Vector2(300f, 50f));
		((Component)root).gameObject.AddComponent<LayoutElement>().ignoreLayout = true;
		Image val3 = ((Component)root).gameObject.AddComponent<Image>();
		((Graphic)val3).color = Color.clear;
		RectTransform val4 = Rect("Horseshoe", (Transform)(object)root, new Vector2(0f, 0.5f), Vector2.zero, new Vector2(40f, 40f));
		val4.pivot = new Vector2(0.5f, 0.5f);
		val4.anchoredPosition = new Vector2(20f, 0f);
		((Transform)val4).localRotation = Quaternion.Euler(0f, 0f, 180f);
		Image val5 = ((Component)val4).gameObject.AddComponent<Image>();
		val5.sprite = val2.sprite;
		val5.preserveAspect = true;
		((Graphic)val5).raycastTarget = false;
		numbers = Text("Values", (Transform)(object)root, new Vector2(48f, 0f), new Vector2(250f, 50f), ((TMP_Text)gold).font, 34f);
		((TMP_Text)numbers).enableAutoSizing = true;
		((TMP_Text)numbers).fontSizeMin = 18f;
		((TMP_Text)numbers).fontSizeMax = 34f;
		tooltip = Rect("Tooltip", (Transform)(object)root, new Vector2(0f, 0f), new Vector2(0f, -8f), new Vector2(400f, 170f));
		tooltip.pivot = new Vector2(0f, 1f);
		Image val6 = ((Component)tooltip).gameObject.AddComponent<Image>();
		((Graphic)val6).color = new Color(0.08f, 0.06f, 0.1f, 0.98f);
		((Graphic)val6).raycastTarget = false;
		description = Text("Description", (Transform)(object)tooltip, new Vector2(16f, 0f), new Vector2(368f, 150f), LangaugeManager.main.chosenFont, 27f);
		((TMP_Text)description).enableWordWrapping = true;
		((Component)tooltip).gameObject.SetActive(false);
		EventTrigger events = ((Component)root).gameObject.AddComponent<EventTrigger>();
		AddEvent(events, (EventTriggerType)0, delegate
		{
			ShowTooltip();
		});
		AddEvent(events, (EventTriggerType)1, delegate
		{
			if (Object.op_Implicit((Object)(object)tooltip))
			{
				((Component)tooltip).gameObject.SetActive(false);
			}
		});
		if (!Object.op_Implicit((Object)(object)((TMP_Text)numbers).font))
		{
			throw new InvalidOperationException("Нет шрифта для индикатора удачи.");
		}
	}

	internal void SetValues(LuckValues current)
	{
		values = current;
		((TMP_Text)numbers).text = Colored("00FF00", LuckValues.Number(values.Uncommon)) + "  " + Colored("FFFF00", LuckValues.Number(values.Rare)) + "  " + Colored("FF00FF", LuckValues.Number(values.Legendary));
		if (((Component)tooltip).gameObject.activeSelf)
		{
			UpdateDescription();
		}
	}

	private void ShowTooltip()
	{
		try
		{
			UpdateDescription();
			((Component)tooltip).gameObject.SetActive(true);
		}
		catch (Exception ex)
		{
			Debug.LogWarning((object)("[LuckHUD] Не удалось показать подсказку удачи: " + ex));
		}
	}

	private void UpdateDescription()
	{
		LangaugeManager main = LangaugeManager.main;
		if (!Object.op_Implicit((Object)(object)main))
		{
			throw new InvalidOperationException("Не найден менеджер локализации.");
		}
		((TMP_Text)description).font = main.chosenFont;
		((TMP_Text)description).text = main.GetTextByKey("luck") + "\n" + Colored("00FF00", main.GetTextByKey("uncommon") + ": " + LuckValues.Number(values.Uncommon)) + "\n" + Colored("FFFF00", main.GetTextByKey("rare") + ": " + LuckValues.Number(values.Rare)) + "\n" + Colored("FF00FF", main.GetTextByKey("legendary") + ": " + LuckValues.Number(values.Legendary));
	}

	private static string Colored(string color, string text)
	{
		return "<color=#" + color + ">" + text + "</color>";
	}

	private static void AddEvent(EventTrigger events, EventTriggerType type, Action action)
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Expected O, but got Unknown
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		Entry val = new Entry();
		val.eventID = type;
		Entry val2 = val;
		((UnityEvent<BaseEventData>)(object)val2.callback).AddListener((UnityAction<BaseEventData>)delegate
		{
			action();
		});
		events.triggers.Add(val2);
	}

	private static RectTransform Rect(string name, Transform parent, Vector2 anchor, Vector2 position, Vector2 size)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Expected O, but got Unknown
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: 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_0038: 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_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		RectTransform val = (RectTransform)new GameObject(name, new Type[1] { typeof(RectTransform) }).transform;
		((Transform)val).SetParent(parent, false);
		Vector2 anchorMin = (val.anchorMax = anchor);
		val.anchorMin = anchorMin;
		val.pivot = new Vector2(0f, 0.5f);
		val.anchoredPosition = position;
		val.sizeDelta = size;
		return val;
	}

	private static TextMeshProUGUI Text(string name, Transform parent, Vector2 position, Vector2 size, TMP_FontAsset font, float fontSize)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		TextMeshProUGUI val = ((Component)Rect(name, parent, new Vector2(0f, 0.5f), position, size)).gameObject.AddComponent<TextMeshProUGUI>();
		((TMP_Text)val).font = font;
		((TMP_Text)val).fontSize = fontSize;
		((TMP_Text)val).alignment = (TextAlignmentOptions)4097;
		((TMP_Text)val).enableWordWrapping = false;
		((Graphic)val).raycastTarget = false;
		return val;
	}

	internal void Dispose()
	{
		if (Object.op_Implicit((Object)(object)root))
		{
			Object.Destroy((Object)(object)((Component)root).gameObject);
		}
		root = null;
	}
}
internal struct LuckValues : IEquatable<LuckValues>
{
	internal readonly float Uncommon;

	internal readonly float Rare;

	internal readonly float Legendary;

	internal LuckValues(float uncommon, float rare, float legendary, float uncommonItems, float rareItems, float legendaryItems)
	{
		Uncommon = uncommon + uncommonItems;
		Rare = rare + rareItems;
		Legendary = legendary + legendaryItems;
		if (!Finite(Uncommon) || !Finite(Rare) || !Finite(Legendary))
		{
			throw new InvalidOperationException("Недопустимое значение удачи: " + Uncommon + ", " + Rare + ", " + Legendary);
		}
	}

	private static bool Finite(float value)
	{
		if (!float.IsNaN(value))
		{
			return !float.IsInfinity(value);
		}
		return false;
	}

	public bool Equals(LuckValues other)
	{
		if (Uncommon == other.Uncommon && Rare == other.Rare)
		{
			return Legendary == other.Legendary;
		}
		return false;
	}

	internal static string Number(float value)
	{
		return value.ToString("0.##", CultureInfo.InvariantCulture);
	}
}
public sealed class Mod : MelonMod
{
	private LuckHudView view;

	private LuckValues last;

	private bool hasValue;

	private int generation;

	public override void OnInitializeMelon()
	{
		MelonLogger.Msg("Luck HUD 0.1.0: отдельный индикатор удачи; зелёный / жёлтый / пурпурный.");
	}

	public override void OnSceneWasLoaded(int buildIndex, string sceneName)
	{
		if (sceneName == "Game")
		{
			MelonCoroutines.Start(Create(++generation));
		}
	}

	public override void OnSceneWasUnloaded(int buildIndex, string sceneName)
	{
		if (!(sceneName != "Game"))
		{
			generation++;
			Dispose();
		}
	}

	private IEnumerator Create(int token)
	{
		for (int i = 0; i < 300; i++)
		{
			if (token != generation)
			{
				break;
			}
			if (Object.op_Implicit((Object)(object)GameManager.main) && Object.op_Implicit((Object)(object)GameManager.main.goldText) && Object.op_Implicit((Object)(object)Player.main) && Object.op_Implicit((Object)(object)LangaugeManager.main) && Object.op_Implicit((Object)(object)LangaugeManager.main.chosenFont))
			{
				try
				{
					Dispose();
					view = new LuckHudView();
					view.Create(GameManager.main.goldText);
					Refresh();
					MelonLogger.Msg("Индикатор удачи создан рядом с золотом. Источник: Player.main, сумма накопленной удачи и удачи от предметов.");
					yield break;
				}
				catch (Exception error)
				{
					Fail(error);
					yield break;
				}
			}
			yield return null;
		}
		if (token == generation)
		{
			Fail(new InvalidOperationException("За 300 кадров не найдены GameManager.goldText, Player или шрифт локализации в сцене Game."));
		}
	}

	public override void OnUpdate()
	{
		if (view == null || !view.Alive || !Object.op_Implicit((Object)(object)Player.main))
		{
			return;
		}
		try
		{
			Refresh();
		}
		catch (Exception error)
		{
			Fail(error);
		}
	}

	private void Refresh()
	{
		Player main = Player.main;
		LuckValues luckValues = new LuckValues(main.uncommonLuck, main.rareLuck, main.legendaryLuck, main.uncommonLuckFromItems, main.rareLuckFromItems, main.legendaryLuckFromItems);
		if (!hasValue || !last.Equals(luckValues))
		{
			view.SetValues(luckValues);
			last = luckValues;
			hasValue = true;
		}
	}

	private void Dispose()
	{
		if (view != null)
		{
			view.Dispose();
		}
		view = null;
		hasValue = false;
	}

	private void Fail(Exception error)
	{
		Dispose();
		MelonLogger.Error("Индикатор удачи отключён: " + error);
		Debug.LogError((object)("[LuckHUD] Индикатор удачи отключён: " + error));
	}
}