Decompiled source of RunesOfRefinement v0.5.2

RunesOfRefinement.dll

Decompiled 13 hours ago
using System;
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.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using RunesOfRefinement.Config;
using RunesOfRefinement.GUI;
using RunesOfRefinement.Items;
using RunesOfRefinement.Patches;
using RunesOfRefinement.Systems;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("RunesOfRefinement")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("PickTeam")]
[assembly: AssemblyProduct("RunesOfRefinement")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("3f480584-8125-43c3-acb4-3621017202b6")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = "")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace RunesOfRefinement
{
	[BepInPlugin("com.pickteam.RunesOfRefinement", "RunesOfRefinement", "0.5.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	internal class RunesOfRefinement : BaseUnityPlugin
	{
		public const string ModGUID = "com.pickteam.RunesOfRefinement";

		public const string ModName = "RunesOfRefinement";

		public const string ModVersion = "0.5.0";

		private Harmony harmony;

		private CustomLocalization localization;

		private FileSystemWatcher _configWatcher;

		private void Awake()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			ModConfig.Init(((BaseUnityPlugin)this).Config);
			harmony = new Harmony("com.pickteam.RunesOfRefinement");
			harmony.CreateClassProcessor(typeof(BiomeDropPatch)).Patch();
			TooltipPatch.Register(harmony);
			StatPatches.Register(harmony);
			OutOfCombatStaminaPatch.Register(harmony);
			CursorApply.Register(harmony);
			localization = LocalizationManager.Instance.GetLocalization();
			LocalizationManager.Instance.AddLocalization(localization);
			LocaleLoader.LoadAll(localization);
			PrefabManager.OnVanillaPrefabsAvailable += AddContent;
			SynchronizationManager.OnConfigurationSynchronized += OnConfigSync;
			SynchronizationManager.OnAdminStatusChanged += OnAdminStatusChanged;
			SetupConfigWatcher();
			Logger.LogInfo((object)"RunesOfRefinement v0.5.0 loaded");
		}

		private void Update()
		{
			CursorApply.UpdateCursorPosition();
		}

		private void AddContent()
		{
			Spheres.Create();
			Omens.Create();
			PrefabManager.OnVanillaPrefabsAvailable -= AddContent;
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			SynchronizationManager.OnConfigurationSynchronized -= OnConfigSync;
			SynchronizationManager.OnAdminStatusChanged -= OnAdminStatusChanged;
			_configWatcher?.Dispose();
		}

		private void OnConfigSync(object sender, ConfigurationSynchronizationEventArgs e)
		{
			Logger.LogInfo((object)("RunesOfRefinement: configuration " + (e.InitialSynchronization ? "initially synced" : "re-synced") + " from server"));
		}

		private void OnAdminStatusChanged()
		{
			Logger.LogInfo((object)string.Format("{0}: admin status = {1}", "RunesOfRefinement", SynchronizationManager.Instance.PlayerIsAdmin));
		}

		private void SetupConfigWatcher()
		{
			string configFilePath = ((BaseUnityPlugin)this).Config.ConfigFilePath;
			string directoryName = Path.GetDirectoryName(configFilePath);
			string fileName = Path.GetFileName(configFilePath);
			_configWatcher = new FileSystemWatcher(directoryName, fileName)
			{
				NotifyFilter = (NotifyFilters.Size | NotifyFilters.LastWrite),
				EnableRaisingEvents = true
			};
			_configWatcher.Changed += delegate
			{
				((BaseUnityPlugin)this).Config.Reload();
				Logger.LogInfo((object)"RunesOfRefinement: config file changed — reloaded");
			};
		}
	}
}
namespace RunesOfRefinement.Config
{
	public static class ModConfig
	{
		public static ConfigEntry<float> DropRateMultiplier;

		public static ConfigEntry<float> OmenDropRateMultiplier;

		public static ConfigEntry<bool> EnableMythicProperties;

		public static ConfigEntry<float> AffixValueMultiplier;

		public static ConfigEntry<bool> EnableOutOfCombatStamina;

		public static ConfigEntry<bool> EnableTooltipColors;

		public static ConfigEntry<bool> EnableReforgeEffects;

		public static void Init(ConfigFile config)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_007e: 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_008c: Expected O, but got Unknown
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			//IL_00b5: 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_00c3: Expected O, but got Unknown
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Expected O, but got Unknown
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Expected O, but got Unknown
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Expected O, but got Unknown
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Expected O, but got Unknown
			config.SaveOnConfigSet = true;
			DropRateMultiplier = config.Bind<float>("DropRates", "SphereDropMultiplier", 1f, new ConfigDescription("Multiplier for all sphere/rune drop rates (1.0 = default, 2.0 = double).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			} }));
			OmenDropRateMultiplier = config.Bind<float>("DropRates", "OmenDropMultiplier", 1f, new ConfigDescription("Multiplier for all omen drop rates.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			} }));
			EnableMythicProperties = config.Bind<bool>("Features", "EnableMythicProperties", true, new ConfigDescription("Enable or disable mythic (legendary) active properties.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			} }));
			AffixValueMultiplier = config.Bind<float>("Balance", "AffixValueMultiplier", 1f, new ConfigDescription("Multiplier for rolled affix values (1.0 = default, 0.5 = half power).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			} }));
			EnableOutOfCombatStamina = config.Bind<bool>("Gameplay", "EnableOutOfCombatStamina", true, new ConfigDescription("When enabled, stamina is not consumed while out of combat (not sensed or targeted).", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			} }));
			EnableTooltipColors = config.Bind<bool>("Visual", "EnableTooltipColors", true, "Enable colored text in item tooltips for rune modifiers.");
			EnableReforgeEffects = config.Bind<bool>("Visual", "EnableReforgeEffects", true, "Enable visual/sound effects when reforging at the Enchantment Altar.");
		}
	}
}
namespace RunesOfRefinement.GUI
{
	internal static class CursorApply
	{
		[HarmonyPatch(typeof(InventoryGui), "SetupDragItem")]
		private static class LeftClickPatch
		{
			[HarmonyPostfix]
			private static void Postfix(InventoryGui __instance)
			{
				if (IsHolding && !((Object)(object)__instance.m_dragGo == (Object)null) && __instance.m_dragItem != null)
				{
					ItemData dragItem = __instance.m_dragItem;
					GameObject dropPrefab = dragItem.m_dropPrefab;
					string prefabName = ((dropPrefab != null) ? ((Object)dropPrefab).name : null) ?? "";
					if (EssenceLogic.IsOmen(prefabName))
					{
						_heldOmen = dragItem;
						__instance.SetupDragItem((ItemData)null, (Inventory)null, 1);
						UpdateCursorVisual();
					}
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGrid), "OnRightClick")]
		private static class RightClickPatch
		{
			[HarmonyPrefix]
			private static bool Prefix(InventoryGrid __instance, UIInputHandler element)
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: 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_001c: Unknown result type (might be due to invalid IL or missing references)
				GameObject gameObject = ((Component)element).gameObject;
				Vector2i buttonPos = __instance.GetButtonPos(gameObject);
				ItemData itemAt = __instance.m_inventory.GetItemAt(buttonPos.x, buttonPos.y);
				if (!IsHolding)
				{
					if (itemAt == null)
					{
						return true;
					}
					GameObject dropPrefab = itemAt.m_dropPrefab;
					string prefabName = ((dropPrefab != null) ? ((Object)dropPrefab).name : null) ?? "";
					if (EssenceLogic.IsSphere(prefabName))
					{
						Hold(itemAt);
						return false;
					}
					return true;
				}
				if (itemAt == null)
				{
					Cancel();
					return false;
				}
				GameObject dropPrefab2 = itemAt.m_dropPrefab;
				string prefabName2 = ((dropPrefab2 != null) ? ((Object)dropPrefab2).name : null) ?? "";
				if (EssenceLogic.IsSphere(prefabName2))
				{
					Hold(itemAt);
					return false;
				}
				if (EssenceLogic.IsOmen(prefabName2))
				{
					_heldOmen = itemAt;
					InventoryGui instance = InventoryGui.instance;
					if (instance != null)
					{
						instance.SetupDragItem((ItemData)null, (Inventory)null, 1);
					}
					UpdateCursorVisual();
					return false;
				}
				TryApply(itemAt, __instance.m_inventory);
				return false;
			}
		}

		[HarmonyPatch(typeof(InventoryGrid), "UpdateGui")]
		private static class GridHighlightPatch
		{
			[HarmonyPostfix]
			private static void Postfix(InventoryGrid __instance)
			{
				//IL_0132: Unknown result type (might be due to invalid IL or missing references)
				//IL_012b: Unknown result type (might be due to invalid IL or missing references)
				if (!IsHolding)
				{
					return;
				}
				ItemData heldSphere = _heldSphere;
				object obj;
				if (heldSphere == null)
				{
					obj = null;
				}
				else
				{
					GameObject dropPrefab = heldSphere.m_dropPrefab;
					obj = ((dropPrefab != null) ? ((Object)dropPrefab).name : null);
				}
				if (obj == null)
				{
					obj = "";
				}
				string spherePrefab = (string)obj;
				int width = __instance.m_inventory.m_width;
				foreach (ItemData allItem in __instance.m_inventory.GetAllItems())
				{
					if (!EssenceLogic.IsEquipment(allItem))
					{
						continue;
					}
					int num = allItem.m_gridPos.y * width + allItem.m_gridPos.x;
					if (num < 0 || num >= __instance.m_elements.Count)
					{
						continue;
					}
					Element val = __instance.m_elements[num];
					Transform val2 = val.m_go.transform.Find("selected");
					if (!((Object)(object)val2 == (Object)null))
					{
						Image component = ((Component)val2).GetComponent<Image>();
						if (!((Object)(object)component == (Object)null))
						{
							bool flag = EssenceLogic.CanApply(allItem, spherePrefab);
							((Component)val2).gameObject.SetActive(true);
							((Graphic)component).color = (flag ? HighlightValid : HighlightInvalid);
						}
					}
				}
			}
		}

		private static ItemData _heldSphere;

		private static ItemData _heldOmen;

		private static GameObject _cursorGo;

		private static Image _cursorIcon;

		private static Image _cursorOmenIcon;

		private static readonly Color HighlightValid = new Color(0.2f, 1f, 0.2f, 0.35f);

		private static readonly Color HighlightInvalid = new Color(1f, 0.2f, 0.2f, 0.25f);

		private static readonly Color CursorBg = new Color(0.1f, 0.05f, 0.02f, 0.92f);

		public static bool IsHolding => _heldSphere != null;

		public static void Hold(ItemData sphere, ItemData omen = null)
		{
			_heldSphere = sphere;
			_heldOmen = omen;
			if ((Object)(object)InventoryGui.instance != (Object)null)
			{
				InventoryGui.instance.SetupDragItem((ItemData)null, (Inventory)null, 1);
			}
			EnsureCursor();
			UpdateCursorVisual();
			GameObject dropPrefab = sphere.m_dropPrefab;
			string obj = ((dropPrefab != null) ? ((Object)dropPrefab).name : null);
			object obj2;
			if (omen == null)
			{
				obj2 = "";
			}
			else
			{
				GameObject dropPrefab2 = omen.m_dropPrefab;
				obj2 = " + " + ((dropPrefab2 != null) ? ((Object)dropPrefab2).name : null);
			}
			Logger.LogInfo((object)("[RoR] Cursor-hold: " + obj + (string?)obj2));
		}

		public static void Cancel()
		{
			_heldSphere = null;
			_heldOmen = null;
			if ((Object)(object)_cursorGo != (Object)null)
			{
				_cursorGo.SetActive(false);
			}
		}

		public static void TryApply(ItemData target, Inventory targetInventory)
		{
			if (_heldSphere == null || target == null)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			Inventory inventory = ((Humanoid)localPlayer).GetInventory();
			if (!inventory.ContainsItem(_heldSphere))
			{
				ShowMessage("$ror_msg_missing_items");
				Cancel();
				return;
			}
			if (!EssenceLogic.IsEquipment(target))
			{
				ShowMessage("$ror_msg_not_equipment");
				return;
			}
			GameObject dropPrefab = _heldSphere.m_dropPrefab;
			string spherePrefab = ((dropPrefab != null) ? ((Object)dropPrefab).name : null) ?? "";
			ItemData heldOmen = _heldOmen;
			object obj;
			if (heldOmen == null)
			{
				obj = null;
			}
			else
			{
				GameObject dropPrefab2 = heldOmen.m_dropPrefab;
				obj = ((dropPrefab2 != null) ? ((Object)dropPrefab2).name : null);
			}
			if (obj == null)
			{
				obj = "";
			}
			string omenPrefab = (string)obj;
			EssenceLogic.ApplyResult applyResult = EssenceLogic.Apply(target, _heldSphere, _heldOmen);
			if (applyResult.Success)
			{
				inventory.RemoveOneItem(_heldSphere);
				if (_heldOmen != null)
				{
					inventory.RemoveOneItem(_heldOmen);
				}
				PlayEffect(localPlayer);
				RuneEffectManager.Invalidate();
				ItemData val = ((IEnumerable<ItemData>)inventory.GetAllItems()).FirstOrDefault((Func<ItemData, bool>)delegate(ItemData i)
				{
					GameObject dropPrefab4 = i.m_dropPrefab;
					return (((dropPrefab4 != null) ? ((Object)dropPrefab4).name : null) ?? "") == spherePrefab;
				});
				ItemData heldOmen2 = null;
				if (omenPrefab != "")
				{
					heldOmen2 = ((IEnumerable<ItemData>)inventory.GetAllItems()).FirstOrDefault((Func<ItemData, bool>)delegate(ItemData i)
					{
						GameObject dropPrefab3 = i.m_dropPrefab;
						return (((dropPrefab3 != null) ? ((Object)dropPrefab3).name : null) ?? "") == omenPrefab;
					});
				}
				if (val != null)
				{
					_heldSphere = val;
					_heldOmen = heldOmen2;
					UpdateCursorVisual();
				}
				else
				{
					Cancel();
				}
			}
			ShowMessage(applyResult.MessageKey);
		}

		public static void UpdateCursorPosition()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			if (!IsHolding)
			{
				return;
			}
			if (Input.GetKeyDown((KeyCode)27))
			{
				Cancel();
				return;
			}
			if ((Object)(object)_cursorGo != (Object)null && _cursorGo.activeSelf)
			{
				_cursorGo.transform.position = Input.mousePosition + new Vector3(32f, -32f, 0f);
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || !((Humanoid)localPlayer).GetInventory().ContainsItem(_heldSphere))
			{
				Cancel();
			}
		}

		private static void EnsureCursor()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Expected O, but got Unknown
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Expected O, but got Unknown
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_cursorGo != (Object)null)
			{
				_cursorGo.SetActive(true);
				return;
			}
			InventoryGui instance = InventoryGui.instance;
			Transform val = ((instance != null) ? ((Component)instance).transform.root : null);
			if (!((Object)(object)val == (Object)null))
			{
				_cursorGo = new GameObject("RoR_CursorApply");
				_cursorGo.transform.SetParent(val, false);
				RectTransform val2 = _cursorGo.AddComponent<RectTransform>();
				val2.sizeDelta = new Vector2(52f, 52f);
				Image val3 = _cursorGo.AddComponent<Image>();
				((Graphic)val3).color = CursorBg;
				GameObject val4 = new GameObject("Icon");
				val4.transform.SetParent(_cursorGo.transform, false);
				RectTransform val5 = val4.AddComponent<RectTransform>();
				val5.anchorMin = new Vector2(0f, 0f);
				val5.anchorMax = new Vector2(1f, 1f);
				val5.offsetMin = new Vector2(4f, 4f);
				val5.offsetMax = new Vector2(-4f, -4f);
				_cursorIcon = val4.AddComponent<Image>();
				_cursorIcon.preserveAspect = true;
				GameObject val6 = new GameObject("OmenIcon");
				val6.transform.SetParent(_cursorGo.transform, false);
				RectTransform val7 = val6.AddComponent<RectTransform>();
				val7.anchorMin = new Vector2(1f, 0f);
				val7.anchorMax = new Vector2(1f, 0f);
				val7.pivot = new Vector2(1f, 0f);
				val7.sizeDelta = new Vector2(22f, 22f);
				val7.anchoredPosition = new Vector2(2f, -2f);
				_cursorOmenIcon = val6.AddComponent<Image>();
				_cursorOmenIcon.preserveAspect = true;
				val6.SetActive(false);
				Canvas val8 = _cursorGo.AddComponent<Canvas>();
				val8.overrideSorting = true;
				val8.sortingOrder = 9999;
				_cursorGo.AddComponent<GraphicRaycaster>();
				_cursorGo.SetActive(true);
			}
		}

		private static void UpdateCursorVisual()
		{
			if (!((Object)(object)_cursorGo == (Object)null) && _heldSphere != null)
			{
				_cursorIcon.sprite = _heldSphere.GetIcon();
				((Behaviour)_cursorIcon).enabled = (Object)(object)_cursorIcon.sprite != (Object)null;
				if (_heldOmen != null)
				{
					_cursorOmenIcon.sprite = _heldOmen.GetIcon();
					((Behaviour)_cursorOmenIcon).enabled = (Object)(object)_cursorOmenIcon.sprite != (Object)null;
					((Component)_cursorOmenIcon).gameObject.SetActive(true);
				}
				else
				{
					((Component)_cursorOmenIcon).gameObject.SetActive(false);
				}
			}
		}

		private static void ShowMessage(string key)
		{
			string text = Localization.instance.Localize(key);
			MessageHud instance = MessageHud.instance;
			if (instance != null)
			{
				instance.ShowMessage((MessageType)2, text, 0, (Sprite)null, false);
			}
		}

		private static void PlayEffect(Player player)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: 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)
			if (ModConfig.EnableReforgeEffects.Value)
			{
				Vector3 position = ((Component)player).transform.position;
				ZNetScene instance = ZNetScene.instance;
				GameObject val = ((instance != null) ? instance.GetPrefab("sfx_build_hammer_metal") : null);
				if ((Object)(object)val != (Object)null)
				{
					Object.Instantiate<GameObject>(val, position, Quaternion.identity);
				}
				ZNetScene instance2 = ZNetScene.instance;
				GameObject val2 = ((instance2 != null) ? instance2.GetPrefab("vfx_FireAddFuel") : null);
				if ((Object)(object)val2 != (Object)null)
				{
					Object.Instantiate<GameObject>(val2, position, Quaternion.identity);
				}
			}
		}

		public static void Register(Harmony harmony)
		{
			harmony.CreateClassProcessor(typeof(LeftClickPatch)).Patch();
			harmony.CreateClassProcessor(typeof(RightClickPatch)).Patch();
			harmony.CreateClassProcessor(typeof(GridHighlightPatch)).Patch();
		}
	}
}
namespace RunesOfRefinement.Patches
{
	[HarmonyPatch(typeof(CharacterDrop), "Start")]
	internal static class BiomeDropPatch
	{
		private struct DropEntry
		{
			public string Prefab;

			public float Chance;
		}

		private static readonly Dictionary<Biome, List<DropEntry>> BiomeDrops = new Dictionary<Biome, List<DropEntry>>
		{
			[(Biome)1] = new List<DropEntry>
			{
				new DropEntry
				{
					Prefab = "RoR_OrbOfTransmutation",
					Chance = 0.025f
				},
				new DropEntry
				{
					Prefab = "RoR_OrbOfAugmentation",
					Chance = 0.015f
				}
			},
			[(Biome)8] = new List<DropEntry>
			{
				new DropEntry
				{
					Prefab = "RoR_OrbOfTransmutation",
					Chance = 0.015f
				},
				new DropEntry
				{
					Prefab = "RoR_OrbOfAugmentation",
					Chance = 0.015f
				},
				new DropEntry
				{
					Prefab = "RoR_RegalOrb",
					Chance = 0.008f
				}
			},
			[(Biome)2] = new List<DropEntry>
			{
				new DropEntry
				{
					Prefab = "RoR_OrbOfAugmentation",
					Chance = 0.01f
				},
				new DropEntry
				{
					Prefab = "RoR_RegalOrb",
					Chance = 0.012f
				},
				new DropEntry
				{
					Prefab = "RoR_ExaltedOrb",
					Chance = 0.008f
				},
				new DropEntry
				{
					Prefab = "RoR_ChaosOrb",
					Chance = 0.008f
				},
				new DropEntry
				{
					Prefab = "RoR_VaalOrb",
					Chance = 0.005f
				}
			},
			[(Biome)4] = new List<DropEntry>
			{
				new DropEntry
				{
					Prefab = "RoR_RegalOrb",
					Chance = 0.008f
				},
				new DropEntry
				{
					Prefab = "RoR_ExaltedOrb",
					Chance = 0.01f
				},
				new DropEntry
				{
					Prefab = "RoR_OrbOfAlchemy",
					Chance = 0.006f
				},
				new DropEntry
				{
					Prefab = "RoR_ChaosOrb",
					Chance = 0.008f
				},
				new DropEntry
				{
					Prefab = "RoR_VaalOrb",
					Chance = 0.004f
				},
				new DropEntry
				{
					Prefab = "RoR_OmenOfElements",
					Chance = 0.005f
				},
				new DropEntry
				{
					Prefab = "RoR_OmenOfProtector",
					Chance = 0.005f
				},
				new DropEntry
				{
					Prefab = "RoR_OmenOfOrder",
					Chance = 0.005f
				},
				new DropEntry
				{
					Prefab = "RoR_OmenSinistral",
					Chance = 0.003f
				},
				new DropEntry
				{
					Prefab = "RoR_OmenDextral",
					Chance = 0.003f
				}
			},
			[(Biome)16] = new List<DropEntry>
			{
				new DropEntry
				{
					Prefab = "RoR_ExaltedOrb",
					Chance = 0.008f
				},
				new DropEntry
				{
					Prefab = "RoR_OrbOfAlchemy",
					Chance = 0.006f
				},
				new DropEntry
				{
					Prefab = "RoR_ChaosOrb",
					Chance = 0.006f
				},
				new DropEntry
				{
					Prefab = "RoR_OrbOfAnnulment",
					Chance = 0.004f
				},
				new DropEntry
				{
					Prefab = "RoR_VaalOrb",
					Chance = 0.004f
				},
				new DropEntry
				{
					Prefab = "RoR_OmenOfElements",
					Chance = 0.003f
				},
				new DropEntry
				{
					Prefab = "RoR_OmenOfProtector",
					Chance = 0.003f
				},
				new DropEntry
				{
					Prefab = "RoR_OmenOfOrder",
					Chance = 0.003f
				},
				new DropEntry
				{
					Prefab = "RoR_OmenSinistral",
					Chance = 0.002f
				},
				new DropEntry
				{
					Prefab = "RoR_OmenDextral",
					Chance = 0.002f
				},
				new DropEntry
				{
					Prefab = "RoR_OmenWhittling",
					Chance = 0.002f
				},
				new DropEntry
				{
					Prefab = "RoR_OmenAbundance",
					Chance = 0.002f
				}
			},
			[(Biome)512] = new List<DropEntry>
			{
				new DropEntry
				{
					Prefab = "RoR_ExaltedOrb",
					Chance = 0.005f
				},
				new DropEntry
				{
					Prefab = "RoR_ChaosOrb",
					Chance = 0.005f
				},
				new DropEntry
				{
					Prefab = "RoR_OrbOfAnnulment",
					Chance = 0.004f
				},
				new DropEntry
				{
					Prefab = "RoR_DivineOrb",
					Chance = 0.003f
				},
				new DropEntry
				{
					Prefab = "RoR_VaalOrb",
					Chance = 0.005f
				},
				new DropEntry
				{
					Prefab = "RoR_OmenOfElements",
					Chance = 0.003f
				},
				new DropEntry
				{
					Prefab = "RoR_OmenOfProtector",
					Chance = 0.003f
				},
				new DropEntry
				{
					Prefab = "RoR_OmenOfOrder",
					Chance = 0.003f
				},
				new DropEntry
				{
					Prefab = "RoR_OmenSinistral",
					Chance = 0.002f
				},
				new DropEntry
				{
					Prefab = "RoR_OmenDextral",
					Chance = 0.002f
				},
				new DropEntry
				{
					Prefab = "RoR_OmenWhittling",
					Chance = 0.002f
				},
				new DropEntry
				{
					Prefab = "RoR_OmenAbundance",
					Chance = 0.002f
				},
				new DropEntry
				{
					Prefab = "RoR_OmenCorruption",
					Chance = 0.001f
				},
				new DropEntry
				{
					Prefab = "RoR_OmenPerfection",
					Chance = 0.001f
				},
				new DropEntry
				{
					Prefab = "RoR_OmenGreaterAnnul",
					Chance = 0.001f
				}
			}
		};

		private static void Postfix(CharacterDrop __instance)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			Biome key = Heightmap.FindBiome(((Component)__instance).transform.position);
			if (!BiomeDrops.TryGetValue(key, out var value))
			{
				return;
			}
			foreach (DropEntry item in value)
			{
				GameObject prefab = PrefabManager.Instance.GetPrefab(item.Prefab);
				if (!((Object)(object)prefab == (Object)null))
				{
					__instance.m_drops.Add(new Drop
					{
						m_prefab = prefab,
						m_amountMin = 1,
						m_amountMax = 1,
						m_chance = item.Chance,
						m_onePerPlayer = false,
						m_levelMultiplier = false
					});
				}
			}
		}
	}
	internal static class TooltipPatch
	{
		public static void Register(Harmony harmony)
		{
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Expected O, but got Unknown
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(typeof(ItemData), "GetTooltip", new Type[5]
			{
				typeof(ItemData),
				typeof(int),
				typeof(bool),
				typeof(float),
				typeof(int)
			}, (Type[])null);
			if (methodInfo == null)
			{
				methodInfo = AccessTools.Method(typeof(ItemData), "GetTooltip", new Type[4]
				{
					typeof(ItemData),
					typeof(int),
					typeof(bool),
					typeof(float)
				}, (Type[])null);
			}
			if (methodInfo == null)
			{
				methodInfo = AccessTools.Method(typeof(ItemData), "GetTooltip", new Type[4]
				{
					typeof(ItemData),
					typeof(int),
					typeof(bool),
					typeof(int)
				}, (Type[])null);
			}
			if (methodInfo != null)
			{
				HarmonyMethod val = new HarmonyMethod(AccessTools.Method(typeof(TooltipPatch), "GetTooltipStaticPostfix", (Type[])null, (Type[])null));
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Logger.LogInfo((object)"TooltipPatch applied (static GetTooltip)");
				return;
			}
			MethodInfo methodInfo2 = AccessTools.Method(typeof(ItemData), "GetTooltip", new Type[1] { typeof(int) }, (Type[])null);
			if (methodInfo2 == null)
			{
				methodInfo2 = AccessTools.Method(typeof(ItemData), "GetTooltip", new Type[3]
				{
					typeof(int),
					typeof(bool),
					typeof(float)
				}, (Type[])null);
			}
			if (methodInfo2 != null)
			{
				HarmonyMethod val2 = new HarmonyMethod(AccessTools.Method(typeof(TooltipPatch), "GetTooltipInstancePostfix", (Type[])null, (Type[])null));
				harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Logger.LogInfo((object)"TooltipPatch applied (instance GetTooltip)");
			}
			else
			{
				Logger.LogWarning((object)"TooltipPatch: Could not find GetTooltip method to patch");
			}
		}

		private static void GetTooltipStaticPostfix(ItemData __0, ref string __result)
		{
			AppendModifiers(__0, ref __result);
		}

		private static void GetTooltipInstancePostfix(ItemData __instance, ref string __result)
		{
			AppendModifiers(__instance, ref __result);
		}

		private static void AppendModifiers(ItemData item, ref string tooltip)
		{
			//IL_004f: 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)
			if (item == null || !ModifierData.HasAnyModifiers(item) || !ModConfig.EnableTooltipColors.Value)
			{
				return;
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine();
			stringBuilder.AppendLine();
			ItemRarity rarity = ModifierData.GetRarity(item);
			string text = ColorUtility.ToHtmlStringRGB(RarityHelper.GetColor(rarity));
			string text2 = rarity switch
			{
				ItemRarity.Magic => Localization.instance.Localize("$ror_rarity_magic"), 
				ItemRarity.Rare => Localization.instance.Localize("$ror_rarity_rare"), 
				_ => Localization.instance.Localize("$ror_rarity_normal"), 
			};
			string text3 = (ModifierData.IsCorrupted(item) ? (" <color=#" + ColorUtility.ToHtmlStringRGB(RarityHelper.CorruptedColor) + ">(" + Localization.instance.Localize("$ror_corrupted") + ")</color>") : "");
			int itemTier = EssenceLogic.GetItemTier(item);
			string text4 = Localization.instance.Localize($"$ror_tier_{itemTier}");
			string text5 = " <color=#AAAAAA>[" + text4 + "]</color>";
			stringBuilder.AppendLine("<color=#" + text + ">" + text2 + text3 + text5 + ":</color>");
			List<RolledAffix> affixes = ModifierData.GetAffixes(item);
			affixes.Sort(delegate(RolledAffix a, RolledAffix b)
			{
				AffixDefinition affixDefinition3 = AffixPool.Get(a.AffixId);
				AffixDefinition affixDefinition4 = AffixPool.Get(b.AffixId);
				int num = ((affixDefinition3 == null || affixDefinition3.Slot != 0) ? 1 : 0);
				int value = ((affixDefinition4 == null || affixDefinition4.Slot != 0) ? 1 : 0);
				return num.CompareTo(value);
			});
			foreach (RolledAffix item2 in affixes)
			{
				AffixDefinition affixDefinition = AffixPool.Get(item2.AffixId);
				if (affixDefinition != null)
				{
					string text6 = Localization.instance.Localize(affixDefinition.NameToken);
					string text7 = string.Format(Localization.instance.Localize(affixDefinition.DescToken), item2.Value);
					string rollQualityColor = AffixPool.GetRollQualityColor(item2);
					stringBuilder.AppendLine("<color=" + rollQualityColor + ">" + text6 + ": " + text7 + "</color>");
				}
			}
			RolledAffix mythicAffix = ModifierData.GetMythicAffix(item);
			if (mythicAffix != null)
			{
				AffixDefinition affixDefinition2 = AffixPool.Get(mythicAffix.AffixId);
				if (affixDefinition2 != null)
				{
					string text8 = Localization.instance.Localize(affixDefinition2.NameToken);
					string text9 = string.Format(Localization.instance.Localize(affixDefinition2.DescToken), mythicAffix.Value);
					stringBuilder.AppendLine("<color=#D966FF>" + text8 + ": " + text9 + "</color>");
				}
			}
			tooltip += stringBuilder.ToString();
		}
	}
	internal static class StatPatches
	{
		[HarmonyPatch(typeof(ItemData), "GetDamage", new Type[]
		{
			typeof(int),
			typeof(float)
		})]
		internal static class WeaponDamagePatch
		{
			private static void Postfix(ItemData __instance, ref DamageTypes __result)
			{
				if (!ModifierData.HasAnyModifiers(__instance))
				{
					return;
				}
				RuneEffectManager.WeaponModifiers weaponModifiers = RuneEffectManager.GetWeaponModifiers(__instance);
				if (weaponModifiers.DamagePercent > 0f)
				{
					float num = 1f + weaponModifiers.DamagePercent / 100f;
					__result.m_blunt *= num;
					__result.m_slash *= num;
					__result.m_pierce *= num;
				}
				__result.m_fire += weaponModifiers.FireDamage;
				__result.m_frost += weaponModifiers.FrostDamage;
				__result.m_lightning += weaponModifiers.LightningDamage;
				__result.m_poison += weaponModifiers.PoisonDamage;
				__result.m_spirit += weaponModifiers.SpiritDamage;
				if (weaponModifiers.ArmorIgnore > 0f)
				{
					__result.m_damage += weaponModifiers.ArmorIgnore;
				}
				if (weaponModifiers.HeimdallDamagePercent > 0f)
				{
					float num2 = 1f + weaponModifiers.HeimdallDamagePercent / 100f;
					__result.m_blunt *= num2;
					__result.m_slash *= num2;
					__result.m_pierce *= num2;
					__result.m_fire *= num2;
					__result.m_frost *= num2;
					__result.m_lightning *= num2;
					__result.m_poison *= num2;
					__result.m_spirit *= num2;
				}
				if (!(__result.m_chop > 0f) && !(__result.m_pickaxe > 0f))
				{
					return;
				}
				RuneEffectManager.ToolModifiers toolModifiers = RuneEffectManager.GetToolModifiers(__instance);
				if (toolModifiers.MiningPercent > 0f && __result.m_pickaxe > 0f)
				{
					__result.m_pickaxe *= 1f + toolModifiers.MiningPercent / 100f;
				}
				if (toolModifiers.ChoppingPercent > 0f && __result.m_chop > 0f)
				{
					__result.m_chop *= 1f + toolModifiers.ChoppingPercent / 100f;
				}
				if (toolModifiers.ToolDamagePercent > 0f)
				{
					if (__result.m_chop > 0f)
					{
						__result.m_chop *= 1f + toolModifiers.ToolDamagePercent / 100f;
					}
					if (__result.m_pickaxe > 0f)
					{
						__result.m_pickaxe *= 1f + toolModifiers.ToolDamagePercent / 100f;
					}
				}
			}
		}

		[HarmonyPatch(typeof(ItemData), "GetArmor", new Type[]
		{
			typeof(int),
			typeof(float)
		})]
		internal static class ArmorBonusPatch
		{
			private static void Postfix(ItemData __instance, ref float __result)
			{
				if (ModifierData.HasAnyModifiers(__instance))
				{
					__result += RuneEffectManager.GetArmorBonus(__instance);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "Update")]
		internal static class PlayerUpdatePatch
		{
			private static void Postfix(Player __instance)
			{
				if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
				{
					RuneEffectManager.Recalculate(__instance);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "AddNoise")]
		internal static class NoiseReductionPatch
		{
			private static void Prefix(ref float range)
			{
				if (RuneEffectManager.NoiseReductionPercent > 0f)
				{
					range *= 1f - RuneEffectManager.NoiseReductionPercent / 100f;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "GetTotalFoodValue")]
		internal static class FoodValueBonusPatch
		{
			private static void Postfix(ref float hp, ref float stamina)
			{
				if (RuneEffectManager.MaxHealthBonus > 0f)
				{
					hp += RuneEffectManager.MaxHealthBonus;
				}
				if (RuneEffectManager.MaxStaminaBonus > 0f)
				{
					stamina += RuneEffectManager.MaxStaminaBonus;
				}
			}
		}

		[HarmonyPatch(typeof(SEMan), "ModifyStaminaRegen")]
		internal static class StaminaRegenPatch
		{
			private static void Postfix(ref float staminaMultiplier)
			{
				if (RuneEffectManager.StaminaRegenPercent > 0f)
				{
					staminaMultiplier += RuneEffectManager.StaminaRegenPercent / 100f;
				}
			}
		}

		[HarmonyPatch(typeof(SEMan), "ModifyHealthRegen")]
		internal static class HealthRegenPatch
		{
			private static void Postfix(ref float regenMultiplier)
			{
				if (RuneEffectManager.HpRegenPercent > 0f)
				{
					regenMultiplier += RuneEffectManager.HpRegenPercent / 100f;
				}
			}
		}

		[HarmonyPatch(typeof(SEMan), "ModifyEitrRegen")]
		internal static class EitrRegenPatch
		{
			private static void Postfix(ref float eitrMultiplier)
			{
				if (RuneEffectManager.EitrRegenPercent > 0f)
				{
					eitrMultiplier += RuneEffectManager.EitrRegenPercent / 100f;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "GetEquipmentMovementModifier")]
		internal static class MoveSpeedPatch
		{
			private static void Postfix(ref float __result)
			{
				if (RuneEffectManager.MoveSpeedPercent > 0f)
				{
					__result += RuneEffectManager.MoveSpeedPercent / 100f;
				}
			}
		}

		[HarmonyPatch(typeof(SEMan), "ModifyMaxCarryWeight")]
		internal static class CarryWeightPatch
		{
			private static void Postfix(ref float limit)
			{
				if (RuneEffectManager.CarryWeightBonus > 0f)
				{
					limit += RuneEffectManager.CarryWeightBonus;
				}
			}
		}

		[HarmonyPatch(typeof(Character), "Stagger")]
		internal static class StaggerResistPatch
		{
			private static bool Prefix(Character __instance)
			{
				if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
				{
					return true;
				}
				if (RuneEffectManager.StaggerResistPercent <= 0f)
				{
					return true;
				}
				return Random.Range(0f, 100f) > RuneEffectManager.StaggerResistPercent;
			}
		}

		[HarmonyPatch(typeof(ItemData), "GetMaxDurability", new Type[] { typeof(int) })]
		internal static class DurabilityPatch
		{
			private static void Postfix(ItemData __instance, ref float __result)
			{
				if (!ModifierData.HasAnyModifiers(__instance))
				{
					return;
				}
				foreach (RolledAffix affix in ModifierData.GetAffixes(__instance))
				{
					if (affix.AffixId == "durability")
					{
						__result += affix.Value;
					}
				}
			}
		}

		[HarmonyPatch(typeof(Minimap), "UpdateExplore")]
		internal static class ExplorerPatch
		{
			private static void Prefix(Minimap __instance)
			{
				if (RuneEffectManager.ExplorerPercent > 0f)
				{
					__instance.m_exploreRadius = 100f * (1f + RuneEffectManager.ExplorerPercent / 100f);
				}
			}
		}

		[HarmonyPatch(typeof(Skills), "RaiseSkill")]
		internal static class ValhallaPatch
		{
			private static void Prefix(ref float factor)
			{
				if (RuneEffectManager.MythicValhallaXpPercent > 0f)
				{
					factor *= 1f + RuneEffectManager.MythicValhallaXpPercent / 100f;
				}
			}
		}

		[HarmonyPatch(typeof(Character), "Damage")]
		internal static class CombatPatch
		{
			private static bool _inLightningStrike;

			private static void Postfix(Character __instance, HitData hit)
			{
				if (_inLightningStrike)
				{
					return;
				}
				Character attacker = hit.GetAttacker();
				if ((Object)(object)attacker == (Object)null)
				{
					return;
				}
				Player val = (Player)(object)((attacker is Player) ? attacker : null);
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer))
				{
					float totalDamage = hit.GetTotalDamage();
					if (RuneEffectManager.LifestealPercent > 0f && totalDamage > 0f)
					{
						float num = totalDamage * RuneEffectManager.LifestealPercent / 100f;
						((Character)val).Heal(num, true);
					}
					if (RuneEffectManager.StaminaOnKill > 0f && __instance.IsDead())
					{
						((Character)val).AddStamina(RuneEffectManager.StaminaOnKill);
					}
					if (RuneEffectManager.MythicLightningChance > 0f && Random.Range(0f, 100f) < RuneEffectManager.MythicLightningChance)
					{
						TriggerLightningStrike(__instance, val);
					}
				}
			}

			private static void TriggerLightningStrike(Character target, Player attacker)
			{
				//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_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Expected O, but got Unknown
				//IL_006e: Unknown result type (might be due to invalid IL or missing references)
				//IL_006f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0081: Unknown result type (might be due to invalid IL or missing references)
				//IL_0086: Unknown result type (might be due to invalid IL or missing references)
				//IL_008a: Unknown result type (might be due to invalid IL or missing references)
				//IL_008f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: 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)
				_inLightningStrike = true;
				try
				{
					Vector3 position = ((Component)target).transform.position;
					ZNetScene instance = ZNetScene.instance;
					GameObject val = ((instance != null) ? instance.GetPrefab("fx_eikthyr_forceField") : null);
					if ((Object)(object)val != (Object)null)
					{
						Object.Instantiate<GameObject>(val, position + Vector3.up * 0.5f, Quaternion.identity);
					}
					HitData val2 = new HitData();
					val2.m_damage.m_lightning = 30f;
					val2.m_point = position;
					Vector3 val3 = position - ((Component)attacker).transform.position;
					val2.m_dir = ((Vector3)(ref val3)).normalized;
					val2.SetAttacker((Character)(object)attacker);
					target.Damage(val2);
					target.Stagger(val2.m_dir);
				}
				finally
				{
					_inLightningStrike = false;
				}
			}
		}

		[HarmonyPatch(typeof(Character), "SetHealth")]
		internal static class UndyingPatch
		{
			private static float _lastUndyingProc;

			private static void Prefix(Character __instance, ref float health)
			{
				//IL_009f: 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)
				if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || RuneEffectManager.MythicUndyingPercent <= 0f || health > 0f)
				{
					return;
				}
				float time = Time.time;
				if (!(time - _lastUndyingProc < 60f))
				{
					health = __instance.GetMaxHealth() * RuneEffectManager.MythicUndyingPercent / 100f;
					_lastUndyingProc = time;
					ZNetScene instance = ZNetScene.instance;
					GameObject val = ((instance != null) ? instance.GetPrefab("vfx_Potion_health_medium") : null);
					if ((Object)(object)val != (Object)null)
					{
						Object.Instantiate<GameObject>(val, ((Component)__instance).transform.position, Quaternion.identity);
					}
					Logger.LogInfo((object)"Mythic Undying triggered — survived lethal blow!");
				}
			}
		}

		[HarmonyPatch(typeof(Character), "RPC_Damage")]
		internal static class HitModifierPatch
		{
			private static void Prefix(Character __instance, HitData hit)
			{
				Character attacker = hit.GetAttacker();
				if ((Object)(object)attacker == (Object)null)
				{
					return;
				}
				Player val = (Player)(object)((attacker is Player) ? attacker : null);
				if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer)
				{
					return;
				}
				ItemData currentWeapon = ((Humanoid)val).GetCurrentWeapon();
				if (currentWeapon != null && ModifierData.HasAnyModifiers(currentWeapon))
				{
					RuneEffectManager.WeaponModifiers weaponModifiers = RuneEffectManager.GetWeaponModifiers(currentWeapon);
					if (weaponModifiers.KnockbackPercent > 0f)
					{
						hit.m_pushForce *= 1f + weaponModifiers.KnockbackPercent / 100f;
					}
					float num = weaponModifiers.BackstabBonusPercent + weaponModifiers.CritStrikePercent;
					if (num > 0f)
					{
						hit.m_backstabBonus += num / 100f;
					}
				}
				if (RuneEffectManager.MythicBerserkerPercent > 0f && ((Character)val).GetHealthPercentage() <= 0.3f)
				{
					float num2 = 1f + RuneEffectManager.MythicBerserkerPercent / 100f;
					hit.m_damage.m_damage *= num2;
					hit.m_damage.m_blunt *= num2;
					hit.m_damage.m_slash *= num2;
					hit.m_damage.m_pierce *= num2;
				}
			}
		}

		[HarmonyPatch(typeof(Character), "Damage")]
		internal static class DamageResistancePatch
		{
			private static void Prefix(Character __instance, HitData hit)
			{
				if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
				{
					if (RuneEffectManager.FireResistance > 0f)
					{
						hit.m_damage.m_fire *= 1f - Mathf.Clamp01(RuneEffectManager.FireResistance / 100f);
					}
					if (RuneEffectManager.FrostResistance > 0f)
					{
						hit.m_damage.m_frost *= 1f - Mathf.Clamp01(RuneEffectManager.FrostResistance / 100f);
					}
					if (RuneEffectManager.PoisonResistance > 0f)
					{
						hit.m_damage.m_poison *= 1f - Mathf.Clamp01(RuneEffectManager.PoisonResistance / 100f);
					}
					if (RuneEffectManager.ShieldAegisPercent > 0f)
					{
						float num = 1f - Mathf.Clamp01(RuneEffectManager.ShieldAegisPercent / 100f);
						hit.m_damage.m_damage *= num;
						hit.m_damage.m_blunt *= num;
						hit.m_damage.m_slash *= num;
						hit.m_damage.m_pierce *= num;
						hit.m_damage.m_fire *= num;
						hit.m_damage.m_frost *= num;
						hit.m_damage.m_lightning *= num;
						hit.m_damage.m_poison *= num;
						hit.m_damage.m_spirit *= num;
					}
				}
			}
		}

		[HarmonyPatch(typeof(CharacterAnimEvent), "CustomFixedUpdate")]
		internal static class AttackSpeedPatch
		{
			private static void Postfix(Character ___m_character, Animator ___m_animator)
			{
				if ((Object)(object)___m_character != (Object)(object)Player.m_localPlayer || !___m_character.InAttack())
				{
					return;
				}
				Player val = (Player)(object)((___m_character is Player) ? ___m_character : null);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				ItemData currentWeapon = ((Humanoid)val).GetCurrentWeapon();
				if (currentWeapon != null && ModifierData.HasAnyModifiers(currentWeapon))
				{
					RuneEffectManager.WeaponModifiers weaponModifiers = RuneEffectManager.GetWeaponModifiers(currentWeapon);
					if (weaponModifiers.AttackSpeedPercent > 0f)
					{
						___m_animator.speed *= 1f + weaponModifiers.AttackSpeedPercent / 100f;
					}
					if (RuneEffectManager.MythicBerserkerPercent > 0f && ((Character)val).GetHealthPercentage() <= 0.3f)
					{
						___m_animator.speed *= 1f + RuneEffectManager.MythicBerserkerPercent / 100f;
					}
					RuneEffectManager.ToolModifiers toolModifiers = RuneEffectManager.GetToolModifiers(currentWeapon);
					if (toolModifiers.SwingSpeedPercent > 0f)
					{
						___m_animator.speed *= 1f + toolModifiers.SwingSpeedPercent / 100f;
					}
				}
			}
		}

		[HarmonyPatch(typeof(Humanoid), "BlockAttack")]
		internal static class FrostShieldPatch
		{
			private static void Postfix(Humanoid __instance, HitData hit, bool __result)
			{
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Expected O, but got Unknown
				//IL_0080: Unknown result type (might be due to invalid IL or missing references)
				//IL_0085: Unknown result type (might be due to invalid IL or missing references)
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				//IL_009c: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00aa: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
				if (!__result || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || RuneEffectManager.MythicFrostSlowPercent <= 0f)
				{
					return;
				}
				Character attacker = hit.GetAttacker();
				if (!((Object)(object)attacker == (Object)null) && !((Object)(object)attacker == (Object)(object)__instance))
				{
					HitData val = new HitData();
					val.m_damage.m_frost = RuneEffectManager.MythicFrostSlowPercent;
					val.m_point = ((Component)attacker).transform.position;
					Vector3 val2 = ((Component)attacker).transform.position - ((Component)__instance).transform.position;
					val.m_dir = ((Vector3)(ref val2)).normalized;
					val.SetAttacker((Character)(object)__instance);
					attacker.Damage(val);
					ZNetScene instance = ZNetScene.instance;
					GameObject val3 = ((instance != null) ? instance.GetPrefab("vfx_ColdBall_launch") : null);
					if ((Object)(object)val3 != (Object)null)
					{
						Object.Instantiate<GameObject>(val3, ((Component)attacker).transform.position + Vector3.up, Quaternion.identity);
					}
				}
			}
		}

		[HarmonyPatch(typeof(Skills), "RaiseSkill")]
		internal static class ToolMasteryPatch
		{
			private static void Prefix(SkillType skillType, ref float factor)
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Invalid comparison between Unknown and I4
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Invalid comparison between Unknown and I4
				if (!(RuneEffectManager.ToolMasteryPercent <= 0f) && ((int)skillType == 13 || (int)skillType == 12))
				{
					factor *= 1f + RuneEffectManager.ToolMasteryPercent / 100f;
				}
			}
		}

		[HarmonyPatch(typeof(Attack), "GetAttackStamina")]
		internal static class ToolStaminaPatch
		{
			private static void Postfix(Attack __instance, ref float __result)
			{
				Humanoid character = __instance.m_character;
				Player val = (Player)(object)((character is Player) ? character : null);
				if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer)
				{
					return;
				}
				ItemData weapon = __instance.m_weapon;
				if (weapon != null && ModifierData.HasAnyModifiers(weapon))
				{
					RuneEffectManager.ToolModifiers toolModifiers = RuneEffectManager.GetToolModifiers(weapon);
					if (toolModifiers.StaminaReductionPercent > 0f)
					{
						__result *= 1f - Mathf.Clamp01(toolModifiers.StaminaReductionPercent / 100f);
					}
					RuneEffectManager.WeaponModifiers weaponModifiers = RuneEffectManager.GetWeaponModifiers(weapon);
					if (weaponModifiers.DamagePercent > 0f)
					{
						__result *= 1.05f;
					}
				}
			}
		}

		[HarmonyPatch(typeof(ItemData), "GetBlockPower", new Type[]
		{
			typeof(int),
			typeof(float)
		})]
		internal static class ShieldBlockPowerPatch
		{
			internal static bool IsParrying;

			private static void Postfix(ItemData __instance, ref float __result)
			{
				if (ModifierData.HasAnyModifiers(__instance))
				{
					RuneEffectManager.ShieldModifiers shieldModifiers = RuneEffectManager.GetShieldModifiers(__instance);
					if (shieldModifiers.FortressPercent > 0f)
					{
						__result *= 1f + shieldModifiers.FortressPercent / 100f;
					}
					if (IsParrying && shieldModifiers.ParryBonusPercent > 0f)
					{
						__result *= 1f + shieldModifiers.ParryBonusPercent / 100f;
					}
				}
			}
		}

		[HarmonyPatch(typeof(Humanoid), "BlockAttack")]
		internal static class ShieldBlockAttackPatch
		{
			private static bool _wasParry;

			private static void Prefix(Humanoid __instance)
			{
				if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
				{
					_wasParry = __instance.m_blockTimer != -1f;
					ShieldBlockPowerPatch.IsParrying = _wasParry;
				}
			}

			private static void Postfix(Humanoid __instance, HitData hit, bool __result)
			{
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: Invalid comparison between Unknown and I4
				//IL_009c: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a3: Expected O, but got Unknown
				//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00da: Unknown result type (might be due to invalid IL or missing references)
				//IL_00df: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e4: 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_00ed: Unknown result type (might be due to invalid IL or missing references)
				ShieldBlockPowerPatch.IsParrying = false;
				if (!__result || (Object)(object)__instance != (Object)(object)Player.m_localPlayer)
				{
					return;
				}
				ItemData leftItem = __instance.m_leftItem;
				if (leftItem == null || (int)leftItem.m_shared.m_itemType != 5 || !ModifierData.HasAnyModifiers(leftItem))
				{
					return;
				}
				RuneEffectManager.ShieldModifiers shieldModifiers = RuneEffectManager.GetShieldModifiers(leftItem);
				Character attacker = hit.GetAttacker();
				if (shieldModifiers.ThornsDamage > 0f && (Object)(object)attacker != (Object)null && (Object)(object)attacker != (Object)(object)__instance)
				{
					HitData val = new HitData();
					val.m_damage.m_blunt = shieldModifiers.ThornsDamage;
					val.m_point = ((Component)attacker).transform.position;
					Vector3 val2 = ((Component)attacker).transform.position - ((Component)__instance).transform.position;
					val.m_dir = ((Vector3)(ref val2)).normalized;
					val.SetAttacker((Character)(object)__instance);
					attacker.Damage(val);
				}
				if (shieldModifiers.ResilienceStamina > 0f && _wasParry)
				{
					Player val3 = (Player)(object)((__instance is Player) ? __instance : null);
					if (val3 != null)
					{
						((Character)val3).AddStamina(shieldModifiers.ResilienceStamina);
					}
				}
			}
		}

		[HarmonyPatch(typeof(Player), "GetSkillFactor")]
		internal static class WeaponSkillPatch
		{
			private static void Postfix(Player __instance, SkillType skill, ref float __result)
			{
				//IL_0014: 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)
				if (!((Object)(object)__instance == (Object)null))
				{
					AddSkillBonusFromItem(((Humanoid)__instance).m_rightItem, skill, ref __result);
					AddSkillBonusFromItem(((Humanoid)__instance).m_leftItem, skill, ref __result);
				}
			}

			private static void AddSkillBonusFromItem(ItemData item, SkillType skill, ref float result)
			{
				//IL_001c: 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)
				if (item != null && ModifierData.HasAnyModifiers(item) && item.m_shared.m_skillType == skill)
				{
					RuneEffectManager.WeaponModifiers weaponModifiers = RuneEffectManager.GetWeaponModifiers(item);
					if (weaponModifiers.SkillBonus > 0f)
					{
						result += weaponModifiers.SkillBonus / 100f;
					}
				}
			}
		}

		public static void Register(Harmony harmony)
		{
			TryPatch(harmony, typeof(WeaponDamagePatch));
			TryPatch(harmony, typeof(ArmorBonusPatch));
			TryPatch(harmony, typeof(HitModifierPatch));
			TryPatch(harmony, typeof(DamageResistancePatch));
			TryPatch(harmony, typeof(AttackSpeedPatch));
			TryPatch(harmony, typeof(PlayerUpdatePatch));
			TryPatch(harmony, typeof(NoiseReductionPatch));
			TryPatch(harmony, typeof(CombatPatch));
			TryPatch(harmony, typeof(FoodValueBonusPatch));
			TryPatch(harmony, typeof(StaminaRegenPatch));
			TryPatch(harmony, typeof(HealthRegenPatch));
			TryPatch(harmony, typeof(EitrRegenPatch));
			TryPatch(harmony, typeof(MoveSpeedPatch));
			TryPatch(harmony, typeof(CarryWeightPatch));
			TryPatch(harmony, typeof(StaggerResistPatch));
			TryPatch(harmony, typeof(DurabilityPatch));
			TryPatch(harmony, typeof(ExplorerPatch));
			TryPatch(harmony, typeof(ValhallaPatch));
			TryPatch(harmony, typeof(UndyingPatch));
			TryPatch(harmony, typeof(FrostShieldPatch));
			TryPatch(harmony, typeof(ToolMasteryPatch));
			TryPatch(harmony, typeof(ToolStaminaPatch));
			TryPatch(harmony, typeof(ShieldBlockPowerPatch));
			TryPatch(harmony, typeof(ShieldBlockAttackPatch));
			TryPatch(harmony, typeof(WeaponSkillPatch));
		}

		private static void TryPatch(Harmony harmony, Type patchClass)
		{
			try
			{
				harmony.CreateClassProcessor(patchClass).Patch();
				Logger.LogInfo((object)("StatPatch applied: " + patchClass.Name));
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("StatPatch skipped " + patchClass.Name + ": " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(Player), "UseStamina")]
	internal static class OutOfCombatStaminaPatch
	{
		private static readonly HashSet<string> IgnoredCreatures = new HashSet<string> { "Deer" };

		private const float CombatRange = 25f;

		private const float IgnoredCreatureCombatRange = 10f;

		private const float CacheInterval = 1f;

		private static float _lastCheckTime;

		private static bool _lastResult;

		private static readonly float CombatRangeSqr = 625f;

		private static readonly float IgnoredRangeSqr = 100f;

		public static void Register(Harmony harmony)
		{
			try
			{
				harmony.CreateClassProcessor(typeof(OutOfCombatStaminaPatch)).Patch();
				Logger.LogInfo((object)"Patch applied: OutOfCombatStaminaPatch");
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("Patch skipped OutOfCombatStaminaPatch: " + ex.Message));
			}
		}

		private static void Prefix(ref Player __instance, ref float v)
		{
			if (ModConfig.EnableOutOfCombatStamina.Value)
			{
				float time = Time.time;
				if (time - _lastCheckTime > 1f)
				{
					_lastCheckTime = time;
					_lastResult = __instance.IsSensed() || IsTargetedByHostile(__instance);
				}
				if (!_lastResult)
				{
					v = 0f;
				}
			}
		}

		private static bool IsTargetedByHostile(Player player)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0058: 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)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)player).transform.position;
			foreach (BaseAI instance in BaseAI.Instances)
			{
				BaseAI val = instance;
				if ((Object)(object)val == (Object)null || (Object)(object)val.GetTargetCreature() != (Object)(object)player)
				{
					continue;
				}
				Vector3 val2 = ((Component)val).transform.position - position;
				float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
				string prefabName = Utils.GetPrefabName(((Component)val).gameObject);
				if (IgnoredCreatures.Contains(prefabName))
				{
					if (sqrMagnitude <= IgnoredRangeSqr)
					{
						return true;
					}
				}
				else if (sqrMagnitude <= CombatRangeSqr)
				{
					return true;
				}
			}
			return false;
		}
	}
}
namespace RunesOfRefinement.Systems
{
	public enum ItemRarity
	{
		Normal,
		Magic,
		Rare
	}
	public static class RarityHelper
	{
		public static readonly Color NormalColor = Color.white;

		public static readonly Color MagicColor = new Color(0.53f, 0.81f, 0.98f);

		public static readonly Color RareColor = new Color(1f, 0.95f, 0.3f);

		public static readonly Color CorruptedColor = new Color(0.85f, 0.2f, 0.2f);

		public static Color GetColor(ItemRarity rarity)
		{
			//IL_0011: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_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)
			return (Color)(rarity switch
			{
				ItemRarity.Magic => MagicColor, 
				ItemRarity.Rare => RareColor, 
				_ => NormalColor, 
			});
		}

		public static int MaxPrefixes(ItemRarity rarity)
		{
			return rarity switch
			{
				ItemRarity.Magic => 1, 
				ItemRarity.Rare => 3, 
				_ => 0, 
			};
		}

		public static int MaxSuffixes(ItemRarity rarity)
		{
			return rarity switch
			{
				ItemRarity.Magic => 1, 
				ItemRarity.Rare => 3, 
				_ => 0, 
			};
		}

		public static int MaxAffixSlots(ItemRarity rarity)
		{
			return MaxPrefixes(rarity) + MaxSuffixes(rarity);
		}
	}
	public enum AffixTarget
	{
		Weapon,
		Armor,
		Tool,
		Shield,
		Any
	}
	public enum AffixCategory
	{
		Offensive,
		Defensive,
		Utility,
		Elemental,
		Mythic
	}
	public enum AffixSlot
	{
		Prefix,
		Suffix
	}
	public class AffixDefinition
	{
		public string Id;

		public string NameToken;

		public string DescToken;

		public AffixTarget Target;

		public AffixCategory Category;

		public AffixSlot Slot;

		public float MinValue;

		public float MaxValue;

		public bool IsMythic;
	}
	public class RolledAffix
	{
		public string AffixId;

		public float Value;

		public override string ToString()
		{
			return AffixId + ":" + Value.ToString("F2", CultureInfo.InvariantCulture);
		}

		public static RolledAffix Parse(string s)
		{
			string[] array = s.Split(new char[1] { ':' });
			return new RolledAffix
			{
				AffixId = array[0],
				Value = float.Parse(array[1], CultureInfo.InvariantCulture)
			};
		}
	}
	public static class AffixPool
	{
		private static readonly Random Rng = new Random();

		internal static readonly float[][] TierScale = new float[6][]
		{
			new float[2] { 0f, 0.25f },
			new float[2] { 0.15f, 0.4f },
			new float[2] { 0.3f, 0.55f },
			new float[2] { 0.45f, 0.7f },
			new float[2] { 0.6f, 0.85f },
			new float[2] { 0.8f, 1f }
		};

		public static readonly List<AffixDefinition> All = new List<AffixDefinition>
		{
			new AffixDefinition
			{
				Id = "heavy_blade",
				NameToken = "$affix_heavy_blade",
				DescToken = "$affix_heavy_blade_desc",
				Target = AffixTarget.Weapon,
				Category = AffixCategory.Offensive,
				Slot = AffixSlot.Prefix,
				MinValue = 3f,
				MaxValue = 10f
			},
			new AffixDefinition
			{
				Id = "armor_pierce",
				NameToken = "$affix_armor_pierce",
				DescToken = "$affix_armor_pierce_desc",
				Target = AffixTarget.Weapon,
				Category = AffixCategory.Offensive,
				Slot = AffixSlot.Prefix,
				MinValue = 2f,
				MaxValue = 8f
			},
			new AffixDefinition
			{
				Id = "crit_strike",
				NameToken = "$affix_crit_strike",
				DescToken = "$affix_crit_strike_desc",
				Target = AffixTarget.Weapon,
				Category = AffixCategory.Offensive,
				Slot = AffixSlot.Prefix,
				MinValue = 3f,
				MaxValue = 12f
			},
			new AffixDefinition
			{
				Id = "backstab_bonus",
				NameToken = "$affix_backstab_bonus",
				DescToken = "$affix_backstab_bonus_desc",
				Target = AffixTarget.Weapon,
				Category = AffixCategory.Offensive,
				Slot = AffixSlot.Prefix,
				MinValue = 10f,
				MaxValue = 40f
			},
			new AffixDefinition
			{
				Id = "elem_fire",
				NameToken = "$affix_elem_fire",
				DescToken = "$affix_elem_fire_desc",
				Target = AffixTarget.Weapon,
				Category = AffixCategory.Elemental,
				Slot = AffixSlot.Prefix,
				MinValue = 3f,
				MaxValue = 15f
			},
			new AffixDefinition
			{
				Id = "elem_frost",
				NameToken = "$affix_elem_frost",
				DescToken = "$affix_elem_frost_desc",
				Target = AffixTarget.Weapon,
				Category = AffixCategory.Elemental,
				Slot = AffixSlot.Prefix,
				MinValue = 3f,
				MaxValue = 15f
			},
			new AffixDefinition
			{
				Id = "elem_lightning",
				NameToken = "$affix_elem_lightning",
				DescToken = "$affix_elem_lightning_desc",
				Target = AffixTarget.Weapon,
				Category = AffixCategory.Elemental,
				Slot = AffixSlot.Prefix,
				MinValue = 3f,
				MaxValue = 15f
			},
			new AffixDefinition
			{
				Id = "elem_poison",
				NameToken = "$affix_elem_poison",
				DescToken = "$affix_elem_poison_desc",
				Target = AffixTarget.Weapon,
				Category = AffixCategory.Elemental,
				Slot = AffixSlot.Prefix,
				MinValue = 3f,
				MaxValue = 15f
			},
			new AffixDefinition
			{
				Id = "elem_spirit",
				NameToken = "$affix_elem_spirit",
				DescToken = "$affix_elem_spirit_desc",
				Target = AffixTarget.Weapon,
				Category = AffixCategory.Elemental,
				Slot = AffixSlot.Prefix,
				MinValue = 3f,
				MaxValue = 15f
			},
			new AffixDefinition
			{
				Id = "swift",
				NameToken = "$affix_swift",
				DescToken = "$affix_swift_desc",
				Target = AffixTarget.Weapon,
				Category = AffixCategory.Offensive,
				Slot = AffixSlot.Suffix,
				MinValue = 1f,
				MaxValue = 5f
			},
			new AffixDefinition
			{
				Id = "warrior_of_north",
				NameToken = "$affix_warrior_of_north",
				DescToken = "$affix_warrior_of_north_desc",
				Target = AffixTarget.Weapon,
				Category = AffixCategory.Utility,
				Slot = AffixSlot.Suffix,
				MinValue = 2f,
				MaxValue = 8f
			},
			new AffixDefinition
			{
				Id = "bloodthirsty",
				NameToken = "$affix_bloodthirsty",
				DescToken = "$affix_bloodthirsty_desc",
				Target = AffixTarget.Weapon,
				Category = AffixCategory.Utility,
				Slot = AffixSlot.Suffix,
				MinValue = 1f,
				MaxValue = 4f
			},
			new AffixDefinition
			{
				Id = "momentum",
				NameToken = "$affix_momentum",
				DescToken = "$affix_momentum_desc",
				Target = AffixTarget.Weapon,
				Category = AffixCategory.Utility,
				Slot = AffixSlot.Suffix,
				MinValue = 3f,
				MaxValue = 10f
			},
			new AffixDefinition
			{
				Id = "knockback",
				NameToken = "$affix_knockback",
				DescToken = "$affix_knockback_desc",
				Target = AffixTarget.Weapon,
				Category = AffixCategory.Offensive,
				Slot = AffixSlot.Suffix,
				MinValue = 10f,
				MaxValue = 40f
			},
			new AffixDefinition
			{
				Id = "hardened",
				NameToken = "$affix_hardened",
				DescToken = "$affix_hardened_desc",
				Target = AffixTarget.Armor,
				Category = AffixCategory.Defensive,
				Slot = AffixSlot.Prefix,
				MinValue = 2f,
				MaxValue = 8f
			},
			new AffixDefinition
			{
				Id = "fortified",
				NameToken = "$affix_fortified",
				DescToken = "$affix_fortified_desc",
				Target = AffixTarget.Armor,
				Category = AffixCategory.Defensive,
				Slot = AffixSlot.Prefix,
				MinValue = 5f,
				MaxValue = 25f
			},
			new AffixDefinition
			{
				Id = "frost_resist",
				NameToken = "$affix_frost_resist",
				DescToken = "$affix_frost_resist_desc",
				Target = AffixTarget.Armor,
				Category = AffixCategory.Defensive,
				Slot = AffixSlot.Prefix,
				MinValue = 5f,
				MaxValue = 30f
			},
			new AffixDefinition
			{
				Id = "fire_resist",
				NameToken = "$affix_fire_resist",
				DescToken = "$affix_fire_resist_desc",
				Target = AffixTarget.Armor,
				Category = AffixCategory.Defensive,
				Slot = AffixSlot.Prefix,
				MinValue = 5f,
				MaxValue = 30f
			},
			new AffixDefinition
			{
				Id = "poison_resist",
				NameToken = "$affix_poison_resist",
				DescToken = "$affix_poison_resist_desc",
				Target = AffixTarget.Armor,
				Category = AffixCategory.Defensive,
				Slot = AffixSlot.Prefix,
				MinValue = 5f,
				MaxValue = 30f
			},
			new AffixDefinition
			{
				Id = "unfazed",
				NameToken = "$affix_unfazed",
				DescToken = "$affix_unfazed_desc",
				Target = AffixTarget.Armor,
				Category = AffixCategory.Defensive,
				Slot = AffixSlot.Prefix,
				MinValue = 5f,
				MaxValue = 20f
			},
			new AffixDefinition
			{
				Id = "sturdy_build",
				NameToken = "$affix_sturdy_build",
				DescToken = "$affix_sturdy_build_desc",
				Target = AffixTarget.Armor,
				Category = AffixCategory.Utility,
				Slot = AffixSlot.Suffix,
				MinValue = 5f,
				MaxValue = 20f
			},
			new AffixDefinition
			{
				Id = "regeneration",
				NameToken = "$affix_regeneration",
				DescToken = "$affix_regeneration_desc",
				Target = AffixTarget.Armor,
				Category = AffixCategory.Utility,
				Slot = AffixSlot.Suffix,
				MinValue = 3f,
				MaxValue = 12f
			},
			new AffixDefinition
			{
				Id = "stealth",
				NameToken = "$affix_stealth",
				DescToken = "$affix_stealth_desc",
				Target = AffixTarget.Armor,
				Category = AffixCategory.Utility,
				Slot = AffixSlot.Suffix,
				MinValue = 5f,
				MaxValue = 15f
			},
			new AffixDefinition
			{
				Id = "sprinter",
				NameToken = "$affix_sprinter",
				DescToken = "$affix_sprinter_desc",
				Target = AffixTarget.Armor,
				Category = AffixCategory.Utility,
				Slot = AffixSlot.Suffix,
				MinValue = 2f,
				MaxValue = 8f
			},
			new AffixDefinition
			{
				Id = "hp_regen",
				NameToken = "$affix_hp_regen",
				DescToken = "$affix_hp_regen_desc",
				Target = AffixTarget.Armor,
				Category = AffixCategory.Defensive,
				Slot = AffixSlot.Suffix,
				MinValue = 5f,
				MaxValue = 20f
			},
			new AffixDefinition
			{
				Id = "carry_weight",
				NameToken = "$affix_carry_weight",
				DescToken = "$affix_carry_weight_desc",
				Target = AffixTarget.Armor,
				Category = AffixCategory.Utility,
				Slot = AffixSlot.Suffix,
				MinValue = 10f,
				MaxValue = 50f
			},
			new AffixDefinition
			{
				Id = "tool_mining",
				NameToken = "$affix_tool_mining",
				DescToken = "$affix_tool_mining_desc",
				Target = AffixTarget.Tool,
				Category = AffixCategory.Offensive,
				Slot = AffixSlot.Prefix,
				MinValue = 5f,
				MaxValue = 25f
			},
			new AffixDefinition
			{
				Id = "tool_chopping",
				NameToken = "$affix_tool_chopping",
				DescToken = "$affix_tool_chopping_desc",
				Target = AffixTarget.Tool,
				Category = AffixCategory.Offensive,
				Slot = AffixSlot.Prefix,
				MinValue = 5f,
				MaxValue = 25f
			},
			new AffixDefinition
			{
				Id = "tool_sharpened",
				NameToken = "$affix_tool_sharpened",
				DescToken = "$affix_tool_sharpened_desc",
				Target = AffixTarget.Tool,
				Category = AffixCategory.Offensive,
				Slot = AffixSlot.Prefix,
				MinValue = 3f,
				MaxValue = 15f
			},
			new AffixDefinition
			{
				Id = "tool_lightweight",
				NameToken = "$affix_tool_lightweight",
				DescToken = "$affix_tool_lightweight_desc",
				Target = AffixTarget.Tool,
				Category = AffixCategory.Utility,
				Slot = AffixSlot.Suffix,
				MinValue = 2f,
				MaxValue = 8f
			},
			new AffixDefinition
			{
				Id = "tool_mastery",
				NameToken = "$affix_tool_mastery",
				DescToken = "$affix_tool_mastery_desc",
				Target = AffixTarget.Tool,
				Category = AffixCategory.Utility,
				Slot = AffixSlot.Suffix,
				MinValue = 5f,
				MaxValue = 25f
			},
			new AffixDefinition
			{
				Id = "tool_efficient",
				NameToken = "$affix_tool_efficient",
				DescToken = "$affix_tool_efficient_desc",
				Target = AffixTarget.Tool,
				Category = AffixCategory.Utility,
				Slot = AffixSlot.Suffix,
				MinValue = 3f,
				MaxValue = 12f
			},
			new AffixDefinition
			{
				Id = "shield_fortress",
				NameToken = "$affix_shield_fortress",
				DescToken = "$affix_shield_fortress_desc",
				Target = AffixTarget.Shield,
				Category = AffixCategory.Defensive,
				Slot = AffixSlot.Prefix,
				MinValue = 5f,
				MaxValue = 20f
			},
			new AffixDefinition
			{
				Id = "shield_thorns",
				NameToken = "$affix_shield_thorns",
				DescToken = "$affix_shield_thorns_desc",
				Target = AffixTarget.Shield,
				Category = AffixCategory.Defensive,
				Slot = AffixSlot.Prefix,
				MinValue = 3f,
				MaxValue = 12f
			},
			new AffixDefinition
			{
				Id = "shield_parry",
				NameToken = "$affix_shield_parry",
				DescToken = "$affix_shield_parry_desc",
				Target = AffixTarget.Shield,
				Category = AffixCategory.Defensive,
				Slot = AffixSlot.Prefix,
				MinValue = 10f,
				MaxValue = 30f
			},
			new AffixDefinition
			{
				Id = "shield_aegis",
				NameToken = "$affix_shield_aegis",
				DescToken = "$affix_shield_aegis_desc",
				Target = AffixTarget.Shield,
				Category = AffixCategory.Defensive,
				Slot = AffixSlot.Suffix,
				MinValue = 2f,
				MaxValue = 8f
			},
			new AffixDefinition
			{
				Id = "shield_resilience",
				NameToken = "$affix_shield_resilience",
				DescToken = "$affix_shield_resilience_desc",
				Target = AffixTarget.Shield,
				Category = AffixCategory.Utility,
				Slot = AffixSlot.Suffix,
				MinValue = 3f,
				MaxValue = 10f
			},
			new AffixDefinition
			{
				Id = "shield_bulwark",
				NameToken = "$affix_shield_bulwark",
				DescToken = "$affix_shield_bulwark_desc",
				Target = AffixTarget.Shield,
				Category = AffixCategory.Defensive,
				Slot = AffixSlot.Suffix,
				MinValue = 2f,
				MaxValue = 8f
			},
			new AffixDefinition
			{
				Id = "durability",
				NameToken = "$affix_durability",
				DescToken = "$affix_durability_desc",
				Target = AffixTarget.Any,
				Category = AffixCategory.Utility,
				Slot = AffixSlot.Suffix,
				MinValue = 50f,
				MaxValue = 200f
			},
			new AffixDefinition
			{
				Id = "eitr_regen",
				NameToken = "$affix_eitr_regen",
				DescToken = "$affix_eitr_regen_desc",
				Target = AffixTarget.Armor,
				Category = AffixCategory.Utility,
				Slot = AffixSlot.Suffix,
				MinValue = 5f,
				MaxValue = 20f
			},
			new AffixDefinition
			{
				Id = "explorer",
				NameToken = "$affix_explorer",
				DescToken = "$affix_explorer_desc",
				Target = AffixTarget.Armor,
				Category = AffixCategory.Utility,
				Slot = AffixSlot.Suffix,
				MinValue = 5f,
				MaxValue = 25f
			},
			new AffixDefinition
			{
				Id = "mythic_lightning_strike",
				NameToken = "$affix_mythic_lightning",
				DescToken = "$affix_mythic_lightning_desc",
				Target = AffixTarget.Weapon,
				Category = AffixCategory.Mythic,
				Slot = AffixSlot.Prefix,
				MinValue = 3f,
				MaxValue = 7f,
				IsMythic = true
			},
			new AffixDefinition
			{
				Id = "mythic_frost_shield",
				NameToken = "$affix_mythic_frost_shield",
				DescToken = "$affix_mythic_frost_shield_desc",
				Target = AffixTarget.Armor,
				Category = AffixCategory.Mythic,
				Slot = AffixSlot.Prefix,
				MinValue = 20f,
				MaxValue = 40f,
				IsMythic = true
			},
			new AffixDefinition
			{
				Id = "mythic_heimdall",
				NameToken = "$affix_mythic_heimdall",
				DescToken = "$affix_mythic_heimdall_desc",
				Target = AffixTarget.Weapon,
				Category = AffixCategory.Mythic,
				Slot = AffixSlot.Prefix,
				MinValue = 8f,
				MaxValue = 15f,
				IsMythic = true
			},
			new AffixDefinition
			{
				Id = "mythic_undying",
				NameToken = "$affix_mythic_undying",
				DescToken = "$affix_mythic_undying_desc",
				Target = AffixTarget.Armor,
				Category = AffixCategory.Mythic,
				Slot = AffixSlot.Prefix,
				MinValue = 15f,
				MaxValue = 30f,
				IsMythic = true
			},
			new AffixDefinition
			{
				Id = "mythic_berserker",
				NameToken = "$affix_mythic_berserker",
				DescToken = "$affix_mythic_berserker_desc",
				Target = AffixTarget.Weapon,
				Category = AffixCategory.Mythic,
				Slot = AffixSlot.Prefix,
				MinValue = 5f,
				MaxValue = 12f,
				IsMythic = true
			},
			new AffixDefinition
			{
				Id = "mythic_valhalla",
				NameToken = "$affix_mythic_valhalla",
				DescToken = "$affix_mythic_valhalla_desc",
				Target = AffixTarget.Armor,
				Category = AffixCategory.Mythic,
				Slot = AffixSlot.Prefix,
				MinValue = 3f,
				MaxValue = 8f,
				IsMythic = true
			}
		};

		public static AffixDefinition Get(string id)
		{
			return All.FirstOrDefault((AffixDefinition a) => a.Id == id);
		}

		public static RolledAffix RollRandom(AffixTarget target, AffixSlot? slotConstraint = null, AffixCategory? forceCategory = null, HashSet<string> exclude = null, int tier = 6)
		{
			List<AffixDefinition> list = All.Where((AffixDefinition a) => !a.IsMythic && (a.Target == target || a.Target == AffixTarget.Any || (target == AffixTarget.Tool && a.Target == AffixTarget.Weapon) || (target == AffixTarget.Shield && a.Target == AffixTarget.Armor)) && (!slotConstraint.HasValue || a.Slot == slotConstraint) && (!forceCategory.HasValue || a.Category == forceCategory) && (exclude == null || !exclude.Contains(a.Id))).ToList();
			if (list.Count == 0)
			{
				return null;
			}
			AffixDefinition def = list[Rng.Next(list.Count)];
			return Roll(def, tier);
		}

		public static RolledAffix RollWithLimits(AffixTarget target, int curPrefixes, int maxPrefixes, int curSuffixes, int maxSuffixes, AffixCategory? forceCategory = null, HashSet<string> exclude = null, int tier = 6)
		{
			bool flag = curPrefixes < maxPrefixes;
			bool flag2 = curSuffixes < maxSuffixes;
			if (!flag && !flag2)
			{
				return null;
			}
			AffixSlot? slotConstraint = null;
			if (flag && !flag2)
			{
				slotConstraint = AffixSlot.Prefix;
			}
			else if (flag2 && !flag)
			{
				slotConstraint = AffixSlot.Suffix;
			}
			return RollRandom(target, slotConstraint, forceCategory, exclude, tier);
		}

		public static RolledAffix RollElemental(AffixTarget target, int tier = 6)
		{
			return RollRandom(target, null, AffixCategory.Elemental, null, tier);
		}

		public static int CountPrefixes(List<RolledAffix> affixes)
		{
			return affixes.Count(delegate(RolledAffix a)
			{
				AffixDefinition affixDefinition = Get(a.AffixId);
				return affixDefinition != null && affixDefinition.Slot == AffixSlot.Prefix;
			});
		}

		public static int CountSuffixes(List<RolledAffix> affixes)
		{
			return affixes.Count(delegate(RolledAffix a)
			{
				AffixDefinition affixDefinition = Get(a.AffixId);
				return affixDefinition != null && affixDefinition.Slot == AffixSlot.Suffix;
			});
		}

		public static RolledAffix RollMythic(AffixTarget target, int tier = 6)
		{
			List<AffixDefinition> list = All.Where((AffixDefinition a) => a.IsMythic && (a.Target == target || a.Target == AffixTarget.Any || (target == AffixTarget.Tool && a.Target == AffixTarget.Weapon) || (target == AffixTarget.Shield && a.Target == AffixTarget.Armor))).ToList();
			if (list.Count == 0)
			{
				return null;
			}
			AffixDefinition def = list[Rng.Next(list.Count)];
			return Roll(def, tier);
		}

		public static RolledAffix RerollValue(RolledAffix existing, int tier = 6)
		{
			AffixDefinition affixDefinition = Get(existing.AffixId);
			if (affixDefinition == null)
			{
				return existing;
			}
			return Roll(affixDefinition, tier);
		}

		public static RolledAffix MaxRollValue(RolledAffix existing, int tier = 6)
		{
			AffixDefinition affixDefinition = Get(existing.AffixId);
			if (affixDefinition == null)
			{
				return existing;
			}
			tier = Mathf.Clamp(tier, 1, 6);
			float num = affixDefinition.MaxValue - affixDefinition.MinValue;
			float num2 = affixDefinition.MinValue + num * TierScale[tier - 1][1];
			num2 = Mathf.Round(num2 * 10f) / 10f;
			return new RolledAffix
			{
				AffixId = affixDefinition.Id,
				Value = num2
			};
		}

		public static string GetRollQualityColor(RolledAffix affix)
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			AffixDefinition affixDefinition = Get(affix.AffixId);
			if (affixDefinition == null)
			{
				return "#CCCCCC";
			}
			float num = affixDefinition.MaxValue - affixDefinition.MinValue;
			float num2 = ((num > 0f) ? Mathf.Clamp01((affix.Value - affixDefinition.MinValue) / num) : 0.5f);
			Color val;
			if (num2 < 0.25f)
			{
				float num3 = num2 / 0.25f;
				val = Color.Lerp(new Color(0.55f, 0.55f, 0.55f), Color.white, num3);
			}
			else if (num2 < 0.5f)
			{
				float num4 = (num2 - 0.25f) / 0.25f;
				val = Color.Lerp(Color.white, new Color(0.4f, 1f, 0.6f), num4);
			}
			else if (num2 < 0.75f)
			{
				float num5 = (num2 - 0.5f) / 0.25f;
				val = Color.Lerp(new Color(0.4f, 1f, 0.6f), new Color(0.4f, 0.7f, 1f), num5);
			}
			else
			{
				float num6 = (num2 - 0.75f) / 0.25f;
				val = Color.Lerp(new Color(0.4f, 0.7f, 1f), new Color(1f, 0.85f, 0.3f), num6);
			}
			return "#" + ColorUtility.ToHtmlStringRGB(val);
		}

		private static RolledAffix Roll(AffixDefinition def, int tier = 6)
		{
			tier = Mathf.Clamp(tier, 1, 6);
			float num = def.MaxValue - def.MinValue;
			float num2 = def.MinValue + num * TierScale[tier - 1][0];
			float num3 = def.MinValue + num * TierScale[tier - 1][1];
			float num4 = (float)((double)num2 + Rng.NextDouble() * (double)(num3 - num2));
			num4 = Mathf.Round(num4 * 10f) / 10f;
			return new RolledAffix
			{
				AffixId = def.Id,
				Value = num4
			};
		}
	}
	public static class ModifierData
	{
		private const string KeyRarity = "ror_rarity";

		private const string KeyAffixCount = "ror_affix_count";

		private const string KeyAffixPrefix = "ror_affix_";

		private const string KeyMythicAffix = "ror_mythic_affix";

		private const string KeyCorrupted = "ror_corrupted";

		public static ItemRarity GetRarity(ItemData item)
		{
			if (item.m_customData.TryGetValue("ror_rarity", out var value))
			{
				switch (value)
				{
				case "magic":
					return ItemRarity.Magic;
				case "rare":
					return ItemRarity.Rare;
				case "mythic":
					return ItemRarity.Rare;
				}
			}
			return ItemRarity.Normal;
		}

		public static void SetRarity(ItemData item, ItemRarity rarity)
		{
			switch (rarity)
			{
			case ItemRarity.Magic:
				item.m_customData["ror_rarity"] = "magic";
				break;
			case ItemRarity.Rare:
				item.m_customData["ror_rarity"] = "rare";
				break;
			default:
				item.m_customData["ror_rarity"] = "normal";
				break;
			}
		}

		public static List<RolledAffix> GetAffixes(ItemData item)
		{
			List<RolledAffix> list = new List<RolledAffix>();
			if (!item.m_customData.TryGetValue("ror_affix_count", out var value))
			{
				return list;
			}
			if (!int.TryParse(value, out var result))
			{
				return list;
			}
			for (int i = 0; i < result; i++)
			{
				if (item.m_customData.TryGetValue("ror_affix_" + i, out var value2))
				{
					list.Add(RolledAffix.Parse(value2));
				}
			}
			return list;
		}

		public static void SetAffixes(ItemData item, List<RolledAffix> affixes)
		{
			if (item.m_customData.TryGetValue("ror_affix_count", out var value) && int.TryParse(value, out var result))
			{
				for (int i = 0; i < result; i++)
				{
					item.m_customData.Remove("ror_affix_" + i);
				}
			}
			item.m_customData["ror_affix_count"] = affixes.Count.ToString();
			for (int j = 0; j < affixes.Count; j++)
			{
				item.m_customData["ror_affix_" + j] = affixes[j].ToString();
			}
		}

		public static RolledAffix GetMythicAffix(ItemData item)
		{
			if (item.m_customData.TryGetValue("ror_mythic_affix", out var value))
			{
				return RolledAffix.Parse(value);
			}
			return null;
		}

		public static void SetMythicAffix(ItemData item, RolledAffix affix)
		{
			item.m_customData["ror_mythic_affix"] = affix.ToString();
		}

		public static bool IsCorrupted(ItemData item)
		{
			return item.m_customData.ContainsKey("ror_corrupted");
		}

		public static void SetCorrupted(ItemData item, bool corrupted)
		{
			if (corrupted)
			{
				item.m_customData["ror_corrupted"] = "1";
			}
			else
			{
				item.m_customData.Remove("ror_corrupted");
			}
		}

		public static bool HasAnyModifiers(ItemData item)
		{
			return item.m_customData.ContainsKey("ror_rarity");
		}
	}
	public static class RuneEffectManager
	{
		public class WeaponModifiers
		{
			public float DamagePercent;

			public float AttackSpeedPercent;

			public float ArmorIgnore;

			public float SkillBonus;

			public float LifestealPercent;

			public float FireDamage;

			public float FrostDamage;

			public float LightningDamage;

			public float PoisonDamage;

			public float SpiritDamage;

			public float CritStrikePercent;

			public float BackstabBonusPercent;

			public float KnockbackPercent;

			public float StaminaOnKill;

			public float DurabilityBonus;

			public float LightningStrikeChance;

			public float HeimdallDamagePercent;

			public float BerserkerPercent;
		}

		public class ToolModifiers
		{
			public float MiningPercent;

			public float ChoppingPercent;

			public float ToolDamagePercent;

			public float SwingSpeedPercent;

			public float MasteryPercent;

			public float StaminaReductionPercent;

			public float DurabilityBonus;
		}

		public class ShieldModifiers
		{
			public float FortressPercent;

			public float ThornsDamage;

			public float ParryBonusPercent;

			public float AegisPercent;

			public float ResilienceStamina;

			public float BulwarkArmor;

			public float DurabilityBonus;
		}

		private static float _bonusDamagePercent;

		private static float _armorIgnore;

		private static float _attackSpeedPercent;

		private static float _lifestealPercent;

		private static float _weaponSkillBonus;

		private static float _fireDamage;

		private static float _frostDamage;

		private static float _lightningDamage;

		private static float _poisonDamage;

		private static float _spiritDamage;

		private static float _critStrikePercent;

		private static float _backstabBonusPercent;

		private static float _knockbackPercent;

		private static float _staminaOnKill;

		private static float _bonusArmorFlat;

		private static float _maxStaminaBonus;

		private static float _staminaRegenPercent;

		private static float _noiseReductionPercent;

		private static float _maxHealthBonus;

		private static float _frostResistance;

		private static float _fireResistance;

		private static float _poisonResistance;

		private static float _staggerResistPercent;

		private static float _moveSpeedPercent;

		private static float _hpRegenPercent;

		private static float _carryWeightBonus;

		private static float _durabilityBonus;

		private static float _eitrRegenPercent;

		private static float _explorerPercent;

		private static float _mythicLightningChance;

		private static float _mythicFrostSlowPercent;

		private static float _mythicHeimdallDamagePercent;

		private static float _mythicUndyingPercent;

		private static float _mythicBerserkerPercent;

		private static float _mythicValhallaXpPercent;

		private static float _toolMiningPercent;

		private static float _toolChoppingPercent;

		private static float _toolDamagePercent;

		private static float _toolSwingSpeedPercent;

		private static float _toolMasteryPercent;

		private static float _toolEfficiencyPercent;

		private static float _shieldFortressPercent;

		private static float _shieldThorns;

		private static float _shieldParryPercent;

		private static float _shieldAegisPercent;

		private static float _shieldResilienceStamina;

		private static float _shieldBulwarkArmor;

		private static int _lastEquipHash;

		public static float BonusDamagePercent => _bonusDamagePercent;

		public static float BonusArmorFlat => _bonusArmorFlat;

		public static float ArmorIgnore => _armorIgnore;

		public static float AttackSpeedPercent => _attackSpeedPercent;

		public static float LifestealPercent => _lifestealPercent;

		public static float WeaponSkillBonus => _weaponSkillBonus;

		public static float MaxStaminaBonus => _maxStaminaBonus;

		public static float StaminaRegenPercent => _staminaRegenPercent;

		public static float NoiseReductionPercent => _noiseReductionPercent;

		public static float MaxHealthBonus => _maxHealthBonus;

		public static float FrostResistance => _frostResistance;

		public static float FireResistance => _fireResistance;

		public static float PoisonResistance => _poisonResistance;

		public static float FireDamage => _fireDamage;

		public static float FrostDamage => _frostDamage;

		public static float LightningDamage => _lightningDamage;

		public static float PoisonDamage => _poisonDamage;

		public static float SpiritDamage => _spiritDamage;

		public static float CritStrikePercent => _critStrikePercent;

		public static float BackstabBonusPercent => _backstabBonusPercent;

		public static float KnockbackPercent => _knockbackPercent;

		public static float StaminaOnKill => _staminaOnKill;

		public static float StaggerResistPercent => _staggerResistPercent;

		public static float MoveSpeedPercent => _moveSpeedPercent;

		public static float HpRegenPercent => _hpRegenPercent;

		public static float CarryWeightBonus => _carryWeightBonus;

		public static float DurabilityBonus => _durabilityBonus;

		public static float EitrRegenPercent => _eitrRegenPercent;

		public static float ExplorerPercent => _explorerPercent;

		public static float MythicLightningChance => _mythicLightningChance;

		public static float MythicFrostSlowPercent => _mythicFrostSlowPercent;

		public static float MythicHeimdallDamagePercent => _mythicHeimdallDamagePercent;

		public static float MythicUndyingPercent => _mythicUndyingPercent;

		public static float MythicBerserkerPercent => _mythicBerserkerPercent;

		public static float MythicValhallaXpPercent => _mythicValhallaXpPercent;

		public static float ToolMiningPercent => _toolMiningPercent;

		public static float ToolChoppingPercent => _toolChoppingPercent;

		public static float ToolDamagePercent => _toolDamagePercent;

		public static float ToolSwingSpeedPercent => _toolSwingSpeedPercent;

		public static float ToolMasteryPercent => _toolMasteryPercent;

		public static float ToolEfficiencyPercent => _toolEfficiencyPercent;

		public static float ShieldFortressPercent => _shieldFortressPercent;

		public static float ShieldThorns => _shieldThorns;

		public static float ShieldParryPercent => _shieldParryPercent;

		public static float ShieldAegisPercent => _shieldAegisPercent;

		public static float ShieldResilienceStamina => _shieldResilienceStamina;

		public static float ShieldBulwarkArmor => _shieldBulwarkArmor;

		public static WeaponModifiers GetWeaponModifiers(ItemData weapon)
		{
			WeaponModifiers weaponModifiers = new WeaponModifiers();
			if (weapon == null || !ModifierData.HasAnyModifiers(weapon))
			{
				return weaponModifiers;
			}
			foreach (RolledAffix affix in ModifierData.GetAffixes(weapon))
			{
				switch (affix.AffixId)
				{
				case "heavy_blade":
					weaponModifiers.DamagePercent += affix.Value;
					break;
				case "swift":
					weaponModifiers.AttackSpeedPercent += affix.Value;
					break;
				case "armor_pierce":
					weaponModifiers.ArmorIgnore += affix.Value;
					break;
				case "warrior_of_north":
					weaponModifiers.SkillBonus += affix.Value;
					break;
				case "bloodthirsty":
					weaponModifiers.LifestealPercent += affix.Value;
					break;
				case "elem_fire":
					weaponModifiers.FireDamage += affix.Value;
					break;
				case "elem_frost":
					weaponModifiers.FrostDamage += affix.Value;
					break;
				case "elem_lightning":
					weaponModifiers.LightningDamage += affix.Value;
					break;
				case "elem_poison":
					weaponModifiers.PoisonDamage += affix.Value;
					break;
				case "elem_spirit":
					weaponModifiers.SpiritDamage += affix.Value;
					break;
				case "crit_strike":
					weaponModifiers.CritStrikePercent += affix.Value;
					break;
				case "backstab_bonus":
					weaponModifiers.BackstabBonusPercent += affix.Value;
					break;
				case "knockback":
					weaponModifiers.KnockbackPercent += affix.Value;
					break;
				case "momentum":
					weaponModifiers.StaminaOnKill += affix.Value;
					break;
				case "durability":
					weaponModifiers.DurabilityBonus += affix.Value;
					break;
				}
			}
			RolledAffix mythicAffix = ModifierData.GetMythicAffix(weapon);
			if (mythicAffix != null)
			{
				switch (mythicAffix.AffixId)
				{
				case "mythic_lightning_strike":
					weaponModifiers.LightningStrikeChance = mythicAffix.Value;
					break;
				case "mythic_heimdall":
					weaponModifiers.HeimdallDamagePercent = mythicAffix.Value;
					break;
				case "mythic_berserker":
					weaponModifiers.BerserkerPercent = mythicAffix.Value;
					break;
				}
			}
			return weaponModifiers;
		}

		public static float GetArmorBonus(ItemData armor)
		{
			if (armor == null || !ModifierData.HasAnyModifiers(armor))
			{
				return 0f;
			}
			float num = 0f;
			foreach (RolledAffix affix in ModifierData.GetAffixes(armor))
			{
				if (affix.AffixId == "hardened")
				{
					num += affix.Value;
				}
				if (affix.AffixId == "shield_bulwark")
				{
					num += affix.Value;
				}
			}
			return num;
		}

		public static ToolModifiers GetToolModifiers(ItemData tool)
		{
			ToolModifiers toolModifiers = new ToolModifiers();
			if (tool == null || !ModifierData.HasAnyModifiers(tool))
			{
				return toolModifiers;
			}
			foreach (RolledAffix affix in ModifierData.GetAffixes(tool))
			{
				switch (affix.AffixId)
				{
				case "tool_mining":
					toolModifiers.MiningPercent += affix.Value;
					break;
				case "tool_chopping":
					toolModifiers.ChoppingPercent += affix.Value;
					break;
				case "tool_sharpened":
					toolModifiers.ToolDamagePercent += affix.Value;
					break;
				case "tool_lightweight":
					toolModifiers.SwingSpeedPercent += affix.Value;
					break;
				case "tool_mastery":
					toolModifiers.MasteryPercent += affix.Value;
					break;
				case "tool_efficient":
					toolModifiers.StaminaReductionPercent += affix.Value;
					break;
				case "durability":
					toolModifiers.DurabilityBonus += affix.Value;
					break;
				}
			}
			return toolModifiers;
		}

		public static ShieldModifiers GetShieldModifiers(ItemData shield)
		{
			ShieldModifiers shieldModifiers = new ShieldModifiers();
			if (shield == null || !ModifierData.HasAnyModifiers(shield))
			{
				return shieldModifiers;
			}
			foreach (RolledAffix affix in ModifierData.GetAffixes(shield))
			{
				switch (affix.AffixId)
				{
				case "shield_fortress":
					shieldModifiers.FortressPercent += affix.Value;
					break;
				case "shield_thorns":
					shieldModifiers.ThornsDamage += affix.Value;
					break;
				case "shield_parry":
					shieldModifiers.ParryBonusPercent += affix.Value;
					break;
				case "shield_aegis":
					shieldModifiers.AegisPercent += affix.Value;
					break;
				case "shield_resilience":
					shieldModifiers.ResilienceStamina += affix.Value;
					break;
				case "shield_bulwark":
					shieldModifiers.BulwarkArmor += affix.Value;
					break;
				case "durability":
					shieldModifiers.DurabilityBonus += affix.Value;
					break;
				}
			}
			return shieldModifiers;
		}

		public static void Recalculate(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			int num = ComputeEquipHash(player);
			if (num == _lastEquipHash)
			{
				return;
			}
			_lastEquipHash = num;
			_bonusDamagePercent = 0f;
			_bonusArmorFlat = 0f;
			_armorIgnore = 0f;
			_attackSpeedPercent = 0f;
			_lifestealPercent = 0f;
			_weaponSkillBonus = 0f;
			_maxStaminaBonus = 0f;
			_staminaRegenPercent = 0f;
			_noiseReductionPercent = 0f;
			_maxHealthBonus = 0f;
			_frostResistance = 0f;
			_fireResistance = 0f;
			_poisonResistance = 0f;
			_fireDamage = 0f;
			_frostDamage = 0f;
			_lightningDamage = 0f;
			_poisonDamage = 0f;
			_spiritDamage = 0f;
			_critStrikePercent = 0f;
			_backstabBonusPercent = 0f;
			_knockbackPercent = 0f;
			_staminaOnKill = 0f;
			_staggerResistPercent = 0f;
			_moveSpeedPercent = 0f;
			_hpRegenPercent = 0f;
			_carryWeightBonus = 0f;
			_durabilityBonus = 0f;
			_eitrRegenPercent = 0f;
			_explorerPercent = 0f;
			_mythicLightningChance = 0f;
			_mythicFrostSlowPercent = 0f;
			_mythicHeimdallDamagePercent = 0f;
			_mythicUndyingPercent = 0f;
			_mythicBerserkerPercent = 0f;
			_mythicValhallaXpPercent = 0f;
			_toolMiningPercent = 0f;
			_toolChoppingPercent = 0f;
			_toolDamagePercent = 0f;
			_toolSwingSpeedPercent = 0f;
			_toolMasteryPercent = 0f;
			_toolEfficiencyPercent = 0f;
			_shieldFortressPercent = 0f;
			_shieldThorns = 0f;
			_shieldParryPercent = 0f;
			_shieldAegisPercent = 0f;
			_shieldResilienceStamina = 0f;
			_shieldBulwarkArmor = 0f;
			Inventory inventory = ((Humanoid)player).GetInventory();
			if (inventory == null)
			{
				return;
			}
			foreach (ItemData equippedItem in inventory.GetEquippedItems())
			{
				if (EssenceLogic.IsEquipment(equippedItem) && ModifierData.HasAnyModifiers(equippedItem))
				{
					ProcessAffixes(ModifierData.GetAffixes(equippedItem));
					ProcessMythic(ModifierData.GetMythicAffix(equippedItem));
				}
			}
		}

		public static void Invalidate()
		{
			_lastEquipHash = -1;
		}

		private static int ComputeEquipHash(Player player)
		{
			int num = 17;
			Inventory inventory = ((Humanoid)player).GetInventory();
			if (inventory == null)
			{
				return num;
			}
			foreach (ItemData equippedItem in inventory.GetEquippedItems())
			{
				if (EssenceLogic.IsEquipment(equippedItem))
				{
					num = num * 31 + equippedItem.m_gridPos.x;
					num = num * 31 + equippedItem.m_gridPos.y;
					num = num * 31 + (equippedItem.m_shared?.m_name?.GetHashCode()).GetValueOrDefault();
					if (equippedItem.m_customData.TryGetValue("ror_affix_count", out var value))
					{
						num = num * 31 + value.GetHashCode();
					}
					if (equippedItem.m_customData.TryGetValue("ror_rarity", out var value2))
					{
						num = num * 31 + value2.GetHashCode();
					}
					if (equippedItem.m_customData.TryGetValue("ror_corrupted",