Decompiled source of TwoRelics v1.0.0

BepInEx/plugins/TwoRelics/TwoRelics.dll

Decompiled 4 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using BepInEx;
using HarmonyLib;
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: AssemblyTitle("TwoRelics")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("TwoRelics")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("880eb189-aa99-447c-aed4-d980ee9251c9")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("com.mozam.tworelics", "Two Relics Mod", "1.0.0")]
public class TwoRelicsPlugin : BaseUnityPlugin
{
	public static Dictionary<int, string> secondRelicDict = new Dictionary<int, string>();

	private Harmony harmony;

	private void Awake()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		harmony = new Harmony("com.mozam.tworelics");
		harmony.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Two Relics Mod loaded - patches applied.");
	}
}
[HarmonyPatch(typeof(RelicChestUI), "Update")]
public static class RelicChestUI_Update_SecondRelicKey_Patch
{
	private static readonly FieldInfo currentPlayerField = typeof(RelicChestUI).GetField("currentPlayer", BindingFlags.Instance | BindingFlags.NonPublic);

	private static readonly FieldInfo currentFocusField = typeof(RelicChestUI).GetField("currentFocus", BindingFlags.Instance | BindingFlags.NonPublic);

	private static readonly FieldInfo currentSelectionListField = typeof(RelicChestUI).GetField("currentSelectionList", BindingFlags.Instance | BindingFlags.NonPublic);

	private static readonly FieldInfo currentStartIndexField = typeof(RelicChestUI).GetField("currentStartIndex", BindingFlags.Instance | BindingFlags.NonPublic);

	private static readonly FieldInfo currentSelectionIndexField = typeof(RelicChestUI).GetField("currentSelectionIndex", BindingFlags.Instance | BindingFlags.NonPublic);

	private static readonly FieldInfo currentIDField = typeof(RelicChestUI).GetField("currentID", BindingFlags.Instance | BindingFlags.NonPublic);

	private static readonly FieldInfo activationPositionField = typeof(RelicChestUI).GetField("activationPosition", BindingFlags.Instance | BindingFlags.NonPublic);

	private static readonly FieldInfo maxDistanceField = typeof(RelicChestUI).GetField("maxDistance", BindingFlags.Instance | BindingFlags.NonPublic);

	private static void Postfix(RelicChestUI __instance)
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Expected O, but got Unknown
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Invalid comparison between Unknown and I4
		if (!__instance.isActive || GameUI.pauseMenu.paused)
		{
			return;
		}
		Player val = (Player)currentPlayerField.GetValue(__instance);
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		Vector2 val2 = (Vector2)activationPositionField.GetValue(__instance);
		float num = (float)maxDistanceField.GetValue(__instance);
		if (Vector2.Distance(Vector2.op_Implicit(((Component)val).transform.position), val2) > num || PlayerUIBase.GetLock("RelicChestUI" + val.playerID))
		{
			return;
		}
		RCFocus val3 = (RCFocus)currentFocusField.GetValue(__instance);
		if ((int)val3 != 1 || !Input.GetKeyDown((KeyCode)50))
		{
			return;
		}
		List<string> list = (List<string>)currentSelectionListField.GetValue(__instance);
		int num2 = (int)currentStartIndexField.GetValue(__instance);
		int num3 = (int)currentSelectionIndexField.GetValue(__instance);
		string text = list[num2 + num3];
		if (!Item.IsUnlocked(text, false))
		{
			SoundManager.PlayAudio("MenuError", 1f, false, -1f, -1f);
			return;
		}
		int playerID = val.playerID;
		if (TwoRelicsPlugin.secondRelicDict.TryGetValue(playerID, out var value) && !string.IsNullOrEmpty(value))
		{
			((Entity)val).inventory.RemoveItem(value, false, false);
		}
		TwoRelicsPlugin.secondRelicDict[playerID] = text;
		TwoRelicsSaveData.Save();
		((Entity)val).inventory.AddItem(text, false, false);
		GameDataManager.Save(true, true);
		((Entity)val).health.RestoreHealth(9999, false, false, true, true);
		currentIDField.SetValue(__instance, text);
		SoundManager.PlayAudio("WoodPickUp", 1f, false, -1f, -1f);
		__instance.SetFocus((RCFocus)0, false, false);
	}
}
internal class SecondRelicUIRefs
{
	public Image icon;

	public Text text;
}
internal static class SecondRelicUI
{
	private static readonly Dictionary<RelicChestUI, SecondRelicUIRefs> cache = new Dictionary<RelicChestUI, SecondRelicUIRefs>();

	private static readonly FieldInfo rcRefField = typeof(RelicChestUI).GetField("rcRef", BindingFlags.Instance | BindingFlags.NonPublic);

	private static readonly Type rcObjRefType = typeof(RelicChestUI).GetNestedType("RelicChestObjRef", BindingFlags.NonPublic);

	private static readonly FieldInfo typePageTransField = rcObjRefType?.GetField("typePageTrans");

	private static readonly Vector2 secondRelicOffset = new Vector2(0f, -40f);

	public static SecondRelicUIRefs GetOrCreate(RelicChestUI instance)
	{
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Expected O, but got Unknown
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: 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)
		if (cache.TryGetValue(instance, out var value))
		{
			return value;
		}
		object value2 = rcRefField.GetValue(instance);
		Transform val = (Transform)typePageTransField.GetValue(value2);
		Transform val2 = val.Find("CurrentRelic");
		GameObject val3 = Object.Instantiate<GameObject>(((Component)val2).gameObject, val);
		((Object)val3).name = "CurrentRelic (Second)";
		RectTransform component = val3.GetComponent<RectTransform>();
		if ((Object)(object)component != (Object)null)
		{
			component.anchoredPosition += secondRelicOffset;
		}
		DisableChildIfPresent(val3.transform, "ConfirmIcon");
		DisableChildIfPresent(val3.transform, "CancelIcon");
		DisableChildIfPresent(val3.transform, "ConfirmText");
		DisableChildIfPresent(val3.transform, "CancelText");
		Transform val4 = val3.transform.Find("Icon");
		Transform val5 = val3.transform.Find("Text");
		SecondRelicUIRefs secondRelicUIRefs = new SecondRelicUIRefs
		{
			icon = ((Component)val4).GetComponent<Image>(),
			text = ((Component)val5).GetComponent<Text>()
		};
		cache.Add(instance, secondRelicUIRefs);
		return secondRelicUIRefs;
	}

	private static void DisableChildIfPresent(Transform parent, string childName)
	{
		Transform val = parent.Find(childName);
		if ((Object)(object)val != (Object)null)
		{
			((Component)val).gameObject.SetActive(false);
		}
	}
}
internal static class SlotHintUI
{
	private static readonly Dictionary<RelicChestUI, bool> created = new Dictionary<RelicChestUI, bool>();

	private static readonly FieldInfo rcRefField = typeof(RelicChestUI).GetField("rcRef", BindingFlags.Instance | BindingFlags.NonPublic);

	private static readonly Type rcObjRefType = typeof(RelicChestUI).GetNestedType("RelicChestObjRef", BindingFlags.NonPublic);

	private static readonly FieldInfo selectPageTransField = rcObjRefType?.GetField("selectPageTrans");

	private static readonly Vector2 hintOffset = new Vector2(0f, -25f);

	public static void EnsureCreated(RelicChestUI instance)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Expected O, but got Unknown
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//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)
		if (!created.ContainsKey(instance))
		{
			object value = rcRefField.GetValue(instance);
			Transform val = (Transform)selectPageTransField.GetValue(value);
			Transform val2 = val.Find("Info/BGImage/ConfirmText");
			GameObject val3 = Object.Instantiate<GameObject>(((Component)val2).gameObject, val2.parent);
			((Object)val3).name = "SlotTwoHintText";
			RectTransform component = val3.GetComponent<RectTransform>();
			if ((Object)(object)component != (Object)null)
			{
				component.anchoredPosition += hintOffset;
			}
			Text component2 = val3.GetComponent<Text>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.text = "2: Equip Slot 2";
			}
			created[instance] = true;
		}
	}
}
[HarmonyPatch(typeof(RelicChestUI), "LoadSelectionPage")]
public static class RelicChestUI_LoadSelectionPage_SlotHint_Patch
{
	private static void Postfix(RelicChestUI __instance)
	{
		SlotHintUI.EnsureCreated(__instance);
	}
}
[HarmonyPatch(typeof(RelicChestUI), "LoadTypePage")]
public static class RelicChestUI_LoadTypePage_SecondRelicDisplay_Patch
{
	private static readonly FieldInfo currentPlayerField = typeof(RelicChestUI).GetField("currentPlayer", BindingFlags.Instance | BindingFlags.NonPublic);

	private static void Postfix(RelicChestUI __instance)
	{
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Expected O, but got Unknown
		SecondRelicUIRefs orCreate = SecondRelicUI.GetOrCreate(__instance);
		if (orCreate == null || (Object)(object)orCreate.icon == (Object)null || (Object)(object)orCreate.text == (Object)null)
		{
			return;
		}
		Player val = (Player)currentPlayerField.GetValue(__instance);
		if (!((Object)(object)val == (Object)null))
		{
			TwoRelicsPlugin.secondRelicDict.TryGetValue(val.playerID, out var value);
			if (string.IsNullOrEmpty(value))
			{
				((Behaviour)orCreate.icon).enabled = false;
				orCreate.text.text = string.Empty;
			}
			else
			{
				((Behaviour)orCreate.icon).enabled = true;
				orCreate.icon.sprite = IconManager.GetItemIcon(value);
				orCreate.text.text = TextManager.GetItemName(value);
			}
		}
	}
}
[HarmonyPatch(typeof(Player), "Start")]
public static class Player_Start_RestoreSecondRelic_Patch
{
	private static void Postfix(Player __instance)
	{
		if (!Globals.IsMuseum && !Globals.IsPvPScene && TwoRelicsPlugin.secondRelicDict.TryGetValue(__instance.playerID, out var value) && !string.IsNullOrEmpty(value))
		{
			((Entity)__instance).inventory.AddItem(value, false, false);
		}
	}
}
[HarmonyPatch(typeof(GameDataManager), "LoadInitial")]
public static class GameDataManager_LoadInitial_Patch
{
	private static void Postfix()
	{
		TwoRelicsSaveData.Load();
	}
}
[HarmonyPatch(typeof(GameDataManager), "ResetAllData")]
public static class GameDataManager_ResetAllData_Patch
{
	private static void Postfix()
	{
		TwoRelicsSaveData.DeleteAll();
	}
}
internal static class TwoRelicsSaveData
{
	private const string fileName = "TwoRelicsData.txt";

	private static string FilePath => Application.persistentDataPath + "/" + GameDataManager.steamIDStr + "TwoRelicsData.txt";

	public static void Save()
	{
		try
		{
			List<string> list = new List<string>();
			foreach (KeyValuePair<int, string> item in TwoRelicsPlugin.secondRelicDict)
			{
				if (!string.IsNullOrEmpty(item.Value))
				{
					list.Add(item.Key + "|" + item.Value);
				}
			}
			File.WriteAllLines(FilePath, list.ToArray());
		}
		catch (Exception ex)
		{
			Debug.LogWarning((object)("[TwoRelics] Failed to save second relic data: " + ex));
		}
	}

	public static void Load()
	{
		try
		{
			TwoRelicsPlugin.secondRelicDict.Clear();
			if (!File.Exists(FilePath))
			{
				return;
			}
			string[] array = File.ReadAllLines(FilePath);
			foreach (string text in array)
			{
				string[] array2 = text.Split(new char[1] { '|' });
				if (array2.Length == 2 && int.TryParse(array2[0], out var result))
				{
					TwoRelicsPlugin.secondRelicDict[result] = array2[1];
				}
			}
		}
		catch (Exception ex)
		{
			Debug.LogWarning((object)("[TwoRelics] Failed to load second relic data: " + ex));
		}
	}

	public static void DeleteAll()
	{
		try
		{
			TwoRelicsPlugin.secondRelicDict.Clear();
			if (File.Exists(FilePath))
			{
				File.Delete(FilePath);
			}
		}
		catch (Exception ex)
		{
			Debug.LogWarning((object)("[TwoRelics] Failed to delete second relic data: " + ex));
		}
	}
}