Decompiled source of RiskOfTheAncients2 v1.0.1
RiskOfTheAncients2.dll
Decompiled 21 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Microsoft.CodeAnalysis; using On.RoR2; using R2API; using R2API.Utils; using ROTA2.Buffs; using ROTA2.Equipment; using ROTA2.Items; using RoR2; using RoR2.Navigation; using RoR2.Skills; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("RiskOfTheAncients2")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+6db19257d7ceaeaf012545ba810c72cd80ac84eb")] [assembly: AssemblyProduct("RiskOfTheAncients2")] [assembly: AssemblyTitle("RiskOfTheAncients2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ROTA2 { internal static class Log { private static ManualLogSource _logSource; internal static void Init(ManualLogSource logSource) { _logSource = logSource; } internal static void Debug(object data) { _logSource.LogDebug(data); } internal static void Error(object data) { _logSource.LogError(data); } internal static void Fatal(object data) { _logSource.LogFatal(data); } internal static void Info(object data) { _logSource.LogInfo(data); } internal static void Message(object data) { _logSource.LogMessage(data); } internal static void Warning(object data) { _logSource.LogWarning(data); } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("Dnarok.RiskOfTheAncients2", "RiskOfTheAncients2", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string PluginGUID = "Dnarok.RiskOfTheAncients2"; public const string PluginAuthor = "Dnarok"; public const string PluginName = "RiskOfTheAncients2"; public const string PluginVersion = "1.0.0"; public List<ItemBase> Items = new List<ItemBase>(); public static Dictionary<ItemBase, bool> ItemsEnabled = new Dictionary<ItemBase, bool>(); public List<EquipmentBase> Equipment = new List<EquipmentBase>(); public static Dictionary<EquipmentBase, bool> EquipmentEnabled = new Dictionary<EquipmentBase, bool>(); public List<BuffBase> Buffs = new List<BuffBase>(); public static SkillDef disabledSkill; public void Awake() { //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) Log.Init(((BaseUnityPlugin)this).Logger); CommandHelper.AddToConsoleWhenReady(); string[] manifestResourceNames = Assembly.GetExecutingAssembly().GetManifestResourceNames(); foreach (string text in manifestResourceNames) { ((BaseUnityPlugin)this).Logger.LogInfo((object)text); } foreach (Type item in from type in Assembly.GetExecutingAssembly().GetTypes() where !type.IsAbstract && (type.IsSubclassOf(typeof(ItemBase)) || type.IsSubclassOf(typeof(EquipmentBase)) || type.IsSubclassOf(typeof(BuffBase))) select type) { if (item.IsSubclassOf(typeof(ItemBase))) { ItemBase itemBase = (ItemBase)Activator.CreateInstance(item); ItemsEnabled.Add(itemBase, ((BaseUnityPlugin)this).Config.Bind<bool>("Item: " + itemBase.ConfigItemName, "Enabled", true, "Should this item be available?").Value); if (ItemsEnabled[itemBase]) { Items.Add(itemBase); itemBase.Init(((BaseUnityPlugin)this).Config); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Item: " + itemBase.ItemName + " initialized!")); } else { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Item: " + itemBase.ItemName + " NOT initialized!")); } } else if (item.IsSubclassOf(typeof(EquipmentBase))) { EquipmentBase equipmentBase = (EquipmentBase)Activator.CreateInstance(item); EquipmentEnabled.Add(equipmentBase, ((BaseUnityPlugin)this).Config.Bind<bool>("Item: " + equipmentBase.EquipmentName, "Enabled", true, "Should this item be available?").Value); if (EquipmentEnabled[equipmentBase]) { Equipment.Add(equipmentBase); equipmentBase.Init(((BaseUnityPlugin)this).Config); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Equipment: " + equipmentBase.EquipmentName + " initialized!")); } else { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Equipment: " + equipmentBase.EquipmentName + " NOT initialized!")); } } else if (item.IsSubclassOf(typeof(BuffBase))) { BuffBase buffBase = (BuffBase)Activator.CreateInstance(item); Buffs.Add(buffBase); buffBase.Init(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Buff: " + buffBase.BuffName + " initialized!")); } } if ((Object)(object)disabledSkill == (Object)null) { SkillDef val = LegacyResourcesAPI.Load<SkillDef>("SkillDefs/CaptainBody/CaptainSkillUsedUp"); disabledSkill = ScriptableObject.CreateInstance<SkillDef>(); disabledSkill.skillName = val.skillName; disabledSkill.skillNameToken = val.skillNameToken; disabledSkill.skillDescriptionToken = val.skillDescriptionToken; disabledSkill.icon = val.icon; disabledSkill.activationStateMachineName = val.activationStateMachineName; disabledSkill.activationState = val.activationState; disabledSkill.interruptPriority = val.interruptPriority; disabledSkill.baseRechargeInterval = val.baseRechargeInterval; disabledSkill.baseMaxStock = val.baseMaxStock; disabledSkill.rechargeStock = val.rechargeStock; disabledSkill.requiredStock = val.requiredStock; disabledSkill.stockToConsume = val.stockToConsume; disabledSkill.beginSkillCooldownOnSkillEnd = val.beginSkillCooldownOnSkillEnd; disabledSkill.fullRestockOnAssign = val.fullRestockOnAssign; disabledSkill.dontAllowPastMaxStocks = val.dontAllowPastMaxStocks; disabledSkill.canceledFromSprinting = val.canceledFromSprinting; disabledSkill.isCombatSkill = val.isCombatSkill; disabledSkill.resetCooldownTimerOnUse = val.resetCooldownTimerOnUse; disabledSkill.cancelSprintingOnActivation = val.cancelSprintingOnActivation; disabledSkill.canceledFromSprinting = val.canceledFromSprinting; disabledSkill.forceSprintDuringState = val.forceSprintDuringState; disabledSkill.mustKeyPress = val.mustKeyPress; disabledSkill.keywordTokens = val.keywordTokens; ContentAddition.AddSkillDef(disabledSkill); } } private void Update() { } public static byte[] ExtractResource(string filename) { using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(filename); if (stream == null) { Log.Warning("Manifest resource stream was null for " + filename + "."); return null; } byte[] array = new byte[stream.Length]; if (stream.Read(array, 0, array.Length) == 0) { Log.Warning("Read 0 bytes from resource " + filename + "."); return null; } return array; } public static Sprite ExtractSprite(string filename) { //IL_0012: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //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_00c1: 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_00fe: 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_008a: Unknown result type (might be due to invalid IL or missing references) if (filename == "") { return Addressables.LoadAssetAsync<Sprite>((object)"RoR2/Base/Common/MiscIcons/texMysteryIcon.png").WaitForCompletion(); } byte[] array = ExtractResource(filename); if (array == null) { Log.Warning("Failed to extract bytes from resource \"" + filename + "\". Falling back to mystery icon."); return Addressables.LoadAssetAsync<Sprite>((object)"RoR2/Base/Common/MiscIcons/texMysteryIcon.png").WaitForCompletion(); } Texture2D val = new Texture2D(512, 512); if (!ImageConversion.LoadImage(val, array)) { Log.Warning("Failed to convert resource bytes from \"" + filename + "\" into texture. Falling back to mystery icon."); return Addressables.LoadAssetAsync<Sprite>((object)"RoR2/Base/Common/MiscIcons/texMysteryIcon.png").WaitForCompletion(); } Log.Info($"Successfully loaded texture from resource \"{filename}\": {((Texture)val).width}x{((Texture)val).height}, {((Texture)val).graphicsFormat:G}."); return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } [ConCommand(/*Could not decode attribute arguments.*/)] private static void GiveItemCommand(ConCommandArgs arguments) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_00b0: 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_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)((ConCommandArgs)(ref arguments)).senderBody) || !Object.op_Implicit((Object)(object)((ConCommandArgs)(ref arguments)).senderBody.inventory)) { return; } string token = ((ConCommandArgs)(ref arguments)).GetArgString(0); ItemBase itemBase = ItemsEnabled.Keys.ToList().Find((ItemBase x) => x.ItemTokenName == token); if (itemBase != null) { Log.Info($"Command and item recognized. Spawning {itemBase.ItemName} at coordinates {((ConCommandArgs)(ref arguments)).senderMaster.GetBodyObject().transform.position}."); PickupDropletController.CreatePickupDroplet(PickupCatalog.FindPickupIndex(itemBase.ItemDef.itemIndex), ((ConCommandArgs)(ref arguments)).senderMaster.GetBodyObject().transform.position, ((ConCommandArgs)(ref arguments)).senderMaster.GetBodyObject().transform.forward * 20f); return; } EquipmentBase equipmentBase = EquipmentEnabled.Keys.ToList().Find((EquipmentBase x) => x.EquipmentTokenName == token); if (equipmentBase != null) { Log.Info($"Command and equipment recognized. Spawning {equipmentBase.EquipmentName} at coordinates {((ConCommandArgs)(ref arguments)).senderMaster.GetBodyObject().transform.position}."); PickupDropletController.CreatePickupDroplet(PickupCatalog.FindPickupIndex(equipmentBase.EquipmentDef.equipmentIndex), ((ConCommandArgs)(ref arguments)).senderMaster.GetBodyObject().transform.position, ((ConCommandArgs)(ref arguments)).senderMaster.GetBodyObject().transform.forward * 20f); } } [ConCommand(/*Could not decode attribute arguments.*/)] private static void RemoveItemCommand(ConCommandArgs arguments) { //IL_0093: 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) if (!Object.op_Implicit((Object)(object)((ConCommandArgs)(ref arguments)).senderBody) || !Object.op_Implicit((Object)(object)((ConCommandArgs)(ref arguments)).senderBody.inventory)) { return; } string token = ((ConCommandArgs)(ref arguments)).GetArgString(0); ItemBase itemBase = ItemsEnabled.Keys.ToList().Find((ItemBase x) => x.ItemTokenName == token); if (itemBase != null && Object.op_Implicit((Object)(object)((ConCommandArgs)(ref arguments)).senderBody.inventory)) { Log.Info("Command and item recognized. Removing " + itemBase.ItemName + " from " + ((Object)arguments.sender).name + "."); ((ConCommandArgs)(ref arguments)).senderBody.inventory.RemoveItem(itemBase.ItemDef, 1); return; } EquipmentBase equipmentBase = EquipmentEnabled.Keys.ToList().Find((EquipmentBase x) => x.EquipmentTokenName == token); if (equipmentBase != null && Object.op_Implicit((Object)(object)((ConCommandArgs)(ref arguments)).senderBody.inventory)) { Log.Info("Command and item recognized. Removing " + equipmentBase.EquipmentName + " from " + ((Object)arguments.sender).name + "."); ((ConCommandArgs)(ref arguments)).senderBody.inventory.SetEquipmentIndex((EquipmentIndex)(-1)); } } } } namespace ROTA2.Items { public class BootsOfSpeed : ItemBase<BootsOfSpeed> { public float MovementSpeedBase; public float MovementSpeedPerStack; public override string ItemName => "Boots of Speed"; public override string ConfigItemName => ItemName; public override string ItemTokenName => "BOOTS_OF_SPEED"; public override string ItemTokenPickup => "Slightly increases base movement speed."; public override string ItemTokenDesc => "Increases " + Utility("base movement speed") + " by " + Utility($"{MovementSpeedBase}") + " " + Stack($"(+{MovementSpeedPerStack} per stack)") + "."; public override string ItemTokenLore => "Fleet footwear, increasing movement."; public override ItemTier Tier => (ItemTier)0; public override string ItemModelPath => "RoR2/Base/Mystery/PickupMystery.prefab"; public override string ItemIconPath => "RiskOfTheAncients2.Icons.boots_of_speed.png"; public override void Hooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(AddMovementSpeed); } public override void Init(ConfigFile configuration) { CreateConfig(configuration); CreateLanguageTokens(); CreateItemDef(); Hooks(); } public void CreateConfig(ConfigFile configuration) { MovementSpeedBase = configuration.Bind<float>("Item: " + ItemName, "Initial Base Movement Speed Bonus", 0.5f, "How much base movement speed should be provided by the first stack?").Value; MovementSpeedPerStack = configuration.Bind<float>("Item: " + ItemName, "Stacking Base Movement Speed Bonus", 0.5f, "How much base movement speed should be provided by subsequent stacks?").Value; } private void AddMovementSpeed(CharacterBody body, StatHookEventArgs arguments) { int count = GetCount(body); if (count > 0) { arguments.baseMoveSpeedAdd += MovementSpeedBase + MovementSpeedPerStack * (float)(count - 1); } } } public class EnchantedMango : ItemBase<EnchantedMango> { public float HealthThreshold; public float DamageBonus; public float DamageDuration; public override string ItemName => "Enchanted Mango"; public override string ConfigItemName => ItemName; public override string ItemTokenName => "ENCHANTED_MANGO"; public override string ItemTokenPickup => "Receive bonus damage and reset all skill cooldowns at low health. Consumed on use."; public override string ItemTokenDesc => "Taking damage to below " + Health($"{HealthThreshold}% health") + " " + Utility("consumes") + " this item, " + Utility("resetting all skill cooldowns") + " and increasing " + Damage("damage") + " by " + Damage($"{DamageBonus}%") + " for " + Damage($"{DamageDuration} seconds") + "."; public override string ItemTokenLore => "The bittersweet flavors of Jidi Isle are irresistible to amphibians."; public override ItemTier Tier => (ItemTier)0; public override string ItemIconPath => "RiskOfTheAncients2.Icons.enchanted_mango.png"; public override void Hooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown HealthComponent.UpdateLastHitTime += new hook_UpdateLastHitTime(OnHit); } public override void Init(ConfigFile configuration) { CreateConfig(configuration); CreateLanguageTokens(); CreateItemDef(); Hooks(); } public void CreateConfig(ConfigFile configuration) { HealthThreshold = configuration.Bind<float>("Item: " + ItemName, "Health Threshold", 50f, "At what percent of health should this item activate?").Value; DamageBonus = configuration.Bind<float>("Item: " + ItemName, "Damage Bonus", 50f, "How much bonus damage should be provided by activation?").Value; DamageDuration = configuration.Bind<float>("Item: " + ItemName, "Damage Duration", 5f, "How long should the bonus damage last?").Value; } private void OnHit(orig_UpdateLastHitTime orig, HealthComponent self, float damageValue, Vector3 damagePosition, bool damageIsSilent, GameObject attacker, bool delayedDamage, bool firstHitOfDelayedDamage) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(self, damageValue, damagePosition, damageIsSilent, attacker, delayedDamage, firstHitOfDelayedDamage); if (!NetworkServer.active || !Object.op_Implicit((Object)(object)self) || GetCount(self.body) <= 0 || !self.IsHealthBelowThreshold(HealthThreshold / 100f) || BuffBase<EnchantedMangoBuff>.Instance.HasThisBuff(self.body)) { return; } BuffBase<EnchantedMangoBuff>.Instance.ApplyTo(new BuffBase.ApplyParameters { victim = self.body, duration = DamageDuration }); if (Object.op_Implicit((Object)(object)self.body.skillLocator)) { GenericSkill[] allSkills = self.body.skillLocator.allSkills; if (allSkills != null) { GenericSkill[] array = allSkills; foreach (GenericSkill val in array) { if (Object.op_Implicit((Object)(object)val) && val.CanApplyAmmoPack() && val.cooldownRemaining > 0f) { val.ApplyAmmoPack(); } } } } self.body.inventory.RemoveItem(ItemDef, 1); } } public class ConsumedMango : ItemBase<ConsumedMango> { public float DamageBase; public float DamagePerStack; public override string ItemName => "Consumed Mango"; public override string ConfigItemName => ItemName; public override string ItemTokenName => "CONSUMED_MANGO"; public override string ItemTokenPickup => "Snack time's over."; public override string ItemTokenDesc => "Increases " + Damage("damage") + " by " + Damage($"{DamageBase}%") + " " + Stack($"(+{DamagePerStack} per stack)") + "."; public override string ItemTokenLore => "I miss it already..."; public override ItemTier Tier => (ItemTier)5; public override ItemTag[] ItemTags => (ItemTag[])(object)new ItemTag[1] { (ItemTag)9 }; public override string ItemIconPath => "RiskOfTheAncients2.Icons.consumed_mango.png"; public override void Hooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(AddDamage); } public override void Init(ConfigFile configuration) { CreateConfig(configuration); CreateLanguageTokens(); CreateItemDef(); Hooks(); } public void CreateConfig(ConfigFile configuration) { DamageBase = configuration.Bind<float>("Item: " + ItemName, "Damage Base", 2.5f, "How much damage should be provided by the first stack?").Value; DamagePerStack = configuration.Bind<float>("Item: " + ItemName, "Damage Per Stack", 2.5f, "How much damage should be provided by subsequent stacks?").Value; } private void AddDamage(CharacterBody body, StatHookEventArgs args) { int count = GetCount(body); if (count > 0) { args.damageMultAdd += DamageBase / 100f + DamagePerStack / 100f * (float)(count - 1); } } } public class FairysTrinket : ItemBase<FairysTrinket> { public float SkillCooldownReductionBase; public float SkillCooldownReductionPerStack; public float DamageBase; public float DamagePerStack; public float MaximumHealthBase; public float MaximumHealthPerStack; public override string ItemName => "Fairy's Trinket"; public override string ConfigItemName => "Fairys Trinket"; public override string ItemTokenName => "FAIRYS_TRINKET"; public override string ItemTokenPickup => "Reduces skill cooldowns and increases damage and health."; public override string ItemTokenDesc => "Reduces " + Utility("skill cooldowns") + " by " + Utility($"{SkillCooldownReductionBase}%") + " " + Stack($"(+{SkillCooldownReductionPerStack}% per stack)") + ", and increases " + Damage("damage") + " by " + Damage($"{DamageBase}%") + " " + Stack($"(+{DamagePerStack}% per stack)") + " and " + Healing("maximum health") + " by " + Healing($"{MaximumHealthBase}") + " " + Stack($"(+{MaximumHealthPerStack} per stack)") + "."; public override string ItemTokenLore => "A small token imbued with the fortune of the fae in recognition of an intriguing display of mortal kindness."; public override ItemTier Tier => (ItemTier)0; public override string ItemIconPath => "RiskOfTheAncients2.Icons.fairys_trinket.png"; public override void Hooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(AddCooldownReduction); RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(AddDamage); RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(AddMaximumHealth); } public override void Init(ConfigFile configuration) { CreateConfig(configuration); CreateLanguageTokens(); CreateItemDef(); Hooks(); } public void CreateConfig(ConfigFile configuration) { SkillCooldownReductionBase = configuration.Bind<float>("Item: " + ConfigItemName, "Initial Skill Cooldown Reduction", 2.5f, "How much skill cooldown reduction should be provided by the first stack?").Value; SkillCooldownReductionPerStack = configuration.Bind<float>("Item: " + ConfigItemName, "Stacking Skill Cooldown Reduction", 2.5f, "How much skill cooldown reduction should be provided by subsequent stacks?").Value; DamageBase = configuration.Bind<float>("Item: " + ConfigItemName, "Initial Damage Bonus", 3.5f, "How much damage should be provided by the first stack?").Value; DamagePerStack = configuration.Bind<float>("Item: " + ConfigItemName, "Stacking Damage Bonus", 3.5f, "How much damage should be provided by subsequent stacks?").Value; MaximumHealthBase = configuration.Bind<float>("Item: " + ConfigItemName, "Initial Maximum Health Bonus", 10f, "How much maximum health should be provided by the first stack?").Value; MaximumHealthPerStack = configuration.Bind<float>("Item: " + ConfigItemName, "Stacking Maximum Health Bonus", 10f, "How much maximum health should be provided by subsequent stacks?").Value; } private void AddCooldownReduction(CharacterBody body, StatHookEventArgs arguments) { int count = GetCount(body); if (count == 1) { arguments.cooldownMultAdd -= 1f - (1f - SkillCooldownReductionBase / 100f); } else if (count > 1) { arguments.cooldownMultAdd -= 1f - (1f - SkillCooldownReductionBase / 100f) * (float)Math.Pow(1f - SkillCooldownReductionPerStack / 100f, count - 1); } } private void AddDamage(CharacterBody body, StatHookEventArgs arguments) { int count = GetCount(body); if (count > 0) { arguments.damageMultAdd += DamageBase / 100f + DamagePerStack / 100f * (float)(count - 1); } } private void AddMaximumHealth(CharacterBody body, StatHookEventArgs arguments) { int count = GetCount(body); if (count > 0) { arguments.baseHealthAdd += MaximumHealthBase + MaximumHealthPerStack * (float)(count - 1); } } } public class HealingSalve : ItemBase<HealingSalve> { public float MaximumHealthRegenerationBase; public float MaximumHealthRegenerationPerStack; public float BuffDuration; public override string ItemName => "Healing Salve"; public override string ConfigItemName => ItemName; public override string ItemTokenName => "HEALING_SALVE"; public override string ItemTokenPickup => "Receive interruptible healing after using your Special skill."; public override string ItemTokenDesc => "Activating your " + Utility("Special skill") + " " + Healing("heals") + " you for " + Healing($"{MaximumHealthRegenerationBase}%") + " " + Stack($"(+{MaximumHealthRegenerationPerStack}% per stack)") + " " + Healing("of your maximum health") + " per second for " + Utility($"{BuffDuration} seconds") + ". Healing is " + Health("interrupted by taking damage."); public override string ItemTokenLore => "A magical salve that can quickly mend even the deepest of wounds."; public override ItemTier Tier => (ItemTier)0; public override string ItemIconPath => "RiskOfTheAncients2.Icons.healing_salve.png"; public override void Hooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown CharacterBody.OnSkillActivated += new hook_OnSkillActivated(OnSkill); } public override void Init(ConfigFile configuration) { CreateConfig(configuration); CreateLanguageTokens(); CreateItemDef(); Hooks(); } public void CreateConfig(ConfigFile configuration) { MaximumHealthRegenerationBase = configuration.Bind<float>("Item: " + ItemName, "Maximum Health Regeneration Base", 2f, "How much maximum health percentage regeneration should the first stack provide?").Value; MaximumHealthRegenerationPerStack = configuration.Bind<float>("Item: " + ItemName, "Maximum Health Regeneration Per Stack", 2f, "How much maximum health percentage regeneration should subsequent stacks provide?").Value; BuffDuration = configuration.Bind<float>("Item: " + ItemName, "Healing Duration", 5f, "How long should the regeneration last?").Value; } private void OnSkill(orig_OnSkillActivated orig, CharacterBody body, GenericSkill skill) { if (GetCount(body) > 0 && (Object)(object)skill == (Object)(object)body.skillLocator.special) { BuffBase<HealingSalveBuff>.Instance.ApplyTo(new BuffBase.ApplyParameters { victim = body, duration = BuffDuration }); } } } public class HeartOfTarrasque : ItemBase<HeartOfTarrasque> { public float MaximumHealthBase; public float MaximumHealthPerStack; public float MaximumHealthRegenerationPercentage; public override string ItemName => "Heart of Tarrasque"; public override string ConfigItemName => ItemName; public override string ItemTokenName => "HEART_OF_TARRASQUE"; public override string ItemTokenPickup => "Massively increases health and health regeneration."; public override string ItemTokenDesc => "Increases " + Healing("base health regeneration") + " by " + Healing($"{MaximumHealthRegenerationPercentage}% of your maximum health") + " per second, and increases " + Healing("maximum health") + " by " + Healing($"{MaximumHealthBase}") + " " + Stack($"(+{MaximumHealthPerStack} per stack)") + "."; public override string ItemTokenLore => "Preserved heart of an extinct monster, it bolsters the bearer's fortitude."; public override ItemTier Tier => (ItemTier)2; public override string ItemModelPath => "RoR2/Base/Mystery/PickupMystery.prefab"; public override string ItemIconPath => "RiskOfTheAncients2.Icons.heart_of_tarrasque.png"; public override void Hooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(AddMaximumHealth); RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(AddHealthRegeneration); } public override void Init(ConfigFile configuration) { CreateConfig(configuration); CreateLanguageTokens(); CreateItemDef(); Hooks(); } public void CreateConfig(ConfigFile configuration) { MaximumHealthBase = configuration.Bind<float>("Item: " + ItemName, "Initial Maximum Health Bonus", 200f, "How much maximum health should be provided by the first stack?").Value; MaximumHealthPerStack = configuration.Bind<float>("Item: " + ItemName, "Stacking Maximum Health Bonus", 200f, "How much maximum health should be provided by subsequent stacks?").Value; MaximumHealthRegenerationPercentage = configuration.Bind<float>("Item: " + ItemName, "Percentage of Maximum Health as Bonus Health Regeneration", 1.4f, "What percentage of maximum health should be provided as health regeneration?").Value; } private void AddMaximumHealth(CharacterBody body, StatHookEventArgs arguments) { int count = GetCount(body); if (count > 0) { arguments.baseHealthAdd += MaximumHealthBase + MaximumHealthPerStack * (float)(count - 1); } } private void AddHealthRegeneration(CharacterBody body, StatHookEventArgs arguments) { if (GetCount(body) > 0) { HealthComponent component = ((Component)body).GetComponent<HealthComponent>(); if (Object.op_Implicit((Object)(object)component)) { arguments.baseRegenAdd += component.fullHealth * MaximumHealthRegenerationPercentage / 100f; } } } } public abstract class ItemBase<T> : ItemBase where T : ItemBase<T> { public static T Instance { get; private set; } public ItemBase() { if (Instance != null) { throw new InvalidOperationException("Singleton class \"" + typeof(T).Name + "\" inheriting ItemBase was instantiated twice."); } Instance = this as T; } } public abstract class ItemBase { public Func<string, string> Damage = (string x) => "<style=cIsDamage>" + x + "</style>"; public Func<string, string> Healing = (string x) => "<style=cIsHealing>" + x + "</style>"; public Func<string, string> Utility = (string x) => "<style=cIsUtility>" + x + "</style>"; public Func<string, string> Stack = (string x) => "<style=cStack>" + x + "</style>"; public Func<string, string> Health = (string x) => "<style=cIsHealth>" + x + "</style>"; public Func<string, string> Gold = (string x) => "<style=cShrine>" + x + "</style>"; public Func<string, string, string> Color = (string x, string hex) => "<" + hex + ">" + x + "</color>"; public ItemDef ItemDef; public abstract string ItemName { get; } public abstract string ConfigItemName { get; } public abstract string ItemTokenName { get; } public abstract string ItemTokenPickup { get; } public abstract string ItemTokenDesc { get; } public abstract string ItemTokenLore { get; } public abstract ItemTier Tier { get; } public virtual string ItemModelPath { get; } = "RoR2/Base/Mystery/PickupMystery.prefab"; public virtual string ItemIconPath { get; } = ""; public virtual ItemTag[] ItemTags { get; } = Array.Empty<ItemTag>(); public virtual bool Removable { get; } = true; public virtual bool Hidden { get; } public abstract void Init(ConfigFile configuration); public abstract void Hooks(); protected void CreateLanguageTokens() { LanguageAPI.Add("ITEM_" + ItemTokenName + "_NAME", ItemName); LanguageAPI.Add("ITEM_" + ItemTokenName + "_PICKUP", ItemTokenPickup); LanguageAPI.Add("ITEM_" + ItemTokenName + "_DESCRIPTION", ItemTokenDesc); LanguageAPI.Add("ITEM_" + ItemTokenName + "_LORE", ItemTokenLore); } protected void CreateItemDef() { //IL_00b2: 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_00ed: 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_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Expected O, but got Unknown //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Expected O, but got Unknown ItemDef = ScriptableObject.CreateInstance<ItemDef>(); ((Object)ItemDef).name = "ITEM_" + ItemTokenName; ItemDef.nameToken = "ITEM_" + ItemTokenName + "_NAME"; ItemDef.pickupToken = "ITEM_" + ItemTokenName + "_PICKUP"; ItemDef.descriptionToken = "ITEM_" + ItemTokenName + "_DESCRIPTION"; ItemDef.loreToken = "ITEM_" + ItemTokenName + "_LORE"; ItemDef.pickupModelPrefab = Addressables.LoadAssetAsync<GameObject>((object)ItemModelPath).WaitForCompletion(); ItemDef.hidden = Hidden; ItemDef.canRemove = Removable; ItemDef.deprecatedTier = Tier; ItemDef.tags = ItemTags; if (ItemIconPath == "") { ItemDef.pickupIconSprite = Addressables.LoadAssetAsync<Sprite>((object)"RoR2/Base/Common/MiscIcons/texMysteryIcon.png").WaitForCompletion(); } else { ItemDef.pickupIconSprite = Plugin.ExtractSprite(ItemIconPath); } ItemAPI.Add(new CustomItem(ItemDef, new ItemDisplayRuleDict((ItemDisplayRule[])null))); } public int GetCount(CharacterBody body) { if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.inventory)) { return body.inventory.GetItemCount(ItemDef); } return 0; } public int GetCount(CharacterMaster master) { if (Object.op_Implicit((Object)(object)master) && Object.op_Implicit((Object)(object)master.inventory)) { return master.inventory.GetItemCount(ItemDef); } return 0; } } public class Javelin : ItemBase<Javelin> { private float ProcChance; private float DamageBase; private float DamagePerStack; private float ProcCoefficient; private ModdedProcType proc; public override string ItemName => "Javelin"; public override string ConfigItemName => ItemName; public override string ItemTokenName => "JAVELIN"; public override string ItemTokenPickup => "Chance on hit to strike a second time for small damage."; public override string ItemTokenDesc => Damage($"{ProcChance}%") + " chance on hit to " + Damage("hit again") + " for " + Damage($"{DamageBase}%") + " " + Stack($"(+{DamagePerStack}% per stack)") + " TOTAL damage."; public override string ItemTokenLore => "A rather typical spear that can sometimes pierce through an enemy's armor when used to attack."; public override ItemTier Tier => (ItemTier)0; public override string ItemIconPath => "RiskOfTheAncients2.Icons.javelin.png"; public override void Hooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown GlobalEventManager.OnHitEnemy += new hook_OnHitEnemy(OnHit); } public override void Init(ConfigFile configuration) { //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) CreateConfig(configuration); CreateLanguageTokens(); CreateItemDef(); Hooks(); proc = ProcTypeAPI.ReserveProcType(); } public void CreateConfig(ConfigFile configuration) { ProcChance = configuration.Bind<float>("Item: " + ItemName, "Proc Chance", 20f, "What is the chance on hit to proc?").Value; DamageBase = configuration.Bind<float>("Item: " + ItemName, "Damage Base", 25f, "How much total damage should the bonus hit do on the first stack?").Value; DamagePerStack = configuration.Bind<float>("Item: " + ItemName, "Damage Per Stack", 15f, "How much extra total damage should the bonus hit do for subsequent stacks?").Value; ProcCoefficient = configuration.Bind<float>("Item: " + ItemName, "Proc Coefficient", 0.2f, "What is the proc coefficient of the bonus hit?").Value; } private void OnHit(orig_OnHitEnemy orig, GlobalEventManager self, DamageInfo info, GameObject victim) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Expected O, but got Unknown if (info.rejected || info.procCoefficient <= 0f || ProcTypeAPI.HasModdedProc(info.procChainMask, proc)) { orig.Invoke(self, info, victim); return; } GameObject attacker = info.attacker; if (Object.op_Implicit((Object)(object)attacker)) { CharacterBody component = attacker.GetComponent<CharacterBody>(); HealthComponent component2 = victim.GetComponent<HealthComponent>(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component2)) { int count = GetCount(component); if (count > 0 && Util.CheckRoll(ProcChance * info.procCoefficient, component.master)) { ProcChainMask procChainMask = info.procChainMask; ProcTypeAPI.AddModdedProc(ref procChainMask, proc); DamageInfo val = new DamageInfo { attacker = attacker, damage = info.damage * (DamageBase / 100f + DamagePerStack / 100f * (float)(count - 1)), position = info.position, damageColorIndex = (DamageColorIndex)9, damageType = info.damageType, procCoefficient = ProcCoefficient, crit = info.crit, procChainMask = procChainMask }; component2.TakeDamage(val); } } } orig.Invoke(self, info, victim); } } public class Kaya : ItemBase<Kaya> { public float SkillCooldownReductionBase; public float SkillCooldownReductionPerStack; public float DamageBase; public float DamagePerStack; public override string ItemName => "Kaya"; public override string ConfigItemName => ItemName; public override string ItemTokenName => "KAYA"; public override string ItemTokenPickup => "Reduces skill cooldowns and increases damage. Combines with Yasha or Sange."; public override string ItemTokenDesc => "Reduces " + Utility("skill cooldowns") + " by " + Utility($"{SkillCooldownReductionBase}%") + " " + Stack($"(+{SkillCooldownReductionPerStack}% per stack)") + " and increases " + Damage("damage") + " by " + Damage($"{DamageBase}%") + " " + Stack($"(+{DamagePerStack}% per stack)") + "."; public override string ItemTokenLore => "The staff of a renowned sorceress, lost for countless millennia."; public override ItemTier Tier => (ItemTier)1; public override string ItemModelPath => "RoR2/Base/Mystery/PickupMystery.prefab"; public override string ItemIconPath => "RiskOfTheAncients2.Icons.kaya.png"; public override void Hooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(AddCooldownReduction); RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(AddDamage); } public override void Init(ConfigFile configuration) { CreateConfig(configuration); CreateLanguageTokens(); CreateItemDef(); Hooks(); } public void CreateConfig(ConfigFile configuration) { SkillCooldownReductionBase = configuration.Bind<float>("Item: " + ItemName, "Initial Skill Cooldown Reduction", 8f, "How much skill cooldown reduction should be provided by the first stack?").Value; SkillCooldownReductionPerStack = configuration.Bind<float>("Item: " + ItemName, "Stacking Skill Cooldown Reduction", 8f, "How much skill cooldown reduction should be provided by subsequent stacks?").Value; DamageBase = configuration.Bind<float>("Item: " + ItemName, "Initial Damage Bonus", 10f, "How much damage should be provided by the first stack?").Value; DamagePerStack = configuration.Bind<float>("Item: " + ItemName, "Stacking Damage Bonus", 10f, "How much damage should be provided by subsequent stacks?").Value; } private void AddCooldownReduction(CharacterBody body, StatHookEventArgs arguments) { int count = GetCount(body); if (count == 1) { arguments.cooldownMultAdd -= 1f - (1f - SkillCooldownReductionBase / 100f); } else if (count > 1) { arguments.cooldownMultAdd -= 1f - (1f - SkillCooldownReductionBase / 100f) * (float)Math.Pow(1f - SkillCooldownReductionPerStack / 100f, count - 1); } } private void AddDamage(CharacterBody body, StatHookEventArgs arguments) { int count = GetCount(body); if (count > 0) { arguments.damageMultAdd += DamageBase / 100f + DamagePerStack / 100f * (float)(count - 1); } } } public class KayaAndSange : ItemBase<KayaAndSange> { public float SkillCooldownReductionBase; public float SkillCooldownReductionPerStack; public float DamageBase; public float DamagePerStack; public float MaximumHealthBase; public float MaximumHealthPerStack; public float BaseHealthRegenerationBase; public float BaseHealthRegenerationPerStack; public override string ItemName => "Kaya and Sange"; public override string ConfigItemName => ItemName; public override string ItemTokenName => "KAYA_AND_SANGE"; public override string ItemTokenPickup => "Reduces skill cooldowns and increases damage, maximum health, and base health regeneration. Combines with Yasha."; public override string ItemTokenDesc => "Reduces " + Utility("skill cooldowns") + " by " + Utility($"{SkillCooldownReductionBase}%") + " " + Stack($"(+{SkillCooldownReductionPerStack}% per stack)") + " and increases " + Damage("damage") + " by " + Damage($"{DamageBase}%") + " " + Stack($"(+{DamagePerStack}% per stack)") + ", " + Healing("maximum health") + " by " + Healing($"{MaximumHealthBase}") + " " + Stack($"(+{MaximumHealthPerStack} per stack)") + ", and " + Healing("base health regeneration") + " by " + Healing($"+{BaseHealthRegenerationBase} hp/s") + " " + Stack($"(+{BaseHealthRegenerationPerStack} hp/s per stack)") + "."; public override string ItemTokenLore => "Two of three known items of unimaginable power that many believe were crafted at the same enchanter's forge."; public override ItemTier Tier => (ItemTier)1; public override ItemTag[] ItemTags => (ItemTag[])(object)new ItemTag[1] { (ItemTag)9 }; public override string ItemModelPath => "RoR2/Base/Mystery/PickupMystery.prefab"; public override string ItemIconPath => "RiskOfTheAncients2.Icons.kaya_and_sange.png"; public override void Hooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(AddCooldownReduction); RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(AddDamage); RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(AddMaximumHealth); RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(AddBaseHealthRegeneration); } public override void Init(ConfigFile configuration) { CreateConfig(configuration); CreateLanguageTokens(); CreateItemDef(); Hooks(); } public void CreateConfig(ConfigFile configuration) { SkillCooldownReductionBase = configuration.Bind<float>("Item: " + ItemName, "Initial Skill Cooldown Reduction", 12f, "How much skill cooldown reduction should be provided by the first stack?").Value; SkillCooldownReductionPerStack = configuration.Bind<float>("Item: " + ItemName, "Stacking Skill Cooldown Reduction", 12f, "How much skill cooldown reduction should be provided by subsequent stacks?").Value; DamageBase = configuration.Bind<float>("Item: " + ItemName, "Initial Damage Bonus", 15f, "How much damage should be provided by the first stack?").Value; DamagePerStack = configuration.Bind<float>("Item: " + ItemName, "Stacking Damage Bonus", 15f, "How much damage should be provided by subsequent stacks?").Value; MaximumHealthBase = configuration.Bind<float>("Item: " + ItemName, "Initial Maximum Health Bonus", 60f, "How much maximum health should be provided by the first stack?").Value; MaximumHealthPerStack = configuration.Bind<float>("Item: " + ItemName, "Stacking Maximum Health Bonus", 60f, "How much maximum health should be provided by subsequent stacks?").Value; BaseHealthRegenerationBase = configuration.Bind<float>("Item: " + ItemName, "Initial Base Health Regeneration Bonus", 2.4f, "How much base health regeneration should be provided by the first stack?").Value; BaseHealthRegenerationPerStack = configuration.Bind<float>("Item: " + ItemName, "Stacking Base Health Regeneration Bonus", 2.4f, "How much base health regeneration should be provided by subsequent stacks?").Value; } private void AddCooldownReduction(CharacterBody body, StatHookEventArgs arguments) { int count = GetCount(body); if (count == 1) { arguments.cooldownMultAdd -= 1f - (1f - SkillCooldownReductionBase / 100f); } else if (count > 1) { arguments.cooldownMultAdd -= 1f - (1f - SkillCooldownReductionBase / 100f) * (float)Math.Pow(1f - SkillCooldownReductionPerStack / 100f, count - 1); } } private void AddDamage(CharacterBody body, StatHookEventArgs arguments) { int count = GetCount(body); if (count > 0) { arguments.damageMultAdd += DamageBase / 100f + DamagePerStack / 100f * (float)(count - 1); } } private void AddMaximumHealth(CharacterBody body, StatHookEventArgs arguments) { int count = GetCount(body); if (count > 0) { arguments.baseHealthAdd += MaximumHealthBase + MaximumHealthPerStack * (float)(count - 1); } } private void AddBaseHealthRegeneration(CharacterBody body, StatHookEventArgs arguments) { int count = GetCount(body); if (count > 0) { arguments.baseRegenAdd += BaseHealthRegenerationBase + BaseHealthRegenerationPerStack * (float)(count - 1); } } } public class OrbOfBlight : ItemBase<OrbOfBlight> { public float ArmorReduction; public int MaxStacksBase; public int MaxStacksPerStack; public float ArmorReductionDuration; public override string ItemName => "Orb of Blight"; public override string ConfigItemName => ItemName; public override string ItemTokenName => "ORB_OF_BLIGHT"; public override string ItemTokenPickup => "Reduces armor on hit, up to a max."; public override string ItemTokenDesc => "On hit reduce " + Damage("armor") + " by " + Damage($"{ArmorReduction}") + " for " + Damage($"{ArmorReductionDuration} seconds") + ", up to " + Damage($"{MaxStacksBase} times") + " " + Stack($"(+{MaxStacksPerStack} per stack)") + "."; public override string ItemTokenLore => "An unnerving stone unearthed beneath the Fields of Endless Carnage."; public override ItemTier Tier => (ItemTier)0; public override string ItemModelPath => "RoR2/Base/Mystery/PickupMystery.prefab"; public override string ItemIconPath => "RiskOfTheAncients2.Icons.orb_of_blight.png"; public override void Hooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown HealthComponent.TakeDamage += new hook_TakeDamage(OnHit); } public override void Init(ConfigFile configuration) { CreateConfig(configuration); CreateLanguageTokens(); CreateItemDef(); Hooks(); } public void CreateConfig(ConfigFile configuration) { ArmorReduction = configuration.Bind<float>("Item: " + ItemName, "Armor Reduction Per Stack", 5f, "How much armor should be removed per stack of the debuff?").Value; MaxStacksBase = configuration.Bind<int>("Item: " + ItemName, "Base Max Stacks", 3, "How many debuff stacks can be applied by the first stack?").Value; MaxStacksPerStack = configuration.Bind<int>("Item: " + ItemName, "Stacking Max Stacks", 2, "How many debuff stacks can be applied by subsequent stack?").Value; ArmorReductionDuration = configuration.Bind<float>("Item: " + ItemName, "Armor Reduction Duration", 3f, "How long should the armor reduction last?").Value; } private void OnHit(orig_TakeDamage orig, HealthComponent self, DamageInfo info) { if (Object.op_Implicit((Object)(object)self) && self.alive && Object.op_Implicit((Object)(object)info.attacker) && info.procCoefficient > 0f) { CharacterBody component = info.attacker.GetComponent<CharacterBody>(); int count = GetCount(component); if (count > 0) { BuffBase<OrbOfBlightBuff>.Instance.ApplyTo(new BuffBase.ApplyParameters { victim = self.body, duration = ArmorReduction, max_stacks = MaxStacksBase + MaxStacksPerStack * (count - 1) }); } } orig.Invoke(self, info); } } public class OrbOfCorrosion : ItemBase<OrbOfCorrosion> { public class OrbOfCorrosionInventoryBehavior : MonoBehaviour { public CharacterBody body; public void Awake() { body = ((Component)this).GetComponent<CharacterBody>(); } public void Update() { //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active && Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.inventory)) { int itemCount = body.inventory.GetItemCount(ItemBase<OrbOfBlight>.Instance.ItemDef); int itemCount2 = body.inventory.GetItemCount(ItemBase<OrbOfFrost>.Instance.ItemDef); int itemCount3 = body.inventory.GetItemCount(ItemBase<OrbOfVenom>.Instance.ItemDef); if (itemCount > 0 && itemCount2 > 0 && itemCount3 > 0) { int num = Math.Min(itemCount, Math.Min(itemCount2, itemCount3)); Log.Info($"Converting {num} blights, frosts, and venoms."); body.inventory.RemoveItem(ItemBase<OrbOfBlight>.Instance.ItemDef, num); body.inventory.RemoveItem(ItemBase<OrbOfFrost>.Instance.ItemDef, num); body.inventory.RemoveItem(ItemBase<OrbOfVenom>.Instance.ItemDef, num); body.inventory.GiveItem(ItemBase<OrbOfCorrosion>.Instance.ItemDef, num); CharacterMasterNotificationQueue.PushItemTransformNotification(body.master, ItemBase<OrbOfBlight>.Instance.ItemDef.itemIndex, ItemBase<OrbOfCorrosion>.Instance.ItemDef.itemIndex, (TransformationType)0); CharacterMasterNotificationQueue.PushItemTransformNotification(body.master, ItemBase<OrbOfFrost>.Instance.ItemDef.itemIndex, ItemBase<OrbOfCorrosion>.Instance.ItemDef.itemIndex, (TransformationType)0); CharacterMasterNotificationQueue.PushItemTransformNotification(body.master, ItemBase<OrbOfVenom>.Instance.ItemDef.itemIndex, ItemBase<OrbOfCorrosion>.Instance.ItemDef.itemIndex, (TransformationType)0); } } } } public float ArmorReduction; public int MaxStacksBase; public int MaxStacksPerStack; public float ArmorReductionDuration; public float MovementSpeedSlowBase; public float MovementSpeedSlowPerStack; public float AttackSpeedSlowBase; public float AttackSpeedSlowPerStack; public float SlowDuration; public float PoisonDamageBase; public float PoisonDamagePerStack; public float PoisonDuration; public override string ItemName => "Orb of Corrosion"; public override string ConfigItemName => ItemName; public override string ItemTokenName => "ORB_OF_CORROSION"; public override string ItemTokenPickup => "Reduces armor, movement speed, and attack speed, and poisons on hit."; public override string ItemTokenDesc => "On hit:\r\n Reduce " + Damage("armor") + " by " + Damage($"{ArmorReduction}") + " for " + Damage($"{ArmorReductionDuration} seconds") + ", up to " + Damage($"{MaxStacksBase}") + " " + Stack($"(+{MaxStacksPerStack} per stack)") + " times.\r\n " + Utility("Slow") + " enemies for " + Utility($"-{MovementSpeedSlowBase}%") + " " + Stack($"(-{MovementSpeedSlowPerStack}% per stack)") + " " + Utility("movement speed") + " and " + Utility($"-{AttackSpeedSlowBase}%") + " " + Stack($"(-{AttackSpeedSlowPerStack}% per stack)") + " " + Utility("attack speed") + " for " + Utility($"{SlowDuration} seconds") + ".\r\n " + Healing("Poison") + " enemies for " + Damage($"{PoisonDamageBase}%") + " " + Stack($"(+{PoisonDamagePerStack}% per stack)") + " base damage over " + Damage($"{PoisonDuration} seconds") + ".\r\nEffects stack with component items."; public override string ItemTokenLore => "Seepage from the wounds of a warrior deity, sealed in an arcanist's orb following a campaign of vicious slaughter."; public override ItemTier Tier => (ItemTier)1; public override ItemTag[] ItemTags => (ItemTag[])(object)new ItemTag[1] { (ItemTag)9 }; public override string ItemModelPath => "RoR2/Base/Mystery/PickupMystery.prefab"; public override string ItemIconPath => "RiskOfTheAncients2.Icons.orb_of_corrosion.png"; public override void Hooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown HealthComponent.TakeDamage += new hook_TakeDamage(OnHit); CharacterBody.onBodyInventoryChangedGlobal += OnInventoryChanged; } public override void Init(ConfigFile configuration) { CreateConfig(configuration); CreateLanguageTokens(); CreateItemDef(); Hooks(); } public void CreateConfig(ConfigFile configuration) { ArmorReduction = configuration.Bind<float>("Item: " + ItemName, "Armor Reduction Per Stack", 7.5f, "How much armor should be removed per stack of the debuff?").Value; MaxStacksBase = configuration.Bind<int>("Item: " + ItemName, "Base Max Stacks", 3, "How many debuff stacks can be applied by the first stack?").Value; MaxStacksPerStack = configuration.Bind<int>("Item: " + ItemName, "Stacking Max Stacks", 2, "How many debuff stacks can be applied by subsequent stack?").Value; ArmorReductionDuration = configuration.Bind<float>("Item: " + ItemName, "Armor Reduction Duration", 3f, "How long should the armor reduction last?").Value; MovementSpeedSlowBase = configuration.Bind<float>("Item: " + ItemName, "Movement Speed Reduction Base", 15f, "How much should movement speed be reduced initially?").Value; MovementSpeedSlowPerStack = configuration.Bind<float>("Item: " + ItemName, "Movement Speed Reduction Per Stack", 15f, "How much should movement speed be reduced per stack?").Value; AttackSpeedSlowBase = configuration.Bind<float>("Item: " + ItemName, "Attack Speed Reduction Base", 15f, "How much should attack speed be reduced initially?").Value; AttackSpeedSlowPerStack = configuration.Bind<float>("Item: " + ItemName, "Attack Speed Reduction Per Stack", 15f, "How much should attack speed be reduced per stack?").Value; SlowDuration = configuration.Bind<float>("Item: " + ItemName, "Slow Duration", 3f, "How long should the slows last?").Value; PoisonDamageBase = configuration.Bind<float>("Item: " + ItemName, "Poison Damage Base", 300f, "How much base damage should the poison do with the first stack?").Value; PoisonDamagePerStack = configuration.Bind<float>("Item: " + ItemName, "Poison Damage Per Stack", 300f, "How much base damage should the poison do with subsequent stacks?").Value; PoisonDuration = configuration.Bind<float>("Item: " + ItemName, "Poison Duration", 3f, "How long should the poison last?").Value; } private void OnHit(orig_TakeDamage orig, HealthComponent self, DamageInfo info) { if (Object.op_Implicit((Object)(object)self) && self.alive && Object.op_Implicit((Object)(object)info.attacker) && info.procCoefficient > 0f) { CharacterBody component = info.attacker.GetComponent<CharacterBody>(); int count = GetCount(component); if (count > 0) { BuffBase<OrbOfCorrosionArmor>.Instance.ApplyTo(new BuffBase.ApplyParameters { victim = self.body, duration = ArmorReductionDuration, max_stacks = MaxStacksBase + MaxStacksPerStack * (count - 1) }); BuffBase<OrbOfCorrosionSlow>.Instance.ApplyTo(new BuffBase.ApplyParameters { victim = self.body, duration = SlowDuration, stacks = count, max_stacks = count }); BuffBase<OrbOfCorrosionPoison>.Instance.ApplyTo(new BuffBase.ApplyParameters { victim = self.body, attacker = component, duration = PoisonDuration, damage = (PoisonDamageBase + PoisonDamagePerStack * (float)(count - 1)) / 100f / PoisonDuration, max_stacks = 1 }); } } orig.Invoke(self, info); } private void OnInventoryChanged(CharacterBody body) { if (!Object.op_Implicit((Object)(object)((Component)body).GetComponent<OrbOfCorrosionInventoryBehavior>())) { ((Component)body).gameObject.AddComponent<OrbOfCorrosionInventoryBehavior>(); } } } public class OrbOfFrost : ItemBase<OrbOfFrost> { public float MovementSpeedSlowBase; public float MovementSpeedSlowPerStack; public float AttackSpeedSlowBase; public float AttackSpeedSlowPerStack; public float DebuffDuration; public override string ItemName => "Orb of Frost"; public override string ConfigItemName => ItemName; public override string ItemTokenName => "ORB_OF_FROST"; public override string ItemTokenPickup => "Slightly slow enemies on hit."; public override string ItemTokenDesc => Utility("Slow") + " enemies on hit for " + Utility($"{MovementSpeedSlowBase}% movement speed") + " " + Stack($"(-{MovementSpeedSlowPerStack}% per stack)") + " and " + Utility($"-{AttackSpeedSlowBase}% attack speed") + " " + Stack($"-{AttackSpeedSlowPerStack}% per stack)") + " for " + Utility($"{DebuffDuration} seconds") + "."; public override string ItemTokenLore => "Freezes your foes with a frosty force."; public override ItemTier Tier => (ItemTier)0; public override string ItemModelPath => "RoR2/Base/Mystery/PickupMystery.prefab"; public override string ItemIconPath => "RiskOfTheAncients2.Icons.orb_of_frost.png"; public override void Hooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown HealthComponent.TakeDamage += new hook_TakeDamage(OnHit); } public override void Init(ConfigFile configuration) { CreateConfig(configuration); CreateLanguageTokens(); CreateItemDef(); Hooks(); } public void CreateConfig(ConfigFile configuration) { MovementSpeedSlowBase = configuration.Bind<float>("Item: " + ItemName, "Movement Speed Reduction Base", 10f, "How much should movement speed be reduced initially?").Value; MovementSpeedSlowPerStack = configuration.Bind<float>("Item: " + ItemName, "Movement Speed Reduction Per Stack", 10f, "How much should movement speed be reduced per stack?").Value; AttackSpeedSlowBase = configuration.Bind<float>("Item: " + ItemName, "Attack Speed Reduction Base", 10f, "How much should attack speed be reduced initially?").Value; AttackSpeedSlowPerStack = configuration.Bind<float>("Item: " + ItemName, "Attack Speed Reduction Per Stack", 10f, "How much should attack speed be reduced per stack?").Value; DebuffDuration = configuration.Bind<float>("Item: " + ItemName, "Slow Duration", 3f, "How long should the slows last?").Value; } private void OnHit(orig_TakeDamage orig, HealthComponent self, DamageInfo info) { if (Object.op_Implicit((Object)(object)self) && self.alive && Object.op_Implicit((Object)(object)info.attacker) && info.procCoefficient > 0f) { CharacterBody component = info.attacker.GetComponent<CharacterBody>(); int count = GetCount(component); if (count > 0) { BuffBase<OrbOfFrostBuff>.Instance.ApplyTo(new BuffBase.ApplyParameters { victim = self.body, duration = DebuffDuration, stacks = count, max_stacks = count }); } } orig.Invoke(self, info); } } public class OrbOfVenom : ItemBase<OrbOfVenom> { public float PoisonDamageBase; public float PoisonDamagePerStack; public float PoisonDuration; public override string ItemName => "Orb of Venom"; public override string ConfigItemName => ItemName; public override string ItemTokenName => "ORB_OF_VENOM"; public override string ItemTokenPickup => "Poisons for a short time on hit."; public override string ItemTokenDesc => "On hit " + Healing("poison") + " for " + Damage($"{PoisonDamageBase}%") + " " + Stack($"(+{PoisonDamagePerStack}% per stack)") + " base damage over " + Damage($"{PoisonDuration} seconds") + "."; public override string ItemTokenLore => "Envenoms your veapon with the venom of a venomous viper."; public override ItemTier Tier => (ItemTier)0; public override string ItemModelPath => "RoR2/Base/Mystery/PickupMystery.prefab"; public override string ItemIconPath => "RiskOfTheAncients2.Icons.orb_of_venom.png"; public override void Hooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown HealthComponent.TakeDamage += new hook_TakeDamage(OnHit); } public override void Init(ConfigFile configuration) { CreateConfig(configuration); CreateLanguageTokens(); CreateItemDef(); Hooks(); } public void CreateConfig(ConfigFile configuration) { PoisonDamageBase = configuration.Bind<float>("Item: " + ItemName, "Poison Damage Base", 200f, "How much base damage should the poison do with the first stack?").Value; PoisonDamagePerStack = configuration.Bind<float>("Item: " + ItemName, "Poison Damage Per Stack", 200f, "How much base damage should the poison do with subsequent stacks?").Value; PoisonDuration = configuration.Bind<float>("Item: " + ItemName, "Poison Duration", 3f, "How long should the poison last?").Value; } private void OnHit(orig_TakeDamage orig, HealthComponent self, DamageInfo info) { if (Object.op_Implicit((Object)(object)self) && self.alive && Object.op_Implicit((Object)(object)info.attacker) && info.procCoefficient > 0f) { CharacterBody component = info.attacker.GetComponent<CharacterBody>(); int count = GetCount(component); if (count > 0) { BuffBase<OrbOfVenomBuff>.Instance.ApplyTo(new BuffBase.ApplyParameters { victim = self.body, attacker = component, duration = PoisonDuration, damage = (PoisonDamageBase + PoisonDamagePerStack * (float)(count - 1)) / 100f / PoisonDuration, max_stacks = 1 }); } } orig.Invoke(self, info); } } public class QuellingBlade : ItemBase<QuellingBlade> { private float DamageBase; private float DamagePerStack; public override string ItemName => "Quelling Blade"; public override string ConfigItemName => ItemName; public override string ItemTokenName => "QUELLING_BLADE"; public override string ItemTokenPickup => "Receive flat skill damage increase against non-boss enemies."; public override string ItemTokenDesc => "Increase " + Damage("outgoing skill damage") + " by " + Damage($"{DamageBase}") + " " + Stack($"(+{DamagePerStack} per stack)") + " against " + Damage("non-Boss enemies") + "."; public override string ItemTokenLore => "The axe of a fallen gnome, it allows you to effectively maneuver the forest."; public override ItemTier Tier => (ItemTier)0; public override string ItemIconPath => "RiskOfTheAncients2.Icons.quelling_blade.png"; public override void Hooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown HealthComponent.TakeDamage += new hook_TakeDamage(OnDamageDealt); } public override void Init(ConfigFile configuration) { CreateConfig(configuration); CreateLanguageTokens(); CreateItemDef(); Hooks(); } public void CreateConfig(ConfigFile configuration) { DamageBase = configuration.Bind<float>("Item: " + ItemName, "Damage Base", 6f, "How much flat damage should the first stack provide?").Value; DamagePerStack = configuration.Bind<float>("Item: " + ItemName, "Damage Per Stack", 6f, "How much flat damage should subsequent stacks provide?").Value; } private void OnDamageDealt(orig_TakeDamage orig, HealthComponent self, DamageInfo info) { if (info.rejected || info.procCoefficient == 0f || !((DamageTypeCombo)(ref info.damageType)).IsDamageSourceSkillBased) { orig.Invoke(self, info); return; } if (Object.op_Implicit((Object)(object)info.attacker) && Object.op_Implicit((Object)(object)self) && Object.op_Implicit((Object)(object)self.body) && !self.body.isBoss) { CharacterBody component = info.attacker.GetComponent<CharacterBody>(); int count = GetCount(component); if (count > 0) { info.damage += (DamageBase + DamagePerStack * (float)(count - 1)) * info.procCoefficient; } } orig.Invoke(self, info); } } public class Radiance : ItemBase<Radiance> { private class RadianceBehavior : MonoBehaviour { private CharacterBody body; private float timer; private void Awake() { body = ((Component)this).GetComponent<CharacterBody>(); } private void FixedUpdate() { //IL_00b1: 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_02a6: Invalid comparison between Unknown and I4 //IL_00b7: 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_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: 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_011b: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: 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_0146: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)body) || (Object.op_Implicit((Object)(object)body.healthComponent) && !body.healthComponent.alive) || !NetworkServer.active || ItemBase<Radiance>.Instance.GetCount(body) <= 0) { return; } timer += Time.fixedDeltaTime; if (!(timer > 1f)) { return; } timer -= 1f; int count = ItemBase<Radiance>.Instance.GetCount(body); float num = ItemBase<Radiance>.Instance.RadiusBase + ItemBase<Radiance>.Instance.RadiusPerStack * (float)(count - 1); num *= num; TeamIndex val = (TeamIndex)0; while ((int)val < 5) { if (val != body.teamComponent.teamIndex) { foreach (TeamComponent teamMember in TeamComponent.GetTeamMembers(val)) { CharacterBody component = ((Component)teamMember).GetComponent<CharacterBody>(); if (Object.op_Implicit((Object)(object)component) && ((Behaviour)component).isActiveAndEnabled && Object.op_Implicit((Object)(object)component.healthComponent)) { Vector3 val2 = component.transform.position - body.transform.position; if (((Vector3)(ref val2)).sqrMagnitude <= num) { InflictDotInfo val3 = default(InflictDotInfo); val3.attackerObject = ((Component)body).gameObject; val3.victimObject = ((Component)component).gameObject; val3.dotIndex = (DotIndex)1; val3.duration = ItemBase<Radiance>.Instance.BurnDuration; val3.damageMultiplier = ItemBase<Radiance>.Instance.BurnBase / 100f + ItemBase<Radiance>.Instance.BurnPerStack / 100f * (float)(count - 1); InflictDotInfo val4 = val3; StrengthenBurnUtils.CheckDotForUpgrade(body.inventory, ref val4); DotController.InflictDot(ref val4); BuffBase<RadianceBuff>.Instance.ApplyTo(new BuffBase.ApplyParameters { victim = component, duration = 1f + ItemBase<Radiance>.Instance.LingerDuration }); DamageInfo val5 = new DamageInfo { attacker = ((Component)body).gameObject, damage = body.damage * (ItemBase<Radiance>.Instance.IgniteBase / 100f + ItemBase<Radiance>.Instance.IgnitePerStack / 100f * (float)(count - 1)), position = component.transform.position, damageType = DamageTypeCombo.op_Implicit((DamageType)131072) }; component.healthComponent.TakeDamage(val5); } } } } val = (TeamIndex)(sbyte)(val + 1); } } } public float RadiusBase; public float RadiusPerStack; public float IgniteBase; public float IgnitePerStack; public float BurnBase; public float BurnPerStack; public float BurnDuration; public float MissChance; public float LingerDuration; public override string ItemName => "Radiance"; public override string ConfigItemName => ItemName; public override string ItemTokenName => "RADIANCE"; public override string ItemTokenPickup => "Ignite and blind nearby enemies."; public override string ItemTokenDesc => Damage("Ignite") + " enemies within " + Damage($"{RadiusBase}m") + " " + Stack($"(+{RadiusPerStack}m per stack)") + " for " + Damage($"{IgniteBase}%") + " " + Stack($"(+{IgnitePerStack}% per stack)") + " base damage. Additionally, enemies " + Damage("burn") + " for " + Damage($"{BurnBase}%") + " " + Stack($"(+{BurnPerStack}% per stack)") + " base damage and are " + Utility("blinded") + ", causing them to " + Utility($"miss {MissChance}%") + " of the time. " + Utility("Unaffected by luck") + "."; public override string ItemTokenLore => "A divine weapon that causes damage and a bright burning effect that lays waste to nearby enemies."; public override string ItemIconPath => "RiskOfTheAncients2.Icons.radiance.png"; public override ItemTier Tier => (ItemTier)2; public override void Hooks() { CharacterBody.onBodyInventoryChangedGlobal += OnInventoryChanged; } public override void Init(ConfigFile configuration) { CreateConfig(configuration); CreateLanguageTokens(); CreateItemDef(); Hooks(); } private void CreateConfig(ConfigFile configuration) { RadiusBase = configuration.Bind<float>("Item: " + ItemName, "Radius Base", 25f, "").Value; RadiusPerStack = configuration.Bind<float>("Item: " + ItemName, "Radius Per Stack", 10f, "").Value; IgniteBase = configuration.Bind<float>("Item: " + ItemName, "Ignite Base Damage", 200f, "").Value; IgnitePerStack = configuration.Bind<float>("Item: " + ItemName, "Ignite Per Stack Damage", 100f, "").Value; BurnBase = configuration.Bind<float>("Item: " + ItemName, "Burn Base Damage", 100f, "").Value; BurnPerStack = configuration.Bind<float>("Item: " + ItemName, "Burn Per Stack Damage", 50f, "").Value; BurnDuration = configuration.Bind<float>("Item: " + ItemName, "Burn Duration", 5f, "").Value; MissChance = configuration.Bind<float>("Item: " + ItemName, "Miss Chance", 15f, "").Value; LingerDuration = configuration.Bind<float>("Item: " + ItemName, "Miss Linger Duration", 1f, "").Value; } private void OnInventoryChanged(CharacterBody body) { if (GetCount(body) > 0 && !Object.op_Implicit((Object)(object)((Component)body).GetComponent<RadianceBehavior>())) { ((Component)body).gameObject.AddComponent<RadianceBehavior>(); } } } public class Sange : ItemBase<Sange> { public float MaximumHealthBase; public float MaximumHealthPerStack; public float BaseHealthRegenerationBase; public float BaseHealthRegenerationPerStack; public override string ItemName => "Sange"; public override string ConfigItemName => ItemName; public override string ItemTokenName => "SANGE"; public override string ItemTokenPickup => "Increases attack and movement speed. Combines with Kaya or Yasha."; public override string ItemTokenDesc => "Increases " + Healing("maximum health") + " by " + Healing($"{MaximumHealthBase}") + " " + Stack($"(+{MaximumHealthPerStack} per stack)") + " and " + Healing("base health regeneration") + " by " + Healing($"+{BaseHealthRegenerationBase} hp/s") + " " + Stack($"(+{BaseHealthRegenerationPerStack} hp/s per stack)") + "."; public override string ItemTokenLore => "Sange is an unusually accurate weapon, seeking weak points automatically."; public override ItemTier Tier => (ItemTier)1; public override string ItemModelPath => "RoR2/Base/Mystery/PickupMystery.prefab"; public override string ItemIconPath => "RiskOfTheAncients2.Icons.sange.png"; public override void Hooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(AddMaximumHealth); RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(AddBaseHealthRegeneration); } public override void Init(ConfigFile configuration) { CreateConfig(configuration); CreateLanguageTokens(); CreateItemDef(); Hooks(); } public void CreateConfig(ConfigFile configuration) { MaximumHealthBase = configuration.Bind<float>("Item: " + ItemName, "Initial Maximum Health Bonus", 40f, "How much maximum health should be provided by the first stack?").Value; MaximumHealthPerStack = configuration.Bind<float>("Item: " + ItemName, "Stacking Maximum Health Bonus", 40f, "How much maximum health should be provided by subsequent stacks?").Value; BaseHealthRegenerationBase = configuration.Bind<float>("Item: " + ItemName, "Initial Base Health Regeneration Bonus", 1.6f, "How much base health regeneration should be provided by the first stack?").Value; BaseHealthRegenerationPerStack = configuration.Bind<float>("Item: " + ItemName, "Stacking Base Health Regeneration Bonus", 1.6f, "How much base health regeneration should be provided by subsequent stacks?").Value; } private void AddMaximumHealth(CharacterBody body, StatHookEventArgs arguments) { int count = GetCount(body); if (count > 0) { arguments.baseHealthAdd += MaximumHealthBase + MaximumHealthPerStack * (float)(count - 1); } } private void AddBaseHealthRegeneration(CharacterBody body, StatHookEventArgs arguments) { int count = GetCount(body); if (count > 0) { arguments.baseRegenAdd += BaseHealthRegenerationBase + BaseHealthRegenerationPerStack * (float)(count - 1); } } } public class SangeAndYasha : ItemBase<SangeAndYasha> { public float MaximumHealthBase; public float MaximumHealthPerStack; public float BaseHealthRegenerationBase; public float BaseHealthRegenerationPerStack; public float AttackSpeedBase; public float AttackSpeedPerStack; public float MovementSpeedBase; public float MovementSpeedPerStack; public override string ItemName => "Sange and Yasha"; public override string ConfigItemName => ItemName; public override string ItemTokenName => "SANGE_AND_YASHA"; public override string ItemTokenPickup => "Increases maximum health, base health regeneration, attack speed, and movement speed. Combines with Kaya."; public override string ItemTokenDesc => "Increases " + Healing("maximum health") + " by " + Healing($"{MaximumHealthBase}") + " " + Stack($"(+{MaximumHealthPerStack} per stack)") + ", " + Healing("base health regeneration") + " by " + Healing($"+{BaseHealthRegenerationBase} hp/s") + " " + Stack($"(+{BaseHealthRegenerationPerStack} hp/s per stack)") + ", " + Damage("attack speed") + " by " + Damage($"{AttackSpeedBase}%") + " " + Stack($"(+{AttackSpeedPerStack}% per stack)") + ", and " + Utility("movement speed") + " by " + Utility($"{MovementSpeedBase}%") + " " + Stack($"(+{MovementSpeedPerStack}% per stack)") + "."; public override string ItemTokenLore => "Sange and Yasha, when attuned by the moonlight and used together, become a very powerful combination."; public override ItemTier Tier => (ItemTier)1; public override ItemTag[] ItemTags => (ItemTag[])(object)new ItemTag[1] { (ItemTag)9 }; public override string ItemModelPath => "RoR2/Base/Mystery/PickupMystery.prefab"; public override string ItemIconPath => "RiskOfTheAncients2.Icons.sange_and_yasha.png"; public override void Hooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(AddMaximumHealth); RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(AddBaseHealthRegeneration); RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(AddAttackSpeed); RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(AddMovementSpeed); } public override void Init(ConfigFile configuration) { CreateConfig(configuration); CreateLanguageTokens(); CreateItemDef(); Hooks(); } public void CreateConfig(ConfigFile configuration) { MaximumHealthBase = configuration.Bind<float>("Item: " + ItemName, "Initial Maximum Health Bonus", 60f, "How much maximum health should be provided by the first stack?").Value; MaximumHealthPerStack = configuration.Bind<float>("Item: " + ItemName, "Stacking Maximum Health Bonus", 60f, "How much maximum health should be provided by subsequent stacks?").Value; BaseHealthRegenerationBase = configuration.Bind<float>("Item: " + ItemName, "Initial Base Health Regeneration Bonus", 2.4f, "How much base health regeneration should be provided by the first stack?").Value; BaseHealthRegenerationPerStack = configuration.Bind<float>("Item: " + ItemName, "Stacking Base Health Regeneration Bonus", 2.4f, "How much base health regeneration should be provided by subsequent stacks?").Value; AttackSpeedBase = configuration.Bind<float>("Item: " + ItemName, "Initial Attack Speed Bonus", 18f, "How much attack speed should be provided by the first stack?").Value; AttackSpeedPerStack = configuration.Bind<float>("Item: " + ItemName, "Stacking Attack Speed Bonus", 18f, "How much attack speed should be provided by subsequent stacks?").Value; MovementSpeedBase = configuration.Bind<float>("Item: " + ItemName, "Initial Movement Speed Bonus", 18f, "How much movement speed should be provided by the first stack?").Value; MovementSpeedPerStack = configuration.Bind<float>("Item: " + ItemName, "Stacking Movement Speed Bonus", 18f, "How much movement speed should be provided by subsequent stacks?").Value; } private void AddMaximumHealth(CharacterBody body, StatHookEventArgs arguments) { int count = GetCount(body); if (count > 0) { arguments.baseHealthAdd += MaximumHealthBase + MaximumHealthPerStack * (float)(count - 1); } } private void AddBaseHealthRegeneration(CharacterBody body, StatHookEventArgs arguments) { int count = GetCount(body); if (count > 0) { arguments.baseRegenAdd += BaseHealthRegenerationBase + BaseHealthRegenerationPerStack * (float)(count - 1); } } private void AddAttackSpeed(CharacterBody body, StatHookEventArgs arguments) { int count = GetCount(body); if (count > 0) { arguments.attackSpeedMultAdd += AttackSpeedBase / 100f + AttackSpeedPerStack / 100f * (float)(count - 1); } } private void AddMovementSpeed(CharacterBody body, StatHookEventArgs arguments) { int count = GetCount(body); if (count > 0) { arguments.moveSpeedMultAdd += MovementSpeedBase / 100f + MovementSpeedPerStack / 100f * (float)(count - 1); } } } public class SkullBasher : ItemBase<SkullBasher> { private float ProcChance; private float DamageBase; private float DamagePerStack; private float BashDuration; private float BashCooldown; public override string ItemName => "Skull Basher"; public override string ConfigItemName => ItemName; public override string ItemTokenName => "SKULL_BASHER"; public override string ItemTokenPickup => "Chance on hit to strike for extra damage and stun. Recharges over time."; public override string ItemTokenDesc => Damage($"{ProcChance}%") + " chance on hit to " + Damage("bash") + " for " + Damage($"{DamageBase}%") + " " + Stack($"(+{DamagePerStack}% per stack)") + " TOTAL damage and " + Utility("stun") + " enemies for " + Utility($"{BashDuration} seconds") + ". Recharges every " + Utility($"{BashCooldown} seconds") + "."; public override string ItemTokenLore => "A rather typical spear that can sometimes pierce through an enemy's armor when used to attack."; public override ItemTier Tier => (ItemTier)1; public override string ItemIconPath => "RiskOfTheAncients2.Icons.skull_basher.png"; public override void Hooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown GlobalEventManager.OnHitEnemy += new hook_OnHitEnemy(OnHit); } public override void Init(ConfigFile configuration) { CreateConfig(configuration); CreateLanguageTokens(); CreateItemDef(); Hooks(); } public void CreateConfig(ConfigFile configuration) { ProcChance = configuration.Bind<float>("Item: " + ItemName, "Proc Chance", 15f, "What is the chance on hit to proc?").Value; DamageBase = configuration.Bind<float>("Item: " + ItemName, "Damage Base", 250f, "How much total damage should the bash do with the first stack?").Value; DamagePerStack = configuration.Bind<float>("Item: " + ItemName, "Damage Per Stack", 250f, "How much extra total damage should the bash do for subsequent stacks?").Value; BashDuration = configuration.Bind<float>("Item: " + ItemName, "Bash Duration", 2.5f, "How long should the bash last?").Value; BashCooldown = configuration.Bind<float>("Item: " + ItemName, "Bash Cooldown", 5f, "How long should it take to recharge before another bash?").Value; } private void OnHit(orig_OnHitEnemy orig, GlobalEventManager self, DamageInfo info, GameObject victim) { //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_009f: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown if (info.rejected || info.procCoefficient <= 0f) { orig.Invoke(self, info, victim); return; } GameObject attacker = info.attacker; if (Object.op_Implicit((Object)(object)attacker)) { CharacterBody component = attacker.GetComponent<CharacterBody>(); HealthComponent component2 = victim.GetComponent<HealthComponent>(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component2) && !BuffBase<SkullBasherCooldown>.Instance.HasThisBuff(component)) { int count = GetCount(component); if (count > 0 && Util.CheckRoll(ProcChance * info.procCoefficient, component.master)) { DamageInfo val = new DamageInfo { attacker = attacker, damage = info.damage * (DamageBase / 100f + DamagePerStack / 100f * (float)(count - 1)), position = info.position, damageColorIndex = (DamageColorIndex)12, damageType = info.damageType, procCoefficient = 0f, crit = info.crit, procChainMask = info.procChainMask }; component2.TakeDamage(val); SetStateOnHurt.SetStunOnObject(victim, BashDuration); BuffBase<SkullBasherCooldown>.Instance.ApplyTo(new BuffBase.ApplyParameters { victim = component, duration = BashCooldown }); } } } orig.Invoke(self, info, victim); } } public class SparkOfCourage : ItemBase<SparkOfCourage> { public float DamageBase; public float DamagePerStack; public float ArmorBase; public float ArmorPerStack; public float HealthThreshold; public override string ItemName => "Spark of Courage"; public override string ConfigItemName => ItemName; public override string ItemTokenName => "SPARK_OF_COURAGE"; public override string ItemTokenPickup => "Increases damage at high health, and armor at low health."; public override string ItemTokenDesc => "Increases " + Damage("damage") + " by " + Damage($"{DamageBase}%") + " " + Stack($"(+{DamagePerStack}% per stack)") + " when " + Health($"above {HealthThreshold}% health") + ", and increases " + Utility("armor") + " by " + Utility($"{ArmorBase}") + " " + Stack($"(+{ArmorPerStack} per stack") + " when " + Health("below") + "."; public override string ItemTokenLore => "Be strong, fortunes can change on a dime."; public override ItemTier Tier => (ItemTier)0; public override string ItemModelPath => "RoR2/Base/Mystery/PickupMystery.prefab"; public override string ItemIconPath => "RiskOfTheAncients2.Icons.spark_of_courage.png"; public override void Hooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(AddDamage); RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(AddArmor); } public override void Init(ConfigFile configuration) { CreateConfig(configuration); CreateLanguageTokens(); CreateItemDef(); Hooks(); } public void CreateConfig(ConfigFile configuration) { DamageBase = configuration.Bind<float>("Item: " + ItemName, "Initial Damage Bonus", 8f, "How much damage should be provided by the first stack?").Value; DamagePerStack = configuration.Bind<float>("Item: " + ItemName, "Stacking Damage Bonus", 8f, "How much damage should be provided by subsequent stacks?").Value; ArmorBase = configuration.Bind<float>("Item: " + ItemName, "Initial Armor Bonus", 8f, "How much armor should be provided by the first stack?").Value; ArmorPerStack = configuration.Bind<float>("Item: " + ItemName, "Stacking Armor Bonus", 8f, "How much armor should be provided by subsequent stacks?").Value; HealthThreshold = configuration.Bind<float>("Item: " + ItemName, "Health Threshold", 50f, "At what percent of maximum health should the bonus flip from damage to armor?").Value; } private void AddDamage(CharacterBody body, StatHookEventArgs arguments) { int count = GetCount(body); if (count > 0) { HealthComponent component = ((Component)body).GetComponent<HealthComponent>(); if (Object.op_Implicit((Object)(object)component) && component.combinedHealthFraction >= HealthThreshold / 100f) { arguments.damageMultAdd += DamageBase / 100f + DamagePerStack / 100f * (float)(count - 1); } } } private void AddArmor(CharacterBody body, StatHookEventArgs arguments) { int count = GetCount(body); if (count > 0) { HealthComponent component = ((Component)body).GetComponent<HealthComponent>(); if (Object.op_Implicit((Object)(object)component) && component.combinedHealthFraction < HealthThreshold / 100f) { arguments.armorAdd += ArmorBase + ArmorPerStack * (float)(count - 1); } } } } public class Trident : ItemBase<Trident> { public class TridentInventoryBehavior : MonoBehaviour { public CharacterBody body; public void Awake() { body = ((Component)this).GetComponent<CharacterBody>(); } public void Update() { //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_0358: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_0387: Unknown result type (might be due to invalid IL or missing references) //IL_0396: Unknown result type (might be due to invalid IL or missing references) //IL_0441: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Unknown result type (might be due to invalid IL or missing references) //IL_0470: Unknown result type (might be due to invalid IL or missing references) //IL_047f: Unknown result type (might be due to invalid IL or missing references) //IL_052e: Unknown result type (might be due to invalid IL or missing references) //IL_053d: Unknown result type (might be due to invalid IL or missing references) //IL_055d: Unknown result type (might be due to invalid IL or missing references) //IL_056c: Unknown result type (might be due to invalid IL or missing references) //IL_061b: Unknown result type (might be due to invalid IL or missing references) //IL_062a: Unknown result type (might be due to invalid IL or missing references) //IL_064a: Unknown result type (might be due to invalid IL or missing references) //IL_0659: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active && Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.inventory)) { int num = body.inventory.GetItemCount(ItemBase<Kaya>.Instance.ItemDef); int num2 = body.inventory.GetItemCount(ItemBase<Sange>.Instance.ItemDef); int num3 = body.inventory.GetItemCount(ItemBase<Yasha>.Instance.ItemDef); int num4 = body.inventory.GetItemCount(ItemBase<KayaAndSange>.Instance.ItemDef); int num5 = body.inventory.GetItemCount(ItemBase<SangeAndYasha>.Instance.ItemDef); int num6 = body.inventory.GetItemCount(ItemBase<YashaAndKaya>.Instance.ItemDef); if (num > 0 && num2 > 0) { int num7 = Math.Min(num, num2); Log.Info($"Converting {num7} kayas and sanges."); body.inventory.RemoveItem(ItemBase<Kaya>.Instance.ItemDef, num7); num -= num7; body.inventory.RemoveItem(ItemBase<Sange>.Instance.ItemDef, num7); num2 -= num7; body.inventory.GiveItem(ItemBase<KayaAndSange>.Instance.ItemDef, num7); num4 += num7; CharacterMasterNotificationQueue.PushItemTransformNotification(body.master, ItemBase<Kaya>.Instance.ItemDef.itemIndex, ItemBase<KayaAndSange>.Instance.ItemDef.itemIndex, (TransformationType)0); CharacterMasterNotificationQueue.PushItemTransformNotification(body.master, ItemBase<Sange>.Instance.ItemDef.itemIndex, ItemBase<KayaAndSange>.Instance.ItemDef.itemIndex, (TransformationType)0); } if (num2 > 0 && num3 > 0) { int num8 = Math.Min(num3, num2); Log.Info($"Converting {num8} sanges and yashas."); body.inventory.RemoveItem(ItemBase<Sange>.Instance.ItemDef, num8); num2 -= num8; body.inventory.RemoveItem(ItemBase<Yasha>.Instance.ItemDef, num8); num3 -= num8; body.inventory.GiveItem(ItemBase<SangeAndYasha>.Instance.ItemDef, num8); num5 += num8; CharacterMasterNotificationQueue.PushItemTransformNotification(body.master, ItemBase<Sange>.Instance.ItemDef.itemIndex, ItemBase<SangeAndYasha>.Instance.ItemDef.itemIndex, (TransformationType)0); CharacterMasterNotificationQueue.PushItemTransformNotification(body.master, ItemBase<Yasha>.Instance.ItemDef.itemIndex, ItemBase<SangeAndYasha>.Instance.ItemDef.itemIndex, (TransformationType)0); } if (num3 > 0 && num > 0) { int num9 = Math.Min(num3, num); Log.Info($"Converting {num9} yashas and kayas."); body.inventory.RemoveItem(ItemBase<Yasha>.Instance.ItemDef, num9); num3 -= num9; body.inventory.RemoveItem(ItemBase<Kaya>.Instance.ItemDef, num9); num -= num9; body.inventory.GiveItem(ItemBase<YashaAndKaya>.Instance.ItemDef, num9); num6 += num9; CharacterMasterNotificationQueue.PushItemTransformNotification(body.master, ItemBase<Yasha>.Instance.ItemDef.itemIndex, ItemBase<YashaAndKaya>.Instance.ItemDef.itemIndex, (TransformationType)0); CharacterMasterNotificationQueue.PushItemTransformNotification(body.master, ItemBase<Kaya>.Instance.ItemDef.itemIndex, ItemBase<YashaAndKaya>.Instance.ItemDef.itemIndex, (TransformationType)0); } if (num4 > 0 && num3 > 0) { int num10 = Math.Min(num4, num3); Log.Info($"Converting {num10} kaya and sanges and yashas."); body.inventory.RemoveItem(ItemBase<KayaAndSange>.Instance.ItemDef, num10); num4 -= num10; body.inventory.RemoveItem(ItemBase<Yasha>.Instance.ItemDef, num10); num3 -= num10; body.inventory.GiveItem(ItemBase<Trident>.Instance.ItemDef, num10); CharacterMasterNotificationQueue.PushItemTransformNotification(body.master, ItemBase<KayaAndSange>.Instance.ItemDef.itemIndex, ItemBase<Trident>.Instance.ItemDef.itemIndex, (TransformationType)0); CharacterMasterNotificationQueue.PushItemTransformNotification(body.master, ItemBase<Yasha>.Instance.ItemDef.itemIndex, ItemBase<Trident>.Instance.ItemDef.itemIndex, (TransformationType)0); } if (num5 > 0 && num > 0) { int num11 = Math.Min(num5, num); Log.Info($"Converting {num11} sange and yashas and kayas."); body.inventory.RemoveItem(ItemBase<SangeAndYasha>.Instance.ItemDef, num11); num5 -= num11; body.inventory.RemoveItem(ItemBase<Kaya>.Instance.ItemDef, num11); num -= num11; body.inventory.GiveItem(ItemBase<Trident>.Instance.ItemDef, num11); CharacterMasterNotificationQueue.PushItemTransformNotification(body.master, ItemBase<SangeAndYasha>.Instance.ItemDef.itemIndex, ItemBase<Trident>.Instance.ItemDef.itemIndex, (TransformationType)0); CharacterMasterNotificationQueue.PushItemTransformNotification(body.master, ItemBase<Kaya>.Instance.ItemDef.itemIndex, ItemBase<Trident>.Instance.ItemDef.itemIndex, (TransformationType)0); } if (num6 > 0 && num2 > 0) {