Decompiled source of VargheimMysticCrafting v1.0.1

VargheimMysticCrafting.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using VargheimProfessions;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.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 VargheimMysticCrafting
{
	[BepInPlugin("digi.vargheim.mysticcrafting", "VargheimMysticCrafting", "1.0.1")]
	[BepInDependency("digi.vargheim.professions", "0.4.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal sealed class Craft
		{
			public string Item;

			public bool Magic;

			public HashSet<ItemData> Before;

			public string SimpleName;

			public int SimpleCount;
		}

		[HarmonyPatch]
		internal static class Patches
		{
			[HarmonyPatch(typeof(Player), "HaveRequirements", new Type[]
			{
				typeof(Recipe),
				typeof(bool),
				typeof(int),
				typeof(int)
			})]
			[HarmonyPostfix]
			private static void Have(Player __instance, Recipe recipe, ref bool __result)
			{
				try
				{
					if (__result && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && !((Object)(object)recipe == (Object)null) && !((Object)(object)recipe.m_item == (Object)null) && Api.Active)
					{
						int num = GemGate(((Object)((Component)recipe.m_item).gameObject).name);
						if (num > 0 && Api.PerkLevel("Jewelcrafting") < num)
						{
							__result = false;
						}
					}
				}
				catch
				{
				}
			}

			[HarmonyPatch(typeof(Smelter), "OnAddOre")]
			[HarmonyPrefix]
			private static bool FurnaceAdd(Smelter __instance, Humanoid user, ref ItemData item, ref bool __result)
			{
				try
				{
					if ((Object)(object)user != (Object)(object)Player.m_localPlayer || (Object)(object)user == (Object)null || !Api.Active || Utils.GetPrefabName(((Component)__instance).gameObject) != "JC_Gemstone_Furnace")
					{
						return true;
					}
					int num = Api.PerkLevel("Jewelcrafting");
					int num2 = 0;
					if (item == null)
					{
						Inventory inventory = user.GetInventory();
						foreach (ItemConversion item3 in __instance.m_conversion)
						{
							if (item3 == null || (Object)(object)item3.m_from == (Object)null || (Object)(object)item3.m_to == (Object)null)
							{
								continue;
							}
							ItemData item2 = inventory.GetItem(item3.m_from.m_itemData.m_shared.m_name, -1, false);
							if (item2 != null)
							{
								int num3 = GemGate(((Object)((Component)item3.m_to).gameObject).name);
								if (num3 <= num)
								{
									item = item2;
									return true;
								}
								num2 = Math.Max(num2, num3);
							}
						}
						if (num2 == 0)
						{
							return true;
						}
					}
					else
					{
						num2 = FurnaceGate(__instance, item);
						if (num2 <= num)
						{
							return true;
						}
					}
					if (Time.time - s_lastFurnaceMsg > 2f)
					{
						s_lastFurnaceMsg = Time.time;
						Api.Message("You need Mystic Crafting " + num2 + " to refine that gem.");
					}
					__result = false;
					return false;
				}
				catch
				{
					return true;
				}
			}

			[HarmonyPatch(typeof(Attack), "GetAttackEitr", new Type[] { })]
			[HarmonyPostfix]
			private static void Eitr(Attack __instance, ref float __result)
			{
				try
				{
					ItemData value = Traverse.Create((object)__instance).Field("m_weapon").GetValue<ItemData>();
					if (value != null && value.m_customData != null && value.m_customData.ContainsKey("vp_attuned"))
					{
						__result *= 1f - FocusCut.Value;
					}
				}
				catch
				{
				}
			}

			[HarmonyPatch(typeof(InventoryGui), "DoCrafting")]
			[HarmonyPrefix]
			private static void CraftPre(InventoryGui __instance, Player player, out Craft __state)
			{
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0074: Invalid comparison between Unknown and I4
				//IL_0077: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: Invalid comparison between Unknown and I4
				__state = null;
				try
				{
					Recipe value = Traverse.Create((object)__instance).Field("m_craftRecipe").GetValue<Recipe>();
					ItemData value2 = Traverse.Create((object)__instance).Field("m_craftUpgradeItem").GetValue<ItemData>();
					if ((Object)(object)value == (Object)null || (Object)(object)value.m_item == (Object)null || value2 != null || (Object)(object)player != (Object)(object)Player.m_localPlayer)
					{
						return;
					}
					SharedData shared = value.m_item.m_itemData.m_shared;
					bool flag = ((int)shared.m_skillType == 9 || (int)shared.m_skillType == 10) && shared.m_maxStackSize == 1;
					bool flag2 = ((Object)((Component)value.m_item).gameObject).name.StartsWith("Simple_", StringComparison.Ordinal);
					if ((flag && Api.HasPerk("Jewelcrafting", FocusLevel.Value)) || (flag2 && Api.HasPerk("Jewelcrafting", CutterLevel.Value)))
					{
						__state = new Craft
						{
							Item = ((Object)((Component)value.m_item).gameObject).name,
							Magic = flag,
							Before = new HashSet<ItemData>(((Humanoid)player).GetInventory().GetAllItems())
						};
						if (flag2 && !flag)
						{
							__state.SimpleName = shared.m_name;
							__state.SimpleCount = ((Humanoid)player).GetInventory().CountItems(shared.m_name, -1, true);
						}
					}
				}
				catch
				{
				}
			}

			[HarmonyPatch(typeof(InventoryGui), "DoCrafting")]
			[HarmonyPostfix]
			private static void CraftPost(Player player, Craft __state)
			{
				if (__state == null || (Object)(object)player == (Object)null)
				{
					return;
				}
				try
				{
					Inventory inventory = ((Humanoid)player).GetInventory();
					if (__state.Magic)
					{
						foreach (ItemData allItem in inventory.GetAllItems())
						{
							if (allItem != null && !__state.Before.Contains(allItem) && (Object)(object)allItem.m_dropPrefab != (Object)null && ((Object)allItem.m_dropPrefab).name == __state.Item)
							{
								allItem.m_customData["vp_attuned"] = player.GetPlayerName();
							}
						}
						return;
					}
					if (__state.SimpleName == null || inventory.CountItems(__state.SimpleName, -1, true) <= __state.SimpleCount || Random.value >= CutterChance.Value)
					{
						return;
					}
					string text = "Perfect_" + __state.Item.Substring("Simple_".Length);
					GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(text);
					GameObject itemPrefab2 = ObjectDB.instance.GetItemPrefab(__state.Item);
					if (!((Object)(object)itemPrefab == (Object)null) && !((Object)(object)itemPrefab2 == (Object)null))
					{
						string name = itemPrefab2.GetComponent<ItemDrop>().m_itemData.m_shared.m_name;
						if (inventory.CountItems(name, -1, true) > 0)
						{
							inventory.RemoveItem(name, 1, -1, true);
							inventory.AddItem(itemPrefab, 1);
							Api.Message("Master cutter: a perfect gem!");
						}
					}
				}
				catch
				{
				}
			}
		}

		public const string Guid = "digi.vargheim.mysticcrafting";

		public const string Version = "1.0.1";

		private const string Prof = "Jewelcrafting";

		internal static ConfigEntry<int> AdvancedLevel;

		internal static ConfigEntry<int> FusionLevel;

		internal static ConfigEntry<int> PerfectLevel;

		internal static ConfigEntry<int> FocusLevel;

		internal static ConfigEntry<int> AppraiserLevel;

		internal static ConfigEntry<int> CutterLevel;

		internal static ConfigEntry<string> SocketLevels;

		internal static ConfigEntry<float> FocusCut;

		internal static ConfigEntry<float> AppraiserBoost;

		internal static ConfigEntry<float> CutterChance;

		internal static Plugin Instance;

		private static float s_lastSocketMsg;

		internal const string GemFurnace = "JC_Gemstone_Furnace";

		private static float s_lastFurnaceMsg;

		private void Awake()
		{
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Expected O, but got Unknown
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Expected O, but got Unknown
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Expected O, but got Unknown
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Expected O, but got Unknown
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Expected O, but got Unknown
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Expected O, but got Unknown
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Expected O, but got Unknown
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Expected O, but got Unknown
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Expected O, but got Unknown
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Expected O, but got Unknown
			Instance = this;
			AdvancedLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Perks", "AdvancedGemsLevel", 35, "Level to cut and upgrade advanced gems.");
			FusionLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Perks", "GemFusionLevel", 50, "Level to craft merged (fused) gems.");
			PerfectLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Perks", "PerfectGemsLevel", 55, "Level to craft perfect gems.");
			SocketLevels = ((BaseUnityPlugin)this).Config.Bind<string>("Perks", "SocketLevels", "0:1,35:2,55:3", "Most sockets a player can add to an item, by Mystic Crafting level: 'level:sockets', separated by ','.");
			FocusLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Perks", "AttunedFocusLevel", 60, "Attuned focus level.");
			FocusCut = ((BaseUnityPlugin)this).Config.Bind<float>("Perks", "AttunedFocusEitrReduction", 0.1f, "Attuned focus: staffs and magic weapons you craft use this much less eitr.");
			AppraiserLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Perks", "AppraiserLevel", 75, "Appraiser level.");
			AppraiserBoost = ((BaseUnityPlugin)this).Config.Bind<float>("Perks", "AppraiserFusionBoost", 0.25f, "Appraiser: fusion boxes you carry fill this much faster.");
			CutterLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Perks", "MasterCutterLevel", 100, "Master cutter level.");
			CutterChance = ((BaseUnityPlugin)this).Config.Bind<float>("Perks", "MasterCutterChance", 0.1f, "Master cutter: chance a gem you cut comes out perfect.");
			Content.AddTooltip((Func<ItemData, string>)Tooltip);
			Api.RegisterLadder("Jewelcrafting", "VargheimMysticCrafting 1.0.1", "Jewelcrafting and Wizardry. Everyone can cut and socket simple gems and add the first socket. Modded mage gear, staffs, wands, rings and necklaces are crafted by mystics, by tier.", (Perk[])(object)new Perk[9]
			{
				new Perk(25, "Mystic gear", "All Wizardry gear by tier (staffs, wands, mage armor, robes); rings and necklaces."),
				new Perk(AdvancedLevel.Value, "Advanced gems", "Cut and upgrade advanced gems; add a second socket."),
				new Perk(35, "Steady hand", "Better socket success with level (Jewelcrafting)."),
				new Perk(45, "Careful salvage", "Failed sockets return materials near where the item was made (Jewelcrafting)."),
				new Perk(FusionLevel.Value, "Gem fusion", "Merge gems into stronger ones."),
				new Perk(PerfectLevel.Value, "Perfect gems", "Craft perfect gems; add a third socket."),
				new Perk(FocusLevel.Value, "Attuned focus", "Staffs and magic weapons you craft use " + Mathf.RoundToInt(FocusCut.Value * 100f) + "% less eitr."),
				new Perk(AppraiserLevel.Value, "Appraiser", "Fusion boxes you carry fill " + Mathf.RoundToInt(AppraiserBoost.Value * 100f) + "% faster."),
				new Perk(CutterLevel.Value, "Master cutter", Mathf.RoundToInt(CutterChance.Value * 100f) + "% chance a gem you cut comes out perfect.")
			});
			Harmony val = new Harmony("digi.vargheim.mysticcrafting");
			val.PatchAll(typeof(Patches));
			try
			{
				PatchJewelcrafting(val);
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Jewelcrafting hooks skipped: " + ex.Message));
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"VargheimMysticCrafting 1.0.1 loaded.");
		}

		internal static int GemGate(string prefab)
		{
			if (prefab == null)
			{
				return 0;
			}
			if (prefab.StartsWith("Perfect_", StringComparison.Ordinal))
			{
				return PerfectLevel.Value;
			}
			if (prefab.IndexOf("Merged", StringComparison.Ordinal) >= 0)
			{
				return FusionLevel.Value;
			}
			if (prefab.StartsWith("Advanced_", StringComparison.Ordinal))
			{
				return AdvancedLevel.Value;
			}
			return 0;
		}

		internal static int SocketCap()
		{
			int num = (Api.Active ? Api.PerkLevel("Jewelcrafting") : 100);
			int num2 = 1;
			string[] array = SocketLevels.Value.Split(',');
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split(':');
				if (array2.Length == 2 && int.TryParse(array2[0].Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) && int.TryParse(array2[1].Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2) && num >= result)
				{
					num2 = Math.Max(num2, result2);
				}
			}
			return num2;
		}

		internal static int SocketCount(ItemData item)
		{
			if (item == null || item.m_customData == null)
			{
				return 0;
			}
			foreach (KeyValuePair<string, string> customDatum in item.m_customData)
			{
				if (customDatum.Key.EndsWith("Jewelcrafting.Sockets", StringComparison.Ordinal))
				{
					return string.IsNullOrEmpty(customDatum.Value) ? 1 : customDatum.Value.Split(',').Length;
				}
			}
			return 0;
		}

		private static string Tooltip(ItemData i)
		{
			if (i == null || i.m_customData == null || !i.m_customData.TryGetValue("vp_attuned", out var value))
			{
				return null;
			}
			return "<color=#b9a3ff>Attuned</color>: " + Mathf.RoundToInt(FocusCut.Value * 100f) + "% less eitr. Made by " + value;
		}

		private static void PatchJewelcrafting(Harmony h)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			Type type = AccessTools.TypeByName("Jewelcrafting.GemStones");
			Type type2 = AccessTools.TypeByName("Jewelcrafting.FusionBoxSetup");
			MethodInfo methodInfo = ((type != null) ? AccessTools.Method(type, "CanAddMoreSockets", (Type[])null, (Type[])null) : null);
			MethodInfo methodInfo2 = ((type2 != null) ? AccessTools.Method(type2, "IncreaseBoxProgress", (Type[])null, (Type[])null) : null);
			if (methodInfo != null)
			{
				h.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "CanAddPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			if (methodInfo2 != null)
			{
				h.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(Plugin), "ProgressPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			if (type != null)
			{
				((BaseUnityPlugin)Instance).Logger.LogInfo((object)("Jewelcrafting found: socket limit " + ((methodInfo != null) ? "on" : "missing") + ", appraiser " + ((methodInfo2 != null) ? "on" : "missing") + "."));
			}
		}

		private static void CanAddPostfix(ItemData item, ref bool __result)
		{
			try
			{
				if (!__result)
				{
					return;
				}
				int num = SocketCap();
				if (SocketCount(item) >= num)
				{
					__result = false;
					if (Time.time - s_lastSocketMsg > 3f)
					{
						s_lastSocketMsg = Time.time;
						Api.Message("You can add " + num + " socket" + ((num == 1) ? "" : "s") + " at your Mystic Crafting level.");
					}
				}
			}
			catch
			{
			}
		}

		private static void ProgressPrefix(ref IEnumerable<float> progress)
		{
			try
			{
				if (progress == null || !Api.HasPerk("Jewelcrafting", AppraiserLevel.Value))
				{
					return;
				}
				List<float> list = new List<float>();
				foreach (float item in progress)
				{
					list.Add(item * (1f + AppraiserBoost.Value));
				}
				progress = list;
			}
			catch
			{
			}
		}

		internal static int FurnaceGate(Smelter s, ItemData item)
		{
			if ((Object)(object)s == (Object)null || item == null || s.m_conversion == null)
			{
				return 0;
			}
			foreach (ItemConversion item2 in s.m_conversion)
			{
				if (item2 != null && (Object)(object)item2.m_from != (Object)null && (Object)(object)item2.m_to != (Object)null && item2.m_from.m_itemData.m_shared.m_name == item.m_shared.m_name)
				{
					return GemGate(((Object)((Component)item2.m_to).gameObject).name);
				}
			}
			return 0;
		}
	}
}