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;
}
}
}