Decompiled source of Jewelcraft v0.8.5

BepInEx/plugins/Jewelcraft/Jewelcraft.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.UI;

[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("Enoq")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.8.5.0")]
[assembly: AssemblyInformationalVersion("0.8.5")]
[assembly: AssemblyProduct("Jewelcraft")]
[assembly: AssemblyTitle("Jewelcraft")]
[assembly: AssemblyVersion("0.8.5.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 Jewelcraft
{
	internal static class ArmorPalettePolicy
	{
		internal static bool IsArmor(int slot)
		{
			if (slot >= 2)
			{
				return slot <= 5;
			}
			return false;
		}
	}
	internal static class Enhancement
	{
		private static bool busy;

		internal static bool Eligible(ItemData item)
		{
			//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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected I4, but got Unknown
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Invalid comparison between Unknown and I4
			if (item?.m_shared == null || item.m_stack != 1 || item.m_shared.m_maxStackSize != 1)
			{
				return false;
			}
			if (EquipmentPalettePolicy.IsUtility(Object.op_Implicit((Object)(object)item.m_dropPrefab) ? ((Object)item.m_dropPrefab).name : null))
			{
				return false;
			}
			ItemType itemType = item.m_shared.m_itemType;
			switch (itemType - 3)
			{
			default:
				if ((int)itemType != 22)
				{
					break;
				}
				goto case 0;
			case 0:
			case 1:
			case 2:
			case 3:
			case 4:
			case 8:
			case 11:
			case 14:
				return true;
			case 5:
			case 6:
			case 7:
			case 9:
			case 10:
			case 12:
			case 13:
				break;
			}
			return false;
		}

		internal static int Level(ItemData item)
		{
			if (item == null || !Rules.TryRead(item.m_customData, out var level))
			{
				return 0;
			}
			return level;
		}

		internal static int VisualLevel(ItemData item)
		{
			if (!Eligible(item))
			{
				return 0;
			}
			return Level(item);
		}

		internal static float Bonus(ItemData item, float amount)
		{
			if (!Eligible(item))
			{
				return 1f;
			}
			return Rules.Multiplier(Level(item), amount);
		}

		internal static ItemData FindGem(Inventory inventory, Gem gem)
		{
			return ((IEnumerable<ItemData>)inventory.GetAllItems()).FirstOrDefault((Func<ItemData, bool>)((ItemData item) => item.m_stack > 0 && Object.op_Implicit((Object)(object)item.m_dropPrefab) && ((Object)item.m_dropPrefab).name == Gems.Prefab(gem)));
		}

		internal static int Count(Inventory inventory, Gem gem)
		{
			return (from item in inventory.GetAllItems()
				where Object.op_Implicit((Object)(object)item.m_dropPrefab) && ((Object)item.m_dropPrefab).name == Gems.Prefab(gem)
				select item).Sum((ItemData item) => item.m_stack);
		}

		internal static string Attempt(Player player, ItemData item, int expectedLevel)
		{
			if (busy || !Object.op_Implicit((Object)(object)player) || (Object)(object)player != (Object)(object)Player.m_localPlayer || ((Character)player).IsDead() || ((Character)player).IsTeleporting())
			{
				return Texts.T("No puedes mejorar ahora.", "You cannot refine right now.");
			}
			if (!RefinementSession.IsUsable(player))
			{
				return Texts.T("Usa un banco de trabajo protegido para refinar.", "Use a sheltered workbench to refine equipment.");
			}
			Inventory inventory = ((Humanoid)player).GetInventory();
			if (!Eligible(item) || !inventory.ContainsItem(item))
			{
				return Texts.T("Selecciona un objeto de tu inventario.", "Select an item in your inventory.");
			}
			if (!Rules.TryRead(item.m_customData, out var level))
			{
				return Texts.T("Datos de mejora desconocidos; objeto conservado.", "Unknown enhancement data; item preserved.");
			}
			if (level != expectedLevel)
			{
				return Texts.T("El objeto cambió. Revisa la nueva mejora.", "The item changed. Review the new upgrade.");
			}
			if (level >= 9)
			{
				return Texts.T("Ya está en +9.", "Already at +9.");
			}
			Gem gem = Rules.RequiredGem(level);
			ItemData val = FindGem(inventory, gem);
			if (val == null)
			{
				return Texts.T("Falta una joya de ", "Missing a jewel of ") + gem.ToString() + ".";
			}
			busy = true;
			try
			{
				bool flag = Rules.Succeeds(Settings.Chance(level), Random.Range(0, 100));
				string value;
				bool flag2 = item.m_customData.TryGetValue("com.enoq.jewelcraft.level.v1", out value);
				if (flag)
				{
					item.m_customData["com.enoq.jewelcraft.level.v1"] = (level + 1).ToString(CultureInfo.InvariantCulture);
				}
				if (!inventory.RemoveItem(val, 1))
				{
					if (flag2)
					{
						item.m_customData["com.enoq.jewelcraft.level.v1"] = value;
					}
					else
					{
						item.m_customData.Remove("com.enoq.jewelcraft.level.v1");
					}
					return Texts.T("La gema ya no está disponible.", "The gem is no longer available.");
				}
				return flag ? (Texts.T("¡Mejora conseguida! ", "Refinement succeeded! ") + Texts.Name(item) + " +" + (level + 1)) : (Texts.T("La gema se consumió. Tu equipo conserva +", "The gem was consumed. Your equipment keeps +") + level + ".");
			}
			finally
			{
				busy = false;
			}
		}
	}
	public sealed class EquipmentGlow : MonoBehaviour
	{
		private sealed class ItemPalette
		{
			internal int Hash;

			internal Texture Texture;

			internal GameObject[] Roots;

			internal GlowStyle Style;

			internal string Overrides;

			internal ResolvedPalette Resolved;
		}

		private const string NetworkKey = "com.enoq.jewelcraft.visual.v1";

		private static readonly string[] ItemFields = new string[8] { "m_leftItem", "m_rightItem", "m_helmetItem", "m_chestItem", "m_legItem", "m_shoulderItem", "m_hiddenLeftItem", "m_hiddenRightItem" };

		private static readonly string[] VisualFields = new string[8] { "m_leftItemInstance", "m_rightItemInstance", "m_helmetItemInstance", "m_chestItemInstances", "m_legItemInstances", "m_shoulderItemInstances", "m_leftBackItemInstance", "m_rightBackItemInstance" };

		private static readonly FieldInfo[] Items = ItemFields.Select((string name) => AccessTools.Field(typeof(Humanoid), name)).ToArray();

		private static readonly FieldInfo[] Visuals = VisualFields.Select((string name) => AccessTools.Field(typeof(VisEquipment), name)).ToArray();

		private static readonly string[] HashFields = new string[8] { "m_currentLeftItemHash", "m_currentRightItemHash", "m_currentHelmetItemHash", "m_currentChestItemHash", "m_currentLegItemHash", "m_currentShoulderItemHash", "m_currentLeftBackItemHash", "m_currentRightBackItemHash" };

		private static readonly FieldInfo[] Hashes = HashFields.Select((string name) => AccessTools.Field(typeof(VisEquipment), name)).ToArray();

		private static readonly HashSet<EquipmentGlow> Active = new HashSet<EquipmentGlow>();

		private static readonly FieldInfo StandView = AccessTools.Field(typeof(ArmorStand), "m_nview");

		private readonly Dictionary<GameObject, JewelGlow> effects = new Dictionary<GameObject, JewelGlow>();

		private readonly HashSet<GameObject> desired = new HashSet<GameObject>();

		private readonly int[] levels = new int[8];

		private readonly int[] equippedHashes = new int[8];

		private readonly ItemPalette[] itemPalettes = new ItemPalette[8];

		private Player player;

		private ArmorStand stand;

		private EquipmentParticles particles;

		private ZDO standData;

		private uint standRevision;

		private readonly int[] standHashes = new int[8];

		private ZNetView view;

		private VisEquipment equipment;

		private readonly GameObject[] bodyControllers = (GameObject[])(object)new GameObject[2];

		private float nextScan;

		private bool failed;

		private void Awake()
		{
			player = ((Component)this).GetComponent<Player>();
			stand = ((Component)this).GetComponent<ArmorStand>();
			view = (ZNetView)(Object.op_Implicit((Object)(object)stand) ? ((object)/*isinst with value type is only supported in some contexts*/) : ((object)((Component)this).GetComponent<ZNetView>()));
			equipment = (Object.op_Implicit((Object)(object)stand) ? stand.m_visEquipment : ((Component)this).GetComponent<VisEquipment>());
			particles = new EquipmentParticles(((Component)this).transform);
			Active.Add(this);
		}

		private void LateUpdate()
		{
			if (failed)
			{
				return;
			}
			try
			{
				Scan();
				particles.Tick();
			}
			catch (Exception ex)
			{
				failed = true;
				Clear();
				Plugin.Warn("Equipment glow disabled for this display after error: " + ex);
			}
		}

		private void Scan()
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Expected O, but got Unknown
			if (Time.unscaledTime < nextScan)
			{
				return;
			}
			nextScan = Time.unscaledTime + 0.4f;
			if ((!Object.op_Implicit((Object)(object)player) && !Object.op_Implicit((Object)(object)stand)) || !Object.op_Implicit((Object)(object)equipment) || !Object.op_Implicit((Object)(object)view) || !view.IsValid())
			{
				Clear();
				return;
			}
			if (Settings.Glow.Value && (!Object.op_Implicit((Object)(object)player) || !((Character)player).IsDead()) && Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				Vector3 val = ((Component)this).transform.position - ((Component)Player.m_localPlayer).transform.position;
				if (!(((Vector3)(ref val)).sqrMagnitude > 1600f))
				{
					ZDO zDO = view.GetZDO();
					for (int i = 0; i < 8; i++)
					{
						equippedHashes[i] = (int)Hashes[i].GetValue(equipment);
					}
					int num = zDO.GetInt("com.enoq.jewelcraft.visual.v1", 0);
					if (Object.op_Implicit((Object)(object)stand))
					{
						num = ReadStandLevels(zDO);
					}
					else if ((Object)(object)player == (Object)(object)Player.m_localPlayer && view.IsOwner())
					{
						for (int j = 0; j < 8; j++)
						{
							ref int reference = ref levels[j];
							object? value = Items[j].GetValue(player);
							reference = Enhancement.VisualLevel((ItemData)((value is ItemData) ? value : null));
						}
						int num2 = Rules.Pack(levels);
						if (num2 != num)
						{
							zDO.Set("com.enoq.jewelcraft.visual.v1", num2);
							num = num2;
						}
					}
					if (num == 0)
					{
						Clear();
						return;
					}
					if (!GlowAssets.Ready())
					{
						Clear();
						return;
					}
					desired.Clear();
					particles.Begin();
					for (int k = 0; k < 8; k++)
					{
						int num3 = Rules.Unpack(num, k);
						if (num3 == 0)
						{
							continue;
						}
						string prefab = PrefabName(equippedHashes[k]);
						if (EquipmentPalettePolicy.IsUtility(prefab))
						{
							continue;
						}
						Texture val2 = ClothingTexture(k);
						GameObject[] array = Roots(Visuals[k].GetValue(equipment)).ToArray();
						ResolvedPalette resolvedPalette = ResolveItemPalette(k, array, val2, prefab);
						GameObject[] array2 = array;
						foreach (GameObject target in array2)
						{
							Touch(target, num3, prefab, val2, resolvedPalette);
						}
						GearVfxTier gearVfxTier = GearVfxResolver.Resolve(prefab);
						GlowPalette glowPalette = resolvedPalette?.Colors ?? array.Select((GameObject r) => effects[r].Colors).FirstOrDefault((GlowPalette c) => c != null);
						if (gearVfxTier != GearVfxTier.Basic && glowPalette != null)
						{
							particles.Set(k, num3, gearVfxTier, glowPalette, array, equipment.m_bodyModel, val2);
						}
						if ((k != 3 && k != 4) || !Object.op_Implicit((Object)(object)equipment.m_bodyModel))
						{
							continue;
						}
						int num4 = k - 3;
						if (Object.op_Implicit((Object)(object)val2))
						{
							if (!Object.op_Implicit((Object)(object)bodyControllers[num4]))
							{
								bodyControllers[num4] = new GameObject("JC_ArmorController_" + num4);
								bodyControllers[num4].transform.SetParent(((Component)equipment).transform, false);
							}
							Touch(bodyControllers[num4], num3, prefab, val2, resolvedPalette, equipment.m_bodyModel, val2);
						}
					}
					particles.End();
					KeyValuePair<GameObject, JewelGlow>[] array3 = effects.ToArray();
					for (int l = 0; l < array3.Length; l++)
					{
						KeyValuePair<GameObject, JewelGlow> keyValuePair = array3[l];
						if (!Object.op_Implicit((Object)(object)keyValuePair.Key) || !desired.Contains(keyValuePair.Key))
						{
							if (Object.op_Implicit((Object)(object)keyValuePair.Value))
							{
								keyValuePair.Value.Release();
								Object.Destroy((Object)(object)keyValuePair.Value);
							}
							effects.Remove(keyValuePair.Key);
						}
					}
					return;
				}
			}
			Clear();
		}

		private int ReadStandLevels(ZDO zdo)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected I4, but got Unknown
			if (standData != zdo || standRevision != zdo.DataRevision)
			{
				Array.Clear(levels, 0, levels.Length);
				Array.Clear(standHashes, 0, standHashes.Length);
				for (int i = 0; i < stand.m_slots.Count; i++)
				{
					int num = GearVfxPolicy.VisualSlot((int)stand.m_slots[i].m_slot);
					if (num >= 0)
					{
						int attachedItem = stand.GetAttachedItem(i);
						GameObject val = (Object.op_Implicit((Object)(object)ObjectDB.instance) ? ObjectDB.instance.GetItemPrefab(attachedItem) : null);
						ItemDrop val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<ItemDrop>() : null);
						if (Object.op_Implicit((Object)(object)val2))
						{
							ItemData val3 = val2.m_itemData.Clone();
							ItemDrop.LoadFromZDO(val3, zdo, i);
							levels[num] = Enhancement.VisualLevel(val3);
							standHashes[num] = attachedItem;
						}
					}
				}
				standData = zdo;
				standRevision = zdo.DataRevision;
			}
			int num2 = 0;
			for (int j = 0; j < 8; j++)
			{
				if (standHashes[j] == equippedHashes[j])
				{
					num2 |= levels[j] << j * 4;
				}
			}
			return num2;
		}

		private static IEnumerable<GameObject> Roots(object value)
		{
			GameObject val = (GameObject)((value is GameObject) ? value : null);
			if (val != null && Object.op_Implicit((Object)(object)val))
			{
				yield return val;
			}
			if (!(value is List<GameObject> list))
			{
				yield break;
			}
			foreach (GameObject item in list)
			{
				if (Object.op_Implicit((Object)(object)item))
				{
					yield return item;
				}
			}
		}

		private static string PrefabName(int hash)
		{
			GameObject val = (Object.op_Implicit((Object)(object)ZNetScene.instance) ? ZNetScene.instance.GetPrefab(hash) : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return "unknown";
			}
			return ((Object)val).name;
		}

		private Texture ClothingTexture(int slot)
		{
			if ((slot != 3 && slot != 4) || !Object.op_Implicit((Object)(object)equipment.m_bodyModel))
			{
				return null;
			}
			Material sharedMaterial = ((Renderer)equipment.m_bodyModel).sharedMaterial;
			string text = ((slot == 3) ? "_ChestTex" : "_LegsTex");
			if (!Object.op_Implicit((Object)(object)sharedMaterial) || !sharedMaterial.HasProperty(text))
			{
				return null;
			}
			return sharedMaterial.GetTexture(text);
		}

		private ResolvedPalette ResolveItemPalette(int slot, GameObject[] roots, Texture texture, string prefab)
		{
			ItemPalette itemPalette = itemPalettes[slot];
			int num = equippedHashes[slot];
			if (itemPalette != null && itemPalette.Hash == num && (Object)(object)itemPalette.Texture == (Object)(object)texture && roots.SequenceEqual(itemPalette.Roots) && itemPalette.Style == Settings.Style.Value && itemPalette.Overrides == Settings.PaletteOverrides.Value)
			{
				return itemPalette.Resolved;
			}
			itemPalette = new ItemPalette
			{
				Hash = num,
				Texture = texture,
				Roots = roots,
				Style = Settings.Style.Value,
				Overrides = Settings.PaletteOverrides.Value,
				Resolved = PaletteResolver.Resolve((IEnumerable<GameObject>)roots, texture, prefab)
			};
			itemPalettes[slot] = itemPalette;
			return itemPalette.Resolved;
		}

		private void Touch(GameObject target, int level, string prefab, Texture colorTexture, ResolvedPalette shared, SkinnedMeshRenderer body = null, Texture mask = null)
		{
			desired.Add(target);
			if (!effects.TryGetValue(target, out var value) || !Object.op_Implicit((Object)(object)value) || !value.Matches(level, mask, prefab, colorTexture, shared))
			{
				if (Object.op_Implicit((Object)(object)value))
				{
					value.Release();
					Object.Destroy((Object)(object)value);
				}
				value = target.AddComponent<JewelGlow>();
				effects[target] = value;
				value.Configure(level, body, mask, prefab, colorTexture, shared);
			}
		}

		private void Clear()
		{
			foreach (JewelGlow value in effects.Values)
			{
				if (Object.op_Implicit((Object)(object)value))
				{
					value.Release();
					Object.Destroy((Object)(object)value);
				}
			}
			effects.Clear();
			particles?.Clear();
			Array.Clear(itemPalettes, 0, itemPalettes.Length);
		}

		private void OnDestroy()
		{
			Clear();
			Active.Remove(this);
			GameObject[] array = bodyControllers;
			foreach (GameObject val in array)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					Object.Destroy((Object)(object)val);
				}
			}
		}

		internal static void Shutdown()
		{
			EquipmentGlow[] array = Active.ToArray();
			foreach (EquipmentGlow equipmentGlow in array)
			{
				if (Object.op_Implicit((Object)(object)equipmentGlow))
				{
					equipmentGlow.Clear();
					Object.Destroy((Object)(object)equipmentGlow);
				}
			}
			Active.Clear();
			SurfaceDraw.Shutdown();
			SurfaceMeshData.Clear();
			GearVfxResolver.Clear();
		}

		internal static void RefreshLocal()
		{
			GlowAssets.Retry();
			PaletteResolver.Clear();
			GearVfxResolver.Clear();
			foreach (EquipmentGlow item in Active)
			{
				if (Object.op_Implicit((Object)(object)item))
				{
					item.failed = false;
					item.Clear();
					item.nextScan = 0f;
				}
			}
		}

		internal static string Status()
		{
			EquipmentGlow local = Active.FirstOrDefault((EquipmentGlow component) => Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.player) && (Object)(object)component.player == (Object)(object)Player.m_localPlayer);
			string text = "Jewelcraft 0.8.5 | " + Settings.Style.Value.ToString() + " | enabled=" + Settings.Glow.Value + " | shader=" + GlowAssets.ShaderStatus;
			if (!Object.op_Implicit((Object)(object)local))
			{
				return text + " | player not ready";
			}
			List<string> list = new List<string>();
			for (int num = 0; num < Items.Length; num++)
			{
				object? value = Items[num].GetValue(local.player);
				ItemData val = (ItemData)((value is ItemData) ? value : null);
				if (val != null)
				{
					list.Add(Texts.Name(val) + " +" + Enhancement.Level(val) + " [" + GearVfxResolver.Resolve(PrefabName(local.equippedHashes[num])).ToString() + "]");
				}
			}
			int num2 = local.effects.Values.Where((JewelGlow effect) => Object.op_Implicit((Object)(object)effect)).Sum((JewelGlow effect) => effect.SurfaceCount);
			IEnumerable<string> values = (from effect in local.effects.Values
				where Object.op_Implicit((Object)(object)effect)
				select effect.PaletteStatus).Distinct();
			IEnumerable<string> values2 = from component in Active.Where((EquipmentGlow component) => Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.stand) && component.effects.Count > 0).OrderBy(delegate(EquipmentGlow component)
				{
					//IL_0006: Unknown result type (might be due to invalid IL or missing references)
					//IL_0016: Unknown result type (might be due to invalid IL or missing references)
					//IL_001b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0020: Unknown result type (might be due to invalid IL or missing references)
					Vector3 val2 = ((Component)component).transform.position - ((Component)local).transform.position;
					return ((Vector3)(ref val2)).sqrMagnitude;
				}).Take(3)
				select component.particles.Status;
			return text + " | layers=" + num2 + " | emitters=" + local.particles.EmitterCount + " | stands=" + Active.Count((EquipmentGlow component) => Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.stand) && component.effects.Count > 0) + " | error=" + local.failed + " | " + string.Join(", ", list) + " | " + string.Join("; ", values) + " | particles=" + local.particles.Status + " | nearby displays=" + string.Join("; ", values2);
		}
	}
	internal static class EquipmentPalettePolicy
	{
		private static readonly Dictionary<string, GlowStyle> Assigned = Build();

		internal static bool TryGet(string prefab, out GlowStyle style)
		{
			style = GlowStyle.Auto;
			if (!string.IsNullOrEmpty(prefab))
			{
				return Assigned.TryGetValue(prefab, out style);
			}
			return false;
		}

		internal static bool IsUtility(string prefab)
		{
			if (!string.IsNullOrEmpty(prefab))
			{
				if (!prefab.StartsWith("Pickaxe", StringComparison.OrdinalIgnoreCase) && !prefab.Equals("KnifeButcher", StringComparison.OrdinalIgnoreCase) && !prefab.Equals("Hammer", StringComparison.OrdinalIgnoreCase) && !prefab.Equals("Hoe", StringComparison.OrdinalIgnoreCase) && !prefab.Equals("Cultivator", StringComparison.OrdinalIgnoreCase) && !prefab.Equals("FishingRod", StringComparison.OrdinalIgnoreCase) && !prefab.Equals("Scythe", StringComparison.OrdinalIgnoreCase))
				{
					return prefab.Equals("Torch", StringComparison.OrdinalIgnoreCase);
				}
				return true;
			}
			return false;
		}

		private static Dictionary<string, GlowStyle> Build()
		{
			Dictionary<string, GlowStyle> result = new Dictionary<string, GlowStyle>(StringComparer.OrdinalIgnoreCase);
			Add(GlowStyle.Gold, "ArmorRagsChest ArmorRagsLegs ArmorLeatherChest ArmorLeatherLegs HelmetLeather CapeDeerHide ArmorBronzeChest ArmorBronzeLegs HelmetBronze");
			Add(GlowStyle.Azure, "ArmorTrollLeatherChest ArmorTrollLeatherLegs HelmetTrollLeather CapeTrollHide ArmorWolfChest ArmorWolfLegs HelmetDrake CapeWolf");
			Add(GlowStyle.Pearl, "ArmorIronChest ArmorIronLegs HelmetIron ArmorPaddedCuirass ArmorPaddedGreaves HelmetPadded CapeLinen ArmorCarapaceChest ArmorCarapaceLegs HelmetCarapace");
			Add(GlowStyle.Emerald, "ArmorRootChest ArmorRootLegs HelmetRoot");
			Add(GlowStyle.Violet, "ArmorFenringChest ArmorFenringLegs HelmetFenring ArmorBerserkerUndeadChest ArmorBerserkerUndeadLegs HelmetBerserkerUndead CapeOdin HelmetOdin");
			Add(GlowStyle.Gold, "ArmorAshlandsMediumChest ArmorAshlandsMediumlegs HelmetAshlandsMediumHood CapeAsksvin ArmorBerserkerChest ArmorBerserkerLegs HelmetBerserkerHood ArmorLoxChest ArmorLoxLegs HelmetLox CapeLox");
			Add(GlowStyle.Ember, "ArmorFlametalChest ArmorFlametalLegs HelmetFlametal CapeAsh");
			Add(GlowStyle.Rose, "ArmorMageChest ArmorMageLegs HelmetMage CapeFeather ArmorMageChest_Ashlands ArmorMageLegs_Ashlands HelmetMage_Ashlands");
			Add(GlowStyle.Gold, "ArmorDeepNorthHeavyChest ArmorDeepNorthHeavylegs HelmetDNHeavy CapeDeepNorth HelmetCrownofValheim HelmetCelebration HelmetPointyHat HelmetStrawHat");
			Add(GlowStyle.Azure, "ArmorDeepNorthMageChest ArmorDeepNorthMagelegs HelmetDNMage CapeDeepNorthMage HelmetFishingHat");
			Add(GlowStyle.Emerald, "ArmorDeepNorthMediumChest ArmorDeepNorthMediumlegs HelmetDNMediumHood HelmetMidsummerCrown ArmorHarvester1 ArmorHarvester2");
			GlowStyle[] array = new GlowStyle[10]
			{
				GlowStyle.Gold,
				GlowStyle.Azure,
				GlowStyle.Ember,
				GlowStyle.Emerald,
				GlowStyle.Violet,
				GlowStyle.Pearl,
				GlowStyle.Rose,
				GlowStyle.Gold,
				GlowStyle.Azure,
				GlowStyle.Emerald
			};
			for (int i = 1; i <= array.Length; i++)
			{
				Add(array[i - 1], "ArmorDress" + i + " ArmorTunic" + i + " HelmetHat" + i);
			}
			Add(GlowStyle.Gold, "Club Bow BowFineWood BowHuntsman ShieldWood ShieldWoodTower ShieldBronzeBuckler AtgeirBronze AxeBronze KnifeCopper MaceBronze SpearBronze SwordBronze SledgeStagbreaker SpearElderbark");
			Add(GlowStyle.Pearl, "AxeStone AxeFlint AxeEarly KnifeFlint SpearFlint ShieldBoneTower ShieldBanded ShieldIronBuckler ShieldIronSquare ShieldIronTower AtgeirIron AxeIron Battleaxe MaceIron SledgeIron SwordIron CrossbowArbalest");
			Add(GlowStyle.Azure, "ShieldSilver KnifeSilver MaceSilver SpearWolfFang SwordSilver BattleaxeCrystal SwordMistwalker AtgeirHimminAfl StaffIceShards");
			Add(GlowStyle.Emerald, "ShieldBlackmetal ShieldBlackmetalTower ShieldSerpentscale AtgeirBlackmetal AxeBlackMetal BattleaxeBlackmetal KnifeBlackMetal MaceNeedle SwordBlackmetal BowDraugrFang AxeJotunBane StaffGreenRoots ShieldRoots");
			Add(GlowStyle.Pearl, "SpearChitin KnifeChitin ShieldCarapace ShieldCarapaceBuckler SpearCarapace SledgeDemolisher");
			Add(GlowStyle.Violet, "KnifeSkollAndHati FistFenrirClaw BowSpineSnap StaffSkeleton KnifeVoid FistBjornUndeadClaw");
			Add(GlowStyle.Gold, "FistBjornClaw BattleaxeSkullSplittur");
			Add(GlowStyle.Ember, "ShieldFlametal ShieldFlametalTower SwordDyrnwyn StaffFireball StaffClusterbomb StaffRedTroll SwordNiedhogg MaceEldner AxeBerzerkr SpearSplitner BowAshlands CrossbowRipper ShieldCore");
			Add(GlowStyle.Rose, "StaffShield SwordNiedhoggBlood MaceEldnerBlood AxeBerzerkrBlood SpearSplitner_Blood BowAshlandsBlood CrossbowRipperBlood");
			Add(GlowStyle.Azure, "SwordNiedhoggLightning MaceEldnerLightning AxeBerzerkrLightning SpearSplitner_Lightning BowAshlandsStorm CrossbowRipperLightning StaffLightning StaffFrostOrbs StaffFrostOrbsUncooked");
			Add(GlowStyle.Emerald, "SwordNiedhoggNature MaceEldnerNature AxeBerzerkrNature SpearSplitner_Nature BowAshlandsRoot CrossbowRipperNature");
			Add(GlowStyle.Rose, "StaffThunderBlood StaffThunderbloodUncooked");
			Add(GlowStyle.Violet, "StaffOrbofAhri StaffOrbofAhriUncooked");
			Add(GlowStyle.Pearl, "StaffSpiritCaller StaffSpiritCallerUncooked");
			Add(GlowStyle.Gold, "ShieldGoldBuckler ShieldBucklerGoldUncooked ShieldGold ShieldRoundGoldUncooked ShieldGoldTower ShieldTowerGoldUncooked");
			string[] array2 = new string[11]
			{
				"Atgeir", "Axe", "Battleaxe", "Bow", "Crossbow", "Fist", "Knife", "Mace", "Sledge", "Spear",
				"Sword"
			};
			foreach (string text in array2)
			{
				Add(GlowStyle.Gold, text + "Gold " + text + "GoldUncooked");
				Add(GlowStyle.Rose, text + "Gold_BloodLightning");
				Add(GlowStyle.Azure, text + "Gold_FrostFire");
			}
			Add(GlowStyle.Gold, "AtgeirWood AxeWood BattleaxeWood KnifeWood MaceWood SledgeWood SpearWood SwordWood");
			return result;
			void Add(GlowStyle color, string names)
			{
				string[] array3 = names.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
				foreach (string key in array3)
				{
					result.Add(key, color);
				}
			}
		}
	}
	internal sealed class EquipmentParticles
	{
		private sealed class Group
		{
			internal int Level;

			internal GlowPalette Palette;

			internal float Intensity;

			internal GearVfxEffects Effects;

			internal GameObject[] Roots;

			internal SkinnedMeshRenderer Body;

			internal Texture MaskSource;

			internal GlowAssets.ClothingMask Mask;

			internal Renderer[] Sources = Array.Empty<Renderer>();

			internal readonly List<SurfaceParticleEmitter> Emitters = new List<SurfaceParticleEmitter>();

			internal readonly List<Material> Materials = new List<Material>();
		}

		private readonly Transform host;

		private readonly Dictionary<int, Group> groups = new Dictionary<int, Group>();

		private readonly HashSet<int> desired = new HashSet<int>();

		internal int EmitterCount => groups.Values.Sum((Group g) => g.Emitters.Count);

		internal string Status => string.Join(", ", from pair in groups
			orderby pair.Key
			select "slot" + pair.Key + " +" + pair.Value.Level + " " + pair.Value.Effects.ToString() + " live=" + string.Join("/", pair.Value.Emitters.Select((SurfaceParticleEmitter e) => (Object.op_Implicit((Object)(object)e.System) ? e.System.particleCount : 0).ToString())));

		internal EquipmentParticles(Transform owner)
		{
			host = owner;
		}

		internal void Begin()
		{
			desired.Clear();
		}

		internal void Set(int slot, int level, GearVfxTier tier, GlowPalette palette, GameObject[] roots, SkinnedMeshRenderer body, Texture clothing)
		{
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			GearVfxEffects gearVfxEffects = GearVfxPolicy.EffectsFor(tier, level, Settings.Sparkles.Value, Settings.Mist.Value);
			if (gearVfxEffects == GearVfxEffects.None)
			{
				return;
			}
			if (slot != 3 && slot != 4)
			{
				body = null;
				clothing = null;
			}
			desired.Add(slot);
			if (groups.TryGetValue(slot, out var value))
			{
				if (value.Level == level && value.Palette == palette && (Object)(object)value.Body == (Object)(object)body && (Object)(object)value.MaskSource == (Object)(object)clothing && value.Effects == gearVfxEffects && value.Intensity == Settings.GlowIntensity.Value && value.Roots.SequenceEqual(roots))
				{
					return;
				}
				Release(value);
				groups.Remove(slot);
			}
			Group group = new Group
			{
				Level = level,
				Palette = palette,
				Roots = roots,
				Body = body,
				MaskSource = clothing,
				Effects = gearVfxEffects,
				Intensity = Settings.GlowIntensity.Value
			};
			groups[slot] = group;
			List<Renderer> list = (from r in roots.SelectMany((GameObject r) => r.GetComponentsInChildren<Renderer>(true))
				where !(r is ParticleSystemRenderer) && !Object.op_Implicit((Object)(object)((Component)r).GetComponent<GlowOverlay>()) && r.sharedMaterials.Any(PaletteResolver.Solid)
				select r).Distinct().ToList();
			List<SurfaceSite> list2 = new List<SurfaceSite>();
			foreach (Renderer item in list)
			{
				Material[] materials = item.sharedMaterials;
				list2.AddRange(SurfaceSite.Sample(item, null, (int num3) => materials.Length != 0 && PaletteResolver.Solid(materials[Mathf.Min(num3, materials.Length - 1)])));
			}
			if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)clothing))
			{
				group.Mask = GlowAssets.AcquireMask(clothing);
				if (group.Mask != null)
				{
					list.Add((Renderer)(object)body);
					list2.AddRange(SurfaceSite.Sample((Renderer)(object)body, (Vector2 uv) => group.Mask.Covers(uv)));
				}
			}
			group.Sources = list.ToArray();
			if (list2.Count == 0)
			{
				Plugin.Warn("No readable covered surface for equipment particles in slot " + slot + ". Surface glow remains active.");
				return;
			}
			Random random = new Random(103 + slot);
			for (int num = list2.Count - 1; num > 0; num--)
			{
				int index = random.Next(num + 1);
				SurfaceSite value2 = list2[num];
				list2[num] = list2[index];
				list2[index] = value2;
			}
			SurfaceSite[] points = list2.ToArray();
			bool flag = slot == 2;
			bool[] array = new bool[2] { false, true };
			foreach (bool flag2 in array)
			{
				if (((uint)gearVfxEffects & (uint)((!flag2) ? 1 : 2)) != 0)
				{
					Material val = (flag2 ? GlowAssets.MistMaterial() : GlowAssets.SparkMaterial());
					group.Materials.Add(val);
					int budget = SurfaceParticleEmitter.Budget(slot, flag2);
					float rate = SurfaceParticleEmitter.Rate(slot, flag2);
					SurfaceParticleEmitter surfaceParticleEmitter = new SurfaceParticleEmitter(host, val, PaletteResolver.UnityColor(flag2 ? palette.Primary : GearVfxPolicy.Accent(palette.Family)), GearVfxPolicy.Strength(level) * group.Intensity * ((flag2 && flag) ? 0.65f : 1f), flag2, points, budget, rate, (uint)(701 + slot * 31 + (flag2 ? 13 : 0)));
					((Component)surfaceParticleEmitter.System).gameObject.AddComponent<GlowOverlay>();
					group.Emitters.Add(surfaceParticleEmitter);
				}
			}
		}

		internal void End()
		{
			int[] array = groups.Keys.ToArray();
			foreach (int num in array)
			{
				if (!desired.Contains(num))
				{
					Release(groups[num]);
					groups.Remove(num);
				}
			}
		}

		internal void Tick()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			int num;
			if (Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				Vector3 val = host.position - ((Component)Player.m_localPlayer).transform.position;
				num = ((((Vector3)(ref val)).sqrMagnitude <= 900f) ? 1 : 0);
			}
			else
			{
				num = 0;
			}
			bool flag = (byte)num != 0;
			foreach (Group value in groups.Values)
			{
				bool active = flag && value.Sources.Any((Renderer r) => Object.op_Implicit((Object)(object)r) && r.enabled && !r.forceRenderingOff && ((Component)r).gameObject.activeInHierarchy && r.isVisible);
				foreach (SurfaceParticleEmitter emitter in value.Emitters)
				{
					emitter.Tick(Time.time, active);
				}
			}
		}

		private static void Release(Group group)
		{
			foreach (SurfaceParticleEmitter emitter in group.Emitters)
			{
				emitter.Dispose();
			}
			foreach (Material material in group.Materials)
			{
				if (Object.op_Implicit((Object)(object)material))
				{
					Object.Destroy((Object)(object)material);
				}
			}
			GlowAssets.ReleaseMask(group.Mask);
		}

		internal void Clear()
		{
			foreach (Group value in groups.Values)
			{
				Release(value);
			}
			groups.Clear();
			desired.Clear();
		}
	}
	internal static class ForgeMenu
	{
		private static InventoryGui owner;

		private static RectTransform modeBar;

		private static RectTransform viewport;

		private static Vector2 viewportTop;

		private static Button qualityButton;

		private static Button gemsButton;

		private static bool gemsMode;

		private static bool controlsVisible;

		private static readonly Dictionary<ItemData, Recipe> recipes = new Dictionary<ItemData, Recipe>();

		private static readonly RefinementSession attempt = new RefinementSession();

		private static ItemData quotedItem;

		private static int quotedLevel;

		private static float nextRefresh;

		private static string status = "";

		private static readonly List<ItemData> shownItems = new List<ItemData>();

		private static readonly List<string> shownLevels = new List<string>();

		private static int shownBless;

		private static int shownSoul;

		private static bool shownUsable;

		private static List<ItemData> Equipment(Player player)
		{
			return (from i in ((Humanoid)player).GetInventory().GetAllItems()
				where Enhancement.Eligible(i) && Object.op_Implicit((Object)(object)i.m_dropPrefab)
				orderby i.m_gridPos.y, i.m_gridPos.x
				select i).ToList();
		}

		private static string StoredLevel(ItemData item)
		{
			if (!item.m_customData.TryGetValue("com.enoq.jewelcraft.level.v1", out var value))
			{
				return "0";
			}
			return value;
		}

		private static bool Context(InventoryGui gui)
		{
			if (Object.op_Implicit((Object)(object)gui) && gui.InUpradeTab())
			{
				return RefinementSession.AtWorkbench(Player.m_localPlayer);
			}
			return false;
		}

		private static bool IsProxy(Recipe recipe)
		{
			if (Object.op_Implicit((Object)(object)recipe))
			{
				return ((Object)recipe).name.StartsWith("Jewelcraft_UI_", StringComparison.Ordinal);
			}
			return false;
		}

		internal static bool OwnsSelection(InventoryGui gui)
		{
			if (Object.op_Implicit((Object)(object)gui))
			{
				if (!gemsMode || !((Object)(object)owner == (Object)(object)gui))
				{
					return IsProxy(NativeCrafting.Recipe(gui));
				}
				return true;
			}
			return false;
		}

		internal static bool OwnsCraft(InventoryGui gui)
		{
			if (Object.op_Implicit((Object)(object)gui))
			{
				if (!OwnsSelection(gui))
				{
					return IsProxy(NativeCrafting.PendingRecipe(gui));
				}
				return true;
			}
			return false;
		}

		private static void Ensure(InventoryGui gui)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)owner == (Object)(object)gui) || !Object.op_Implicit((Object)(object)modeBar))
			{
				Close();
				owner = gui;
				viewport = (RectTransform)((Transform)gui.m_recipeListRoot).parent;
				modeBar = new GameObject("JewelcraftUpgradeModes", new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>();
				((Transform)modeBar).SetParent(((Transform)viewport).parent, false);
				RectTransform obj = modeBar;
				RectTransform obj2 = modeBar;
				RectTransform obj3 = modeBar;
				Vector2 val = default(Vector2);
				((Vector2)(ref val))..ctor(0f, 1f);
				obj3.pivot = val;
				Vector2 anchorMin = (obj2.anchorMax = val);
				obj.anchorMin = anchorMin;
				modeBar.anchoredPosition = Vector2.zero;
				RectTransform obj4 = modeBar;
				Rect rect = viewport.rect;
				obj4.sizeDelta = new Vector2(((Rect)(ref rect)).width, 30f);
				qualityButton = ModeButton(gui.m_tabCraft, "Quality", 0f, delegate
				{
					SetMode(gems: false);
				});
				gemsButton = ModeButton(gui.m_tabCraft, "Gems", 0.5f, delegate
				{
					SetMode(gems: true);
				});
				((Component)modeBar).gameObject.SetActive(false);
			}
		}

		private static Button ModeButton(Button template, string name, float x, Action action)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			Button val = Object.Instantiate<Button>(template, (Transform)(object)modeBar, false);
			((Object)val).name = "Jewelcraft" + name;
			val.onClick = new ButtonClickedEvent();
			((UnityEvent)val.onClick).AddListener((UnityAction)delegate
			{
				action();
			});
			ButtonTextColor component = ((Component)val).GetComponent<ButtonTextColor>();
			if (Object.op_Implicit((Object)(object)component))
			{
				((Behaviour)component).enabled = false;
			}
			Transform val2 = ((Component)val).transform.Find("Text");
			Transform val3 = ((Component)val).transform.Find("Selected");
			if (Object.op_Implicit((Object)(object)val3))
			{
				TMP_Text[] componentsInChildren = ((Component)val3).GetComponentsInChildren<TMP_Text>(true);
				for (int num = 0; num < componentsInChildren.Length; num++)
				{
					((Component)componentsInChildren[num]).gameObject.SetActive(false);
				}
			}
			if (Object.op_Implicit((Object)(object)val2))
			{
				val2.SetAsLastSibling();
			}
			Transform val4 = ((Component)val).transform.Find("gamepad_hint");
			if (Object.op_Implicit((Object)(object)val4))
			{
				((Component)val4).gameObject.SetActive(false);
				Object.Destroy((Object)(object)((Component)val4).gameObject);
			}
			UIGamePad component2 = ((Component)val).GetComponent<UIGamePad>();
			UIGamePad component3 = ((Component)owner.m_variantButton).GetComponent<UIGamePad>();
			if (Object.op_Implicit((Object)(object)component2))
			{
				component2.m_zinputKey = "JoyButtonA";
				component2.m_keyCode = (KeyCode)0;
				component2.m_hint = null;
				if (Object.op_Implicit((Object)(object)component3) && Object.op_Implicit((Object)(object)component3.m_hint))
				{
					component2.m_hint = Object.Instantiate<GameObject>(component3.m_hint, ((Component)val).transform, false);
					((Object)component2.m_hint).name = "JewelcraftModeHint";
					RectTransform component4 = component2.m_hint.GetComponent<RectTransform>();
					Vector2 val5 = default(Vector2);
					((Vector2)(ref val5))..ctor(0f, 0.5f);
					component4.pivot = val5;
					Vector2 anchorMin = (component4.anchorMax = val5);
					component4.anchorMin = anchorMin;
					component4.anchoredPosition = new Vector2(3f, 0f);
					component4.sizeDelta = new Vector2(22f, 22f);
					component2.m_hint.SetActive(false);
				}
			}
			RectTransform component5 = ((Component)val).GetComponent<RectTransform>();
			component5.anchorMin = new Vector2(x, 0f);
			component5.anchorMax = new Vector2(x + 0.5f, 1f);
			component5.pivot = new Vector2(0.5f, 0.5f);
			component5.offsetMin = new Vector2(1f, 1f);
			component5.offsetMax = new Vector2(-1f, -1f);
			((Component)val).gameObject.SetActive(true);
			return val;
		}

		private static void ModeLabel(Button button, string label, bool selected, bool busy)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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_0077: 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)
			TMP_Text component = ((Component)((Component)button).transform.Find("Text")).GetComponent<TMP_Text>();
			component.text = label;
			component.enableAutoSizing = true;
			component.fontSizeMin = 12f;
			component.fontSizeMax = 18f;
			((Graphic)component).color = (selected ? new Color(1f, 0.83f, 0.49f) : new Color(1f, 0.7f, 0.32f));
			Vector2 offsetMin = component.rectTransform.offsetMin;
			offsetMin.x = (ZInput.IsGamepadActive() ? 22 : 0);
			component.rectTransform.offsetMin = offsetMin;
			((Selectable)button).interactable = !selected && !busy;
			Transform val = ((Component)button).transform.Find("Selected");
			if (Object.op_Implicit((Object)(object)val))
			{
				((Component)val).gameObject.SetActive(selected);
			}
		}

		internal static void SyncControls(InventoryGui gui)
		{
			if (!Context(gui))
			{
				if ((Object)(object)owner == (Object)(object)gui)
				{
					if (gemsMode)
					{
						Leave(rebuild: true);
					}
					ShowControls(show: false);
				}
			}
			else
			{
				Ensure(gui);
				ShowControls(show: true);
				bool busy = NativeCrafting.Timer.Invoke(gui) >= 0f || attempt.Pending;
				ModeLabel(qualityButton, Texts.T("Calidad", "Quality"), !gemsMode, busy);
				ModeLabel(gemsButton, Texts.T("Gemas", "Gems"), gemsMode, busy);
			}
		}

		private static void ShowControls(bool show)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)modeBar) && show != controlsVisible)
			{
				if (show)
				{
					viewportTop = viewport.offsetMax;
					viewport.offsetMax = viewportTop - new Vector2(0f, 34f);
				}
				else if (Object.op_Implicit((Object)(object)viewport))
				{
					viewport.offsetMax = viewportTop;
				}
				controlsVisible = show;
				((Component)modeBar).gameObject.SetActive(show);
			}
		}

		private static void SetMode(bool gems)
		{
			if (Context(owner) && !(NativeCrafting.Timer.Invoke(owner) >= 0f) && gemsMode != gems)
			{
				Cancel();
				quotedItem = null;
				status = "";
				NativeCrafting.Deselect(owner);
				gemsMode = gems;
				if (!gems)
				{
					RestoreButtonLabel();
				}
				NativeCrafting.Rebuild(owner);
				if (!gems)
				{
					ReleaseRecipes();
				}
				SyncControls(owner);
			}
		}

		internal static bool BuildList(InventoryGui gui)
		{
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)owner != (Object)(object)gui || !gemsMode)
			{
				return false;
			}
			if (!Context(gui))
			{
				Leave(rebuild: false);
				return false;
			}
			Player localPlayer = Player.m_localPlayer;
			NativeCrafting.ClearRows(gui);
			List<ItemData> list = Equipment(localPlayer);
			bool flag = RefinementSession.IsUsable(localPlayer);
			foreach (ItemData item in list)
			{
				ItemDrop component = item.m_dropPrefab.GetComponent<ItemDrop>();
				if (Object.op_Implicit((Object)(object)component))
				{
					if (!recipes.TryGetValue(item, out var value))
					{
						value = ScriptableObject.CreateInstance<Recipe>();
						((Object)value).name = "Jewelcraft_UI_" + recipes.Count;
						value.m_item = component;
						value.m_amount = 1;
						recipes.Add(item, value);
					}
					int level;
					bool flag2 = Rules.TryRead(item.m_customData, out level);
					bool flag3 = flag && flag2 && level < 9 && Enhancement.FindGem(((Humanoid)localPlayer).GetInventory(), Rules.RequiredGem(level)) != null;
					NativeCrafting.AddRow(gui, localPlayer, value, item, flag3);
					IList list2 = NativeCrafting.Rows(gui);
					GameObject obj = NativeCrafting.Element(list2[list2.Count - 1]);
					Image component2 = ((Component)obj.transform.Find("icon")).GetComponent<Image>();
					component2.sprite = item.GetIcon();
					((Graphic)component2).color = (Color)(flag3 ? Color.white : new Color(1f, 1f, 1f, 0.65f));
					((Component)obj.transform.Find("QualityLevel")).GetComponent<TMP_Text>().text = (flag2 ? ("+" + level) : "?");
				}
			}
			RectTransform recipeListRoot = gui.m_recipeListRoot;
			Rect rect = viewport.rect;
			recipeListRoot.SetSizeWithCurrentAnchors((Axis)1, Mathf.Max(((Rect)(ref rect)).height, (float)NativeCrafting.Rows(gui).Count * gui.m_recipeListSpace));
			nextRefresh = Time.unscaledTime + 0.4f;
			shownItems.Clear();
			shownItems.AddRange(list);
			shownLevels.Clear();
			shownLevels.AddRange(list.Select(StoredLevel));
			shownBless = Enhancement.Count(((Humanoid)localPlayer).GetInventory(), Gem.Bless);
			shownSoul = Enhancement.Count(((Humanoid)localPlayer).GetInventory(), Gem.Soul);
			shownUsable = flag;
			return true;
		}

		internal static bool UpdateRecipe(InventoryGui gui, Player player, float dt)
		{
			//IL_05b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ed: Expected O, but got Unknown
			SyncControls(gui);
			if ((Object)(object)owner != (Object)(object)gui || !gemsMode || !Context(gui))
			{
				return false;
			}
			if (Time.unscaledTime >= nextRefresh)
			{
				nextRefresh = Time.unscaledTime + 0.4f;
				List<ItemData> list = Equipment(player);
				if (!shownItems.SequenceEqual(list) || !shownLevels.SequenceEqual(list.Select(StoredLevel)) || shownBless != Enhancement.Count(((Humanoid)player).GetInventory(), Gem.Bless) || shownSoul != Enhancement.Count(((Humanoid)player).GetInventory(), Gem.Soul) || shownUsable != RefinementSession.IsUsable(player))
				{
					NativeCrafting.Rebuild(gui);
				}
			}
			ItemData val = NativeCrafting.Item(gui);
			if (quotedItem != val)
			{
				status = "";
			}
			if (attempt.Pending && (!attempt.Valid(player) || val != attempt.Item || NativeCrafting.Timer.Invoke(gui) < 0f))
			{
				Cancel();
				status = Texts.T("Refinamiento cancelado. No se consumió ninguna gema.", "Refinement canceled. No gem was consumed.");
			}
			quotedItem = val;
			CraftingStation currentCraftingStation = player.GetCurrentCraftingStation();
			gui.m_craftingStationName.text = Localization.instance.Localize(currentCraftingStation.m_name);
			((Component)gui.m_craftingStationIcon).gameObject.SetActive(true);
			gui.m_craftingStationIcon.sprite = currentCraftingStation.m_icon;
			((Component)gui.m_craftingStationLevelRoot).gameObject.SetActive(true);
			gui.m_craftingStationLevel.text = currentCraftingStation.GetLevel(true).ToString();
			((Component)gui.m_qualityPanel).gameObject.SetActive(false);
			((Component)gui.m_variantButton).gameObject.SetActive(false);
			((Component)gui.m_minStationLevelIcon).gameObject.SetActive(false);
			GameObject[] recipeRequirementList = gui.m_recipeRequirementList;
			for (int i = 0; i < recipeRequirementList.Length; i++)
			{
				InventoryGui.HideRequirement(recipeRequirementList[i].transform);
			}
			((Behaviour)gui.m_recipeIcon).enabled = val != null;
			TMP_Text recipeName = gui.m_recipeName;
			bool enabled = (((Behaviour)gui.m_recipeDecription).enabled = true);
			((Behaviour)recipeName).enabled = enabled;
			((Component)gui.m_itemCraftType).gameObject.SetActive(val != null);
			((Selectable)gui.m_craftButton).interactable = false;
			((Component)gui.m_craftButton).GetComponentInChildren<TMP_Text>().text = Texts.T("Refinar", "Refine");
			string text = "";
			if (val == null)
			{
				gui.m_recipeName.text = Texts.T("Refinar con gemas", "Gem refinement");
				gui.m_recipeDecription.text = Texts.T("Lleva un arma, escudo o armadura en tu inventario.\n\nBless: +1 a +6\nSoul: +7 a +9", "Carry a weapon, shield, or armor in your inventory.\n\nBless: +1 to +6\nSoul: +7 to +9");
			}
			else
			{
				gui.m_recipeIcon.sprite = val.GetIcon();
				bool flag2 = Rules.TryRead(val.m_customData, out quotedLevel);
				gui.m_recipeName.text = Texts.Name(val) + (flag2 ? ("  +" + quotedLevel) : "");
				gui.m_itemCraftType.text = Texts.T("Refinamiento", "Refinement") + (flag2 ? ("  +" + quotedLevel + ((quotedLevel < 9) ? (" → +" + (quotedLevel + 1)) : "")) : "");
				if (!flag2)
				{
					text = Texts.T("Datos de mejora desconocidos; objeto conservado.", "Unknown enhancement data; item preserved.");
				}
				else if (quotedLevel == 9)
				{
					text = Texts.T("Refinamiento máximo: +9.", "Maximum refinement: +9.");
				}
				else
				{
					Gem gem = Rules.RequiredGem(quotedLevel);
					GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(Gems.Prefab(gem));
					if (Object.op_Implicit((Object)(object)itemPrefab) && gui.m_recipeRequirementList.Length != 0)
					{
						Requirement val2 = new Requirement
						{
							m_resItem = itemPrefab.GetComponent<ItemDrop>(),
							m_amount = 1
						};
						InventoryGui.SetupRequirement(gui.m_recipeRequirementList[0].transform, val2, player, true, 1, 1);
					}
					if (!RefinementSession.IsUsable(player))
					{
						text = Texts.T("El banco necesita techo, protección y estar a tu alcance.", "The workbench must be sheltered and within reach.");
					}
					else if (Enhancement.FindGem(((Humanoid)player).GetInventory(), gem) == null)
					{
						text = Texts.T("Necesitas una joya de ", "Requires one jewel of ") + gem.ToString() + ".";
					}
					((Selectable)gui.m_craftButton).interactable = !attempt.Pending && RefinementSession.CanAttempt(player, val, quotedLevel);
				}
				gui.m_recipeDecription.text = Description(val, flag2, quotedLevel, text);
			}
			UITooltip component = ((Component)gui.m_craftButton).GetComponent<UITooltip>();
			if (Object.op_Implicit((Object)(object)component))
			{
				component.m_text = text;
			}
			((Component)gui.m_craftButton).gameObject.SetActive(!attempt.Pending);
			((Component)gui.m_craftProgressPanel).gameObject.SetActive(attempt.Pending);
			if (attempt.Pending)
			{
				float num = Mathf.Max(0.5f, gui.m_craftDuration);
				NativeCrafting.Timer.Invoke(gui) += Mathf.Max(0f, dt);
				gui.m_craftProgressBar.SetMaxValue(num);
				gui.m_craftProgressBar.SetValue(NativeCrafting.Timer.Invoke(gui));
				if (NativeCrafting.Timer.Invoke(gui) >= num)
				{
					ItemData item = attempt.Item;
					int level = attempt.Level;
					NativeCrafting.Timer.Invoke(gui) = -1f;
					status = attempt.Complete(player);
					((Character)player).Message((MessageType)2, status, 0, (Sprite)null, false);
					if (Enhancement.Level(item) > level)
					{
						currentCraftingStation.m_craftItemDoneEffects.Create(((Component)player).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
					}
					NativeCrafting.Rebuild(gui);
				}
			}
			return true;
		}

		private static string Description(ItemData item, bool known, int level, string reason)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected I4, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Invalid comparison between Unknown and I4
			string text = Localization.instance.Localize("$item_quality") + ": " + item.m_quality + Texts.T(" (se conserva)", " (unchanged)");
			if (!known || level >= 9)
			{
				return text + "\n\n" + reason + ((status.Length > 0) ? ("\n\n" + status) : "");
			}
			ItemType itemType = item.m_shared.m_itemType;
			string text2;
			float value;
			switch (itemType - 5)
			{
			default:
				if ((int)itemType == 17)
				{
					goto case 1;
				}
				goto case 3;
			case 0:
				text2 = Texts.T("Bloqueo", "Block power");
				value = Settings.Block.Value;
				break;
			case 1:
			case 2:
			case 6:
				text2 = Texts.T("Armadura", "Armor");
				value = Settings.Armor.Value;
				break;
			case 3:
			case 4:
			case 5:
				text2 = Texts.T("Daño", "Damage");
				value = Settings.Damage.Value;
				break;
			}
			return text + "\n\n<color=orange>" + Texts.T("Refinamiento", "Refinement") + $"  +{level} → +{level + 1}</color>\n" + text2 + $": +{(float)level * value:P0} → +{(float)(level + 1) * value:P0}\n" + Texts.T("Probabilidad de éxito: ", "Success chance: ") + Settings.Chance(level) + "%\n" + Texts.T("Coste: 1 joya de ", "Cost: 1 jewel of ") + Rules.RequiredGem(level).ToString() + "\n\n" + Texts.T("Si falla, consumes la gema y conservas el nivel.", "Failure consumes the gem and keeps the level.") + ((reason.Length > 0) ? ("\n\n" + reason) : "") + ((status.Length > 0) ? ("\n\n" + status) : "");
		}

		internal static bool Start(InventoryGui gui)
		{
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: 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)
			if (!OwnsSelection(gui))
			{
				return false;
			}
			Player localPlayer = Player.m_localPlayer;
			if (!Context(gui) || !InventoryGui.IsVisible() || quotedItem != NativeCrafting.Item(gui) || NativeCrafting.Timer.Invoke(gui) >= 0f || !attempt.Begin(localPlayer, quotedItem, quotedLevel))
			{
				return true;
			}
			status = "";
			NativeCrafting.Timer.Invoke(gui) = 0f;
			if (Object.op_Implicit((Object)(object)gui.CraftingVibration))
			{
				Object.Instantiate<GameObject>(gui.CraftingVibration);
			}
			localPlayer.GetCurrentCraftingStation().m_craftItemEffects.Create(((Component)localPlayer).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
			return true;
		}

		internal static void Cancel()
		{
			if (attempt.Pending && Object.op_Implicit((Object)(object)owner))
			{
				NativeCrafting.Timer.Invoke(owner) = -1f;
			}
			attempt.Cancel();
		}

		internal static void Leave(bool rebuild)
		{
			Cancel();
			quotedItem = null;
			status = "";
			bool flag = gemsMode;
			gemsMode = false;
			if (Object.op_Implicit((Object)(object)owner) && flag)
			{
				RestoreButtonLabel();
				NativeCrafting.Deselect(owner);
				NativeCrafting.ClearRows(owner);
				if (rebuild && Object.op_Implicit((Object)(object)Player.m_localPlayer))
				{
					NativeCrafting.Rebuild(owner);
				}
			}
			ReleaseRecipes();
		}

		private static void ReleaseRecipes()
		{
			foreach (Recipe value in recipes.Values)
			{
				if (Object.op_Implicit((Object)(object)value))
				{
					Object.Destroy((Object)(object)value);
				}
			}
			recipes.Clear();
			shownItems.Clear();
			shownLevels.Clear();
		}

		private static void RestoreButtonLabel()
		{
			if (Object.op_Implicit((Object)(object)owner))
			{
				((Component)owner.m_craftButton).GetComponentInChildren<TMP_Text>(true).text = Localization.instance.Localize("$inventory_upgradebutton");
			}
		}

		internal static void Hidden(InventoryGui gui)
		{
			if (!((Object)(object)owner != (Object)(object)gui))
			{
				Leave(rebuild: false);
				ShowControls(show: false);
			}
		}

		internal static void Tick()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)owner) && !InventoryGui.IsVisible())
			{
				Hidden(owner);
			}
			Player localPlayer = Player.m_localPlayer;
			if (!Object.op_Implicit((Object)(object)localPlayer))
			{
				return;
			}
			KeyboardShortcut value = Settings.Hotkey.Value;
			if (!((KeyboardShortcut)(ref value)).IsDown() || Console.IsVisible() || (Object.op_Implicit((Object)(object)Chat.instance) && Chat.instance.HasFocus()) || Menu.IsVisible() || TextInput.IsVisible())
			{
				return;
			}
			if (!InventoryGui.IsVisible() || !RefinementSession.AtWorkbench(localPlayer))
			{
				((Character)localPlayer).Message((MessageType)2, Texts.T("Abre el banco de trabajo y selecciona Mejorar → Gemas.", "Open the workbench and select Upgrade → Gems."), 0, (Sprite)null, false);
				return;
			}
			InventoryGui instance = InventoryGui.instance;
			if (!(NativeCrafting.Timer.Invoke(instance) >= 0f))
			{
				instance.OnTabUpgradePressed();
				Ensure(instance);
				SetMode(gems: true);
			}
		}

		internal static void Close()
		{
			Leave(rebuild: true);
			ShowControls(show: false);
			if (Object.op_Implicit((Object)(object)modeBar))
			{
				Object.Destroy((Object)(object)((Component)modeBar).gameObject);
			}
			modeBar = (viewport = null);
			qualityButton = (gemsButton = null);
			owner = null;
			controlsVisible = false;
		}
	}
	internal enum GearVfxTier
	{
		Basic,
		Glints,
		Mist
	}
	[Flags]
	internal enum GearVfxEffects
	{
		None = 0,
		Glints = 1,
		Mist = 2
	}
	internal static class GearVfxPolicy
	{
		private static readonly HashSet<string> Middle = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
		{
			"Iron", "Silver", "AncientBark", "Guck", "Root", "WolfPelt", "WolfFang", "WolfHairBundle", "FenringClaw", "WolfClaw",
			"ElderBark", "WrithanRoots", "Chitin", "Obsidian", "FreezeGland", "SerpentScale", "Chain", "Crystal", "Upgrader2Armor", "Upgrader2Weapon",
			"Upgrader3Armor", "Upgrader3Weapon"
		};

		private static readonly HashSet<string> High = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
		{
			"BlackMetal", "LinenThread", "LoxPelt", "Needle", "Tar", "YggdrasilWood", "Carapace", "Mandible", "ScaleHide", "Softtissue",
			"Eitr", "MechanicalSpring", "BlackCore", "BlackMarble", "GiantBloodSack", "Flametal", "FlametalNew", "Ashwood", "AskHide", "MorgenSinew",
			"BonemawSerpentTooth", "CharredBone", "Blackwood", "CelestialFeather", "GemstoneRed", "GemstoneBlue", "GemstoneGreen", "Gold", "NornThread", "MooseHide",
			"MooseSinew", "SealHide", "Frostwood", "ElakingHairBundle", "Upgrader4Armor", "Upgrader4Weapon", "Upgrader5Armor", "Upgrader5Weapon", "Upgrader6Armor", "Upgrader6Weapon",
			"Upgrader7Armor", "Upgrader7Weapon"
		};

		internal static GearVfxEffects EffectsFor(GearVfxTier tier, int level, bool sparkles, bool mist)
		{
			if (level <= 0 || tier == GearVfxTier.Basic)
			{
				return GearVfxEffects.None;
			}
			GearVfxEffects gearVfxEffects = (sparkles ? GearVfxEffects.Glints : GearVfxEffects.None);
			if (tier == GearVfxTier.Mist && mist)
			{
				gearVfxEffects |= GearVfxEffects.Mist;
			}
			return gearVfxEffects;
		}

		internal static GearVfxTier FromRecipe(IEnumerable<string> resources, string station)
		{
			if (string.Equals(station, "blackforge", StringComparison.OrdinalIgnoreCase) || string.Equals(station, "piece_magetable", StringComparison.OrdinalIgnoreCase))
			{
				return GearVfxTier.Mist;
			}
			GearVfxTier result = GearVfxTier.Basic;
			if (resources != null)
			{
				foreach (string resource in resources)
				{
					if (resource != null)
					{
						if (High.Contains(resource))
						{
							return GearVfxTier.Mist;
						}
						if (Middle.Contains(resource))
						{
							result = GearVfxTier.Glints;
						}
					}
				}
			}
			return result;
		}

		internal static GearVfxTier Override(string rules, string prefab, GearVfxTier fallback)
		{
			if (string.IsNullOrWhiteSpace(rules) || string.IsNullOrEmpty(prefab))
			{
				return fallback;
			}
			string[] array = rules.Split(new char[1] { ';' });
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split(new char[1] { '=' });
				if (array2.Length == 2 && array2[0].Trim().Equals(prefab, StringComparison.OrdinalIgnoreCase) && Enum.TryParse<GearVfxTier>(array2[1].Trim(), ignoreCase: true, out var result) && Enum.IsDefined(typeof(GearVfxTier), result))
				{
					fallback = result;
				}
			}
			return fallback;
		}

		internal static float Strength(int level)
		{
			if (level > 0)
			{
				return 0.18f + 0.82f * (float)Math.Min(9, level) / 9f;
			}
			return 0f;
		}

		internal static Rgb Accent(GlowStyle family)
		{
			(float, float, float) tuple = GlintPalette.Get(family.ToString());
			return new Rgb(tuple.Item1, tuple.Item2, tuple.Item3);
		}

		internal static int VisualSlot(int nativeSlot)
		{
			return nativeSlot switch
			{
				0 => 0, 
				1 => 1, 
				2 => 6, 
				3 => 7, 
				4 => 3, 
				5 => 4, 
				6 => 2, 
				7 => 5, 
				_ => -1, 
			};
		}
	}
	internal static class GearVfxResolver
	{
		private static readonly Dictionary<string, GearVfxTier> Cache = new Dictionary<string, GearVfxTier>();

		private static ObjectDB database;

		private static int recipeCount;

		internal static GearVfxTier Resolve(string prefab)
		{
			ObjectDB instance = ObjectDB.instance;
			if (!Object.op_Implicit((Object)(object)instance))
			{
				return GearVfxPolicy.Override(Settings.EquipmentVfxOverrides.Value, prefab, GearVfxTier.Basic);
			}
			if ((Object)(object)database != (Object)(object)instance || recipeCount != instance.m_recipes.Count)
			{
				Cache.Clear();
				database = instance;
				recipeCount = instance.m_recipes.Count;
				foreach (Recipe recipe in instance.m_recipes)
				{
					if (Object.op_Implicit((Object)(object)recipe) && Object.op_Implicit((Object)(object)recipe.m_item))
					{
						string name = ((Object)((Component)recipe.m_item).gameObject).name;
						GearVfxTier gearVfxTier = GearVfxPolicy.FromRecipe((from r in recipe.m_resources?.Where((Requirement r) => Object.op_Implicit((Object)(object)r?.m_resItem))
							select ((Object)((Component)r.m_resItem).gameObject).name), Object.op_Implicit((Object)(object)recipe.m_craftingStation) ? ((Object)((Component)recipe.m_craftingStation).gameObject).name : "");
						if (!Cache.TryGetValue(name, out var value) || gearVfxTier > value)
						{
							Cache[name] = gearVfxTier;
						}
					}
				}
			}
			Cache.TryGetValue(prefab, out var value2);
			return GearVfxPolicy.Override(Settings.EquipmentVfxOverrides.Value, prefab, value2);
		}

		internal static void Clear()
		{
			Cache.Clear();
			database = null;
			recipeCount = 0;
		}
	}
	internal static class Gems
	{
		private static bool registered;

		internal static string Prefab(Gem gem)
		{
			if (gem != Gem.Bless)
			{
				return "Enoq_JewelSoul";
			}
			return "Enoq_JewelBless";
		}

		internal static Color ColorOf(Gem gem)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (gem != Gem.Bless)
			{
				return new Color(0.4f, 0.65f, 0.82f);
			}
			return new Color(0.8f, 0.4f, 0.4f);
		}

		internal static void Register()
		{
			if (!registered)
			{
				Add(Gem.Bless, "Amber");
				Add(Gem.Soul, "Ruby");
				registered = true;
				PrefabManager.OnVanillaPrefabsAvailable -= Register;
			}
		}

		private static void Add(Gem gem, string original)
		{
			//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_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: 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_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Expected O, but got Unknown
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: 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_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Expected O, but got Unknown
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Expected O, but got Unknown
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			string text = ((gem == Gem.Bless) ? "jc_bless" : "jc_soul");
			GameObject val = null;
			Sprite val2 = null;
			try
			{
				val = GlowAssets.LoadBundledAsset<GameObject>("Assets/Jewelcraft/Gems/" + gem.ToString() + "-Visual.prefab");
				val2 = GlowAssets.LoadBundledAsset<Sprite>("Assets/Jewelcraft/Gems/" + gem.ToString() + "-Icon.png");
				if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2))
				{
					throw new InvalidOperationException("Incomplete gem assets: " + gem);
				}
			}
			catch (Exception ex)
			{
				val = null;
				val2 = null;
				Plugin.Warn("Using fallback gem visuals for " + gem.ToString() + ": " + ex.Message);
			}
			CustomItem val3 = new CustomItem(Prefab(gem), original, new ItemConfig
			{
				Name = "$" + text,
				Description = "$" + text + "_desc",
				StackSize = 50,
				Weight = 0.1f,
				Requirements = Array.Empty<RequirementConfig>(),
				Icon = (Object.op_Implicit((Object)(object)val2) ? val2 : CreateIcon(ColorOf(gem)))
			});
			val3.ItemDrop.m_itemData.m_shared.m_value = 0;
			val3.ItemDrop.m_itemData.m_shared.m_teleportable = true;
			if (Object.op_Implicit((Object)(object)val))
			{
				GemVisualFactory.Replace(val3.ItemPrefab, val);
				Transform attach = val3.ItemPrefab.transform.Find("attach");
				Vector3 rotation = GemVisualFactory.StandRotation(gem == Gem.Soul, horizontal: false);
				Vector3 rotation2 = GemVisualFactory.StandRotation(gem == Gem.Soul, horizontal: true);
				val3.ItemDrop.m_itemData.m_shared.m_itemStandOffsets = new List<OrientationSettings>
				{
					new OrientationSettings
					{
						m_orientations = (Orientation)1,
						m_rotation = rotation,
						m_position = GemVisualFactory.StandOffset(attach, horizontal: false, rotation)
					},
					new OrientationSettings
					{
						m_orientations = (Orientation)2,
						m_rotation = rotation2,
						m_position = GemVisualFactory.StandOffset(attach, horizontal: true, rotation2)
					}
				};
			}
			else
			{
				MeshRenderer[] componentsInChildren = val3.ItemPrefab.GetComponentsInChildren<MeshRenderer>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					Material[] materials = ((Renderer)componentsInChildren[i]).materials;
					foreach (Material val4 in materials)
					{
						if (val4.HasProperty("_Color"))
						{
							val4.SetColor("_Color", ColorOf(gem));
						}
						if (val4.HasProperty("_EmissionColor"))
						{
							val4.EnableKeyword("_EMISSION");
							val4.SetColor("_EmissionColor", ColorOf(gem) * 1.8f);
						}
					}
				}
			}
			GameObject prefab = PrefabManager.Instance.GetPrefab("fx_ItemSparkles");
			if (Object.op_Implicit((Object)(object)prefab) && !Object.op_Implicit((Object)(object)val3.ItemPrefab.transform.Find("JC_LootSparkles")))
			{
				GameObject obj = Object.Instantiate<GameObject>(prefab, val3.ItemPrefab.transform, false);
				((Object)obj).name = "JC_LootSparkles";
				obj.transform.localPosition = new Vector3(0f, 0.12f, 0f);
				obj.SetActive(true);
			}
			if (!ItemManager.Instance.AddItem(val3))
			{
				throw new InvalidOperationException("Cannot register " + Prefab(gem));
			}
		}

		private static Sprite CreateIcon(Color color)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: 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_007e: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false)
			{
				name = "JewelcraftGem",
				filterMode = (FilterMode)1
			};
			Color[] array = (Color[])(object)new Color[4096];
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 64; j++)
				{
					float num = ((float)j - 31.5f) / 25f;
					float num2 = ((float)i - 31.5f) / 29f;
					float num3 = Mathf.Abs(num) + Mathf.Abs(num2);
					if (num3 > 1f)
					{
						array[i * 64 + j] = new Color(color.r, color.g, color.b, Mathf.Max(0f, 1.2f - num3) * 0.65f);
						continue;
					}
					float num4 = ((num < 0f) ? 0.85f : 0.5f);
					if (num2 > 0f)
					{
						num4 += 0.25f;
					}
					Color val2 = Color.Lerp(color * num4, Color.white, (num3 > 0.89f) ? 0.7f : ((Mathf.Abs(num + num2 * 0.3f) < 0.055f) ? 0.5f : 0f));
					val2.a = 1f;
					array[i * 64 + j] = val2;
				}
			}
			val.SetPixels(array);
			val.Apply();
			return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f));
		}
	}
	[HarmonyPatch(typeof(ItemStand), "IsSupported")]
	internal static class GemStandPatch
	{
		private static void Postfix(ItemStand __instance, ItemData item, ref bool __result)
		{
			if (!__result && Object.op_Implicit((Object)(object)item?.m_dropPrefab) && GemStandPolicy.Supports(((Object)((Component)__instance).gameObject).name, ((Object)item.m_dropPrefab).name))
			{
				__result = (Object)(object)ItemStand.GetAttachPrefab(item.m_dropPrefab) != (Object)null;
			}
		}
	}
	internal static class GemStandPolicy
	{
		internal static bool Supports(string stand, string item)
		{
			switch (stand)
			{
			case "itemstand":
			case "itemstand(Clone)":
			case "itemstandh":
			case "itemstandh(Clone)":
				if (!(item == Gems.Prefab(Gem.Bless)))
				{
					return item == Gems.Prefab(Gem.Soul);
				}
				return true;
			default:
				return false;
			}
		}
	}
	internal static class GlowAssets
	{
		internal sealed class ClothingMask
		{
			internal Texture Source;

			internal Texture2D Texture;

			internal Color[] Pixels;

			internal int Users;

			internal bool Covers(Vector2 uv)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				int num = Mathf.Clamp((int)(uv.x * 128f), 0, 127);
				int num2 = Mathf.Clamp((int)(uv.y * 128f), 0, 127);
				return Pixels[num2 * 128 + num].r > 0.85f;
			}
		}

		private static readonly Dictionary<Texture, ClothingMask> Masks = new Dictionary<Texture, ClothingMask>();

		private static Texture2D star;

		private static AssetBundle bundle;

		private static Shader surfaceShader;

		private static Shader particleShader;

		private static Shader mistShader;

		private static bool warned;

		private static float nextLookup;

		private static string failure = "custom bundle not loaded";

		internal const string BundleName = "jewelcraft-glow-windows";

		internal static string ShaderStatus
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)surfaceShader))
				{
					return failure;
				}
				return ((Object)surfaceShader).name + " (custom)";
			}
		}

		internal static void Retry()
		{
			nextLookup = 0f;
			warned = false;
		}

		internal static T LoadBundledAsset<T>(string assetPath) where T : Object
		{
			if (!Object.op_Implicit((Object)(object)bundle))
			{
				string text = Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location), "jewelcraft-glow-windows");
				if (!File.Exists(text))
				{
					throw new FileNotFoundException("Missing Jewelcraft asset bundle", text);
				}
				bundle = AssetBundle.LoadFromFile(text);
				if (!Object.op_Implicit((Object)(object)bundle))
				{
					throw new InvalidOperationException("Jewelcraft asset bundle could not be loaded");
				}
			}
			return bundle.LoadAsset<T>(assetPath);
		}

		internal static bool Ready()
		{
			//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)
			if (Object.op_Implicit((Object)(object)surfaceShader) && Object.op_Implicit((Object)(object)particleShader) && Object.op_Implicit((Object)(object)mistShader))
			{
				return true;
			}
			if (Time.unscaledTime < nextLookup)
			{
				return false;
			}
			nextLookup = Time.unscaledTime + 5f;
			string text = Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location), "jewelcraft-glow-windows");
			try
			{
				if (!File.Exists(text))
				{
					throw new FileNotFoundException("Missing compiled shader bundle", text);
				}
				if (!Object.op_Implicit((Object)(object)bundle))
				{
					bundle = AssetBundle.LoadFromFile(text);
				}
				if (!Object.op_Implicit((Object)(object)bundle))
				{
					throw new InvalidOperationException("Shader AssetBundle could not be loaded");
				}
				Shader val = bundle.LoadAsset<Shader>("Assets/Jewelcraft/Shaders/JewelSurface.shader");
				Shader val2 = bundle.LoadAsset<Shader>("Assets/Jewelcraft/Shaders/JewelGlint.shader");
				Shader val3 = bundle.LoadAsset<Shader>("Assets/Jewelcraft/Shaders/JewelMist.shader");
				if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)val3) || !val.isSupported || !val2.isSupported || !val3.isSupported)
				{
					throw new InvalidOperationException("Custom shaders unsupported on " + ((object)SystemInfo.graphicsDeviceType/*cast due to .constrained prefix*/).ToString());
				}
				if (((Object)val).name != "Enoq/Jewelcraft/Surface" || ((Object)val2).name != "Enoq/Jewelcraft/Glint" || ((Object)val3).name != "Enoq/Jewelcraft/Mist")
				{
					throw new InvalidOperationException("Unexpected shaders in Jewelcraft bundle");
				}
				surfaceShader = val;
				particleShader = val2;
				mistShader = val3;
				Plugin.Info("Glow renderer ready: " + ShaderStatus);
				return true;
			}
			catch (Exception ex)
			{
				failure = ex.Message;
				if (!warned)
				{
					Plugin.Warn("Glow disabled: " + failure + ". Expected bundle beside DLL: " + text);
					warned = true;
				}
				surfaceShader = (particleShader = (mistShader = null));
				return false;
			}
		}

		internal static Material Surface(int level, bool masked, GlowPalette palette)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Expected O, but got Unknown
			if (!Ready())
			{
				return null;
			}
			Material val = new Material(surfaceShader)
			{
				name = "JC_CustomSurface",
				renderQueue = 3001
			};
			Color val2 = PaletteResolver.UnityColor(palette.Primary);
			Color val3 = PaletteResolver.UnityColor(palette.Secondary);
			Color val4 = PaletteResolver.UnityColor(palette.Accent);
			Color val5 = PaletteResolver.UnityColor(palette.Core);
			val.SetColor("_Gold", val2);
			val.SetColor("_Rose", val3);
			val.SetColor("_Iris", val4);
			val.SetColor("_Core", val5);
			val.SetFloat("_Intensity", GlowDesign.Intensity(level) * Settings.GlowIntensity.Value);
			val.SetFloat("_Softness", Settings.GlowSoftness.Value);
			val.SetTexture("_MaskTex", (Texture)(object)Texture2D.whiteTexture);
			return val;
		}

		internal static ClothingMask AcquireMask(Texture source)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_0094: 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_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)source) || source.width < 8 || source.height < 8)
			{
				return null;
			}
			if (Masks.TryGetValue(source, out var value))
			{
				value.Users++;
				return value;
			}
			RenderTexture active = RenderTexture.active;
			RenderTexture temporary = RenderTexture.GetTemporary(128, 128, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)1);
			Texture2D val = null;
			Texture2D val2 = null;
			try
			{
				Graphics.Blit(source, temporary);
				RenderTexture.active = temporary;
				val = new Texture2D(((Texture)temporary).width, ((Texture)temporary).height, (TextureFormat)4, false, true);
				val.ReadPixels(new Rect(0f, 0f, (float)((Texture)temporary).width, (float)((Texture)temporary).height), 0, 0);
				val.Apply();
				Color[] pixels = val.GetPixels();
				int num = 0;
				for (int i = 0; i < pixels.Length; i++)
				{
					float num2 = GlowDesign.ClothMask(pixels[i].a);
					if (num2 > 0.1f)
					{
						num++;
					}
					pixels[i] = new Color(num2, num2, num2, 1f);
				}
				if (num == 0 || (float)num > (float)pixels.Length * 0.7f)
				{
					return null;
				}
				val2 = new Texture2D(((Texture)temporary).width, ((Texture)temporary).height, (TextureFormat)4, false, true)
				{
					name = "JC_StationaryClothMask",
					wrapMode = (TextureWrapMode)1,
					filterMode = (FilterMode)1
				};
				val2.SetPixels(pixels);
				val2.Apply(false, true);
				value = new ClothingMask
				{
					Source = source,
					Users = 1,
					Texture = val2,
					Pixels = pixels
				};
				Masks.Add(source, value);
				return value;
			}
			catch
			{
				if (Object.op_Implicit((Object)(object)val2))
				{
					Object.Destroy((Object)(object)val2);
				}
				throw;
			}
			finally
			{
				RenderTexture.active = active;
				RenderTexture.ReleaseTemporary(temporary);
				if (Object.op_Implicit((Object)(object)val))
				{
					Object.Destroy((Object)(object)val);
				}
			}
		}

		internal static void ReleaseMask(ClothingMask mask)
		{
			if (mask != null && --mask.Users <= 0)
			{
				Masks.Remove(mask.Source);
				if (Object.op_Implicit((Object)(object)mask.Texture))
				{
					Object.Destroy((Object)(object)mask.Texture);
				}
			}
		}

		internal static Material SparkMaterial()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			if (!Ready())
			{
				return null;
			}
			if (!Object.op_Implicit((Object)(object)star))
			{
				star = ArmorParticleFactory.StarTexture();
			}
			return new Material(particleShader)
			{
				name = "JC_Glint",
				mainTexture = (Texture)(object)star
			};
		}

		internal static Material MistMaterial()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			if (!Ready())
			{
				return null;
			}
			return new Material(mistShader)
			{
				name = "JC_Mist"
			};
		}

		internal static void Shutdown()
		{
			PaletteResolver.Clear();
			foreach (ClothingMask value in Masks.Values)
			{
				if (Object.op_Implicit((Object)(object)value.Texture))
				{
					Object.Destroy((Object)(object)value.Texture);
				}
			}
			Masks.Clear();
			if (Object.op_Implicit((Object)(object)star))
			{
				Object.Destroy((Object)(object)star);
			}
			if (Object.op_Implicit((Object)(object)bundle))
			{
				bundle.Unload(true);
			}
			star = null;
			bundle = null;
			surfaceShader = (particleShader = (mistShader = null));
			nextLookup = 0f;
		}
	}
	internal static class GlowCommand
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static ConsoleEvent <>9__0_0;

			public static Func<string, string> <>9__0_2;

			public static ConsoleOptionsFetcher <>9__0_1;

			internal void <Register>b__0_0(ConsoleEventArgs args)
			{
				GlowStyle result;
				if (args.Args.Length == 1 || (args.Args.Length == 2 && args.Args[1].Equals("status", StringComparison.OrdinalIgnoreCase)))
				{
					string text = EquipmentGlow.Status();
					args.Context.AddString(text);
					Plugin.Info(text);
				}
				else if (args.Args.Length == 2 && args.Args[1].Equals("refresh", StringComparison.OrdinalIgnoreCase))
				{
					EquipmentGlow.RefreshLocal();
					args.Context.AddString(Texts.T("Brillo: recarga solicitada. Revisa jewelglow status.", "Glow refresh requested. Check jewelglow status."));
				}
				else if (args.Args.Length == 2 && Enum.TryParse<GlowStyle>(args.Args[1], ignoreCase: true, out result) && Enum.IsDefined(typeof(GlowStyle), result))
				{
					Settings.Style.Value = result;
					EquipmentGlow.RefreshLocal();
					args.Context.AddString(Texts.T("Estilo guardado: ", "Style saved: ") + result.ToString() + " | jewelglow status");
				}
				else
				{
					args.Context.AddString("Jewelcraft: " + Settings.Style.Value.ToString() + " | auto, pearl, azure, rose, gold, emerald, violet, ember, rosegold, classicgold");
				}
			}

			internal List<string> <Register>b__0_1()
			{
				return (from name in Enum.GetNames(typeof(GlowStyle))
					select name.ToLowerInvariant()).Concat(new string[2] { "status", "refresh" }).ToList();
			}

			internal string <Register>b__0_2(string name)
			{
				return name.ToLowerInvariant();
			}
		}

		internal static void Register()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			object obj = <>c.<>9__0_0;
			if (obj == null)
			{
				ConsoleEvent val = delegate(ConsoleEventArgs args)
				{
					GlowStyle result;
					if (args.Args.Length == 1 || (args.Args.Length == 2 && args.Args[1].Equals("status", StringComparison.OrdinalIgnoreCase)))
					{
						string text = EquipmentGlow.Status();
						args.Context.AddString(text);
						Plugin.Info(text);
					}
					else if (args.Args.Length == 2 && args.Args[1].Equals("refresh", StringComparison.OrdinalIgnoreCase))
					{
						EquipmentGlow.RefreshLocal();
						args.Context.AddString(Texts.T("Brillo: recarga solicitada. Revisa jewelglow status.", "Glow refresh requested. Check jewelglow status."));
					}
					else if (args.Args.Length == 2 && Enum.TryParse<GlowStyle>(args.Args[1], ignoreCase: true, out result) && Enum.IsDefined(typeof(GlowStyle), result))
					{
						Settings.Style.Value = result;
						EquipmentGlow.RefreshLocal();
						args.Context.AddString(Texts.T("Estilo guardado: ", "Style saved: ") + result.ToString() + " | jewelglow status");
					}
					else
					{
						args.Context.AddString("Jewelcraft: " + Settings.Style.Value.ToString() + " | auto, pearl, azure, rose, gold, emerald, violet, ember, rosegold, classicgold");
					}
				};
				<>c.<>9__0_0 = val;
				obj = (object)val;
			}
			object obj2 = <>c.<>9__0_1;
			if (obj2 == null)
			{
				ConsoleOptionsFetcher val2 = () => (from name in Enum.GetNames(typeof(GlowStyle))
					select name.ToLowerInvariant()).Concat(new string[2] { "status", "refresh" }).ToList();
				<>c.<>9__0_1 = val2;
				obj2 = (object)val2;
			}
			new ConsoleCommand("jewelglow", "[auto|pearl|azure|rose|gold|emerald|violet|ember|rosegold|classicgold|status|refresh] Local appearance.", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)obj2, false, false, false);
		}
	}
	internal enum GlowStyle
	{
		RoseGold,
		ClassicGold,
		Auto,
		Pearl,
		Azure,
		Rose,
		Gold,
		Emerald,
		Violet,
		Ember
	}
	internal static class GlowDesign
	{
		internal const int TextureSize = 128;

		internal const int MaxSurfaces = 8;

		internal static int Layers(int level)
		{
			return (level > 0) ? 1 : 0;
		}

		internal static float Intensity(int level)
		{
			if (level > 0)
			{
				if (level > 3)
				{
					if (level > 6)
					{
						return level switch
						{
							8 => 1.2f, 
							7 => 0.9f, 
							_ => 1.65f, 
						};
					}
					return 0.3f;
				}
				return 0.12f;
			}
			return 0f;
		}

		internal static float ClothMask(float alpha)
		{
			return Math.Max(0f, Math.Min(1f, (alpha - 0.75f) * 4f));
		}
	}
	public sealed class GlowOverlay : MonoBehaviour
	{
	}
	public sealed class JewelGlow : MonoBehaviour
	{
		private sealed class Surface
		{
			internal SurfaceDraw.Entry Draw;

			internal Material Material;
		}

		private readonly List<Surface> surfaces = new List<Surface>();

		private readonly List<Material> materials = new List<Material>();

		private GlowAssets.ClothingMask clothingMask;

		private Texture maskSource;

		private GlowStyle style;

		private float intensity;

		private float softness;

		private string prefab;

		private string overrides;

		private Texture paletteTexture;

		private GlowPalette palette;

		private ResolvedPalette sharedPalette;

		private bool glints;

		private bool released;

		private bool configured;

		internal string PaletteStatus { get; private set; }

		internal int Level { get; private set; }

		internal int SurfaceCount => surfaces.Count;

		internal GlowPalette Colors => palette;

		internal bool Matches(int level, Texture mask, string itemPrefab, Texture colorTexture, ResolvedPalette armorPalette)
		{
			if (!released && configured && Level == level && (Object)(object)maskSource == (Object)(object)mask && sharedPalette == armorPalette && prefab == itemPrefab && (Object)(object)paletteTexture == (Object)(object)colorTexture && overrides == Settings.PaletteOverrides.Value && softness == Settings.GlowSoftness.Value && style == Settings.Style.Value && intensity == Settings.GlowIntensity.Value)
			{
				return glints == Settings.Sparkles.Value;
			}
			return false;
		}

		internal void Configure(int level, SkinnedMeshRenderer body, Texture mask, string itemPrefab, Texture colorTexture, ResolvedPalette armorPalette)
		{
			Level = level;
			maskSource = mask;
			style = Settings.Style.Value;
			intensity = Settings.GlowIntensity.Value;
			glints = Settings.Sparkles.Value;
			prefab = itemPrefab;
			paletteTexture = colorTexture;
			overrides = Settings.PaletteOverrides.Value;
			softness = Settings.GlowSoftness.Value;
			if (!GlowAssets.Ready())
			{
				return;
			}
			configured = true;
			sharedPalette = armorPalette;
			ResolvedPalette resolvedPalette = sharedPalette ?? PaletteResolver.Resolve(((Component)this).gameObject, colorTexture, prefab);
			palette = resolvedPalette.Colors;
			PaletteStatus = prefab + ": " + resolvedPalette.Description;
			if (Object.op_Implicit((Object)(object)body))
			{
				clothingMask = GlowAssets.AcquireMask(mask);
				if (clothingMask == null)
				{
					return;
				}
			}
			for (int i = 0; i < GlowDesign.Layers(level); i++)
			{
				Material val = GlowAssets.Surface(level, Object.op_Implicit((Object)(object)body), palette);
				if (clothingMask != null)
				{
					val.SetTexture("_MaskTex", (Texture)(object)clothingMask.Texture);
				}
				materials.Add(val);
			}
			if (Object.op_Implicit((Object)(object)body))
			{
				AddSurface((Renderer)(object)body, body.sharedMesh);
				return;
			}
			int num = 0;
			Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
			MeshFilter val5 = default(MeshFilter);
			foreach (Renderer val2 in componentsInChildren)
			{
				if (num >= 8 || Object.op_Implicit((Object)(object)((Component)val2).GetComponent<GlowOverlay>()))
				{
					continue;
				}
				Mesh val3 = null;
				SkinnedMeshRenderer val4 = (SkinnedMeshRenderer)(object)((val2 is SkinnedMeshRenderer) ? val2 : null);
				if (val4 != null)
				{
					val3 = val4.sharedMesh;
				}
				else if (val2 is MeshRenderer && ((Component)val2).TryGetComponent<MeshFilter>(ref val5))
				{
					val3 = val5.sharedMesh;
				}
				if (!Object.op_Implicit((Object)(object)val3) || val3.subMeshCount == 0)
				{
					continue;
				}
				bool flag = false;
				Material[] sharedMaterials = val2.sharedMaterials;
				foreach (Material val6 in sharedMaterials)
				{
					if (Object.op_Implicit((Object)(object)val6) && Object.op_Implicit((Object)(object)val6.shader) && val6.renderQueue < 3000 && !((Object)val6.shader).name.Contains("Glow") && !((Object)val6.shader).name.Contains("Particle"))
					{
						flag = true;
					}
				}
				if (flag)
				{
					AddSurface(val2, val3);
					num++;
				}
			}
		}

		private void AddSurface(Renderer source, Mesh mesh)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: 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_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)mesh))
			{
				return;
			}
			for (int i = 0; i < materials.Count; i++)
			{
				Material[] sharedMaterials = source.sharedMaterials;
				for (int j = 0; j < mesh.subMeshCount; j++)
				{
					Material val = ((sharedMaterials.Length == 0) ? null : sharedMaterials[Mathf.Min(j, sharedMaterials.Length - 1)]);
					bool flag = clothingMask != null;
					if (flag || PaletteResolver.Solid(val))
					{
						Material val2 = new Material(materials[i]);
						Surface surface = new Surface
						{
							Material = val2
						};
						surfaces.Add(surface);
						Texture val3 = (flag ? maskSource : ((Object.op_Implicit((Object)(object)val) && val.HasProperty("_MainTex")) ? val.GetTexture("_MainTex") : null));
						Vector2 val4 = ((!flag && Object.op_Implicit((Object)(object)val3)) ? val.GetTextureScale("_MainTex") : Vector2.one);
						Vector2 val5 = ((!flag && Object.op_Implicit((Object)(object)val3)) ? val.GetTextureOffset("_MainTex") : Vector2.zero);
						val2.SetTexture("_SurfaceTex", (Texture)(Object.op_Implicit((Object)(object)val3) ? ((object)val3) : ((object)Texture2D.whiteTexture)));
						val2.SetVector("_SurfaceTex_ST", new Vector4(val4.x, val4.y, val5.x, val5.y));
						val2.SetFloat("_DetailStrength", Object.op_Implicit((Object)(object)val3) ? 0.75f : 0f);
						val2.SetFloat("_AlphaCutoff", (!flag && Object.op_Implicit((Object)(object)val) && val.renderQueue >= 2450 && val.HasProperty("_Cutoff")) ? val.GetFloat("_Cutoff") : 0f);
						val2.SetFloat("_SurfaceEnabled", (float)((flag || PaletteResolver.Solid(val)) ? 1 : 0));
						surface.Draw = SurfaceDraw.Add(source, val2, j);
					}
				}
			}
		}

		internal void Release()
		{
			if (released)
			{
				return;
			}
			released = true;
			Level = 0;
			foreach (Surface surface in surfaces)
			{
				SurfaceDraw.Remove(surface.Draw);
				if (Object.op_Implicit((Object)(object)surface.Material))
				{
					Object.Destroy((Object)(object)surface.Material);
				}
			}
			surfaces.Clear();
			foreach (Material material in materials)
			{
				if (Object.op_Implicit((Object)(object)material))
				{
					Object.Destroy((Object)(object)material);
				}
			}
			materials.Clear();
			GlowAssets.ReleaseMask(clothingMask);
			clothingMask = null;
		}

		private void OnDestroy()
		{
			Release();
		}
	}
	internal static class MonsterLoot
	{
		private sealed class DeathRoll
		{
			internal bool Rolled;
		}

		private static readonly ConditionalWeakTable<CharacterDrop, DeathRoll> rolls = new ConditionalWeakTable<CharacterDrop, DeathRoll>();

		internal static void Append(CharacterDrop source, bool dropsEnabled, List<KeyValuePair<GameObject, int>> loot, int blessChance, int soulChance)
		{
			if (!Object.op_Implicit((Object)(object)source) || !dropsEnabled || loot == null)
			{
				r