Decompiled source of RiskOfTheAncients2 v1.0.1

RiskOfTheAncients2.dll

Decompiled 21 hours ago
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)
					{