Decompiled source of HalcyonShrineBestGrill v0.1.0

HalcyonShrineBestGrill/HalcyonShrineBestGrill.dll

Decompiled 5 months ago
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
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 System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HG.Reflection;
using HalcyonShrineBestGrill.Items;
using Microsoft.CodeAnalysis;
using On.RoR2;
using R2API;
using RoR2;
using RoR2.Items;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: OptIn]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("HalcyonShrineBestGrill")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("HalcyonShrineBestGrill")]
[assembly: AssemblyTitle("HalcyonShrineBestGrill")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace HalcyonShrineBestGrill
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.whitet.halcyonshrinebestgrill", "Halcyon Shrine Best Grill", "0.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger;

		internal static ConfigFile Conf;

		internal static string AssemblyDir;

		public readonly List<ItemBase> Items = new List<ItemBase>();

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Conf = ((BaseUnityPlugin)this).Config;
			AssemblyDir = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			Type baseType = typeof(ItemBase);
			foreach (ItemBase item in (from t in Assembly.GetExecutingAssembly().GetTypes()
				where !t.IsAbstract && baseType.IsAssignableFrom(t)
				select (ItemBase)Activator.CreateInstance(t) into i
				orderby i.InitOrder
				select i).ToList())
			{
				if (!((BaseUnityPlugin)this).Config.Bind<bool>(item.ConfigSection, "Enable Item?", item.EnabledByDefault, "Set to false to exclude this item from runs.").Value)
				{
					Logger.LogInfo((object)("Skipping disabled item: " + item.ItemName));
					continue;
				}
				item.Init(((BaseUnityPlugin)this).Config);
				Items.Add(item);
				Logger.LogInfo((object)("Registered item: " + item.ItemName));
			}
			Logger.LogInfo((object)string.Format("{0} loaded {1} items.", "Halcyon Shrine Best Grill", Items.Count));
		}

		public static Sprite LoadSprite(string fileNameInIconsDir, float ppu = 100f)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = File.ReadAllBytes(Path.Combine(AssemblyDir, "Icons", fileNameInIconsDir));
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false)
			{
				wrapMode = (TextureWrapMode)1,
				filterMode = (FilterMode)1
			};
			ImageConversion.LoadImage(val, array);
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), ppu);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "com.whitet.halcyonshrinebestgrill";

		public const string PLUGIN_NAME = "Halcyon Shrine Best Grill";

		public const string PLUGIN_VERSION = "0.1.0";
	}
}
namespace HalcyonShrineBestGrill.Items
{
	public class CrowbarSteak : ItemBase
	{
		public float HpThresholdPct;

		public float BaseDamagePct;

		public float StackDamagePct;

		public float BaseHp;

		public float StackHp;

		public override string ItemName => "Crowbar Taped to a Steak";

		public override string ItemLangTokenName => "CROWBAR_STEAK";

		public override string ItemPickupDesc => "Deal bonus damage to healthy enemies. Gain max health.";

		public override string ItemFullDescription => $"Deal <style=cIsDamage>{BaseDamagePct}%</style> <style=cStack>(+{StackDamagePct}% per stack)</style> " + $"TOTAL bonus damage to enemies above <style=cIsDamage>{HpThresholdPct}%</style> health. " + $"Gain <style=cIsHealing>{BaseHp}</style> <style=cStack>(+{StackHp} per stack)</style> maximum health.";

		public override string ItemLore => "Engineering at its finest.";

		public override ItemTier Tier => (ItemTier)0;

		public override ItemTag[] ItemTags => (ItemTag[])(object)new ItemTag[2]
		{
			(ItemTag)1,
			(ItemTag)2
		};

		public override string IconFileName => "texCrowbarSteak.png";

		public override string PickupModelAddress => "RoR2/Base/Bear/PickupBear.prefab";

		protected override void CreateConfig(ConfigFile config)
		{
			string configSection = base.ConfigSection;
			HpThresholdPct = config.Bind<float>(configSection, "HP Threshold %", 90f, "Victim must be above this % of full combined HP for the damage bonus.").Value;
			BaseDamagePct = config.Bind<float>(configSection, "Base Damage %", 30f, "First-stack bonus damage vs healthy enemies (% of total damage).").Value;
			StackDamagePct = config.Bind<float>(configSection, "Stack Damage %", 15f, "Additional bonus damage per stack (%).").Value;
			BaseHp = config.Bind<float>(configSection, "Base Max HP", 15f, "First-stack max HP bonus.").Value;
			StackHp = config.Bind<float>(configSection, "Stack Max HP", 15f, "Additional max HP per stack.").Value;
		}

		protected 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
			GlobalEventManager.OnHitEnemy += new hook_OnHitEnemy(OnHit);
			RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(OnGetStats);
		}

		private void OnHit(orig_OnHitEnemy orig, GlobalEventManager self, DamageInfo di, GameObject victim)
		{
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: 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_00fa: 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_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Expected O, but got Unknown
			orig.Invoke(self, di, victim);
			if (!NetworkServer.active || di == null || (Object)(object)di.attacker == (Object)null || (Object)(object)victim == (Object)null || di.procCoefficient <= 0f)
			{
				return;
			}
			CharacterBody component = di.attacker.GetComponent<CharacterBody>();
			if ((Object)(object)((component != null) ? component.inventory : null) == (Object)null)
			{
				return;
			}
			int itemCount = component.inventory.GetItemCount(ItemDef);
			if (itemCount > 0)
			{
				HealthComponent component2 = victim.GetComponent<HealthComponent>();
				if (!((Object)(object)component2 == (Object)null) && !(component2.fullCombinedHealth <= 0f) && !((component2.combinedHealth + di.damage) / component2.fullCombinedHealth < HpThresholdPct / 100f))
				{
					float num = ItemBase.FirstThenPerStack(itemCount, BaseDamagePct, StackDamagePct) / 100f;
					DamageInfo val = new DamageInfo
					{
						damage = di.damage * num,
						attacker = di.attacker,
						inflictor = di.attacker,
						crit = false,
						damageColorIndex = (DamageColorIndex)3,
						damageType = DamageTypeCombo.op_Implicit((DamageType)0),
						procCoefficient = 0f,
						position = di.position,
						procChainMask = di.procChainMask
					};
					component2.TakeDamage(val);
				}
			}
		}

		private void OnGetStats(CharacterBody body, StatHookEventArgs args)
		{
			int count = GetCount(body);
			if (count > 0)
			{
				args.baseHealthAdd += ItemBase.FirstThenPerStack(count, BaseHp, StackHp);
			}
		}
	}
	public class Edgekeeper : ItemBase
	{
		public class EdgekeeperBehavior : BaseItemBodyBehavior
		{
			private float timer;

			[ItemDefAssociation(useOnServer = true, useOnClient = false)]
			private static ItemDef GetItemDef()
			{
				return Instance?.ItemDef;
			}

			private void FixedUpdate()
			{
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				if (NetworkServer.active && Instance != null && !((Object)(object)((BaseItemBodyBehavior)this).body == (Object)null))
				{
					timer += Time.fixedDeltaTime;
					if (!(timer < Instance.TickInterval))
					{
						timer = 0f;
						int num = CountWoundedNearby();
						((BaseItemBodyBehavior)this).body.SetBuffCount(Instance.FocusBuff.buffIndex, num);
					}
				}
			}

			private int CountWoundedNearby()
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0099: Unknown result type (might be due to invalid IL or missing references)
				//IL_009e: Unknown result type (might be due to invalid IL or missing references)
				//IL_009f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
				int num = 0;
				Vector3 corePosition = ((BaseItemBodyBehavior)this).body.corePosition;
				float num2 = Instance.Radius * Instance.Radius;
				ReadOnlyCollection<TeamComponent> teamMembers = TeamComponent.GetTeamMembers((TeamIndex)2);
				for (int i = 0; i < teamMembers.Count; i++)
				{
					TeamComponent val = teamMembers[i];
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					CharacterBody body = val.body;
					HealthComponent val2 = ((body != null) ? body.healthComponent : null);
					if ((Object)(object)val2 == (Object)null || !val2.alive)
					{
						continue;
					}
					float fullCombinedHealth = val2.fullCombinedHealth;
					if (fullCombinedHealth <= 0f || val2.combinedHealth / fullCombinedHealth >= 1f)
					{
						continue;
					}
					Vector3 val3 = ((Component)val).transform.position - corePosition;
					if (!(((Vector3)(ref val3)).sqrMagnitude > num2))
					{
						num++;
						if (num >= Instance.MaxStacks)
						{
							return num;
						}
					}
				}
				return num;
			}

			private void OnDisable()
			{
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				if (NetworkServer.active && Instance != null && (Object)(object)((BaseItemBodyBehavior)this).body != (Object)null && (Object)(object)Instance.FocusBuff != (Object)null)
				{
					((BaseItemBodyBehavior)this).body.SetBuffCount(Instance.FocusBuff.buffIndex, 0);
				}
			}
		}

		public static Edgekeeper Instance;

		public BuffDef FocusBuff;

		public float Radius;

		public float TickInterval;

		public int MaxStacks;

		public float BaseDamagePct;

		public float StackDamagePct;

		public override string ItemName => "The Edgekeeper";

		public override string ItemLangTokenName => "EDGEKEEPER";

		public override string ItemPickupDesc => "Gain bonus damage for each nearby wounded enemy.";

		public override string ItemFullDescription => $"Gain <style=cIsDamage>{BaseDamagePct}%</style> <style=cStack>(+{StackDamagePct}% per stack)</style> " + "bonus damage for each nearby enemy that is wounded but still alive. " + $"Scans within <style=cIsUtility>{Radius}m</style>, up to {MaxStacks} enemies.";

		public override string ItemLore => "Almost. Almost. Almost. ...Almost.";

		public override ItemTier Tier => (ItemTier)1;

		public override ItemTag[] ItemTags => (ItemTag[])(object)new ItemTag[1] { (ItemTag)1 };

		public override string IconFileName => "texLuckyPenny.png";

		public override string PickupModelAddress => "RoR2/Base/Bear/PickupBear.prefab";

		public override bool EnabledByDefault => false;

		public override void Init(ConfigFile config)
		{
			Instance = this;
			base.Init(config);
		}

		protected override void CreateConfig(ConfigFile config)
		{
			string configSection = base.ConfigSection;
			Radius = config.Bind<float>(configSection, "Radius", 25f, "Scan radius for wounded enemies (meters).").Value;
			TickInterval = config.Bind<float>(configSection, "Tick Interval", 0.25f, "Seconds between scans.").Value;
			MaxStacks = config.Bind<int>(configSection, "Max Stacks", 20, "Maximum wounded-enemy stacks.").Value;
			BaseDamagePct = config.Bind<float>(configSection, "Base Damage %", 2f, "First-stack damage bonus per wounded enemy (%).").Value;
			StackDamagePct = config.Bind<float>(configSection, "Stack Damage %", 1f, "Additional damage bonus per item stack per wounded enemy (%).").Value;
		}

		protected override void CreateBuffs()
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			FocusBuff = ScriptableObject.CreateInstance<BuffDef>();
			((Object)FocusBuff).name = "HSBG_EdgekeeperFocus";
			FocusBuff.canStack = true;
			FocusBuff.isDebuff = false;
			FocusBuff.isCooldown = false;
			FocusBuff.iconSprite = ItemDef.pickupIconSprite;
			FocusBuff.buffColor = new Color(0.2f, 0.95f, 0.55f);
			ContentAddition.AddBuffDef(FocusBuff);
		}

		protected 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(OnGetStats);
		}

		private void OnGetStats(CharacterBody body, StatHookEventArgs args)
		{
			if ((Object)(object)body == (Object)null || (Object)(object)FocusBuff == (Object)null)
			{
				return;
			}
			int count = GetCount(body);
			if (count > 0)
			{
				int buffCount = body.GetBuffCount(FocusBuff);
				if (buffCount > 0)
				{
					float num = ItemBase.FirstThenPerStack(count, BaseDamagePct, StackDamagePct);
					args.damageMultAdd += num / 100f * (float)buffCount;
				}
			}
		}
	}
	public class Hatemace : ItemBase
	{
		public BuffDef HateDebuff;

		public float BaseChance;

		public float StackChance;

		public float BaseDuration;

		public float StackDuration;

		public float DamageBonusPct;

		public override string ItemName => "Hatemace";

		public override string ItemLangTokenName => "HATEMACE";

		public override string ItemPickupDesc => "Chance on hit to make enemies take increased damage from all sources.";

		public override string ItemFullDescription => $"<style=cIsDamage>{BaseChance}%</style> chance <style=cStack>(+{StackChance}% per stack)</style> on hit to apply " + $"<style=cIsDamage>Hated</style> for <style=cIsUtility>{BaseDuration}s</style> " + $"<style=cStack>(+{StackDuration}s per stack)</style>. Hated enemies take " + $"<style=cIsDamage>{DamageBonusPct}%</style> more damage from all sources.";

		public override string ItemLore => "Forged in the Spaceking's fury. It doesn't solve problems. It IS the problem.";

		public override ItemTier Tier => (ItemTier)1;

		public override ItemTag[] ItemTags => (ItemTag[])(object)new ItemTag[1] { (ItemTag)1 };

		public override string IconFileName => "texHatemace.png";

		public override string PickupModelAddress => "RoR2/Base/Bear/PickupBear.prefab";

		protected override void CreateConfig(ConfigFile config)
		{
			string configSection = base.ConfigSection;
			BaseChance = config.Bind<float>(configSection, "Base Chance", 10f, "First-stack proc chance (%).").Value;
			StackChance = config.Bind<float>(configSection, "Stack Chance", 5f, "Additional proc chance per stack (%).").Value;
			BaseDuration = config.Bind<float>(configSection, "Base Duration", 4f, "First-stack debuff duration (seconds).").Value;
			StackDuration = config.Bind<float>(configSection, "Stack Duration", 1f, "Additional debuff duration per stack (seconds).").Value;
			DamageBonusPct = config.Bind<float>(configSection, "Damage Bonus %", 20f, "Bonus damage victims take while Hated (%).").Value;
		}

		protected override void CreateBuffs()
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			HateDebuff = ScriptableObject.CreateInstance<BuffDef>();
			((Object)HateDebuff).name = "HSBG_Hated";
			HateDebuff.canStack = false;
			HateDebuff.isDebuff = true;
			HateDebuff.isCooldown = false;
			HateDebuff.iconSprite = ItemDef.pickupIconSprite;
			HateDebuff.buffColor = new Color(0.7f, 0.1f, 0.1f);
			ContentAddition.AddBuffDef(HateDebuff);
		}

		protected 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
			GlobalEventManager.OnHitEnemy += new hook_OnHitEnemy(OnHit);
			HealthComponent.TakeDamage += new hook_TakeDamage(OnTakeDamage);
		}

		private void OnHit(orig_OnHitEnemy orig, GlobalEventManager self, DamageInfo di, GameObject victim)
		{
			orig.Invoke(self, di, victim);
			if (!NetworkServer.active || di == null || (Object)(object)di.attacker == (Object)null || (Object)(object)victim == (Object)null || di.procCoefficient <= 0f)
			{
				return;
			}
			CharacterBody component = di.attacker.GetComponent<CharacterBody>();
			if ((Object)(object)((component != null) ? component.inventory : null) == (Object)null)
			{
				return;
			}
			int itemCount = component.inventory.GetItemCount(ItemDef);
			if (itemCount > 0 && Util.CheckRoll(ItemBase.FirstThenPerStack(itemCount, BaseChance, StackChance) * di.procCoefficient, component.master))
			{
				CharacterBody component2 = victim.GetComponent<CharacterBody>();
				if (!((Object)(object)component2 == (Object)null))
				{
					float num = ItemBase.FirstThenPerStack(itemCount, BaseDuration, StackDuration);
					component2.AddTimedBuff(HateDebuff, num);
				}
			}
		}

		private void OnTakeDamage(orig_TakeDamage orig, HealthComponent self, DamageInfo di)
		{
			if (NetworkServer.active && (Object)(object)self != (Object)null && di != null && (Object)(object)self.body != (Object)null && (Object)(object)HateDebuff != (Object)null && self.body.HasBuff(HateDebuff))
			{
				di.damage *= 1f + DamageBonusPct / 100f;
			}
			orig.Invoke(self, di);
		}
	}
	public abstract class ItemBase
	{
		public ItemDef ItemDef;

		public abstract string ItemName { get; }

		public abstract string ItemLangTokenName { get; }

		public abstract string ItemPickupDesc { get; }

		public abstract string ItemFullDescription { get; }

		public abstract string ItemLore { get; }

		public abstract ItemTier Tier { get; }

		public virtual ItemTag[] ItemTags => Array.Empty<ItemTag>();

		public abstract string IconFileName { get; }

		public abstract string PickupModelAddress { get; }

		public virtual int InitOrder => 0;

		public virtual bool EnabledByDefault => true;

		public string ConfigSection => "Item: " + Regex.Replace(ItemName, "[=\\n\\t\\\\\"'\\[\\]]", "");

		public virtual void Init(ConfigFile config)
		{
			CreateConfig(config);
			CreateLang();
			CreateItem();
			CreateBuffs();
			Hooks();
		}

		protected virtual void CreateConfig(ConfigFile config)
		{
		}

		protected virtual void CreateBuffs()
		{
		}

		protected void CreateLang()
		{
			LanguageAPI.Add("ITEM_" + ItemLangTokenName + "_NAME", ItemName);
			LanguageAPI.Add("ITEM_" + ItemLangTokenName + "_PICKUP", ItemPickupDesc);
			LanguageAPI.Add("ITEM_" + ItemLangTokenName + "_DESCRIPTION", ItemFullDescription);
			LanguageAPI.Add("ITEM_" + ItemLangTokenName + "_LORE", ItemLore);
		}

		protected void CreateItem()
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Expected O, but got Unknown
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Expected O, but got Unknown
			ItemDef = ScriptableObject.CreateInstance<ItemDef>();
			((Object)ItemDef).name = "ITEM_" + ItemLangTokenName;
			ItemDef.nameToken = "ITEM_" + ItemLangTokenName + "_NAME";
			ItemDef.pickupToken = "ITEM_" + ItemLangTokenName + "_PICKUP";
			ItemDef.descriptionToken = "ITEM_" + ItemLangTokenName + "_DESCRIPTION";
			ItemDef.loreToken = "ITEM_" + ItemLangTokenName + "_LORE";
			ItemDef.tags = ItemTags;
			ItemDef.deprecatedTier = Tier;
			ItemDef.canRemove = true;
			ItemDef.hidden = false;
			ItemDef.pickupIconSprite = Plugin.LoadSprite(IconFileName);
			ItemDef.pickupModelPrefab = Addressables.LoadAssetAsync<GameObject>((object)PickupModelAddress).WaitForCompletion();
			ItemAPI.Add(new CustomItem(ItemDef, new ItemDisplayRuleDict((ItemDisplayRule[])null)));
		}

		protected abstract void Hooks();

		public int GetCount(CharacterBody body)
		{
			if (!Object.op_Implicit((Object)(object)((body != null) ? body.inventory : null)))
			{
				return 0;
			}
			return body.inventory.GetItemCount(ItemDef);
		}

		public static float FirstThenPerStack(int count, float firstStack, float perAdditional)
		{
			if (count > 0)
			{
				return firstStack + perAdditional * (float)(count - 1);
			}
			return 0f;
		}
	}
	public class PippinsChonkArmor : ItemBase
	{
		public float BaseHp;

		public float StackHp;

		public float BaseSlowPct;

		public float StackSlowPct;

		public float MaxSlowPct;

		public override string ItemName => "Pippin's Chonk Armor";

		public override string ItemLangTokenName => "PIPPINS_CHONK_ARMOR";

		public override string ItemPickupDesc => "Greatly increase maximum health. Reduce movement speed.";

		public override string ItemFullDescription => $"Gain <style=cIsHealing>{BaseHp}</style> <style=cStack>(+{StackHp} per stack)</style> maximum health. " + $"<style=cIsHealth>Reduce movement speed</style> by <style=cIsHealth>{BaseSlowPct}%</style> " + $"<style=cStack>(+{StackSlowPct}% per stack, capped at {MaxSlowPct}%)</style>.";

		public override string ItemLore => "Small. Fat. Immovable.";

		public override ItemTier Tier => (ItemTier)0;

		public override ItemTag[] ItemTags => (ItemTag[])(object)new ItemTag[2]
		{
			(ItemTag)2,
			(ItemTag)3
		};

		public override string IconFileName => "texLuckyPenny.png";

		public override string PickupModelAddress => "RoR2/Base/Bear/PickupBear.prefab";

		public override bool EnabledByDefault => false;

		protected override void CreateConfig(ConfigFile config)
		{
			string configSection = base.ConfigSection;
			BaseHp = config.Bind<float>(configSection, "Base Max HP", 37f, "First-stack max HP bonus.").Value;
			StackHp = config.Bind<float>(configSection, "Stack Max HP", 37f, "Additional max HP per stack.").Value;
			BaseSlowPct = config.Bind<float>(configSection, "Base Slow %", 5f, "First-stack move speed reduction (%).").Value;
			StackSlowPct = config.Bind<float>(configSection, "Stack Slow %", 5f, "Additional move speed reduction per stack (%).").Value;
			MaxSlowPct = config.Bind<float>(configSection, "Max Slow %", 50f, "Ceiling on total move speed reduction (%).").Value;
		}

		protected 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(OnGetStats);
		}

		private void OnGetStats(CharacterBody body, StatHookEventArgs args)
		{
			int count = GetCount(body);
			if (count > 0)
			{
				args.baseHealthAdd += ItemBase.FirstThenPerStack(count, BaseHp, StackHp);
				float num = Mathf.Min(ItemBase.FirstThenPerStack(count, BaseSlowPct, StackSlowPct), MaxSlowPct);
				args.moveSpeedMultAdd -= num / 100f;
			}
		}
	}
	public class SiliconeMassager : ItemBase
	{
		public BuffDef RegenBuff;

		public float BaseRegen;

		public float StackRegen;

		public float Duration;

		public override string ItemName => "Silicone Face Lifting Massager";

		public override string ItemLangTokenName => "SILICONE_MASSAGER";

		public override string ItemPickupDesc => "On taking damage, briefly gain regeneration.";

		public override string ItemFullDescription => $"Upon taking damage, gain <style=cIsHealing>{BaseRegen} HP/s</style> " + $"<style=cStack>(+{StackRegen} HP/s per stack)</style> regeneration for " + $"<style=cIsUtility>{Duration}s</style>.";

		public override string ItemLore => "Imported. Discreet packaging. 'Therapeutic use only.'";

		public override ItemTier Tier => (ItemTier)1;

		public override ItemTag[] ItemTags => (ItemTag[])(object)new ItemTag[1] { (ItemTag)2 };

		public override string IconFileName => "texSiliconeMassager.png";

		public override string PickupModelAddress => "RoR2/Base/Bear/PickupBear.prefab";

		protected override void CreateConfig(ConfigFile config)
		{
			string configSection = base.ConfigSection;
			BaseRegen = config.Bind<float>(configSection, "Base Regen", 8f, "First-stack regen while buff is active (HP/s).").Value;
			StackRegen = config.Bind<float>(configSection, "Stack Regen", 2f, "Additional regen per stack (HP/s).").Value;
			Duration = config.Bind<float>(configSection, "Duration", 4f, "Buff duration after a damage hit (seconds).").Value;
		}

		protected override void CreateBuffs()
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			RegenBuff = ScriptableObject.CreateInstance<BuffDef>();
			((Object)RegenBuff).name = "HSBG_SiliconeRegen";
			RegenBuff.canStack = true;
			RegenBuff.isDebuff = false;
			RegenBuff.isCooldown = false;
			RegenBuff.iconSprite = ItemDef.pickupIconSprite;
			RegenBuff.buffColor = new Color(1f, 0.6f, 0.85f);
			ContentAddition.AddBuffDef(RegenBuff);
		}

		protected 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
			HealthComponent.TakeDamage += new hook_TakeDamage(OnTakeDamage);
			RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(OnGetStats);
		}

		private void OnTakeDamage(orig_TakeDamage orig, HealthComponent self, DamageInfo di)
		{
			orig.Invoke(self, di);
			if (NetworkServer.active && !((Object)(object)self == (Object)null) && di != null && !(di.damage <= 0f))
			{
				CharacterBody body = self.body;
				if (!((Object)(object)body == (Object)null) && !((Object)(object)body.inventory == (Object)null) && body.inventory.GetItemCount(ItemDef) > 0)
				{
					body.AddTimedBuff(RegenBuff, Duration);
				}
			}
		}

		private void OnGetStats(CharacterBody body, StatHookEventArgs args)
		{
			if (!((Object)(object)body == (Object)null) && !((Object)(object)RegenBuff == (Object)null) && body.GetBuffCount(RegenBuff) > 0)
			{
				int count = GetCount(body);
				if (count > 0)
				{
					args.baseRegenAdd += ItemBase.FirstThenPerStack(count, BaseRegen, StackRegen);
				}
			}
		}
	}
	public class TwoMeatPatties : ItemBase
	{
		public class TwoMeatPattiesBehavior : BaseItemBodyBehavior
		{
			private float timer;

			[ItemDefAssociation(useOnServer = true, useOnClient = false)]
			private static ItemDef GetItemDef()
			{
				return Instance?.ItemDef;
			}

			private void FixedUpdate()
			{
				//IL_009f: Unknown result type (might be due to invalid IL or missing references)
				if (!NetworkServer.active || Instance == null || (Object)(object)((BaseItemBodyBehavior)this).body == (Object)null || (Object)(object)Instance.SafeBuff == (Object)null)
				{
					return;
				}
				timer += Time.fixedDeltaTime;
				if (!(timer < Instance.TickInterval))
				{
					timer = 0f;
					bool flag = !AnyEnemyWithin(Instance.SafeRadius);
					bool flag2 = ((BaseItemBodyBehavior)this).body.HasBuff(Instance.SafeBuff);
					if (flag != flag2)
					{
						((BaseItemBodyBehavior)this).body.SetBuffCount(Instance.SafeBuff.buffIndex, flag ? 1 : 0);
						((BaseItemBodyBehavior)this).body.MarkAllStatsDirty();
					}
				}
			}

			private bool AnyEnemyWithin(float radius)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: Unknown result type (might be due to invalid IL or missing references)
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				Vector3 corePosition = ((BaseItemBodyBehavior)this).body.corePosition;
				float num = radius * radius;
				ReadOnlyCollection<TeamComponent> teamMembers = TeamComponent.GetTeamMembers((TeamIndex)2);
				for (int i = 0; i < teamMembers.Count; i++)
				{
					TeamComponent val = teamMembers[i];
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					CharacterBody body = val.body;
					HealthComponent val2 = ((body != null) ? body.healthComponent : null);
					if (!((Object)(object)val2 == (Object)null) && val2.alive)
					{
						Vector3 val3 = ((Component)val).transform.position - corePosition;
						if (((Vector3)(ref val3)).sqrMagnitude <= num)
						{
							return true;
						}
					}
				}
				return false;
			}

			private void OnDisable()
			{
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				if (NetworkServer.active && Instance != null && (Object)(object)((BaseItemBodyBehavior)this).body != (Object)null && (Object)(object)Instance.SafeBuff != (Object)null && ((BaseItemBodyBehavior)this).body.HasBuff(Instance.SafeBuff))
				{
					((BaseItemBodyBehavior)this).body.SetBuffCount(Instance.SafeBuff.buffIndex, 0);
					((BaseItemBodyBehavior)this).body.MarkAllStatsDirty();
				}
			}
		}

		public static TwoMeatPatties Instance;

		public BuffDef SafeBuff;

		public float BaseHp;

		public float StackHp;

		public float BaseRegen;

		public float StackRegen;

		public float BaseSafeRegen;

		public float StackSafeRegen;

		public float SafeRadius;

		public float TickInterval;

		public override string ItemName => "Two Meat Patties";

		public override string ItemLangTokenName => "TWO_MEAT_PATTIES";

		public override string ItemPickupDesc => "Increase max health. Regenerate much faster when no enemies are near.";

		public override string ItemFullDescription => $"Gain <style=cIsHealing>{BaseHp}</style> <style=cStack>(+{StackHp} per stack)</style> maximum health " + $"and <style=cIsHealing>{BaseRegen} HP/s</style> <style=cStack>(+{StackRegen} HP/s per stack)</style> base regeneration. " + $"While no enemies are within <style=cIsUtility>{SafeRadius}m</style>, gain " + $"<style=cIsHealing>{BaseSafeRegen} HP/s</style> <style=cStack>(+{StackSafeRegen} HP/s per stack)</style> bonus regeneration.";

		public override string ItemLore => "No bun. No lettuce. Just meat.";

		public override ItemTier Tier => (ItemTier)0;

		public override ItemTag[] ItemTags => (ItemTag[])(object)new ItemTag[2]
		{
			(ItemTag)2,
			(ItemTag)3
		};

		public override string IconFileName => "texTwoMeatPatties.png";

		public override string PickupModelAddress => "RoR2/Base/Bear/PickupBear.prefab";

		public override void Init(ConfigFile config)
		{
			Instance = this;
			base.Init(config);
		}

		protected override void CreateConfig(ConfigFile config)
		{
			string configSection = base.ConfigSection;
			BaseHp = config.Bind<float>(configSection, "Base Max HP", 25f, "First-stack max HP bonus.").Value;
			StackHp = config.Bind<float>(configSection, "Stack Max HP", 25f, "Additional max HP per stack.").Value;
			BaseRegen = config.Bind<float>(configSection, "Base Regen", 1f, "First-stack base regen bonus (HP/s).").Value;
			StackRegen = config.Bind<float>(configSection, "Stack Regen", 1f, "Additional regen per stack (HP/s).").Value;
			BaseSafeRegen = config.Bind<float>(configSection, "Base Safe Regen", 10f, "First-stack bonus regen while no enemies nearby (HP/s).").Value;
			StackSafeRegen = config.Bind<float>(configSection, "Stack Safe Regen", 10f, "Additional bonus regen per stack while safe (HP/s).").Value;
			SafeRadius = config.Bind<float>(configSection, "Safe Radius", 30f, "Enemy-free radius required for bonus regen (meters).").Value;
			TickInterval = config.Bind<float>(configSection, "Tick Interval", 0.25f, "Seconds between proximity scans.").Value;
		}

		protected override void CreateBuffs()
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			SafeBuff = ScriptableObject.CreateInstance<BuffDef>();
			((Object)SafeBuff).name = "HSBG_TwoMeatPattiesSafe";
			SafeBuff.canStack = false;
			SafeBuff.isDebuff = false;
			SafeBuff.isCooldown = false;
			SafeBuff.iconSprite = ItemDef.pickupIconSprite;
			SafeBuff.buffColor = new Color(0.95f, 0.55f, 0.35f);
			ContentAddition.AddBuffDef(SafeBuff);
		}

		protected 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(OnGetStats);
		}

		private void OnGetStats(CharacterBody body, StatHookEventArgs args)
		{
			int count = GetCount(body);
			if (count > 0)
			{
				args.baseHealthAdd += ItemBase.FirstThenPerStack(count, BaseHp, StackHp);
				args.baseRegenAdd += ItemBase.FirstThenPerStack(count, BaseRegen, StackRegen);
				if ((Object)(object)SafeBuff != (Object)null && body.HasBuff(SafeBuff))
				{
					args.baseRegenAdd += ItemBase.FirstThenPerStack(count, BaseSafeRegen, StackSafeRegen);
				}
			}
		}
	}
	public class Tylanol : ItemBase
	{
		public float BaseProcPct;

		public float StackProcPct;

		public float BaseSlowPct;

		public float StackSlowPct;

		public float MaxSlowPct;

		public override string ItemName => "Tylanol";

		public override string ItemLangTokenName => "TYLANOL";

		public override string ItemPickupDesc => "Increase all item proc coefficients. Reduce movement speed.";

		public override string ItemFullDescription => $"Increase all outgoing proc coefficients by <style=cIsDamage>{BaseProcPct}%</style> " + $"<style=cStack>(+{StackProcPct}% per stack)</style>. " + $"<style=cIsHealth>Reduce movement speed</style> by <style=cIsHealth>{BaseSlowPct}%</style> " + $"<style=cStack>(+{StackSlowPct}% per stack, capped at {MaxSlowPct}%)</style>.";

		public override string ItemLore => "Side effects may include heightened pattern recognition and an inability to make eye contact.";

		public override ItemTier Tier => (ItemTier)1;

		public override ItemTag[] ItemTags => (ItemTag[])(object)new ItemTag[2]
		{
			(ItemTag)1,
			(ItemTag)3
		};

		public override string IconFileName => "texLuckyPenny.png";

		public override string PickupModelAddress => "RoR2/Base/Bear/PickupBear.prefab";

		public override bool EnabledByDefault => false;

		public override int InitOrder => 100;

		protected override void CreateConfig(ConfigFile config)
		{
			string configSection = base.ConfigSection;
			BaseProcPct = config.Bind<float>(configSection, "Base Proc %", 15f, "First-stack proc coefficient increase (%).").Value;
			StackProcPct = config.Bind<float>(configSection, "Stack Proc %", 15f, "Additional proc coefficient increase per stack (%).").Value;
			BaseSlowPct = config.Bind<float>(configSection, "Base Slow %", 3f, "First-stack move speed reduction (%).").Value;
			StackSlowPct = config.Bind<float>(configSection, "Stack Slow %", 3f, "Additional move speed reduction per stack (%).").Value;
			MaxSlowPct = config.Bind<float>(configSection, "Max Slow %", 100f, "Ceiling on total move speed reduction (%).").Value;
		}

		protected 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
			GlobalEventManager.OnHitEnemy += new hook_OnHitEnemy(OnHit);
			RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(OnGetStats);
		}

		private void OnHit(orig_OnHitEnemy orig, GlobalEventManager self, DamageInfo di, GameObject victim)
		{
			if (di == null || (Object)(object)di.attacker == (Object)null || di.procCoefficient <= 0f)
			{
				orig.Invoke(self, di, victim);
				return;
			}
			CharacterBody component = di.attacker.GetComponent<CharacterBody>();
			if ((Object)(object)((component != null) ? component.inventory : null) == (Object)null)
			{
				orig.Invoke(self, di, victim);
				return;
			}
			int itemCount = component.inventory.GetItemCount(ItemDef);
			if (itemCount <= 0)
			{
				orig.Invoke(self, di, victim);
				return;
			}
			float procCoefficient = di.procCoefficient;
			float num = 1f + ItemBase.FirstThenPerStack(itemCount, BaseProcPct, StackProcPct) / 100f;
			di.procCoefficient = procCoefficient * num;
			try
			{
				orig.Invoke(self, di, victim);
			}
			finally
			{
				di.procCoefficient = procCoefficient;
			}
		}

		private void OnGetStats(CharacterBody body, StatHookEventArgs args)
		{
			int count = GetCount(body);
			if (count > 0)
			{
				float num = Mathf.Min(ItemBase.FirstThenPerStack(count, BaseSlowPct, StackSlowPct), MaxSlowPct);
				args.moveSpeedMultAdd -= num / 100f;
			}
		}
	}
}