Decompiled source of CiCisTrinketAndBindingFramework v1.0.0

plugins/TrinketAndBindingFramework/TrinketAndBindingFramework.dll

Decompiled 4 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("TrinketAndBindingFramework")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("TrinketAndBindingFramework")]
[assembly: AssemblyTitle("TrinketAndBindingFramework")]
[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 TrinketAndBindingFramework
{
	[BepInPlugin("com.cicismods.trinketandbindingframework", "CiCi's Trinket & Binding Framework", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string GUID = "com.cicismods.trinketandbindingframework";

		public const string NAME = "CiCi's Trinket & Binding Framework";

		public const string VERSION = "1.0.0";

		public static ManualLogSource Log;

		private void Awake()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			new Harmony("com.cicismods.trinketandbindingframework").PatchAll();
			Log.LogInfo((object)"CiCi's Trinket & Binding Framework 1.0.0 loaded");
		}
	}
	public static class TrinketRegistry
	{
		internal class Entry
		{
			public string id;

			public string title;

			public string description;

			public string flavorText;

			public bool isBinding;

			public int cost;

			public float scoreMultiplierBonus;

			public float scoreBonus;

			public Sprite icon;

			public Func<List<Item_Object>> itemsToGrantFactory;

			public Func<List<Perk>> perksToGrantFactory;

			public int pouchesToGrant;

			public Trinket runtime;
		}

		internal static readonly Dictionary<string, Entry> _registry = new Dictionary<string, Entry>();

		public static Trinket GetRuntimeTrinket(string id)
		{
			if (string.IsNullOrEmpty(id))
			{
				return null;
			}
			if (!_registry.TryGetValue(id, out var value))
			{
				return null;
			}
			return value.runtime;
		}

		public static void RegisterTrinket(string id, string title, string description, string flavorText = "", int cost = 1, float scoreMultiplierBonus = 0f, float scoreBonus = 0f, Sprite icon = null, Func<List<Item_Object>> itemsToGrantFactory = null, Func<List<Perk>> perksToGrantFactory = null, int pouchesToGrant = 0)
		{
			Register(id, title, description, flavorText, isBinding: false, cost, scoreMultiplierBonus, scoreBonus, icon, itemsToGrantFactory, perksToGrantFactory, pouchesToGrant);
		}

		public static void RegisterBinding(string id, string title, string description, string flavorText = "", int cost = 1, float scoreMultiplierBonus = 0f, float scoreBonus = 0f, Sprite icon = null, Func<List<Item_Object>> itemsToGrantFactory = null, Func<List<Perk>> perksToGrantFactory = null, int pouchesToGrant = 0)
		{
			Register(id, title, description, flavorText, isBinding: true, cost, scoreMultiplierBonus, scoreBonus, icon, itemsToGrantFactory, perksToGrantFactory, pouchesToGrant);
		}

		private static void Register(string id, string title, string description, string flavorText, bool isBinding, int cost, float scoreMultiplierBonus, float scoreBonus, Sprite icon, Func<List<Item_Object>> itemsToGrantFactory, Func<List<Perk>> perksToGrantFactory, int pouchesToGrant)
		{
			if (string.IsNullOrEmpty(id))
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"[Registry] empty id, skipped");
				}
				return;
			}
			_registry[id] = new Entry
			{
				id = id,
				title = title,
				description = description,
				flavorText = (flavorText ?? ""),
				isBinding = isBinding,
				cost = cost,
				scoreMultiplierBonus = scoreMultiplierBonus,
				scoreBonus = scoreBonus,
				icon = icon,
				itemsToGrantFactory = itemsToGrantFactory,
				perksToGrantFactory = perksToGrantFactory,
				pouchesToGrant = pouchesToGrant
			};
			ManualLogSource log2 = Plugin.Log;
			if (log2 != null)
			{
				log2.LogInfo((object)("[Registry] " + (isBinding ? "binding" : "trinket") + ": " + id));
			}
		}
	}
	[HarmonyPatch(typeof(Trinket), "GetLockedDescription")]
	public static class LockedDescriptionNullGuardPatch
	{
		[HarmonyPrefix]
		public static bool Prefix(Trinket __instance, ref string __result)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			if ((Object)(object)__instance.progressionUnlock == (Object)null && !__instance.comingSoon)
			{
				__result = __instance.GetDescription() + "\n<color=grey>(Locked by current selection.)</color>";
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(CL_AssetManager), "GetTrinketAsset")]
	public static class TrinketAssetLookupPatch
	{
		[HarmonyPostfix]
		public static void Postfix(string id, ref Trinket __result)
		{
			if ((Object)(object)__result != (Object)null || string.IsNullOrEmpty(id))
			{
				return;
			}
			string value = id.ToLowerInvariant();
			foreach (KeyValuePair<string, TrinketRegistry.Entry> item in TrinketRegistry._registry)
			{
				TrinketRegistry.Entry value2 = item.Value;
				if (!((Object)(object)value2.runtime == (Object)null) && ((Object)value2.runtime).name != null && ((Object)value2.runtime).name.ToLowerInvariant().Contains(value))
				{
					__result = value2.runtime;
					break;
				}
			}
		}
	}
	[HarmonyPatch(typeof(UI_TrinketPicker), "ReloadTrinkets")]
	public static class TrinketInjectionPatch
	{
		[HarmonyPrefix]
		public static void Prefix(UI_TrinketPicker __instance)
		{
			object? obj = AccessTools.Field(typeof(UI_TrinketPicker), "currentGamemode")?.GetValue(__instance);
			M_Gamemode val = (M_Gamemode)(((obj is M_Gamemode) ? obj : null) ?? CL_GameManager.GetBaseGamemode());
			if ((Object)(object)val?.availableTrinkets == (Object)null)
			{
				return;
			}
			Sprite val2 = FindBorrowableIcon(val.availableTrinkets?.trinkets);
			Sprite val3 = FindBorrowableIcon(val.availableTrinkets?.bindings);
			foreach (KeyValuePair<string, TrinketRegistry.Entry> item in TrinketRegistry._registry)
			{
				TrinketRegistry.Entry value = item.Value;
				if ((Object)(object)value.runtime == (Object)null)
				{
					value.runtime = BuildTrinketSO(value);
				}
				if ((Object)(object)value.runtime == (Object)null)
				{
					continue;
				}
				if ((Object)(object)value.runtime.icon == (Object)null)
				{
					Sprite val4 = (value.isBinding ? val3 : val2);
					value.runtime.icon = value.icon ?? val4;
					value.runtime.lockIcon = value.runtime.icon;
				}
				if (value.itemsToGrantFactory != null)
				{
					try
					{
						value.runtime.itemsToGrant = value.itemsToGrantFactory() ?? new List<Item_Object>();
					}
					catch (Exception ex)
					{
						ManualLogSource log = Plugin.Log;
						if (log != null)
						{
							log.LogWarning((object)("[Registry] " + value.id + " items factory: " + ex.Message));
						}
					}
				}
				if (value.perksToGrantFactory != null)
				{
					try
					{
						value.runtime.perksToGrant = value.perksToGrantFactory() ?? new List<Perk>();
					}
					catch (Exception ex2)
					{
						ManualLogSource log2 = Plugin.Log;
						if (log2 != null)
						{
							log2.LogWarning((object)("[Registry] " + value.id + " perks factory: " + ex2.Message));
						}
					}
				}
				List<Trinket> list = (value.isBinding ? val.availableTrinkets.bindings : val.availableTrinkets.trinkets);
				if (list != null && !list.Contains(value.runtime))
				{
					list.Add(value.runtime);
				}
			}
		}

		private static Sprite FindBorrowableIcon(List<Trinket> source)
		{
			if (source == null)
			{
				return null;
			}
			foreach (Trinket item in source)
			{
				if (!((Object)(object)item == (Object)null) && !((Object)(object)item.icon == (Object)null) && !item.comingSoon && item.IsUnlocked())
				{
					return item.icon;
				}
			}
			foreach (Trinket item2 in source)
			{
				if ((Object)(object)item2 != (Object)null && (Object)(object)item2.icon != (Object)null)
				{
					return item2.icon;
				}
			}
			return null;
		}

		private static Trinket BuildTrinketSO(TrinketRegistry.Entry e)
		{
			Trinket obj = ScriptableObject.CreateInstance<Trinket>();
			((Object)obj).name = "Trinket_" + e.id;
			obj.title = e.title;
			obj.description = e.description;
			obj.flavorText = e.flavorText;
			obj.isBinding = e.isBinding;
			obj.cost = e.cost;
			obj.scoreMultiplierBonus = e.scoreMultiplierBonus;
			obj.scoreBonus = e.scoreBonus;
			obj.comingSoon = false;
			obj.settingBlacklist = new List<string>();
			obj.itemsToGrant = new List<Item_Object>();
			obj.perksToGrant = new List<Perk>();
			obj.pouchesToGrant = e.pouchesToGrant;
			obj.progressionUnlock = null;
			obj.icon = e.icon;
			obj.lockIcon = e.icon;
			Object.DontDestroyOnLoad((Object)(object)obj);
			return obj;
		}
	}
	[HarmonyPatch(typeof(UI_TrinketPicker), "ReloadTrinkets")]
	public static class TrinketPickerScrollPatch
	{
		private const string ScrollViewportName = "CiCi_ScrollViewport";

		private const float ViewportTopInset = 25f;

		private const float ViewportBottomInset = 70f;

		private const float ScrollSensitivity = 10f;

		[HarmonyPostfix]
		public static void Postfix(UI_TrinketPicker __instance)
		{
			EnsureScroll(__instance.trinketIconRoot);
			EnsureScroll(__instance.bindingIconRoot);
		}

		private static void EnsureScroll(Transform iconRoot)
		{
			//IL_005d: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)iconRoot == (Object)null)
			{
				return;
			}
			RectTransform val = (RectTransform)(object)((iconRoot is RectTransform) ? iconRoot : null);
			if (!((Object)(object)val == (Object)null) && (!((Object)(object)iconRoot.parent != (Object)null) || !(((Object)iconRoot.parent).name == "CiCi_ScrollViewport")))
			{
				Transform parent = iconRoot.parent;
				RectTransform val2 = (RectTransform)(object)((parent is RectTransform) ? parent : null);
				if (!((Object)(object)val2 == (Object)null))
				{
					Canvas.ForceUpdateCanvases();
					Rect rect = val.rect;
					Vector2 size = ((Rect)(ref rect)).size;
					Vector2 anchorMin = val.anchorMin;
					Vector2 anchorMax = val.anchorMax;
					Vector2 pivot = val.pivot;
					Vector2 anchoredPosition = val.anchoredPosition;
					Vector2 sizeDelta = val.sizeDelta;
					GameObject val3 = new GameObject("CiCi_ScrollViewport", new Type[1] { typeof(RectTransform) });
					RectTransform val4 = (RectTransform)val3.transform;
					((Transform)val4).SetParent((Transform)(object)val2, false);
					val4.anchorMin = anchorMin;
					val4.anchorMax = anchorMax;
					val4.pivot = pivot;
					float num = 22.5f;
					val4.anchoredPosition = anchoredPosition + new Vector2(0f, num);
					val4.sizeDelta = sizeDelta + new Vector2(0f, -95f);
					((Transform)val4).SetSiblingIndex(((Transform)val).GetSiblingIndex());
					((Transform)val).SetParent((Transform)(object)val4, false);
					val.anchorMin = new Vector2(0f, 1f);
					val.anchorMax = new Vector2(1f, 1f);
					val.pivot = new Vector2(0.5f, 1f);
					val.anchoredPosition = Vector2.zero;
					val.sizeDelta = new Vector2(0f, size.y);
					val3.AddComponent<RectMask2D>();
					Image obj = val3.AddComponent<Image>();
					((Graphic)obj).color = new Color(0f, 0f, 0f, 0f);
					((Graphic)obj).raycastTarget = true;
					ContentSizeFitter obj2 = ((Component)val).GetComponent<ContentSizeFitter>() ?? ((Component)val).gameObject.AddComponent<ContentSizeFitter>();
					obj2.horizontalFit = (FitMode)0;
					obj2.verticalFit = (FitMode)2;
					ScrollRect obj3 = val3.AddComponent<ScrollRect>();
					obj3.content = val;
					obj3.viewport = val4;
					obj3.horizontal = false;
					obj3.vertical = true;
					obj3.movementType = (MovementType)1;
					obj3.elasticity = 0.1f;
					obj3.scrollSensitivity = 10f;
					obj3.inertia = true;
					obj3.decelerationRate = 0.135f;
				}
			}
		}
	}
}