Decompiled source of Enchantments Unbound v0.3.0

EnchantmentsUnbound.dll

Decompiled 3 weeks 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.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PerfectRandom.Sulfur.Core;
using PerfectRandom.Sulfur.Core.Audio;
using PerfectRandom.Sulfur.Core.CharacterStats;
using PerfectRandom.Sulfur.Core.Items;
using PerfectRandom.Sulfur.Core.Stats;
using PerfectRandom.Sulfur.Core.UI;
using PerfectRandom.Sulfur.Core.UI.Inventory;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("EnchantmentsUnbound")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+9222a75a5140c3b8c638443164b438d816b33643")]
[assembly: AssemblyProduct("EnchantmentsUnbound")]
[assembly: AssemblyTitle("EnchantmentsUnbound")]
[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 EnchantmentsUnbound
{
	public static class ModInfo
	{
		public const string Id = "lingyun67.enchantments_unbound";

		public const string Name = "Enchantments Unbound";

		public const string Version = "0.3.0";
	}
	[BepInPlugin("lingyun67.enchantments_unbound", "Enchantments Unbound", "0.3.0")]
	public sealed class Plugin : BaseUnityPlugin
	{
		private const float MinExtendedRankXpGrowth = 1f;

		private const float MaxExtendedRankXpGrowth = 2.5f;

		private const float DefaultExtendedRankXpGrowth = 1.5f;

		private const int DisabledMaxRankLevel = 0;

		private const int MinMaxRankLevel = 5;

		private const int MaxMaxRankLevel = 200;

		private const int DefaultMaxRankLevel = 0;

		private static ConfigEntry<float> extendedRankXpGrowth;

		private static ConfigEntry<int> maxRankLevel;

		private Harmony harmony;

		private void Awake()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			extendedRankXpGrowth = ((BaseUnityPlugin)this).Config.Bind<float>("Progression", "ExtendedRankXpGrowth", 1.5f, new ConfigDescription("How much more XP each rank past 5 costs compared to the previous rank. Ranks 1-5 always use the vanilla curve. 1.0 = every rank past 5 costs the same as rank 5, 2.5 = keep compounding like the vanilla curve (XP requirements explode quickly).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 2.5f), Array.Empty<object>()));
			maxRankLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Progression", "MaxRankLevel", 0, new ConfigDescription("Highest weapon rank a weapon can reach. 0 disables the cap so weapons rank up without limit (the default). When set, the value is the maximum rank; values below 5 are treated as 5 so the cap never falls below vanilla (rank 5 is required by features such as the Telia weapon sacrifice). Stored XP is never lost: a capped weapon keeps accumulating XP, and raising or removing the cap later unlocks the higher ranks.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 200), Array.Empty<object>()));
			harmony = new Harmony("lingyun67.enchantments_unbound");
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Enchantments Unbound loaded.");
		}

		private void OnDestroy()
		{
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		internal static float GetExtendedRankXpGrowth()
		{
			if (extendedRankXpGrowth == null)
			{
				return 1.5f;
			}
			float value = extendedRankXpGrowth.Value;
			if (float.IsNaN(value) || float.IsInfinity(value))
			{
				return 1.5f;
			}
			if (value < 1f)
			{
				return 1f;
			}
			if (value > 2.5f)
			{
				return 2.5f;
			}
			return value;
		}

		internal static int GetMaxRankLevel()
		{
			if (maxRankLevel == null)
			{
				return 0;
			}
			int value = maxRankLevel.Value;
			if (value <= 0)
			{
				return 0;
			}
			if (value < 5)
			{
				return 5;
			}
			if (value > 200)
			{
				return 200;
			}
			return value;
		}
	}
}
namespace EnchantmentsUnbound.Patches
{
	[HarmonyPatch(typeof(InventoryItem))]
	internal static class InventoryItemPatches
	{
		[HarmonyPatch("IsEnchantmentCompatible", new Type[] { typeof(EnchantmentDefinition) })]
		[HarmonyPrefix]
		private static bool IsEnchantmentCompatiblePrefix(InventoryItem __instance, EnchantmentDefinition enchantment, ref bool __result)
		{
			__result = (Object)(object)enchantment != (Object)null && __instance.HasFreeEnchantmentSlot;
			return false;
		}

		[HarmonyPatch("GetRankLevelProgress")]
		[HarmonyPrefix]
		private static bool GetRankLevelProgressPrefix(InventoryItem __instance, ref float __result)
		{
			__result = CalculateUnlimitedRankProgress(__instance.GetExperience());
			return false;
		}

		[HarmonyPatch("AddEnchantment")]
		[HarmonyPrefix]
		private static bool AddEnchantmentPrefix(InventoryItem __instance, ItemDefinition enchantmentItem, bool announce)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)enchantmentItem == (Object)null || !((EnchantmentId)(ref enchantmentItem.appliesEnchantment)).IsValid)
			{
				Debug.LogError((object)"Trying to add invalid enchantment item.");
				return false;
			}
			EnchantmentDefinition asset = AssetAccess.GetAsset(enchantmentItem.appliesEnchantment);
			if ((Object)(object)asset == (Object)null)
			{
				Debug.LogError((object)"Trying to add null enchantment.");
				return false;
			}
			asset.RegisterAppliedBy(enchantmentItem);
			__instance.enchantments.Add(asset);
			StaticInstance<AchievementManager>.Instance.EnchantmentAppliedToItem(asset, __instance.itemDefinition, __instance.enchantments.Count);
			if (HasRandomOilAttribute(asset))
			{
				for (int i = 0; i < asset.modifiersApplied.Count; i++)
				{
					AddRandomOilAttributes(__instance, asset.modifiersApplied[i].attribute, asset);
				}
			}
			else
			{
				AddEnchantmentModifiers(__instance, asset, GlobalId.op_Implicit(((EnchantmentId)(ref asset.id)).AsGlobalId()));
			}
			if (announce)
			{
				StaticInstance<SoundBank>.Instance.soundUiWeaponOilEnchant.UIPlay();
			}
			__instance.SyncWithInstancedVersion();
			return false;
		}

		private static float CalculateUnlimitedRankProgress(float experience)
		{
			if (experience <= 0f)
			{
				return 0f;
			}
			float extendedRankXpGrowth = Plugin.GetExtendedRankXpGrowth();
			float num = 0f;
			float num2 = 50f;
			int num3 = 0;
			while (experience >= num2 && num3 < 200)
			{
				num3++;
				float num4 = num2 - num;
				num = num2;
				num2 = ((num3 >= 5) ? (num + num4 * extendedRankXpGrowth) : (num * 2.5f));
			}
			float num5 = ((!(num2 <= num)) ? ((float)num3 + (experience - num) / (num2 - num)) : ((float)num3));
			int maxRankLevel = Plugin.GetMaxRankLevel();
			if (maxRankLevel > 0 && num5 > (float)maxRankLevel)
			{
				num5 = maxRankLevel;
			}
			return num5;
		}

		private static bool HasRandomOilAttribute(EnchantmentDefinition enchantment)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			if (enchantment.modifiersApplied == null)
			{
				return false;
			}
			for (int i = 0; i < enchantment.modifiersApplied.Count; i++)
			{
				if ((int)enchantment.modifiersApplied[i].attribute == 84)
				{
					return true;
				}
			}
			return false;
		}

		private static void AddRandomOilAttributes(InventoryItem inventoryItem, ItemAttributes attribute, EnchantmentDefinition randomOilEnchantment)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			if ((int)attribute != 84)
			{
				return;
			}
			inventoryItem.enchantments.Remove(randomOilEnchantment);
			ItemDefinition val = null;
			EnchantmentDefinition val2 = null;
			LootTable enchantmentOilLootTable = StaticInstance<GameManager>.Instance.Settings.LootSettings.enchantmentOilLootTable;
			if ((Object)(object)enchantmentOilLootTable == (Object)null || enchantmentOilLootTable.entries == null)
			{
				return;
			}
			bool flag = false;
			int count = enchantmentOilLootTable.entries.Count;
			for (int i = 0; i < count; i++)
			{
				val = enchantmentOilLootTable.SelectOneItem();
				if (!((Object)(object)val == (Object)null) && ((EnchantmentId)(ref val.appliesEnchantment)).IsValid)
				{
					val2 = AssetAccess.GetAsset(val.appliesEnchantment);
					if ((Object)(object)val2 != (Object)null && val2.modifiersApplied != null && randomOilEnchantment.id != val.appliesEnchantment && val2.modifiersApplied.Count > 0)
					{
						flag = true;
						break;
					}
				}
			}
			if (flag && !((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null))
			{
				val2.RegisterAppliedBy(val);
				inventoryItem.enchantments.Add(val2);
				AddEnchantmentModifiers(inventoryItem, val2, GlobalId.op_Implicit(((EnchantmentId)(ref val.appliesEnchantment)).AsGlobalId()));
			}
		}

		private static void AddEnchantmentModifiers(InventoryItem inventoryItem, EnchantmentDefinition enchantment, uint sourceId)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_003d: Expected O, but got Unknown
			if (enchantment.modifiersApplied != null)
			{
				for (int i = 0; i < enchantment.modifiersApplied.Count; i++)
				{
					ItemModifierContainer val = enchantment.modifiersApplied[i];
					inventoryItem.stats.AddModifier(val.attribute, new StatModifier(val.value, val.modType, sourceId));
				}
			}
		}
	}
	[HarmonyPatch(typeof(Paperdoll), "GetItemsCompatibleWithEnchantment")]
	internal static class PaperdollEnchantmentHighlightPatch
	{
		private static bool Prefix(Paperdoll __instance, EnchantmentDefinition enchantment, ref List<InventoryItem> __result)
		{
			List<InventoryItem> list = new List<InventoryItem>();
			List<PaperdollSlot> slots = __instance.GetSlots();
			for (int i = 0; i < slots.Count; i++)
			{
				InventoryItem itemInSlot = slots[i].itemInSlot;
				if ((Object)(object)itemInSlot != (Object)null && itemInSlot.IsEnchantmentCompatible(enchantment))
				{
					list.Add(itemInSlot);
				}
			}
			__result = list;
			return false;
		}
	}
	[HarmonyPatch(typeof(ItemGrid), "GetItemsCompatibleWithEnchantment")]
	internal static class ItemGridEnchantmentHighlightPatch
	{
		private static bool Prefix(ItemGrid __instance, EnchantmentDefinition enchantment, ref List<InventoryItem> __result)
		{
			List<InventoryItem> list = new List<InventoryItem>();
			GridSlot[,] slots = __instance.Slots;
			int upperBound = slots.GetUpperBound(0);
			int upperBound2 = slots.GetUpperBound(1);
			for (int i = slots.GetLowerBound(0); i <= upperBound; i++)
			{
				for (int j = slots.GetLowerBound(1); j <= upperBound2; j++)
				{
					InventoryItem itemInSlot = slots[i, j].ItemInSlot;
					if ((Object)(object)itemInSlot != (Object)null && itemInSlot.IsEnchantmentCompatible(enchantment) && !list.Contains(itemInSlot))
					{
						list.Add(itemInSlot);
					}
				}
			}
			if ((Object)(object)StaticInstance<UIManager>.Instance != (Object)null && (Object)(object)StaticInstance<UIManager>.Instance.Paperdoll != (Object)null)
			{
				list.AddRange(StaticInstance<UIManager>.Instance.Paperdoll.GetItemsCompatibleWithEnchantment(enchantment));
			}
			__result = list;
			return false;
		}
	}
}