using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BalrondItemRarity.Runeforging; using BalrondItemRarity.UI; using BalrondItemRarity.VFX; using BepInEx; using HarmonyLib; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.Rendering; 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: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("BalrondItemRarity")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("BalrondItemRarity")] [assembly: AssemblyTitle("BalrondItemRarity")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace BalrondItemRarity { public static class ItemFilters { public static bool IsRarityEligible(ItemData item) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected I4, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Invalid comparison between Unknown and I4 if (item == null || item.m_shared == null) { return false; } ItemType itemType = item.m_shared.m_itemType; ItemType val = itemType; switch (val - 3) { default: if ((int)val != 22) { break; } goto case 0; case 0: case 1: case 2: case 3: case 4: case 8: case 9: case 11: case 14: return !item.m_shared.m_attack.m_consumeItem; case 5: case 6: case 7: case 10: case 12: case 13: break; } return false; } public static RarityStatProfile GetProfile(ItemData item) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected I4, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Invalid comparison between Unknown and I4 if (item == null || item.m_shared == null) { return RarityStatProfile.Utility; } ItemType itemType = item.m_shared.m_itemType; ItemType val = itemType; switch (val - 3) { default: if ((int)val != 22) { break; } goto case 0; case 3: case 4: case 8: case 9: case 14: return RarityStatProfile.Armor; case 2: return RarityStatProfile.Shield; case 0: case 1: case 11: return RarityStatProfile.Weapon; case 5: case 6: case 7: case 10: case 12: case 13: break; } return RarityStatProfile.Utility; } } public enum ItemRarity { Common, Uncommon, Rare, Epic, Legendary } public enum RarityStatProfile { Armor, Weapon, Shield, Utility } public sealed class RarityDef { public ItemRarity Rarity; public string Label; public string HexColor; public Color Color; public float ArmorBaseMultiplier; public float ArmorPerLevelMultiplier; public float WeaponBaseMultiplier; public float WeaponPerLevelMultiplier; public float DurabilityMultiplier; public float DurabilityPerLevelMultiplier; public float WeightMultiplier; public float ImproveCostMultiplier; public float ShieldBlockMultiplier; public float ShieldDeflectionMultiplier; public float ShieldTimedBlockFlatBonus; public float ShieldTimedBlockTowerValue; public RarityDef(ItemRarity rarity, string label, string hex, float armor, float weapon, float durability, float weight, float improveCost, float shieldBlock, float shieldDeflection, float shieldTimedBlockFlatBonus, float shieldTimedBlockTowerValue) { Rarity = rarity; Label = label; HexColor = hex; ColorUtility.TryParseHtmlString(hex, ref Color); ArmorBaseMultiplier = 1f + armor; ArmorPerLevelMultiplier = 1f + armor; WeaponBaseMultiplier = 1f + weapon; WeaponPerLevelMultiplier = 1f + weapon; DurabilityMultiplier = 1f + durability; DurabilityPerLevelMultiplier = 1f + durability; WeightMultiplier = 1f + weight; ImproveCostMultiplier = improveCost; ShieldBlockMultiplier = 1f + shieldBlock; ShieldDeflectionMultiplier = 1f + shieldDeflection; ShieldTimedBlockFlatBonus = shieldTimedBlockFlatBonus; ShieldTimedBlockTowerValue = shieldTimedBlockTowerValue; } } public static class RarityConfig { private static readonly Dictionary _defs = new Dictionary(); public static void Init() { //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) _defs.Clear(); _defs[ItemRarity.Common] = new RarityDef(ItemRarity.Common, "Common", "#D9D8D2", 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f); _defs[ItemRarity.Uncommon] = new RarityDef(ItemRarity.Uncommon, "Uncommon", "#40FF40", 0.1f, 0.06f, 0.08f, 0.01f, 0.4f, 0.06f, 0.06f, 0.05f, 1.05f); _defs[ItemRarity.Rare] = new RarityDef(ItemRarity.Rare, "Rare", "#4090FF", 0.15f, 0.1f, 0.15f, 0.02f, 0.6f, 0.1f, 0.1f, 0.1f, 1.1f); _defs[ItemRarity.Epic] = new RarityDef(ItemRarity.Epic, "Epic", "#B040FF", 0.2f, 0.15f, 0.25f, 0.03f, 0.8f, 0.15f, 0.15f, 0.15f, 1.15f); _defs[ItemRarity.Legendary] = new RarityDef(ItemRarity.Legendary, "Legendary", "#FFC640", 0.25f, 0.2f, 0.35f, 0.05f, 1.2f, 0.2f, 0.2f, 0.2f, 1.2f); RarityVisualSettings.SetRarityLayerColorOverride(ItemRarity.Epic, RarityVisualLayer.WorldBeam, new Color(1f, 0f, 1f, 1f)); RarityVisualSettings.SetRarityLayerColorOverride(ItemRarity.Epic, RarityVisualLayer.WorldGlow, new Color(1f, 0f, 1f, 1f)); RarityVisualSettings.SetRarityLayerColorOverride(ItemRarity.Epic, RarityVisualLayer.EquippedGlow, new Color(1f, 0f, 1f, 1f)); } public static RarityDef Get(ItemRarity rarity) { RarityDef value; return _defs.TryGetValue(rarity, out value) ? value : _defs[ItemRarity.Common]; } public static ItemRarity Next(ItemRarity rarity) { if (rarity >= ItemRarity.Legendary) { return ItemRarity.Legendary; } return rarity + 1; } public static bool IsMagic(ItemRarity rarity) { return rarity > ItemRarity.Common; } } public static class RarityData { public const string KeyRarity = "Balrond.Rarity"; public const string KeyCreatorId = "Balrond.CreatorID"; public const string KeyCreatorName = "Balrond.CreatorName"; public const string KeyCustomName = "Balrond.CustomName"; public const string KeyVersion = "Balrond.Version"; public const string Version = "1"; public static ItemRarity GetRarity(this ItemData item) { if (item == null || item.m_customData == null) { return ItemRarity.Common; } if (!item.m_customData.TryGetValue("Balrond.Rarity", out var value)) { return ItemRarity.Common; } if (int.TryParse(value, out var result) && result >= 0 && result <= 4) { return (ItemRarity)result; } if (Enum.TryParse(value, ignoreCase: true, out var result2)) { return result2; } return ItemRarity.Common; } public static void SetRarityPreviewOnly(this ItemData item, ItemRarity rarity) { Ensure(item); Dictionary customData = item.m_customData; int num = (int)rarity; customData["Balrond.Rarity"] = num.ToString(); item.m_customData["Balrond.Version"] = "1"; } public static void SetRarity(this ItemData item, ItemRarity rarity) { Ensure(item); Dictionary customData = item.m_customData; int num = (int)rarity; customData["Balrond.Rarity"] = num.ToString(); item.m_customData["Balrond.Version"] = "1"; RarityLegendaryBonuses.ApplyPermanentBonuses(item); } public static bool HasRarity(this ItemData item) { return item != null && item.GetRarity() > ItemRarity.Common; } public static void SetCreator(this ItemData item, Player player) { Ensure(item); if (!((Object)(object)player == (Object)null)) { item.m_customData["Balrond.CreatorID"] = player.GetPlayerID().ToString(); item.m_customData["Balrond.CreatorName"] = player.GetPlayerName(); } } public static long GetCreatorId(this ItemData item) { if (item == null || item.m_customData == null) { return 0L; } string value; long result; return (item.m_customData.TryGetValue("Balrond.CreatorID", out value) && long.TryParse(value, out result)) ? result : 0; } public static string GetCreatorName(this ItemData item) { if (item == null || item.m_customData == null) { return string.Empty; } string value; return item.m_customData.TryGetValue("Balrond.CreatorName", out value) ? value : string.Empty; } public static bool CanRename(this ItemData item, Player player) { if (item == null || (Object)(object)player == (Object)null) { return false; } if (item.GetRarity() != ItemRarity.Legendary) { return false; } long creatorId = item.GetCreatorId(); return creatorId == 0L || creatorId == player.GetPlayerID(); } public static string GetCustomName(this ItemData item) { if (item == null || item.m_customData == null) { return string.Empty; } string value; return item.m_customData.TryGetValue("Balrond.CustomName", out value) ? value : string.Empty; } public static void SetCustomName(this ItemData item, string name) { Ensure(item); if (string.IsNullOrEmpty(name)) { item.m_customData.Remove("Balrond.CustomName"); } else { item.m_customData["Balrond.CustomName"] = name.Trim(); } } public static string GetDisplayName(this ItemData item) { string customName = item.GetCustomName(); return string.IsNullOrEmpty(customName) ? Localization.instance.Localize(item.m_shared.m_name) : customName; } public static string GetColoredDisplayName(this ItemData item) { ItemRarity rarity = item.GetRarity(); RarityDef rarityDef = RarityConfig.Get(rarity); string displayName = item.GetDisplayName(); if (rarity == ItemRarity.Common) { return displayName; } return "" + displayName + ""; } private static void Ensure(ItemData item) { if (item.m_customData == null) { item.m_customData = new Dictionary(); } } } public static class RarityLegendaryBonuses { public const string LegendaryAppliedKey = "$balrond_legendary_bonuses_applied"; public const float GlobalMovementModifierBonus = 0.01f; public const float HelmetDodgeStaminaBonus = -0.02f; public const float ChestAttackStaminaBonus = -0.02f; public const float LegsRunStaminaBonus = -0.02f; public const float ShieldBlockStaminaBonus = -0.05f; public const float TowerShieldTimedBlockMinimum = 1.1f; public const float CapeArmorBonus = 1f; public const float MaceDurabilityBonusMultiplier = 1.05f; public const float TwoHandedMaceDurabilityBonusMultiplier = 1.1f; public const float SwordBlockStaminaBonus1H = -0.02f; public const float SwordBlockStaminaBonus2H = -0.04f; public const float AxeDodgeStaminaBonus1H = -0.02f; public const float AxeDodgeStaminaBonus2H = -0.04f; public const float SpearRunStaminaBonus = -0.02f; public const float PolearmRunStaminaBonus = -0.04f; public const float KnifeSneakStaminaBonus = -0.08f; public const float BowAttackStaminaBonus = -0.02f; public const float CrossbowAttackStaminaBonus = -0.03f; public const float PickaxeAttackStaminaBonus = -0.05f; public const float MagicEitrRegenBonus1H = 0.03f; public const float MagicEitrRegenBonus2H = 0.06f; public static bool IsLegendary(ItemData item) { return item != null && item.m_shared != null && ItemFilters.IsRarityEligible(item) && item.GetRarity() == ItemRarity.Legendary; } public static bool IsTowerShield(ItemData item) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 if (item == null || item.m_shared == null) { return false; } if ((int)item.m_shared.m_itemType != 5) { return false; } return item.m_shared.m_timedBlockBonus <= 1f; } public static void ApplyPermanentBonuses(ItemData item) { if (IsLegendary(item) && item.m_shared != null && (!item.m_customData.TryGetValue("$balrond_legendary_bonuses_applied", out var value) || !(value == "true"))) { ApplyPermanentMovementModifier(item); ApplyPermanentStaminaModifiers(item); ApplyPermanentWeaponSpecificBonus(item); item.m_customData["$balrond_legendary_bonuses_applied"] = "true"; } } private static void ApplyPermanentMovementModifier(ItemData item) { if (item != null && item.m_shared != null && item.m_shared.m_movementModifier < 0f) { item.m_shared.m_movementModifier = Mathf.Min(0f, item.m_shared.m_movementModifier + 0.01f); } } private static void ApplyPermanentStaminaModifiers(ItemData item) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_004b: Expected I4, but got Unknown if (item == null || item.m_shared == null) { return; } ItemType itemType = item.m_shared.m_itemType; ItemType val = itemType; switch (val - 5) { case 1: { SharedData shared2 = item.m_shared; shared2.m_dodgeStaminaModifier += -0.02f; break; } case 2: { SharedData shared4 = item.m_shared; shared4.m_attackStaminaModifier += -0.02f; break; } case 6: { SharedData shared3 = item.m_shared; shared3.m_runStaminaModifier += -0.02f; break; } case 0: if (!IsTowerShield(item)) { SharedData shared = item.m_shared; shared.m_blockStaminaModifier += -0.05f; } break; case 3: case 4: case 5: break; } } private static void ApplyPermanentWeaponSpecificBonus(ItemData item) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected I4, but got Unknown if (item == null || item.m_shared == null || !item.IsWeapon()) { return; } bool flag = item.IsTwoHanded(); if (UsesEitrForAnyAttack(item)) { SharedData shared = item.m_shared; shared.m_eitrRegenModifier += (flag ? 0.06f : 0.03f); return; } SkillType skillType = item.m_shared.m_skillType; SkillType val = skillType; switch (val - 1) { case 11: { SharedData shared4 = item.m_shared; shared4.m_attackStaminaModifier += -0.05f; break; } case 0: { SharedData shared3 = item.m_shared; shared3.m_blockStaminaModifier += (flag ? (-0.04f) : (-0.02f)); break; } case 6: { SharedData shared5 = item.m_shared; shared5.m_dodgeStaminaModifier += (flag ? (-0.04f) : (-0.02f)); break; } case 2: break; case 4: { SharedData shared10 = item.m_shared; shared10.m_runStaminaModifier += -0.02f; break; } case 3: { SharedData shared9 = item.m_shared; shared9.m_runStaminaModifier += -0.04f; break; } case 1: { SharedData shared8 = item.m_shared; shared8.m_sneakStaminaModifier += -0.08f; break; } case 7: { SharedData shared7 = item.m_shared; shared7.m_attackStaminaModifier += -0.02f; break; } case 13: { SharedData shared6 = item.m_shared; shared6.m_attackStaminaModifier += -0.03f; break; } case 8: case 9: { SharedData shared2 = item.m_shared; shared2.m_eitrRegenModifier += (flag ? 0.06f : 0.03f); break; } case 5: case 10: case 12: break; } } public static float ApplyCapeArmorBonus(ItemData item, float armor) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 if (!IsLegendary(item)) { return armor; } if ((int)item.m_shared.m_itemType != 17) { return armor; } return armor + 1f; } public static float ApplyWeaponDurability(ItemData item, float durability) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Invalid comparison between Unknown and I4 if (!IsLegendary(item)) { return durability; } if (!item.IsWeapon()) { return durability; } if (item.m_shared == null) { return durability; } if ((int)item.m_shared.m_skillType != 3) { return durability; } if (item.IsTwoHanded()) { return durability * 1.1f; } return durability * 1.05f; } public static bool UsesEitrForAnyAttack(ItemData item) { if (item == null || item.m_shared == null) { return false; } return AttackUsesEitr(item.m_shared.m_attack) || AttackUsesEitr(item.m_shared.m_secondaryAttack); } private static bool AttackUsesEitr(Attack attack) { if (attack == null) { return false; } FieldInfo[] fields = typeof(Attack).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (!(fieldInfo == null) && !string.IsNullOrEmpty(fieldInfo.Name) && fieldInfo.Name.IndexOf("eitr", StringComparison.OrdinalIgnoreCase) >= 0) { object value = fieldInfo.GetValue(attack); if (value is float && (float)value > 0f) { return true; } if (value is int && (int)value > 0) { return true; } } } return false; } } public struct RarityCraftChances { public float Common; public float Uncommon; public float Rare; public float Epic; public float Legendary; } public static class RarityMath { public static float GetRuneforgingFactor() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return 0f; } return RuneforgingSkillSystem.GetSkillFactor(localPlayer); } public static float GetCraftsmanshipFactor() { return GetRuneforgingFactor(); } public static float GetImproveDiscountFactor() { float num = Mathf.Clamp01(GetRuneforgingFactor()); return 1f - num * Mathf.Clamp01(Plugin.ImproveMaxDiscount); } public static RarityCraftChances GetCraftChances(float skillFactor) { return RarityProgression.GetCraftChances(skillFactor); } public static ItemRarity RollCraftedRarity(float skillFactor) { RarityCraftChances craftChances = GetCraftChances(skillFactor); float num = craftChances.Common + craftChances.Uncommon + craftChances.Rare + craftChances.Epic + craftChances.Legendary; if (num <= 0f) { return ItemRarity.Common; } float num2 = Random.Range(0f, num); if (num2 < craftChances.Common) { return ItemRarity.Common; } num2 -= craftChances.Common; if (num2 < craftChances.Uncommon) { return ItemRarity.Uncommon; } num2 -= craftChances.Uncommon; if (num2 < craftChances.Rare) { return ItemRarity.Rare; } num2 -= craftChances.Rare; if (num2 < craftChances.Epic) { return ItemRarity.Epic; } return ItemRarity.Legendary; } public static float ApplyArmor(ItemData item, int quality, float vanilla) { ItemRarity rarity = item.GetRarity(); if (rarity == ItemRarity.Common) { return vanilla; } RarityDef rarityDef = RarityConfig.Get(rarity); float num = item.m_shared.m_armor * rarityDef.ArmorBaseMultiplier; float num2 = item.m_shared.m_armorPerLevel * rarityDef.ArmorPerLevelMultiplier * (float)Mathf.Max(0, quality - 1); return num + num2; } public static float ApplyDurability(ItemData item, int quality, float vanilla) { ItemRarity rarity = item.GetRarity(); if (rarity == ItemRarity.Common) { return vanilla; } RarityDef rarityDef = RarityConfig.Get(rarity); float num = item.m_shared.m_maxDurability * rarityDef.DurabilityMultiplier; float num2 = item.m_shared.m_durabilityPerLevel * rarityDef.DurabilityPerLevelMultiplier * (float)Mathf.Max(0, quality - 1); return num + num2; } public static DamageTypes ApplyDamage(ItemData item, int quality, DamageTypes vanilla) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_005d: Unknown result type (might be due to invalid IL or missing references) ItemRarity rarity = item.GetRarity(); if (rarity == ItemRarity.Common) { return vanilla; } RarityDef rarityDef = RarityConfig.Get(rarity); DamageTypes result = ScaleDamage(item.m_shared.m_damages, rarityDef.WeaponBaseMultiplier); DamageTypes val = ScaleDamage(item.m_shared.m_damagesPerLevel, rarityDef.WeaponPerLevelMultiplier); ((DamageTypes)(ref result)).Add(val, quality - 1); return result; } public static float ApplyBlockPower(ItemData item, int quality, float vanilla) { ItemRarity rarity = item.GetRarity(); if (rarity == ItemRarity.Common) { return vanilla; } RarityDef rarityDef = RarityConfig.Get(rarity); float num = item.m_shared.m_blockPower * rarityDef.ShieldBlockMultiplier; float num2 = item.m_shared.m_blockPowerPerLevel * rarityDef.ShieldBlockMultiplier * (float)Mathf.Max(0, quality - 1); return num + num2; } public static float ApplyDeflectionForce(ItemData item, int quality, float vanilla) { ItemRarity rarity = item.GetRarity(); if (rarity == ItemRarity.Common) { return vanilla; } RarityDef rarityDef = RarityConfig.Get(rarity); float num = item.m_shared.m_deflectionForce * rarityDef.ShieldDeflectionMultiplier; float num2 = item.m_shared.m_deflectionForcePerLevel * rarityDef.ShieldDeflectionMultiplier * (float)Mathf.Max(0, quality - 1); return num + num2; } private static DamageTypes ScaleDamage(DamageTypes source, float multiplier) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_008b: Unknown result type (might be due to invalid IL or missing references) DamageTypes result = source; result.m_damage *= multiplier; result.m_blunt *= multiplier; result.m_slash *= multiplier; result.m_pierce *= multiplier; result.m_chop *= multiplier; result.m_pickaxe *= multiplier; result.m_fire *= multiplier; result.m_frost *= multiplier; result.m_lightning *= multiplier; result.m_poison *= multiplier; result.m_spirit *= multiplier; return result; } } public static class RarityProgression { public const float SkillIncreaseStep = 0.75f; public const float CraftBaseXP = 0.75f; public const float CraftBonusXPUncommon = 1.25f; public const float CraftBonusXPRare = 2.25f; public const float CraftBonusXPEpic = 3.25f; public const float CraftBonusXPLegendary = 5.25f; public const float ImproveXPToUncommon = 1f; public const float ImproveXPToRare = 2f; public const float ImproveXPToEpic = 3f; public const float ImproveXPToLegendary = 4f; public static RarityCraftChances GetCraftChances(float skillFactor) { float skill = Mathf.Clamp01(skillFactor) * 100f; RarityCraftChances result = default(RarityCraftChances); result.Uncommon = SmoothChance(skill, 0f, 100f, 55f); result.Rare = SmoothChance(skill, 40f, 100f, 25f); result.Epic = SmoothChance(skill, 80f, 100f, 5f); result.Legendary = SmoothChance(skill, 90f, 100f, 0.5f); result.Common = Mathf.Max(0f, 100f - result.Uncommon - result.Rare - result.Epic - result.Legendary); return result; } public static float GetCraftXPReward(ItemRarity craftedRarity) { return craftedRarity switch { ItemRarity.Uncommon => 2f, ItemRarity.Rare => 3f, ItemRarity.Epic => 4f, ItemRarity.Legendary => 6f, _ => 0.75f, }; } public static float GetImproveXPReward(ItemRarity targetRarity) { return targetRarity switch { ItemRarity.Uncommon => 1f, ItemRarity.Rare => 2f, ItemRarity.Epic => 3f, ItemRarity.Legendary => 4f, _ => 0f, }; } private static float SmoothChance(float skill, float startSkill, float maxSkill, float maxChance) { if (skill <= startSkill) { return 0f; } if (skill >= maxSkill) { return maxChance; } float num = Mathf.InverseLerp(startSkill, maxSkill, skill); num = Mathf.SmoothStep(0f, 1f, num); return maxChance * num; } } [BepInPlugin("balrond.valheim.itemrarity", "Balrond Item Rarity", "0.1.0")] public class Plugin : BaseUnityPlugin { public const string ModGuid = "balrond.valheim.itemrarity"; public const string ModName = "Balrond Item Rarity"; public const string ModVersion = "0.1.0"; internal static Plugin Instance; internal static Harmony Harmony; public AssetBundle assetBundle; public static bool EnableLootBeams = true; public static bool EnableInventoryIconGlow = true; public static bool EnableDecimalArmorTooltip = true; public static float ImproveMaxDiscount = 0.25f; public static int LegendaryNameLimit = 50; public static bool AllowTowerShieldParry = false; public static Material rarityGlowMaterial; public static Sprite runeforging_icon; private void Awake() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown string text = "Assets/Custom/BalrondRuneforging/"; string text2 = ".png"; Instance = this; assetBundle = GetAssetBundleFromResources("balrondrarity"); runeforging_icon = assetBundle.LoadAsset(text + "runeforging" + text2); rarityGlowMaterial = assetBundle.LoadAsset(text + "rarityglow.mat"); RarityConfig.Init(); RuneforgingSkillSystem.Initialize(); Harmony = new Harmony("balrond.valheim.itemrarity"); Harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Balrond Item Rarity loaded"); } private void OnDestroy() { if (Harmony != null) { Harmony.UnpatchSelf(); } } private AssetBundle GetAssetBundleFromResources(string filename) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string text = null; string[] manifestResourceNames = executingAssembly.GetManifestResourceNames(); foreach (string text2 in manifestResourceNames) { if (text2.EndsWith(filename)) { text = text2; break; } } if (text == null) { return null; } using Stream stream = executingAssembly.GetManifestResourceStream(text); return AssetBundle.LoadFromStream(stream); } } } namespace BalrondItemRarity.VFX { public class RarityAttachedGlow : MonoBehaviour { private enum EquippedGlowShapeKind { Sphere, Box, FlatBox } private struct EquippedGlowProfile { public EquippedGlowShapeKind ShapeKind; public Vector3 LocalOffset; public Vector3 LocalEulerAngles; public float RadiusMultiplier; public float RadiusExtra; public float MinRadius; public float MaxRadius; public float BoxSizeMultiplier; public float BoxThickness; } private ItemData _item; private GameObject _root; private ParticleSystem _glow; private ParticleSystemRenderer _renderer; private ItemRarity _lastRarity = RarityVisualSettings.InvalidRarity; private float _nextRefresh; public void SetItem(ItemData item) { _item = item; Refresh(force: true); } private void OnDisable() { Hide(); } private void OnDestroy() { Hide(); } private void LateUpdate() { if (!(Time.time < _nextRefresh)) { _nextRefresh = Time.time + 0.15f; Refresh(force: false); } } private void Refresh(bool force) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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) if (!ShouldShow()) { Hide(); return; } if ((Object)(object)_root == (Object)null) { CreateGlow(); } if (!((Object)(object)_root == (Object)null)) { Bounds bounds; bool hasBounds = RarityVFXBounds.TryGetVisualBounds(((Component)this).transform, _root.transform, Vector3.one * 0.25f, out bounds); ApplyTransform(bounds, hasBounds); ApplyColorAndIntensity(_item.GetRarity(), force); if (!_root.activeSelf) { _root.SetActive(true); } } } private bool ShouldShow() { if (_item == null || _item.m_shared == null) { return false; } if (!ItemFilters.IsRarityEligible(_item)) { return false; } return _item.GetRarity() > ItemRarity.Common; } private void CreateGlow() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) RarityVFXFactory.EnsureInitialized(); _root = new GameObject("Balrond_AttachedRarityGlow"); _root.transform.SetParent(((Component)this).transform, false); _root.transform.localPosition = Vector3.zero; _root.transform.localRotation = Quaternion.identity; _root.transform.localScale = Vector3.one; _glow = RarityVFXFactory.CreateGlow(_root.transform, "Glow", RarityVisualSettings.EquippedGlow, out _renderer); if ((Object)(object)_glow != (Object)null) { MainModule main = _glow.main; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; } } private void ApplyTransform(Bounds bounds, bool hasBounds) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_007b: Unknown result type (might be due to invalid IL or missing references) //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_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_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_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_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root == (Object)null) { return; } EquippedGlowProfile glowProfile = GetGlowProfile(_item); if (UseManualBoxProfile(_item)) { ApplyManualBoxTransform(glowProfile); return; } Vector3 localPosition = glowProfile.LocalOffset; float radius = 0.4f; Vector3 val = Vector3.one * 0.4f; if (hasBounds) { localPosition = ((Component)this).transform.InverseTransformPoint(((Bounds)(ref bounds)).center) + glowProfile.LocalOffset; Vector3 extents = ((Bounds)(ref bounds)).extents; float num = Mathf.Max(extents.x, Mathf.Max(extents.y, extents.z)); radius = Mathf.Clamp(num * glowProfile.RadiusMultiplier + glowProfile.RadiusExtra, glowProfile.MinRadius, glowProfile.MaxRadius); val = CalculateBoxSize(((Bounds)(ref bounds)).size, glowProfile); } _root.transform.localPosition = localPosition; _root.transform.localRotation = Quaternion.Euler(glowProfile.LocalEulerAngles); if (!((Object)(object)_glow == (Object)null)) { ShapeModule shape = _glow.shape; switch (glowProfile.ShapeKind) { case EquippedGlowShapeKind.Box: ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)5; ((ShapeModule)(ref shape)).scale = val; ((ShapeModule)(ref shape)).radiusThickness = 1f; break; case EquippedGlowShapeKind.FlatBox: ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)5; ((ShapeModule)(ref shape)).scale = FlattenSmallestAxis(val, glowProfile.BoxThickness); ((ShapeModule)(ref shape)).radiusThickness = 1f; break; default: ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0; ((ShapeModule)(ref shape)).radius = radius; ((ShapeModule)(ref shape)).radiusThickness = 0.18f; break; } } } private static bool UseManualBoxProfile(ItemData item) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Invalid comparison between Unknown and I4 //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Invalid comparison between Unknown and I4 if (item == null || item.m_shared == null) { return false; } ItemType itemType = item.m_shared.m_itemType; ItemType val = itemType; if (val - 3 <= 2 || val - 14 <= 1 || (int)val == 22) { return true; } return false; } private void ApplyManualBoxTransform(EquippedGlowProfile profile) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0076: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root == (Object)null)) { _root.transform.localPosition = profile.LocalOffset; _root.transform.localRotation = Quaternion.Euler(profile.LocalEulerAngles); if (!((Object)(object)_glow == (Object)null)) { ShapeModule shape = _glow.shape; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)5; ((ShapeModule)(ref shape)).scale = GetManualBoxSize(_item, profile); ((ShapeModule)(ref shape)).radiusThickness = 1f; } } } private static Vector3 GetManualBoxSize(ItemData item, EquippedGlowProfile profile) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Invalid comparison between Unknown and I4 //IL_0033: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Invalid comparison between Unknown and I4 //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected I4, but got Unknown //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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_0097: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Invalid comparison between Unknown and I4 //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Invalid comparison between Unknown and I4 //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_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) float num = Mathf.Max(0.01f, profile.BoxThickness); if (item == null || item.m_shared == null) { return new Vector3(num, num, 0.85f * profile.BoxSizeMultiplier); } ItemType itemType = item.m_shared.m_itemType; ItemType val = itemType; if ((int)val <= 14) { switch (val - 3) { case 2: return new Vector3(0.72f * profile.BoxSizeMultiplier, num, 0.9f * profile.BoxSizeMultiplier); case 1: return new Vector3(num, num, 1.25f * profile.BoxSizeMultiplier); case 0: goto IL_00cb; } if ((int)val == 14) { goto IL_00b5; } } else { if ((int)val == 15) { goto IL_00cb; } if ((int)val == 22) { goto IL_00b5; } } return new Vector3(num, num, 0.85f * profile.BoxSizeMultiplier); IL_00b5: return new Vector3(num, num, 1.45f * profile.BoxSizeMultiplier); IL_00cb: return new Vector3(num, num, 0.82f * profile.BoxSizeMultiplier); } private static Vector3 CalculateBoxSize(Vector3 boundsSize, EquippedGlowProfile profile) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) Vector3 val = boundsSize * profile.BoxSizeMultiplier; val.x = Mathf.Max(val.x, profile.BoxThickness); val.y = Mathf.Max(val.y, profile.BoxThickness); val.z = Mathf.Max(val.z, profile.BoxThickness); return val; } private static Vector3 FlattenSmallestAxis(Vector3 size, float thickness) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_003f: 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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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) if (size.x <= size.y && size.x <= size.z) { size.x = thickness; } else if (size.y <= size.x && size.y <= size.z) { size.y = thickness; } else { size.z = thickness; } size.x = Mathf.Max(size.x, thickness); size.y = Mathf.Max(size.y, thickness); size.z = Mathf.Max(size.z, thickness); return size; } private static EquippedGlowProfile GetGlowProfile(ItemData item) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009a: 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_009e: 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_00e3: Expected I4, but got Unknown //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_0320: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_0390: Unknown result type (might be due to invalid IL or missing references) //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: 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_01bc: 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_03f0: Unknown result type (might be due to invalid IL or missing references) //IL_03f5: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Unknown result type (might be due to invalid IL or missing references) //IL_040e: Invalid comparison between Unknown and I4 //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0416: Unknown result type (might be due to invalid IL or missing references) //IL_041c: Invalid comparison between Unknown and I4 //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Invalid comparison between Unknown and I4 //IL_0424: Unknown result type (might be due to invalid IL or missing references) //IL_042a: Invalid comparison between Unknown and I4 //IL_047e: Unknown result type (might be due to invalid IL or missing references) //IL_0483: Unknown result type (might be due to invalid IL or missing references) //IL_0447: Unknown result type (might be due to invalid IL or missing references) //IL_044c: Unknown result type (might be due to invalid IL or missing references) EquippedGlowProfile equippedGlowProfile = default(EquippedGlowProfile); equippedGlowProfile.ShapeKind = EquippedGlowShapeKind.Sphere; equippedGlowProfile.LocalOffset = Vector3.zero; equippedGlowProfile.LocalEulerAngles = Vector3.zero; equippedGlowProfile.RadiusMultiplier = 0.4f; equippedGlowProfile.RadiusExtra = 0.02f; equippedGlowProfile.MinRadius = 0.3f; equippedGlowProfile.MaxRadius = 0.5f; equippedGlowProfile.BoxSizeMultiplier = 1f; equippedGlowProfile.BoxThickness = 0.15f; EquippedGlowProfile result = equippedGlowProfile; if (item == null || item.m_shared == null) { return result; } ItemType itemType = item.m_shared.m_itemType; ItemType val = itemType; switch (val - 3) { default: if ((int)val != 22) { break; } goto case 11; case 3: result.ShapeKind = EquippedGlowShapeKind.Sphere; result.LocalOffset = new Vector3(0f, 0f, 0.02f); result.RadiusMultiplier = 0.75f; result.RadiusExtra = 0.08f; result.MinRadius = 0.1f; result.MaxRadius = 0.3f; break; case 4: result.ShapeKind = EquippedGlowShapeKind.Sphere; result.LocalOffset = new Vector3(0f, 0.08f, 0f); result.RadiusMultiplier = 0.95f; result.RadiusExtra = 0.16f; result.MinRadius = 0.34f; result.MaxRadius = 0.62f; break; case 8: result.ShapeKind = EquippedGlowShapeKind.Sphere; result.LocalOffset = new Vector3(0f, -0.32f, 0f); result.RadiusMultiplier = 0.55f; result.RadiusExtra = 0.02f; result.MinRadius = 0.35f; result.MaxRadius = 0.26f; break; case 14: result.ShapeKind = EquippedGlowShapeKind.FlatBox; result.LocalOffset = new Vector3(0f, 0.1f, -0.01f); result.BoxSizeMultiplier = 0.72f; result.BoxThickness = 0.06f; result.RadiusMultiplier = 0.9f; result.RadiusExtra = 0.18f; result.MinRadius = 0.2f; result.MaxRadius = 0.5f; break; case 2: result.ShapeKind = EquippedGlowShapeKind.FlatBox; result.LocalOffset = new Vector3(0f, -0.01f, 0.03f); result.LocalEulerAngles = new Vector3(90f, 0f, 0f); result.BoxSizeMultiplier = 1.1f; result.BoxThickness = 0.5f; result.RadiusMultiplier = 0.9f; result.RadiusExtra = 0.1f; result.MinRadius = 0.2f; result.MaxRadius = 0.5f; break; case 0: case 12: result.LocalEulerAngles = Vector3.zero; result.ShapeKind = EquippedGlowShapeKind.Box; result.LocalOffset = new Vector3(0f, -0.05f, 0.15f); result.BoxSizeMultiplier = 1.1f; result.BoxThickness = 0.018f; result.RadiusMultiplier = 0.22f; result.RadiusExtra = 0f; result.MinRadius = 0.04f; result.MaxRadius = 0.08f; break; case 1: result.ShapeKind = EquippedGlowShapeKind.Box; result.LocalOffset = new Vector3(0f, 0f, 0.12f); result.LocalEulerAngles = RarityVisualSettings.EquippedBowEulerAngles; result.BoxSizeMultiplier = 1.05f; result.BoxThickness = 0.018f; result.RadiusMultiplier = 0.22f; result.RadiusExtra = 0f; result.MinRadius = 0.04f; result.MaxRadius = 0.08f; break; case 11: result.LocalEulerAngles = Vector3.zero; result.ShapeKind = EquippedGlowShapeKind.Box; if ((int)item.m_shared.m_skillType == 3 || (int)item.m_shared.m_skillType == 1 || (int)item.m_shared.m_skillType == 7) { result.LocalOffset = new Vector3(0f, -0.05f, 0.38f); result.BoxSizeMultiplier = 0.9f; result.BoxThickness = 0.03f; } else { result.LocalOffset = new Vector3(0f, -0.05f, 0.15f); result.BoxSizeMultiplier = 1.1f; result.BoxThickness = 0.018f; } result.RadiusMultiplier = 0.22f; result.RadiusExtra = 0f; result.MinRadius = 0.04f; result.MaxRadius = 0.08f; break; case 5: case 6: case 7: case 9: case 10: case 13: break; } return result; } private void ApplyColorAndIntensity(ItemRarity rarity, bool force) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) RarityVisualTuning tuning = RarityVisualSettings.GetTuning(rarity); if (force || _lastRarity != rarity || (Object)(object)_glow == (Object)null) { Color visualColor = RarityVisualSettings.GetVisualColor(rarity, RarityVisualLayer.EquippedGlow, tuning.EquippedGlowAlpha); if ((Object)(object)_glow != (Object)null) { MainModule main = _glow.main; ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(visualColor); } if ((Object)(object)_renderer != (Object)null && (Object)(object)((Renderer)_renderer).material != (Object)null) { RarityVFXFactory.TrySetColor(((Renderer)_renderer).material, visualColor); } _lastRarity = rarity; } if ((Object)(object)_glow != (Object)null) { EmissionModule emission = _glow.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(tuning.EquippedGlowEmission); } } private void Hide() { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); _root = null; } _glow = null; _renderer = null; _lastRarity = RarityVisualSettings.InvalidRarity; } } [HarmonyPatch(typeof(Player), "Update")] public static class PlayerEquippedRarityVFXPatch { private static readonly FieldInfo FI_VisEquipment = AccessTools.Field(typeof(Humanoid), "m_visEquipment") ?? AccessTools.Field(typeof(Player), "m_visEquipment"); private static readonly FieldInfo FI_RightItemInstance = AccessTools.Field(typeof(VisEquipment), "m_rightItemInstance"); private static readonly FieldInfo FI_LeftItemInstance = AccessTools.Field(typeof(VisEquipment), "m_leftItemInstance"); private static readonly FieldInfo FI_RightBackItemInstance = AccessTools.Field(typeof(VisEquipment), "m_rightBackItemInstance"); private static readonly FieldInfo FI_LeftBackItemInstance = AccessTools.Field(typeof(VisEquipment), "m_leftBackItemInstance"); private static readonly FieldInfo FI_HelmetItemInstance = AccessTools.Field(typeof(VisEquipment), "m_helmetItemInstance"); private static readonly FieldInfo FI_ChestItemInstances = AccessTools.Field(typeof(VisEquipment), "m_chestItemInstances"); private static readonly FieldInfo FI_LegItemInstances = AccessTools.Field(typeof(VisEquipment), "m_legItemInstances"); private static readonly FieldInfo FI_ShoulderItemInstances = AccessTools.Field(typeof(VisEquipment), "m_shoulderItemInstances"); private static readonly FieldInfo FI_UtilityItemInstances = AccessTools.Field(typeof(VisEquipment), "m_utilityItemInstances"); private static readonly FieldInfo FI_TrinketItemInstances = AccessTools.Field(typeof(VisEquipment), "m_trinketItemInstances"); private static readonly MethodInfo MI_GetRightItem = AccessTools.Method(typeof(Humanoid), "GetRightItem", (Type[])null, (Type[])null) ?? AccessTools.Method(typeof(Player), "GetRightItem", (Type[])null, (Type[])null); private static readonly MethodInfo MI_GetLeftItem = AccessTools.Method(typeof(Humanoid), "GetLeftItem", (Type[])null, (Type[])null) ?? AccessTools.Method(typeof(Player), "GetLeftItem", (Type[])null, (Type[])null); private static readonly FieldInfo FI_RightItem = AccessTools.Field(typeof(Humanoid), "m_rightItem") ?? AccessTools.Field(typeof(Player), "m_rightItem"); private static readonly FieldInfo FI_LeftItem = AccessTools.Field(typeof(Humanoid), "m_leftItem") ?? AccessTools.Field(typeof(Player), "m_leftItem"); private static readonly FieldInfo FI_HelmetItem = AccessTools.Field(typeof(Humanoid), "m_helmetItem") ?? AccessTools.Field(typeof(Player), "m_helmetItem"); private static readonly FieldInfo FI_ChestItem = AccessTools.Field(typeof(Humanoid), "m_chestItem") ?? AccessTools.Field(typeof(Player), "m_chestItem"); private static readonly FieldInfo FI_LegItem = AccessTools.Field(typeof(Humanoid), "m_legItem") ?? AccessTools.Field(typeof(Player), "m_legItem"); private static readonly FieldInfo FI_ShoulderItem = AccessTools.Field(typeof(Humanoid), "m_shoulderItem") ?? AccessTools.Field(typeof(Player), "m_shoulderItem"); private static readonly FieldInfo FI_UtilityItem = AccessTools.Field(typeof(Humanoid), "m_utilityItem") ?? AccessTools.Field(typeof(Player), "m_utilityItem"); private static readonly FieldInfo FI_TrinketItem = AccessTools.Field(typeof(Humanoid), "m_trinketItem") ?? AccessTools.Field(typeof(Player), "m_trinketItem"); private static readonly Dictionary NextUpdateByInstance = new Dictionary(); private static void Postfix(Player __instance) { if ((Object)(object)__instance == (Object)null) { return; } int instanceID = ((Object)__instance).GetInstanceID(); if (!NextUpdateByInstance.TryGetValue(instanceID, out var value) || !(Time.time < value)) { NextUpdateByInstance[instanceID] = Time.time + 0.2f; VisEquipment val = (VisEquipment)((FI_VisEquipment != null) ? /*isinst with value type is only supported in some contexts*/: null); if (!((Object)(object)val == (Object)null)) { ItemData rightItem = GetRightItem(__instance); ItemData leftItem = GetLeftItem(__instance); AttachToSingle(FI_RightItemInstance, val, rightItem); AttachToSingle(FI_LeftItemInstance, val, leftItem); AttachToSingle(FI_RightBackItemInstance, val, rightItem); AttachToSingle(FI_LeftBackItemInstance, val, leftItem); AttachToSingle(FI_HelmetItemInstance, val, GetFieldItem(FI_HelmetItem, __instance)); AttachToCollection(FI_ChestItemInstances, val, GetFieldItem(FI_ChestItem, __instance)); AttachToCollection(FI_LegItemInstances, val, GetFieldItem(FI_LegItem, __instance)); AttachToCollection(FI_ShoulderItemInstances, val, GetFieldItem(FI_ShoulderItem, __instance)); AttachToCollection(FI_UtilityItemInstances, val, GetFieldItem(FI_UtilityItem, __instance)); AttachToCollection(FI_TrinketItemInstances, val, GetFieldItem(FI_TrinketItem, __instance)); } } } private static ItemData GetRightItem(Player player) { if ((Object)(object)player == (Object)null) { return null; } if (MI_GetRightItem != null) { object? obj = MI_GetRightItem.Invoke(player, null); return (ItemData)((obj is ItemData) ? obj : null); } return GetFieldItem(FI_RightItem, player); } private static ItemData GetLeftItem(Player player) { if ((Object)(object)player == (Object)null) { return null; } if (MI_GetLeftItem != null) { object? obj = MI_GetLeftItem.Invoke(player, null); return (ItemData)((obj is ItemData) ? obj : null); } return GetFieldItem(FI_LeftItem, player); } private static ItemData GetFieldItem(FieldInfo field, Player player) { if (field == null || (Object)(object)player == (Object)null) { return null; } object? value = field.GetValue(player); return (ItemData)((value is ItemData) ? value : null); } private static void AttachToSingle(FieldInfo instanceField, VisEquipment vis, ItemData item) { if (!(instanceField == null) && !((Object)(object)vis == (Object)null)) { object? value = instanceField.GetValue(vis); GameObject go = (GameObject)((value is GameObject) ? value : null); AttachToGameObject(go, item); } } private static void AttachToCollection(FieldInfo instanceField, VisEquipment vis, ItemData item) { if (instanceField == null || (Object)(object)vis == (Object)null) { return; } object value = instanceField.GetValue(vis); if (value == null) { return; } GameObject val = (GameObject)((value is GameObject) ? value : null); if ((Object)(object)val != (Object)null) { AttachToGameObject(val, item); } else { if (!(value is IEnumerable enumerable)) { return; } foreach (object item2 in enumerable) { AttachToGameObject((GameObject)((item2 is GameObject) ? item2 : null), item); } } } private static void AttachToGameObject(GameObject go, ItemData item) { if (!((Object)(object)go == (Object)null)) { RarityAttachedGlow rarityAttachedGlow = go.GetComponent(); if ((Object)(object)rarityAttachedGlow == (Object)null) { rarityAttachedGlow = go.AddComponent(); } rarityAttachedGlow.SetItem(item); } } } public static class RarityVFXBounds { public static bool TryGetVisualBounds(Transform owner, Transform ownVFXRoot, Vector3 fallbackSize, out Bounds bounds) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) Vector3 val = (((Object)(object)owner != (Object)null) ? owner.position : Vector3.zero); bounds = new Bounds(val, fallbackSize); if ((Object)(object)owner == (Object)null) { return false; } bool flag = false; Renderer[] componentsInChildren = ((Component)owner).GetComponentsInChildren(false); foreach (Renderer val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null) && val2.enabled && !IsOwnVFX(((Component)val2).transform, ownVFXRoot) && !(val2 is ParticleSystemRenderer) && !(val2 is LineRenderer)) { if (!flag) { bounds = val2.bounds; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val2.bounds); } } } return flag; } public static bool IsOwnVFX(Transform transformToCheck, Transform ownVFXRoot) { if ((Object)(object)transformToCheck == (Object)null || (Object)(object)ownVFXRoot == (Object)null) { return false; } return (Object)(object)transformToCheck == (Object)(object)ownVFXRoot || transformToCheck.IsChildOf(ownVFXRoot); } } public static class RarityVFXFactory { private static Material _beamMaterial; private static Material _fallbackParticleMaterial; public static Material BeamMaterial { get { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_beamMaterial != (Object)null) { return _beamMaterial; } _beamMaterial = new Material(FindBestVFXShader()); ((Object)_beamMaterial).name = "Balrond_Rarity_Beam_Material"; TrySetColor(_beamMaterial, Color.white); return _beamMaterial; } } private static Material FallbackParticleMaterial { get { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_fallbackParticleMaterial != (Object)null) { return _fallbackParticleMaterial; } _fallbackParticleMaterial = new Material(FindBestVFXShader()); ((Object)_fallbackParticleMaterial).name = "Balrond_Rarity_Glow_Fallback_Material"; TrySetColor(_fallbackParticleMaterial, Color.white); return _fallbackParticleMaterial; } } public static void EnsureInitialized() { Material beamMaterial = BeamMaterial; Material fallbackParticleMaterial = FallbackParticleMaterial; } public static Material GetParticleMaterialInstance() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown Material val = (((Object)(object)Plugin.rarityGlowMaterial != (Object)null) ? Plugin.rarityGlowMaterial : FallbackParticleMaterial); Material val2 = new Material(val); ((Object)val2).name = "Balrond_Rarity_Glow_Material_Instance"; return val2; } public static ParticleSystem CreateGlow(Transform parent, string name, RarityParticleGlowSettings settings, out ParticleSystemRenderer renderer) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one; ParticleSystem val2 = val.AddComponent(); renderer = val.GetComponent(); ConfigureGlow(val2, renderer, settings); val2.Play(); return val2; } public static void ConfigureGlow(ParticleSystem glow, ParticleSystemRenderer renderer, RarityParticleGlowSettings settings) { //IL_0014: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_00b4: 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_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_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) if (!((Object)(object)glow == (Object)null)) { MainModule main = glow.main; ((MainModule)(ref main)).loop = true; ((MainModule)(ref main)).playOnAwake = true; ((MainModule)(ref main)).duration = settings.Duration; ((MainModule)(ref main)).startLifetime = new MinMaxCurve(settings.LifetimeMin, settings.LifetimeMax); ((MainModule)(ref main)).startSpeed = new MinMaxCurve(settings.SpeedMin, settings.SpeedMax); ((MainModule)(ref main)).startSize = new MinMaxCurve(settings.SizeMin, settings.SizeMax); ((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(0f); ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; ((MainModule)(ref main)).maxParticles = settings.MaxParticles; EmissionModule emission = glow.emission; ((EmissionModule)(ref emission)).enabled = true; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(settings.BaseEmission); ShapeModule shape = glow.shape; ((ShapeModule)(ref shape)).enabled = true; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0; ((ShapeModule)(ref shape)).radius = settings.ShapeRadius; ((ShapeModule)(ref shape)).radiusThickness = settings.ShapeRadiusThickness; ColorOverLifetimeModule colorOverLifetime = glow.colorOverLifetime; ((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true; ((ColorOverLifetimeModule)(ref colorOverLifetime)).color = MinMaxGradient.op_Implicit(CreateWhiteFadeGradient(settings.AlphaPeak, settings.AlphaPeakTime)); VelocityOverLifetimeModule velocityOverLifetime = glow.velocityOverLifetime; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled = false; if ((Object)(object)renderer != (Object)null) { ((Renderer)renderer).material = GetParticleMaterialInstance(); renderer.renderMode = (ParticleSystemRenderMode)0; ((Renderer)renderer).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)renderer).receiveShadows = false; renderer.sortingFudge = settings.SortingFudge; } } } public static Gradient CreateWhiteFadeGradient(float alphaPeak, float alphaPeakTime) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0010: Unknown result type (might be due to invalid IL or missing references) //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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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) Gradient val = new Gradient(); val.SetKeys((GradientColorKey[])(object)new GradientColorKey[2] { new GradientColorKey(Color.white, 0f), new GradientColorKey(Color.white, 1f) }, (GradientAlphaKey[])(object)new GradientAlphaKey[3] { new GradientAlphaKey(0f, 0f), new GradientAlphaKey(alphaPeak, alphaPeakTime), new GradientAlphaKey(0f, 1f) }); return val; } public static void TrySetColor(Material material, Color color) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)material == (Object)null)) { if (material.HasProperty("_TintColor")) { material.SetColor("_TintColor", color); } if (material.HasProperty("_Color")) { material.SetColor("_Color", color); } if (material.HasProperty("_BaseColor")) { material.SetColor("_BaseColor", color); } if (material.HasProperty("_EmissionColor")) { material.SetColor("_EmissionColor", color); } } } private static Shader FindBestVFXShader() { Shader val = Shader.Find("Sprites/Default"); if ((Object)(object)val != (Object)null) { return val; } val = Shader.Find("Unlit/Color"); if ((Object)(object)val != (Object)null) { return val; } val = Shader.Find("Particles/Standard Unlit"); if ((Object)(object)val != (Object)null) { return val; } val = Shader.Find("Legacy Shaders/Particles/Additive"); if ((Object)(object)val != (Object)null) { return val; } return Shader.Find("Standard"); } } public enum RarityVisualLayer { UIGradient, UIOutline, WorldBeam, WorldGlow, EquippedGlow, TooltipGradient, TooltipBorder } public static class RarityVisualSettings { public static readonly ItemRarity InvalidRarity = (ItemRarity)(-999); public const float WorldRefreshInterval = 0.2f; public const float EquippedRefreshInterval = 0.15f; public const float PlayerEquippedPatchRefreshInterval = 0.2f; public const string WorldRootName = "Balrond_RarityWorldVFX"; public const string EquippedRootName = "Balrond_AttachedRarityGlow"; public const int UIGradientTextureWidth = 4; public const int UIGradientTextureHeight = 32; public const float UIGradientPixelsPerUnit = 64f; public const float UIGradientTextureAlphaTop = 0.95f; public const float UIGradientTextureAlphaBottom = 0.1f; public const float UIGradientTextureAlphaMultiplier = 1f; public const float WorldDefaultCenterYOffset = 0.18f; public const float WorldBoundsCenterYOffset = 0.1f; public const float WorldBeamBaseYOffset = -0.1f; public const float WorldDefaultBeamHeight = 3.5f; public const float WorldMinBeamHeight = 3f; public const float WorldMaxBeamHeight = 6.5f; public const float WorldBeamHeightExtra = 4f; public const float WorldDefaultRadius = 0.4f; public const float WorldMinRadius = 0.3f; public const float WorldMaxRadius = 0.9f; public const float WorldRadiusExtra = 0.2f; public const float WorldBeamWidthRadiusMultiplier = 0.28f; public const float WorldBeamMinWidth = 0.1f; public const float WorldBeamMaxWidth = 0.24f; public const float EquippedDefaultRadius = 0.4f; public const float EquippedMinRadius = 0.3f; public const float EquippedMaxRadius = 0.5f; public const float EquippedRadiusMultiplier = 0.4f; public const float EquippedRadiusExtra = 0.02f; public const float EquippedHelmetYOffset = 0f; public const float EquippedHelmetForwardOffset = 0.02f; public const float EquippedHelmetRadiusMultiplier = 0.75f; public const float EquippedHelmetRadiusExtra = 0.08f; public const float EquippedHelmetMinRadius = 0.1f; public const float EquippedHelmetMaxRadius = 0.3f; public const float EquippedChestYOffset = 0.08f; public const float EquippedChestRadiusMultiplier = 0.95f; public const float EquippedChestRadiusExtra = 0.16f; public const float EquippedChestMinRadius = 0.44f; public const float EquippedChestMaxRadius = 0.62f; public const float EquippedLegsYOffset = -0.25f; public const float EquippedLegsRadiusMultiplier = 0.8f; public const float EquippedLegsRadiusExtra = 0.1f; public const float EquippedLegsMaxRadius = 0.45f; public const float EquippedLegsMinRadius = 0.35f; public const float EquippedCapeYOffset = 0.1f; public const float EquippedCapeRadiusMultiplier = 0.9f; public const float EquippedCapeRadiusExtra = 0.18f; public const float EquippedCapeMinRadius = 0.2f; public const float EquippedCapeMaxRadius = 0.5f; public const float EquippedWeaponRadiusMultiplier = 0.22f; public const float EquippedWeaponRadiusExtra = 0f; public const float EquippedWeaponMinRadius = 0.04f; public const float EquippedWeaponMaxRadius = 0.08f; public const float EquippedShieldRadiusMultiplier = 0.9f; public const float EquippedShieldRadiusExtra = 0.1f; public const float EquippedShieldMinRadius = 0.2f; public const float EquippedShieldMaxRadius = 0.5f; public const float EquippedGlowRadiusThickness = 0.22f; public const float TooltipBackgroundAlpha = 0.82f; public const float TooltipBorderAlpha = 0.85f; public const float TooltipBorderSize = 1.5f; public const int TooltipGradientTextureWidth = 4; public const int TooltipGradientTextureHeight = 64; public const float TooltipGradientPixelsPerUnit = 100f; public const float TooltipGradientTextureAlphaTop = 0.65f; public const float TooltipGradientTextureAlphaBottom = 0.04f; public const float EquippedWeaponYOffset = -0.05f; public const float EquippedWeaponForwardOffset = 0.15f; public const float EquippedWeaponBoxSizeMultiplier = 1.1f; public const float EquippedWeaponBoxThickness = 0.018f; public const float EquippedTwoHandedHeadHeavyYOffset = -0.05f; public const float EquippedTwoHandedHeadHeavyForwardOffset = 0.38f; public const float EquippedTwoHandedHeadHeavyBoxSizeMultiplier = 0.9f; public const float EquippedTwoHandedHeadHeavyBoxThickness = 0.03f; public const float EquippedBowYOffset = 0f; public const float EquippedBowForwardOffset = 0.12f; public const float EquippedBowBoxSizeMultiplier = 1.05f; public const float EquippedBowBoxThickness = 0.018f; public static readonly Vector3 EquippedBowEulerAngles = new Vector3(0f, -20f, 0f); public const float EquippedShieldYOffset = -0.01f; public const float EquippedShieldForwardOffset = 0.03f; public const float EquippedShieldBoxSizeMultiplier = 1.1f; public const float EquippedShieldBoxThickness = 0.5f; public const float EquippedCapeBoxSizeMultiplier = 0.72f; public const float EquippedCapeBoxThickness = 0.06f; public const float EquippedCapeBackOffset = -0.01f; public const float EquippedArmorSphereRadiusThickness = 0.18f; public const float EquippedBoxRadiusThickness = 1f; public static readonly RarityParticleGlowSettings WorldGlow = new RarityParticleGlowSettings { LifetimeMin = 0.65f, LifetimeMax = 1.15f, SpeedMin = 0.001f, SpeedMax = 0.008f, SizeMin = 0.18f, SizeMax = 0.42f, MaxParticles = 90, BaseEmission = 32f, ShapeRadius = 0.28f, ShapeRadiusThickness = 0.65f, AlphaPeak = 0.55f, AlphaPeakTime = 0.35f, SortingFudge = 1f }; public static readonly RarityParticleGlowSettings EquippedGlow = new RarityParticleGlowSettings { Duration = 1f, LifetimeMin = 0.4f, LifetimeMax = 0.8f, SpeedMin = 0.001f, SpeedMax = 0.008f, SizeMin = 0.15f, SizeMax = 0.25f, MaxParticles = 66, BaseEmission = 20f, ShapeRadius = 0.22f, ShapeRadiusThickness = 0.22f, AlphaPeak = 0.55f, AlphaPeakTime = 0.45f, SortingFudge = 1f }; private static readonly Dictionary LayerColorOverrides = new Dictionary(); private static readonly Dictionary RarityLayerColorOverrides = new Dictionary(); public static float CalculateUIGradientTextureAlpha(float t) { t = Mathf.Clamp01(t); float num = Mathf.SmoothStep(0f, 1f, t); float num2 = Mathf.Lerp(0.95f, 0.1f, num); num2 *= 1f; return Mathf.Clamp01(num2); } public static RarityVisualTuning GetTuning(ItemRarity rarity) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: 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_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) RarityVisualTuning result = default(RarityVisualTuning); switch (rarity) { case ItemRarity.Common: result.UIGradientAlpha = 0.01f; result.UIOutlineAlpha = 0.08f; result.UIOutlineDistance = new Vector2(0.45f, -0.45f); result.WorldBeamAlpha = 0.33f; result.WorldBeamEndAlphaMultiplier = 0.03f; result.WorldGlowAlpha = 0f; result.WorldGlowEmission = 0f; result.EquippedGlowAlpha = 0f; result.EquippedGlowEmission = 0f; break; case ItemRarity.Uncommon: result.UIGradientAlpha = 0.135f; result.UIOutlineAlpha = 0.62f; result.UIOutlineDistance = new Vector2(0.65f, -0.65f); result.WorldBeamAlpha = 0.33f; result.WorldBeamEndAlphaMultiplier = 0.04f; result.WorldGlowAlpha = 0.72f; result.WorldGlowEmission = 20f; result.EquippedGlowAlpha = 0.76f; result.EquippedGlowEmission = 15f; break; case ItemRarity.Rare: result.UIGradientAlpha = 0.135f; result.UIOutlineAlpha = 0.62f; result.UIOutlineDistance = new Vector2(0.85f, -0.85f); result.WorldBeamAlpha = 0.33f; result.WorldBeamEndAlphaMultiplier = 0.05f; result.WorldGlowAlpha = 0.72f; result.WorldGlowEmission = 20f; result.EquippedGlowAlpha = 0.76f; result.EquippedGlowEmission = 15f; break; case ItemRarity.Epic: result.UIGradientAlpha = 0.135f; result.UIOutlineAlpha = 0.62f; result.UIOutlineDistance = new Vector2(1.05f, -1.05f); result.WorldBeamAlpha = 0.33f; result.WorldBeamEndAlphaMultiplier = 0.06f; result.WorldGlowAlpha = 0.72f; result.WorldGlowEmission = 20f; result.EquippedGlowAlpha = 0.76f; result.EquippedGlowEmission = 15f; break; case ItemRarity.Legendary: result.UIGradientAlpha = 0.135f; result.UIOutlineAlpha = 0.78f; result.UIOutlineDistance = new Vector2(1.25f, -1.25f); result.WorldBeamAlpha = 0.44f; result.WorldBeamEndAlphaMultiplier = 0.07f; result.WorldGlowAlpha = 0.72f; result.WorldGlowEmission = 20f; result.EquippedGlowAlpha = 0.76f; result.EquippedGlowEmission = 15f; break; default: result.UIGradientAlpha = 0f; result.UIOutlineAlpha = 0f; result.UIOutlineDistance = Vector2.zero; result.WorldBeamAlpha = 0f; result.WorldBeamEndAlphaMultiplier = 0.05f; result.WorldGlowAlpha = 0f; result.WorldGlowEmission = 0f; result.EquippedGlowAlpha = 0f; result.EquippedGlowEmission = 0f; break; } return result; } public static Color GetVisualColor(ItemRarity rarity, RarityVisualLayer layer, float alpha) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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_003d: Unknown result type (might be due to invalid IL or missing references) string rarityLayerKey = GetRarityLayerKey(rarity, layer); if (!RarityLayerColorOverrides.TryGetValue(rarityLayerKey, out var value) && !LayerColorOverrides.TryGetValue(layer, out value)) { value = RarityConfig.Get(rarity).Color; } value.a = alpha; return value; } public static float CalculateTooltipGradientTextureAlpha(float t) { t = Mathf.Clamp01(t); float num = Mathf.SmoothStep(0f, 1f, t); return Mathf.Clamp01(Mathf.Lerp(0.65f, 0.04f, num)); } public static void SetLayerColorOverride(RarityVisualLayer layer, Color color) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) LayerColorOverrides[layer] = color; } public static void SetRarityLayerColorOverride(ItemRarity rarity, RarityVisualLayer layer, Color color) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) RarityLayerColorOverrides[GetRarityLayerKey(rarity, layer)] = color; } public static void ClearLayerColorOverride(RarityVisualLayer layer) { if (LayerColorOverrides.ContainsKey(layer)) { LayerColorOverrides.Remove(layer); } } public static void ClearRarityLayerColorOverride(ItemRarity rarity, RarityVisualLayer layer) { string rarityLayerKey = GetRarityLayerKey(rarity, layer); if (RarityLayerColorOverrides.ContainsKey(rarityLayerKey)) { RarityLayerColorOverrides.Remove(rarityLayerKey); } } public static void ClearAllColorOverrides() { LayerColorOverrides.Clear(); RarityLayerColorOverrides.Clear(); } private static string GetRarityLayerKey(ItemRarity rarity, RarityVisualLayer layer) { int num = (int)rarity; string text = num.ToString(); num = (int)layer; return text + ":" + num; } } public struct RarityVisualTuning { public float UIGradientAlpha; public float UIOutlineAlpha; public Vector2 UIOutlineDistance; public float WorldBeamAlpha; public float WorldBeamEndAlphaMultiplier; public float WorldGlowAlpha; public float WorldGlowEmission; public float EquippedGlowAlpha; public float EquippedGlowEmission; } public struct RarityParticleGlowSettings { public float Duration; public float LifetimeMin; public float LifetimeMax; public float SpeedMin; public float SpeedMax; public float SizeMin; public float SizeMax; public int MaxParticles; public float BaseEmission; public float ShapeRadius; public float ShapeRadiusThickness; public float AlphaPeak; public float AlphaPeakTime; public float SortingFudge; } [RequireComponent(typeof(ItemDrop))] public class RarityWorldVFX : MonoBehaviour { private ItemDrop _itemDrop; private GameObject _root; private LineRenderer _beam; private ParticleSystem _glow; private ParticleSystemRenderer _glowRenderer; private float _nextSlowRefresh; private ItemRarity _lastRarity = RarityVisualSettings.InvalidRarity; private void Awake() { _itemDrop = ((Component)this).GetComponent(); RarityVFXFactory.EnsureInitialized(); } private void OnDisable() { Hide(); } private void OnDestroy() { Hide(); } private void LateUpdate() { RefreshFastTransform(); if (!(Time.time < _nextSlowRefresh)) { _nextSlowRefresh = Time.time + 0.2f; RefreshState(); } } private void RefreshState() { if (!Plugin.EnableLootBeams) { Hide(); return; } if ((Object)(object)_itemDrop == (Object)null || _itemDrop.m_itemData == null) { Hide(); return; } ItemData itemData = _itemDrop.m_itemData; if (!ItemFilters.IsRarityEligible(itemData)) { Hide(); return; } ItemRarity rarity = itemData.GetRarity(); if ((Object)(object)_root == (Object)null) { CreateVFX(); } if (!((Object)(object)_root == (Object)null)) { ApplyColorsAndIntensity(rarity); RefreshFastTransform(); if (!_root.activeSelf) { _root.SetActive(true); } _lastRarity = rarity; } } private void RefreshFastTransform() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root == (Object)null) && !((Object)(object)_itemDrop == (Object)null) && _itemDrop.m_itemData != null) { Bounds bounds; bool hasBounds = RarityVFXBounds.TryGetVisualBounds(((Component)this).transform, _root.transform, Vector3.one * 0.35f, out bounds); ApplyTransform(bounds, hasBounds); } } private void CreateVFX() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) _root = new GameObject("Balrond_RarityWorldVFX"); _root.transform.SetParent(((Component)this).transform, false); _root.transform.localPosition = Vector3.zero; _root.transform.localRotation = Quaternion.identity; _root.transform.localScale = Vector3.one; CreateBeam(); CreateGlow(); } private void CreateBeam() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown GameObject val = new GameObject("Beam"); val.transform.SetParent(_root.transform, false); _beam = val.AddComponent(); _beam.useWorldSpace = true; _beam.loop = false; _beam.positionCount = 2; _beam.alignment = (LineAlignment)0; _beam.textureMode = (LineTextureMode)0; ((Renderer)_beam).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)_beam).receiveShadows = false; ((Renderer)_beam).material = new Material(RarityVFXFactory.BeamMaterial); _beam.widthMultiplier = 0.14f; } private void CreateGlow() { _glow = RarityVFXFactory.CreateGlow(_root.transform, "AmbientGlow", RarityVisualSettings.WorldGlow, out _glowRenderer); } private void ApplyTransform(Bounds bounds, bool hasBounds) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_0070: 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_007a: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root == (Object)null)) { Vector3 val = ((Component)this).transform.position + Vector3.up * 0.18f; Vector3 localPosition = Vector3.up * 0.18f; float num = 3.5f; float num2 = 0.4f; if (hasBounds) { val = ((Bounds)(ref bounds)).center + Vector3.up * 0.1f; localPosition = ((Component)this).transform.InverseTransformPoint(val); Vector3 extents = ((Bounds)(ref bounds)).extents; num2 = Mathf.Max(0.3f, Mathf.Min(0.9f, Mathf.Max(extents.x, extents.z) + 0.2f)); num = Mathf.Max(3f, Mathf.Min(6.5f, ((Bounds)(ref bounds)).size.y + 4f)); } _root.transform.localPosition = localPosition; _root.transform.localRotation = Quaternion.identity; if ((Object)(object)_beam != (Object)null) { Vector3 val2 = val + Vector3.up * -0.1f; _beam.SetPosition(0, val2); _beam.SetPosition(1, val2 + Vector3.up * num); _beam.widthMultiplier = Mathf.Clamp(num2 * 0.28f, 0.1f, 0.24f); } if ((Object)(object)_glow != (Object)null) { ShapeModule shape = _glow.shape; ((ShapeModule)(ref shape)).radius = num2; ((Component)_glow).transform.position = val; } } } private void ApplyColorsAndIntensity(ItemRarity rarity) { RarityVisualTuning tuning = RarityVisualSettings.GetTuning(rarity); if (_lastRarity != rarity || (Object)(object)_beam == (Object)null || (Object)(object)_glow == (Object)null) { ApplyBeamColor(rarity, tuning); ApplyGlowColor(rarity, tuning); } ApplyGlowIntensity(tuning); } private void ApplyBeamColor(ItemRarity rarity, RarityVisualTuning tuning) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_beam == (Object)null)) { Color visualColor = RarityVisualSettings.GetVisualColor(rarity, RarityVisualLayer.WorldBeam, tuning.WorldBeamAlpha); _beam.startColor = visualColor; Color endColor = visualColor; endColor.a *= tuning.WorldBeamEndAlphaMultiplier; _beam.endColor = endColor; if ((Object)(object)((Renderer)_beam).material != (Object)null) { RarityVFXFactory.TrySetColor(((Renderer)_beam).material, visualColor); } } } private void ApplyGlowColor(ItemRarity rarity, RarityVisualTuning tuning) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_glow == (Object)null)) { Color visualColor = RarityVisualSettings.GetVisualColor(rarity, RarityVisualLayer.WorldGlow, tuning.WorldGlowAlpha); MainModule main = _glow.main; ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(visualColor); if ((Object)(object)_glowRenderer != (Object)null && (Object)(object)((Renderer)_glowRenderer).material != (Object)null) { RarityVFXFactory.TrySetColor(((Renderer)_glowRenderer).material, visualColor); } } } private void ApplyGlowIntensity(RarityVisualTuning tuning) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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) if (!((Object)(object)_glow == (Object)null)) { ((Component)_glow).gameObject.SetActive(tuning.WorldGlowEmission > 0f); EmissionModule emission = _glow.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(tuning.WorldGlowEmission); } } private void Hide() { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); _root = null; } _beam = null; _glow = null; _glowRenderer = null; _lastRarity = RarityVisualSettings.InvalidRarity; } } [HarmonyPatch(typeof(ItemDrop), "Awake")] public static class AddRarityWorldVFXPatch { private static void Postfix(ItemDrop __instance) { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)((Component)__instance).GetComponent() != (Object)null)) { ((Component)__instance).gameObject.AddComponent(); } } } [HarmonyPatch(typeof(ObjectDB), "Awake")] public static class ObjectDB_RarityVFX_Init_Patch { private static void Postfix() { RarityVFXFactory.EnsureInitialized(); } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] public static class ObjectDB_CopyOtherDB_RarityVFX_Init_Patch { private static void Postfix() { RarityVFXFactory.EnsureInitialized(); } } } namespace BalrondItemRarity.UI { public sealed class ImproveCostEntry { public ItemDrop Item; public int Amount; } public static class ImproveCost { public static List GetCost(ItemData item) { List list = new List(); if (item == null) { return list; } Recipe recipe = ObjectDB.instance.GetRecipe(item); if ((Object)(object)recipe == (Object)null || recipe.m_resources == null) { return list; } ItemRarity rarity = item.GetRarity(); ItemRarity itemRarity = RarityConfig.Next(rarity); if (itemRarity == rarity) { return list; } RarityDef rarityDef = RarityConfig.Get(itemRarity); float num = rarityDef.ImproveCostMultiplier * RarityMath.GetImproveDiscountFactor(); for (int i = 0; i < recipe.m_resources.Length; i++) { Requirement val = recipe.m_resources[i]; if (val != null && !((Object)(object)val.m_resItem == (Object)null)) { int amount = val.GetAmount(1); int num2 = Mathf.CeilToInt((float)amount * num); if (num2 <= 0 && amount > 0) { num2 = 1; } if (num2 > 0) { list.Add(new ImproveCostEntry { Item = val.m_resItem, Amount = num2 }); } } } return list; } public static bool PlayerHasCost(Player player, List cost) { if ((Object)(object)player == (Object)null) { return false; } Inventory inventory = ((Humanoid)player).GetInventory(); for (int i = 0; i < cost.Count; i++) { if (inventory.CountItems(cost[i].Item.m_itemData.m_shared.m_name, -1, true) < cost[i].Amount) { return false; } } return true; } public static void Consume(Player player, List cost) { if (!((Object)(object)player == (Object)null) && !player.NoCostCheat() && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)20)) { Inventory inventory = ((Humanoid)player).GetInventory(); for (int i = 0; i < cost.Count; i++) { inventory.RemoveItem(cost[i].Item.m_itemData.m_shared.m_name, cost[i].Amount, -1, true); } } } } public static class ImproveUIState { public static Button TabButton; public static bool Active; public static bool IsImproving; public static float ImproveTimer = -1f; public static ItemData PendingImproveItem; public static void Reset() { Active = false; CancelImproveProgress(); if ((Object)(object)TabButton != (Object)null) { ((Selectable)TabButton).interactable = true; } } public static void CancelImproveProgress() { IsImproving = false; ImproveTimer = -1f; PendingImproveItem = null; } } [HarmonyPatch(typeof(InventoryGui), "Awake")] public static class ImproveTabAwakePatch { private static void Postfix(InventoryGui __instance) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown if ((Object)(object)ImproveUIState.TabButton != (Object)null) { return; } Button tabUpgrade = __instance.m_tabUpgrade; Button val = Object.Instantiate