Decompiled source of RunesOfRefinement v0.5.2
RunesOfRefinement.dll
Decompiled 13 hours ago
The result has been truncated due to the large size, download it to view full contents!
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",