Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of RunesOfRefinement v0.5.2
RunesOfRefinement.dll
Decompiled 3 months 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",