Decompiled source of T4ylorItems v1.0.0

plugins/T4ylorItems.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using EntityStates;
using EntityStates.GoldGat;
using EntityStates.HallowedCauldron;
using EntityStates.ScavMonster;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using On.EntityStates.HallowedCauldron;
using On.RoR2;
using R2API;
using RoR2;
using RoR2.Items;
using RoR2.Orbs;
using RoR2.Projectile;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;

[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("T4ylor")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright T4ylor")]
[assembly: AssemblyDescription("Configurable item balance changes with optional LookingGlass item stats for Risk of Rain 2.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("T4ylorItems")]
[assembly: AssemblyTitle("T4ylorItems")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[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 T4ylorItems
{
	[BepInPlugin("com.t4ylor.ror2.items", "T4ylorItems", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		private readonly ConditionalWeakTable<BlastAttack, object> behemothBlasts = new ConditionalWeakTable<BlastAttack, object>();

		private BuffDef raincoatSpeed;

		private bool raincoatRegistered;

		private NetworkSoundEventDef shieldRechargeSound;

		private NetworkSoundEventDef shieldBoosterSound;

		private bool shieldSoundsRegistered;

		private GoldGatApproval? goldApproval;

		private LookingGlassRegistry? lookingGlass;

		public const string Guid = "com.t4ylor.ror2.items";

		public const string Version = "1.0.0";

		public const string Author = "T4ylor";

		private Settings settings;

		private readonly List<IDisposable> hooks = new List<IDisposable>();

		private readonly bool[] ready = new bool[21];

		private string? networkKey;

		private GameObject? tornado;

		private GameObject? ghostPrefab;

		private Transform? hitbox;

		private Vector3 oldHitboxScale;

		private Vector3 oldGhostScale;

		private bool initialized;

		private bool languageHook;

		private void InstallBatch2()
		{
			Install(5, settings.Lenses, delegate
			{
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Expected O, but got Unknown
				//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00df: Expected O, but got Unknown
				//IL_009d: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a5: Expected O, but got Unknown
				//IL_00aa: Expected O, but got Unknown
				LensesFeature lenses = new LensesFeature(() => ready[5], settings.LensesDamage);
				hooks.Add(lenses);
				AddIL(5, typeof(HealthComponent), "TakeDamageProcess", (Manipulator)delegate(ILContext il)
				{
					Batch2Emitters.LensesGate<HealthComponent>(il, lenses.BossGate);
				});
				string[] phaseTypes = EncounterBosses.PhaseTypes;
				Manipulator val = default(Manipulator);
				foreach (string name in phaseTypes)
				{
					Type type = typeof(Run).Assembly.GetType(name, throwOnError: true);
					Manipulator obj = val;
					if (obj == null)
					{
						Manipulator val2 = delegate(ILContext il)
						{
							Batch2Patterns.ValidatePhase(il.Method, "phaseScriptedCombatEncounter");
							Batch2Emitters.AtReturn<EntityState>(il, lenses.Bosses.RegisterPhase);
						};
						Manipulator val3 = val2;
						val = val2;
						obj = val3;
					}
					AddIL(5, type, "OnEnter", obj);
				}
				AddIL(5, typeof(SolusWebMissionController), "Awake", (Manipulator)delegate(ILContext il)
				{
					Batch2Patterns.ValidatePhase(il.Method, "combatSquad");
					Batch2Emitters.AtReturn<SolusWebMissionController>(il, lenses.Bosses.RegisterSolus);
				});
				lenses.Enable();
			});
			Install(6, settings.Behemoth, delegate
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Expected O, but got Unknown
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Expected O, but got Unknown
				AddIL(6, typeof(GlobalEventManager), "OnHitAllProcess", (Manipulator)delegate(ILContext il)
				{
					Batch2Emitters.BehemothMark(il, delegate(BlastAttack blast)
					{
						if (ready[6])
						{
							behemothBlasts.GetValue(blast, (BlastAttack _) => new object());
						}
						return blast;
					});
				});
				AddIL(6, typeof(BlastAttack), "HandleHits", (Manipulator)delegate(ILContext il)
				{
					Batch2Emitters.BehemothDamage(il, (float native, BlastAttack blast, float distance) => (!ready[6] || !behemothBlasts.TryGetValue(blast, out object _)) ? native : (native * Batch2Rules.BehemothCoefficient(distance, blast.radius, settings.BehemothEdge) / 0.6f));
				});
			});
			Install(7, settings.Seed, delegate
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Expected O, but got Unknown
				AddIL(7, typeof(GlobalEventManager), "ProcessHitEnemy", (Manipulator)delegate(ILContext il)
				{
					Batch2Emitters.Seed(il, () => ready[7], settings.SeedHeal);
				});
			});
			Install(8, settings.Singularity, delegate
			{
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_0048: Invalid comparison between Unknown and I4
				//IL_007a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0085: Expected O, but got Unknown
				GameObject obj = LegacyResourcesAPI.Load<GameObject>("Prefabs/Projectiles/ElementalRingVoidBlackHole");
				ProjectileExplosion component = obj.GetComponent<ProjectileExplosion>();
				ProjectileFuse component2 = obj.GetComponent<ProjectileFuse>();
				if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component2) || component.blastDamageCoefficient != 1f || component.blastRadius != 15f || (int)component.falloffModel != 1 || component2.fuse != 5f)
				{
					throw new InvalidOperationException("Singularity native detonation/pull timing changed; refusing to multiply a modified prefab.");
				}
				AddIL(8, typeof(GlobalEventManager), "ProcessHitEnemy", (Manipulator)delegate(ILContext il)
				{
					Batch2Emitters.Singularity(il, () => ready[8], settings.SingularityDamage, settings.SingularityCooldown);
				});
			});
		}

		private void RegisterDefensiveContent()
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				raincoatSpeed = ScriptableObject.CreateInstance<BuffDef>();
				((Object)raincoatSpeed).name = "T4ylorItems_RaincoatSpeed";
				raincoatSpeed.canStack = false;
				raincoatSpeed.isDebuff = false;
				raincoatSpeed.isHidden = false;
				raincoatSpeed.buffColor = Color32.op_Implicit(new Color32((byte)197, (byte)134, byte.MaxValue, byte.MaxValue));
				raincoatRegistered = ContentAddition.AddBuffDef(raincoatSpeed);
				if (!raincoatRegistered)
				{
					throw new InvalidOperationException("ContentAddition rejected the Raincoat speed buff");
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("R01 Raincoat disabled; speed buff registration failed: " + ex));
				raincoatRegistered = false;
			}
			try
			{
				shieldRechargeSound = ScriptableObject.CreateInstance<NetworkSoundEventDef>();
				((Object)shieldRechargeSound).name = "T4ylorItems_ShieldRecharge";
				shieldRechargeSound.eventName = "Play_item_proc_personal_shield_recharge";
				shieldBoosterSound = ScriptableObject.CreateInstance<NetworkSoundEventDef>();
				((Object)shieldBoosterSound).name = "T4ylorItems_ShieldBoosterRecharge";
				shieldBoosterSound.eventName = "Play_item_use_shieldBooster_regen";
				bool flag = ContentAddition.AddNetworkSoundEventDef(shieldRechargeSound);
				bool flag2 = ContentAddition.AddNetworkSoundEventDef(shieldBoosterSound);
				shieldSoundsRegistered = flag && flag2;
				if (!shieldSoundsRegistered)
				{
					throw new InvalidOperationException("ContentAddition rejected shield audio definitions");
				}
			}
			catch (Exception ex2)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("L02 Transcendence disabled; shield sound registration failed: " + ex2));
				shieldSoundsRegistered = false;
			}
		}

		private void InstallBatch3()
		{
			if (raincoatRegistered)
			{
				raincoatSpeed.iconSprite = Buffs.ImmuneToDebuffReady.iconSprite;
			}
			DefensiveFeature defense = new DefensiveFeature(settings, ready, raincoatSpeed, shieldRechargeSound, shieldBoosterSound);
			Manipulator val = default(Manipulator);
			Manipulator val4 = default(Manipulator);
			Install(9, settings.Spaces, delegate
			{
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				//IL_0035: Expected O, but got Unknown
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Expected O, but got Unknown
				//IL_0071: Expected O, but got Unknown
				Plugin plugin = this;
				Type? typeFromHandle = typeof(HealthComponent);
				Manipulator obj = val;
				if (obj == null)
				{
					Manipulator val2 = delegate(ILContext il)
					{
						DefenseEmitters.ResourceWrites<HealthComponent>(il, defense.Resource);
					};
					Manipulator val3 = val2;
					val = val2;
					obj = val3;
				}
				plugin.AddIL(9, typeFromHandle, "TakeDamageProcess", obj);
				Plugin plugin2 = this;
				Type? typeFromHandle2 = typeof(CharacterBody);
				Manipulator obj2 = val4;
				if (obj2 == null)
				{
					Manipulator val5 = delegate(ILContext il)
					{
						DefenseEmitters.BuffDelta<CharacterBody, TimedBuff>(il, defense.BuffDelta);
					};
					Manipulator val3 = val5;
					val4 = val5;
					obj2 = val3;
				}
				plugin2.AddIL(9, typeFromHandle2, "UpdateBuffs", obj2);
			});
			Manipulator val6 = default(Manipulator);
			Manipulator val8 = default(Manipulator);
			Install(10, settings.Transcendence && shieldSoundsRegistered, delegate
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Invalid comparison between Unknown and I4
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Invalid comparison between Unknown and I4
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Expected O, but got Unknown
				//IL_0071: Expected O, but got Unknown
				//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a8: Expected O, but got Unknown
				//IL_00ad: Expected O, but got Unknown
				//IL_00dd: 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: Expected O, but got Unknown
				//IL_00e9: Expected O, but got Unknown
				//IL_0119: Unknown result type (might be due to invalid IL or missing references)
				//IL_011e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0120: Expected O, but got Unknown
				//IL_0125: Expected O, but got Unknown
				if ((int)shieldRechargeSound.index < 0 || (int)shieldBoosterSound.index < 0)
				{
					throw new InvalidOperationException("Shield recharge sound catalog is unavailable");
				}
				defense.ValidateShield();
				Plugin plugin = this;
				Type? typeFromHandle = typeof(HealthComponent);
				Manipulator obj = val;
				if (obj == null)
				{
					Manipulator val2 = delegate(ILContext il)
					{
						DefenseEmitters.ShieldGate<HealthComponent>(il, defense.ShieldGate, defense.ForcedShieldGate);
					};
					Manipulator val3 = val2;
					val = val2;
					obj = val3;
				}
				plugin.AddIL(10, typeFromHandle, "ServerFixedUpdate", obj);
				Plugin plugin2 = this;
				Type? typeFromHandle2 = typeof(HealthComponent);
				Manipulator obj2 = val4;
				if (obj2 == null)
				{
					Manipulator val5 = delegate(ILContext il)
					{
						DefenseEmitters.ShieldRecharge<HealthComponent>(il, defense.ShieldRecharge);
					};
					Manipulator val3 = val5;
					val4 = val5;
					obj2 = val3;
				}
				plugin2.AddIL(10, typeFromHandle2, "ServerFixedUpdate", obj2);
				Plugin plugin3 = this;
				Type? typeFromHandle3 = typeof(HealthComponent);
				Manipulator obj3 = val6;
				if (obj3 == null)
				{
					Manipulator val7 = delegate(ILContext il)
					{
						DefenseEmitters.ResourceWrites<HealthComponent>(il, defense.ShieldResource);
					};
					Manipulator val3 = val7;
					val6 = val7;
					obj3 = val3;
				}
				plugin3.AddIL(10, typeFromHandle3, "TakeDamageProcess", obj3);
				Plugin plugin4 = this;
				Type? typeFromHandle4 = typeof(CharacterBody);
				Manipulator obj4 = val8;
				if (obj4 == null)
				{
					Manipulator val9 = delegate(ILContext il)
					{
						DefenseEmitters.ShieldSound<GameObject>(il, defense.EarlyShieldSound);
					};
					Manipulator val3 = val9;
					val8 = val9;
					obj4 = val3;
				}
				plugin4.AddIL(10, typeFromHandle4, "OnOutOfDangerChanged", obj4);
			});
			Install(11, settings.Raincoat && raincoatRegistered, delegate
			{
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				//IL_0035: Expected O, but got Unknown
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Expected O, but got Unknown
				//IL_0071: Expected O, but got Unknown
				Plugin plugin = this;
				Type? typeFromHandle = typeof(ImmuneToDebuffBehavior);
				Manipulator obj = val;
				if (obj == null)
				{
					Manipulator val2 = delegate(ILContext il)
					{
						DefenseEmitters.Raincoat<CharacterBody>(il, defense.Prevention);
					};
					Manipulator val3 = val2;
					val = val2;
					obj = val3;
				}
				plugin.AddIL(11, typeFromHandle, "TryApplyOverride", obj);
				Plugin plugin2 = this;
				Type? typeFromHandle2 = typeof(CharacterBody);
				Manipulator obj2 = val4;
				if (obj2 == null)
				{
					Manipulator val5 = delegate(ILContext il)
					{
						DefenseEmitters.Movement<CharacterBody>(il, defense.Speed);
					};
					Manipulator val3 = val5;
					val4 = val5;
					obj2 = val3;
				}
				plugin2.AddIL(11, typeFromHandle2, "RecalculateStats", obj2);
			});
			Install(12, settings.Aegis, delegate
			{
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				//IL_0035: Expected O, but got Unknown
				Plugin plugin = this;
				Type? typeFromHandle = typeof(HealthComponent);
				Manipulator obj = val;
				if (obj == null)
				{
					Manipulator val2 = delegate(ILContext il)
					{
						DefenseEmitters.Decay<HealthComponent>(il, defense.Decay);
					};
					Manipulator val3 = val2;
					val = val2;
					obj = val3;
				}
				plugin.AddIL(12, typeFromHandle, "GetBarrierDecayRate", obj);
			});
			Manipulator val10 = default(Manipulator);
			Manipulator val12 = default(Manipulator);
			Manipulator val14 = default(Manipulator);
			Install(13, settings.Wake, delegate
			{
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: Expected O, but got Unknown
				//IL_0045: Expected O, but got Unknown
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_007a: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Expected O, but got Unknown
				//IL_0081: Expected O, but got Unknown
				//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b8: Expected O, but got Unknown
				//IL_00bd: Expected O, but got Unknown
				//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_00f4: Expected O, but got Unknown
				//IL_00f9: Expected O, but got Unknown
				//IL_0129: Unknown result type (might be due to invalid IL or missing references)
				//IL_012e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0130: Expected O, but got Unknown
				//IL_0135: Expected O, but got Unknown
				//IL_0165: Unknown result type (might be due to invalid IL or missing references)
				//IL_016a: Unknown result type (might be due to invalid IL or missing references)
				//IL_016c: Expected O, but got Unknown
				//IL_0171: Expected O, but got Unknown
				//IL_01a1: 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)
				//IL_01a8: Expected O, but got Unknown
				//IL_01ad: Expected O, but got Unknown
				defense.Wake.ValidateBindings();
				Plugin plugin = this;
				Type? typeFromHandle = typeof(GlobalEventManager);
				Manipulator obj = val;
				if (obj == null)
				{
					Manipulator val2 = delegate(ILContext il)
					{
						DefenseEmitters.WakeSteal<CharacterBody, BuffIndex>(il, defense.Wake.Grant);
					};
					Manipulator val3 = val2;
					val = val2;
					obj = val3;
				}
				plugin.AddIL(13, typeFromHandle, "OnCharacterDeath", obj);
				Plugin plugin2 = this;
				Type? typeFromHandle2 = typeof(HealthComponent);
				Manipulator obj2 = val4;
				if (obj2 == null)
				{
					Manipulator val5 = delegate(ILContext il)
					{
						DefenseEmitters.WakeDamage<HealthComponent, DamageInfo>(il, defense.Wake.Reduce);
					};
					Manipulator val3 = val5;
					val4 = val5;
					obj2 = val3;
				}
				plugin2.AddIL(13, typeFromHandle2, "TakeDamageProcess", obj2);
				Plugin plugin3 = this;
				Type? typeFromHandle3 = typeof(ProjectileManager);
				Manipulator obj3 = val6;
				if (obj3 == null)
				{
					Manipulator val7 = delegate(ILContext il)
					{
						Batch2Emitters.AtReturn<ProjectileController>(il, defense.Wake.Projectile);
					};
					Manipulator val3 = val7;
					val6 = val7;
					obj3 = val3;
				}
				plugin3.AddIL(13, typeFromHandle3, "InitializeProjectile", obj3);
				Plugin plugin4 = this;
				Type? typeFromHandle4 = typeof(ProjectileController);
				Manipulator obj4 = val8;
				if (obj4 == null)
				{
					Manipulator val9 = delegate(ILContext il)
					{
						Batch2Emitters.AtReturn<ProjectileController>(il, defense.Wake.Projectile);
					};
					Manipulator val3 = val9;
					val8 = val9;
					obj4 = val3;
				}
				plugin4.AddIL(13, typeFromHandle4, "SetOwner", obj4);
				Plugin plugin5 = this;
				Type? typeFromHandle5 = typeof(ProjectileController);
				Manipulator obj5 = val10;
				if (obj5 == null)
				{
					Manipulator val11 = delegate(ILContext il)
					{
						Batch2Emitters.AtReturn<ProjectileController>(il, defense.Wake.ProjectileFallback);
					};
					Manipulator val3 = val11;
					val10 = val11;
					obj5 = val3;
				}
				plugin5.AddIL(13, typeFromHandle5, "Start", obj5);
				Plugin plugin6 = this;
				Type? typeFromHandle6 = typeof(DotController);
				Manipulator obj6 = val12;
				if (obj6 == null)
				{
					Manipulator val13 = delegate(ILContext il)
					{
						DefenseEmitters.DotAdded<object>(il, defense.Wake.DotAdded);
					};
					Manipulator val3 = val13;
					val12 = val13;
					obj6 = val3;
				}
				plugin6.AddIL(13, typeFromHandle6, "OnDotStackAddedServer", obj6);
				Plugin plugin7 = this;
				Type? typeFromHandle7 = typeof(DotController);
				Manipulator obj7 = val14;
				if (obj7 == null)
				{
					Manipulator val15 = delegate(ILContext il)
					{
						DefenseEmitters.DotDamage<DotController, object>(il, defense.Wake.DotAmount);
						DefenseEmitters.DotMark<DamageInfo>(il, defense.Wake.MarkDot);
					};
					Manipulator val3 = val15;
					val14 = val15;
					obj7 = val3;
				}
				plugin7.AddIL(13, typeFromHandle7, "EvaluateDotStacksForType", obj7);
			});
			hooks.Add(defense);
			defense.Enable();
		}

		private void InstallBatch4()
		{
			KillFeature feature = new KillFeature(settings, ready);
			Manipulator val4 = default(Manipulator);
			Manipulator val = default(Manipulator);
			Install(14, settings.Berzerker, delegate
			{
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Expected O, but got Unknown
				//IL_0040: Expected O, but got Unknown
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_0077: Expected O, but got Unknown
				//IL_007c: Expected O, but got Unknown
				feature.Validate();
				Plugin plugin = this;
				Type? typeFromHandle = typeof(CharacterBody);
				Manipulator obj = val;
				if (obj == null)
				{
					Manipulator val2 = delegate(ILContext il)
					{
						KillEmitters.Frenzy<CharacterBody, BuffDef>(il, feature.Kill, feature.Grant);
					};
					Manipulator val3 = val2;
					val = val2;
					obj = val3;
				}
				plugin.AddIL(14, typeFromHandle, "AddMultiKill", obj);
				Plugin plugin2 = this;
				Type? typeFromHandle2 = typeof(CharacterBody);
				Manipulator obj2 = val4;
				if (obj2 == null)
				{
					Manipulator val5 = delegate(ILContext il)
					{
						KillEmitters.Expiry<CharacterBody, TimedBuff>(il, feature.Expire);
					};
					Manipulator val3 = val5;
					val4 = val5;
					obj2 = val3;
				}
				plugin2.AddIL(14, typeFromHandle2, "UpdateBuffs", obj2);
			});
			Install(15, settings.Harpoon, delegate
			{
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				//IL_0035: Expected O, but got Unknown
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Expected O, but got Unknown
				//IL_0071: Expected O, but got Unknown
				Plugin plugin = this;
				Type? typeFromHandle = typeof(GlobalEventManager);
				Manipulator obj = val;
				if (obj == null)
				{
					Manipulator val2 = delegate(ILContext il)
					{
						KillEmitters.Harpoon(il, () => ready[15], settings.HarpoonStacks, settings.HarpoonFirst, settings.HarpoonAdditional);
					};
					Manipulator val3 = val2;
					val = val2;
					obj = val3;
				}
				plugin.AddIL(15, typeFromHandle, "OnCharacterDeath", obj);
				Plugin plugin2 = this;
				Type? typeFromHandle2 = typeof(CharacterBody);
				Manipulator obj2 = val4;
				if (obj2 == null)
				{
					Manipulator val5 = delegate(ILContext il)
					{
						KillEmitters.HarpoonSpeed<CharacterBody>(il, feature.Speed);
					};
					Manipulator val3 = val5;
					val4 = val5;
					obj2 = val3;
				}
				plugin2.AddIL(15, typeFromHandle2, "RecalculateStats", obj2);
			});
			Install(16, settings.Nectar, delegate
			{
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				//IL_0035: Expected O, but got Unknown
				Plugin plugin = this;
				Type? typeFromHandle = typeof(CharacterBody);
				Manipulator obj = val;
				if (obj == null)
				{
					Manipulator val2 = delegate(ILContext il)
					{
						KillEmitters.Nectar<CharacterBody>(il, feature.Nectar);
					};
					Manipulator val3 = val2;
					val = val2;
					obj = val3;
				}
				plugin.AddIL(16, typeFromHandle, "RecalculateStats", obj);
			});
			hooks.Add(feature);
			feature.Enable();
		}

		private void InstallBatch5()
		{
			Install(17, settings.Gesture, delegate
			{
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				//IL_009c: Expected O, but got Unknown
				//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c0: Expected O, but got Unknown
				//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e4: Expected O, but got Unknown
				//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
				//IL_0108: Expected O, but got Unknown
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Gesture: validating native bindings and installing equipped-action/Gateway/Crowdfunder hooks.");
				GestureFeature gesture = new GestureFeature(settings, () => ready[17]);
				gesture.Validate();
				goldApproval = new GoldGatApproval(gesture, () => ready[17], delegate(Exception e)
				{
					ready[17] = false;
					((BaseUnityPlugin)this).Logger.LogError((object)("Gesture disabled: Crowdfunder approval transport unavailable: " + e));
					if (networkKey != null)
					{
						RefreshNetworkKey();
					}
				});
				hooks.Add(goldApproval);
				AddIL(17, typeof(EquipmentSlot), "Execute", (Manipulator)delegate(ILContext il)
				{
					GenerationEmitters.Equipment<EquipmentSlot, EquipmentDef, EquipmentLocation>(il, gesture.Action, all: false);
				});
				AddIL(17, typeof(EquipmentSlot), "ExecuteAllIfReady", (Manipulator)delegate(ILContext il)
				{
					GenerationEmitters.Equipment<EquipmentSlot, EquipmentDef, EquipmentLocation>(il, gesture.Action, all: true);
				});
				AddIL(17, typeof(EquipmentSlot), "FireGateway", (Manipulator)delegate(ILContext il)
				{
					GenerationEmitters.Gateway<EquipmentSlot>(il, gesture.Gateway);
				});
				AddIL(17, typeof(GoldGatIdle), "Update", (Manipulator)delegate(ILContext il)
				{
					GenerationEmitters.GoldGate<GoldGatIdle>(il, goldApproval.Allow);
				});
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Gesture hooks installed. Enabled description/misfire will be active; Crowdfunder transport is checked when networking starts.");
			});
			Install(18, settings.SaleStar, delegate
			{
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Expected O, but got Unknown
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Expected O, but got Unknown
				//IL_0089: Unknown result type (might be due to invalid IL or missing references)
				//IL_0094: Expected O, but got Unknown
				//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b8: Expected O, but got Unknown
				//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ee: Expected O, but got Unknown
				//IL_0107: Unknown result type (might be due to invalid IL or missing references)
				//IL_0112: Expected O, but got Unknown
				//IL_012b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0136: Expected O, but got Unknown
				//IL_014f: Unknown result type (might be due to invalid IL or missing references)
				//IL_015a: Expected O, but got Unknown
				//IL_0173: Unknown result type (might be due to invalid IL or missing references)
				//IL_017e: Expected O, but got Unknown
				//IL_0197: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a2: Expected O, but got Unknown
				//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c6: Expected O, but got Unknown
				//IL_01df: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ea: Expected O, but got Unknown
				//IL_0203: Unknown result type (might be due to invalid IL or missing references)
				//IL_0220: Expected O, but got Unknown
				//IL_0239: Unknown result type (might be due to invalid IL or missing references)
				//IL_0244: Expected O, but got Unknown
				//IL_025d: Unknown result type (might be due to invalid IL or missing references)
				//IL_028c: Expected O, but got Unknown
				//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_02b0: Expected O, but got Unknown
				//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_02d4: Expected O, but got Unknown
				SaleStarFeature star = new SaleStarFeature(() => ready[18]);
				star.Validate();
				AddIL(18, typeof(PickupDropTable), "GeneratePickup", (Manipulator)delegate(ILContext il)
				{
					GenerationEmitters.AtReturns<UniquePickup>(il, star.Map);
				});
				AddIL(18, typeof(PickupDropTable), "GenerateDrop", (Manipulator)delegate(ILContext il)
				{
					GenerationEmitters.AtReturns<PickupIndex>(il, star.MapIndex);
				});
				AddIL(18, typeof(PickupDropTable), "GenerateUniqueDrops", (Manipulator)delegate(ILContext il)
				{
					GenerationEmitters.AtReturns<PickupIndex[]>(il, star.MapArray);
				});
				AddIL(18, typeof(PickupDropTable), "GenerateDistinctPickups", (Manipulator)delegate(ILContext il)
				{
					GenerationEmitters.GeneratedList<List<UniquePickup>>(il, star.MapList);
				});
				AddIL(18, typeof(ShopTerminalBehavior), "GenerateNewPickupServer", (Manipulator)delegate(ILContext il)
				{
					GenerationEmitters.ShopFallback<UniquePickup>(il, star.Map);
				}, new Type[1] { typeof(bool) });
				AddIL(18, typeof(MultiShopController), "CreateTerminals", (Manipulator)delegate(ILContext il)
				{
					GenerationEmitters.PreserveTransfer<UniquePickup>(il, star.Map);
				});
				AddIL(18, typeof(ChestBehavior), "PickFromList", (Manipulator)delegate(ILContext il)
				{
					GenerationEmitters.SelectedIndex<PickupIndex>(il, star.MapIndex, "NextElementUniform");
				});
				AddIL(18, typeof(ScavBackpackBehavior), "PickFromList", (Manipulator)delegate(ILContext il)
				{
					GenerationEmitters.SelectedIndex<PickupIndex>(il, star.MapIndex, "NextElementUniform");
				});
				AddIL(18, typeof(BossGroup), "DropRewards", (Manipulator)delegate(ILContext il)
				{
					GenerationEmitters.SelectedIndex<PickupIndex>(il, star.MapIndex, "NextElementUniform");
				});
				AddIL(18, typeof(ShrineChanceBehavior), "AddShrineStack", (Manipulator)delegate(ILContext il)
				{
					GenerationEmitters.SelectedIndex<PickupIndex>(il, star.MapIndex, "Evaluate");
				});
				AddIL(18, typeof(EquipmentSlot), "FireRecycle", (Manipulator)delegate(ILContext il)
				{
					GenerationEmitters.Recycle<PickupIndex>(il, star.MapIndex);
				});
				AddIL(18, typeof(CharacterMaster), "TryCloverVoidUpgrades", (Manipulator)delegate(ILContext il)
				{
					GenerationEmitters.NewItemTargets<ItemIndex>(il, star.MapItem, clover: true);
				});
				AddIL(18, typeof(Inventory), "GiveRandomItems", (Manipulator)delegate(ILContext il)
				{
					GenerationEmitters.NewItemTargets<ItemIndex>(il, star.MapItem, clover: false);
				}, new Type[1] { typeof(GiveRandomItemsArgs) });
				AddIL(18, typeof(FindItem), "OnEnter", (Manipulator)delegate(ILContext il)
				{
					GenerationEmitters.ScavSelection<PickupIndex>(il, star.MapIndex);
				});
				AddIL(18, typeof(ItemTransformation), "CanTake", (Manipulator)delegate(ILContext il)
				{
					GenerationEmitters.GuardTake<Inventory, CanTakeResult>(il, star.GuardTake, star.AllowTake);
				}, new Type[2]
				{
					typeof(Inventory),
					typeof(CanTakeResult).MakeByRefType()
				});
				AddIL(18, typeof(ItemTransferOrbDroppable), "OnArrival", (Manipulator)delegate(ILContext il)
				{
					GenerationEmitters.PreserveTransfer<UniquePickup>(il, star.Preserve);
				});
				AddIL(18, typeof(ProjectileTransferItem), "DropItem", (Manipulator)delegate(ILContext il)
				{
					GenerationEmitters.PreserveTransfer<UniquePickup>(il, star.Preserve);
				});
				hooks.Add(star);
				star.Enable();
			});
		}

		private void Update()
		{
			if (initialized && ready[17])
			{
				goldApproval?.Tick();
			}
		}

		private void InstallAuditFeatures()
		{
			Install(19, settings.LaserScope, delegate
			{
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Expected O, but got Unknown
				AddIL(19, typeof(CharacterBody), "RecalculateStats", (Manipulator)delegate(ILContext il)
				{
					IntegrationEmitters.Scope(il, (float ordinary, CharacterBody body) => (!ready[19] || !Object.op_Implicit((Object)(object)body.inventory)) ? ordinary : IntegrationRules.Crit(ordinary, body.inventory.GetItemCountEffective(Items.CritDamage), settings.CritFloor));
				});
			});
			Install(20, settings.Suffering, delegate
			{
				//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ad: Expected O, but got Unknown
				MethodInfo clone = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic) ?? throw new MissingMethodException("object.MemberwiseClone");
				FieldInfo owner = typeof(SharedSufferingBuffController).GetField("attacker", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (owner == null || owner.FieldType != typeof(CharacterBody))
				{
					throw new MissingFieldException("SharedSufferingBuffController.attacker");
				}
				AddIL(20, typeof(SharedSufferingManager), "DealDamage", (Manipulator)delegate(ILContext il)
				{
					IntegrationEmitters.Suffering(il, delegate(HealthComponent victim, DamageInfo info)
					{
						//IL_005b: Unknown result type (might be due to invalid IL or missing references)
						//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
						//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
						//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
						//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
						//IL_00da: Unknown result type (might be due to invalid IL or missing references)
						//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
						//IL_00ff: Expected O, but got Unknown
						if (ready[20] && NetworkServer.active && Object.op_Implicit((Object)(object)victim) && Object.op_Implicit((Object)(object)victim.body))
						{
							SharedSufferingBuffController component = ((Component)victim.body).GetComponent<SharedSufferingBuffController>();
							CharacterBody val = ((!Object.op_Implicit((Object)(object)component)) ? ((CharacterBody)null) : ((CharacterBody)owner.GetValue(component)));
							if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.healthComponent) && val.healthComponent.alive && Object.op_Implicit((Object)(object)val.inventory) && val.inventory.GetItemCountEffective(Items.SharedSuffering) > 0 && victim.body.HasBuff(Buffs.SharedSuffering))
							{
								Vector3 corePosition = val.corePosition;
								Vector3 corePosition2 = victim.body.corePosition;
								LayerIndex world = LayerIndex.world;
								if (Physics.Linecast(corePosition, corePosition2, LayerMask.op_Implicit(((LayerIndex)(ref world)).mask), (QueryTriggerInteraction)1))
								{
									DamageInfo val2 = (DamageInfo)clone.Invoke(info, null);
									val2.damage = IntegrationRules.Payout(info.damage, obstructed: true, settings.OccludedDamage);
									victim.TakeDamage(val2);
									return;
								}
							}
						}
						victim.TakeDamage(info);
					});
				});
			});
		}

		private ItemStatContext StatContext(object? source)
		{
			CharacterBody val = (CharacterBody)((source is CharacterBody) ? source : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return new ItemStatContext();
			}
			Inventory inventory = val.inventory;
			HealthComponent healthComponent = val.healthComponent;
			return new ItemStatContext
			{
				HasBody = true,
				Damage = val.damage,
				Crit = val.crit,
				MoveSpeed = val.moveSpeed,
				Barrier = (Object.op_Implicit((Object)(object)healthComponent) ? healthComponent.barrier : 0f),
				BarrierCapacity = (Object.op_Implicit((Object)(object)healthComponent) ? healthComponent.fullBarrier : 0f),
				SpurCharge = val.GetBuffCount(Buffs.JumpDamageStrikeCharge),
				HarpoonBuffs = val.GetBuffCount(Buffs.KillMoveSpeed),
				NectarBuffs = val.GetBuffCount(Buffs.BoostAllStatsBuff),
				HarpoonOwned = (Object.op_Implicit((Object)(object)inventory) && inventory.GetItemCountEffective(Items.MoveSpeedOnKill) > 0),
				NectarOwned = (Object.op_Implicit((Object)(object)inventory) && inventory.GetItemCountEffective(Items.BoostAllStats) > 0),
				RaincoatSpeed = (Object.op_Implicit((Object)(object)raincoatSpeed) && val.HasBuff(raincoatSpeed) && Object.op_Implicit((Object)(object)inventory) && inventory.GetItemCountEffective(Items.ImmuneToDebuff) > 0),
				ActiveStars = (Object.op_Implicit((Object)(object)inventory) ? inventory.GetItemCountEffective(Items.LowerPricedChests) : 0),
				ConsumedStars = (Object.op_Implicit((Object)(object)inventory) ? inventory.GetItemCountEffective(Items.LowerPricedChestsConsumed) : 0)
			};
		}

		private void InitializeLookingGlass()
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Expected O, but got Unknown
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Expected I4, but got Unknown
			//IL_021a: Expected I4, but got Unknown
			if (!Chainloader.PluginInfos.TryGetValue("droppod.lookingglass", out var value))
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"LookingGlass not installed; optional item stats skipped.");
				return;
			}
			int count = hooks.Count;
			try
			{
				Assembly assembly = ((object)value.Instance).GetType().Assembly;
				lookingGlass = new LookingGlassRegistry(assembly);
				hooks.Add(lookingGlass);
				LookingGlassRegistry registry = lookingGlass;
				Type type = assembly.GetType("LookingGlass.ItemStatsNameSpace.ItemStats", throwOnError: true);
				ILHook item = new ILHook((MethodBase)type.GetMethod("GetItemDescription", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic), (Manipulator)delegate(ILContext il)
				{
					Patch(il, delegate(ILContext context)
					{
						LookingGlassEmitters.Item(context, registry.ItemCalculator);
					});
				});
				hooks.Add((IDisposable)item);
				hooks.Add((IDisposable)new ILHook((MethodBase)type.GetMethod("SkillIcon_SkillInfoCDProc", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic), (Manipulator)delegate(ILContext il)
				{
					Patch(il, delegate(ILContext context)
					{
						LookingGlassEmitters.Skill(context, registry.SkillMarkup);
					});
				}));
				ItemDef[] array = (ItemDef[])(object)new ItemDef[21]
				{
					Items.ChainLightningVoid,
					Items.HalfAttackSpeedHalfCooldowns,
					Items.FireRing,
					Items.IceRing,
					Items.JumpDamageStrike,
					Items.CritGlassesVoid,
					Items.Behemoth,
					Items.Seed,
					Items.ElementalRingVoid,
					Items.BearVoid,
					Items.ShieldOnly,
					Items.ImmuneToDebuff,
					Items.BarrierOnOverHeal,
					Items.HeadHunter,
					Items.WarCryOnMultiKill,
					Items.MoveSpeedOnKill,
					Items.BoostAllStats,
					Items.AutoCastEquipment,
					Items.LowerPricedChests,
					Items.CritDamage,
					Items.SharedSuffering
				};
				int num = 0;
				for (int num2 = 0; num2 < array.Length; num2++)
				{
					int id = num2;
					if (ready[id])
					{
						lookingGlass.Install((int)array[id].itemIndex, () => ready[id], (object? body, int n) => ItemStatRows.Build(id, n, settings, StatContext(body)), (id == 7) ? ((Func<float, int, float, List<float>>)((float _, int n, float proc) => new List<float> { (proc > 0f) ? (settings.SeedHeal * (float)Math.Max(0, n)) : 0f })) : null);
						num++;
					}
				}
				if (ready[18])
				{
					lookingGlass.Install((int)Items.LowerPricedChestsConsumed.itemIndex, () => ready[18], (object? body, int n) => ItemStatRows.Build(18, n, settings, StatContext(body), consumedStar: true));
					num++;
				}
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"LookingGlass {value.Metadata.Version}: {num} item stat definitions installed (includes consumed Sale Star). Gameplay unchanged.");
				void Patch(ILContext il, Action<ILContext> apply)
				{
					try
					{
						apply(il);
					}
					catch (Exception ex2)
					{
						registry.Dispose();
						((BaseUnityPlugin)this).Logger.LogWarning((object)("LookingGlass UI hook unavailable; original definitions restored. " + ex2));
						throw;
					}
				}
			}
			catch (Exception ex)
			{
				for (int num3 = hooks.Count - 1; num3 >= count; num3--)
				{
					hooks[num3].Dispose();
					hooks.RemoveAt(num3);
				}
				lookingGlass = null;
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Optional LookingGlass stats unavailable; original definitions retained. " + ex));
			}
		}

		private void Awake()
		{
			settings = new Settings(((BaseUnityPlugin)this).Config);
			RegisterDefensiveContent();
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(Initialize));
		}

		private static MethodInfo Method(Type type, string name)
		{
			return type.GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) ?? throw new MissingMethodException(type.FullName, name);
		}

		private void Initialize()
		{
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			if (initialized)
			{
				return;
			}
			initialized = true;
			Install(0, settings.Polylute, delegate
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Expected O, but got Unknown
				AddIL(0, typeof(GlobalEventManager), "ProcessHitEnemy", (Manipulator)delegate(ILContext il)
				{
					Emitters.Constant(il, Patterns.Polylute((IList<Instruction>)il.Body.Instructions), () => ready[0], settings.PolyluteDamage);
				});
			});
			Install(1, settings.LightFlux, delegate
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Expected O, but got Unknown
				AddIL(1, typeof(CharacterBody), "RecalculateStats", (Manipulator)delegate(ILContext il)
				{
					Emitters.LightFlux(il, () => ready[1], settings.AttackPenalty, settings.ArmorPenalty);
				});
			});
			Install(2, settings.Kjaro, delegate
			{
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Expected O, but got Unknown
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Expected O, but got Unknown
				PrepareTornado();
				AddIL(2, typeof(GlobalEventManager), "ProcessHitEnemy", (Manipulator)delegate(ILContext il)
				{
					Emitters.Constant(il, Patterns.BandDamage((IList<Instruction>)il.Body.Instructions, fire: true), () => ready[2], settings.KjaroDamage);
				});
				AddIL(2, typeof(OverlapAttack), "Fire", (Manipulator)delegate(ILContext il)
				{
					Emitters.Filter<OverlapAttack, HurtBox>(il, WithinTornado);
				});
			});
			Install(3, settings.Runald, delegate
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Expected O, but got Unknown
				AddIL(3, typeof(GlobalEventManager), "ProcessHitEnemy", (Manipulator)delegate(ILContext il)
				{
					int index = Patterns.BandDamage((IList<Instruction>)il.Body.Instructions, fire: false);
					int index2 = Patterns.Slow((IList<Instruction>)il.Body.Instructions);
					Emitters.Constant(il, index2, () => ready[3], settings.SlowSeconds);
					Emitters.Constant(il, index, () => ready[3], settings.RunaldDamage);
				});
			});
			Install(4, settings.Faraday, delegate
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Expected O, but got Unknown
				AddIL(4, typeof(CharacterBody), "RecalculateStats", (Manipulator)delegate(ILContext il)
				{
					int index = Patterns.Faraday((IList<Instruction>)il.Body.Instructions);
					Emitters.Constant(il, index, () => ready[4], settings.FaradaySpeed / 100f);
				});
			});
			InstallBatch2();
			InstallBatch3();
			InstallBatch4();
			InstallBatch5();
			InstallAuditFeatures();
			Language.GetLocalizedStringByToken += new hook_GetLocalizedStringByToken(Language);
			languageHook = true;
			InitializeLookingGlass();
			RefreshNetworkKey();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("T4ylorItems 1.0.0: V01/L03/G05/G06/G08/V02/R06/G03/V04/V03/L02/R01/R04/R03/G01/G02/R05/L01/G07/R02/R07 ready = " + string.Join(",", ready) + ". Restart after settings changes. Identical version, settings and hook readiness required on every peer."));
		}

		private void Install(int id, bool enabled, Action action)
		{
			if (!enabled)
			{
				return;
			}
			int count = hooks.Count;
			try
			{
				ready[id] = true;
				action();
				if (!ready[id])
				{
					throw new InvalidOperationException("IL validation failed");
				}
			}
			catch (Exception arg)
			{
				ready[id] = false;
				for (int num = hooks.Count - 1; num >= count; num--)
				{
					hooks[num].Dispose();
					hooks.RemoveAt(num);
				}
				if (id == 2)
				{
					RestoreTornado();
				}
				((BaseUnityPlugin)this).Logger.LogError((object)$"Item module {id} disabled; vanilla mechanics and descriptions retained: {arg}");
			}
		}

		private void AddIL(int id, Type type, string name, Manipulator patch, Type[]? parameters = null)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected O, but got Unknown
			MethodInfo methodInfo = ((parameters == null) ? Method(type, name) : (type.GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, parameters, null) ?? throw new MissingMethodException(type.FullName, name)));
			hooks.Add((IDisposable)new ILHook((MethodBase)methodInfo, (Manipulator)delegate(ILContext il)
			{
				try
				{
					patch.Invoke(il);
				}
				catch (Exception ex)
				{
					ready[id] = false;
					if (id == 2)
					{
						RestoreTornado();
					}
					((BaseUnityPlugin)this).Logger.LogError((object)$"Item module {id} IL unavailable in {type.Name}.{name}; active description suppressed. Restart required: {ex}");
					if (networkKey != null)
					{
						RefreshNetworkKey();
					}
					throw;
				}
			}));
		}

		private void PrepareTornado()
		{
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: 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_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			tornado = LegacyResourcesAPI.Load<GameObject>("Prefabs/Projectiles/FireTornado");
			HitBoxGroup component = tornado.GetComponent<HitBoxGroup>();
			ProjectileOverlapAttack component2 = tornado.GetComponent<ProjectileOverlapAttack>();
			ProjectileSimple component3 = tornado.GetComponent<ProjectileSimple>();
			ProjectileController component4 = tornado.GetComponent<ProjectileController>();
			if (!Object.op_Implicit((Object)(object)component) || component.hitBoxes.Length != 1 || !Object.op_Implicit((Object)(object)component2) || component2.isSphereOverlap || !Object.op_Implicit((Object)(object)component3) || Mathf.Abs(component3.lifetime - 3.3f) > 0.001f || Mathf.Abs(component2.resetInterval - 0.3f) > 0.001f)
			{
				throw new InvalidOperationException("FireTornado components/timing changed.");
			}
			hitbox = ((Component)component.hitBoxes[0]).transform;
			oldHitboxScale = hitbox.localScale;
			if (Mathf.Abs(oldHitboxScale.x - 13.09843f) > 0.001f || Mathf.Abs(oldHitboxScale.z - 13.09843f) > 0.001f || (Object)(object)hitbox.parent != (Object)(object)tornado.transform)
			{
				throw new InvalidOperationException("FireTornado hitbox changed or another mod resized it.");
			}
			ghostPrefab = Addressables.LoadAssetAsync<GameObject>((object)component4.ghostPrefabAddress).WaitForCompletion();
			if (!Object.op_Implicit((Object)(object)ghostPrefab))
			{
				throw new InvalidOperationException("FireTornado ghost unavailable.");
			}
			oldGhostScale = ghostPrefab.transform.localScale;
			hitbox.localScale = new Vector3(settings.KjaroRadius * 2f, oldHitboxScale.y, settings.KjaroRadius * 2f);
			ghostPrefab.transform.localScale = new Vector3(oldGhostScale.x * settings.KjaroRadius / 5f, oldGhostScale.y, oldGhostScale.z * settings.KjaroRadius / 5f);
		}

		private bool WithinTornado(bool vanilla, OverlapAttack attack, HurtBox target)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			if (!vanilla || !ready[2] || !Object.op_Implicit((Object)(object)attack.inflictor) || !Object.op_Implicit((Object)(object)tornado))
			{
				return vanilla;
			}
			ProjectileController component = attack.inflictor.GetComponent<ProjectileController>();
			if (!Object.op_Implicit((Object)(object)component) || component.catalogIndex != tornado.GetComponent<ProjectileController>().catalogIndex)
			{
				return vanilla;
			}
			Collider component2 = ((Component)target).GetComponent<Collider>();
			Vector3 position = ((Component)attack.hitBoxGroup.hitBoxes[0]).transform.position;
			Vector3 val = (Object.op_Implicit((Object)(object)component2) ? component2.ClosestPoint(position) : ((Component)target).transform.position);
			float num = val.x - position.x;
			float num2 = val.z - position.z;
			return num * num + num2 * num2 <= settings.KjaroRadius * settings.KjaroRadius;
		}

		private void RestoreTornado()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)hitbox))
			{
				hitbox.localScale = oldHitboxScale;
			}
			if (Object.op_Implicit((Object)(object)ghostPrefab))
			{
				ghostPrefab.transform.localScale = oldGhostScale;
			}
			hitbox = null;
			ghostPrefab = null;
		}

		private string Language(orig_GetLocalizedStringByToken orig, Language language, string token)
		{
			string original = orig.Invoke(language, token);
			return Text.Override(token, original, settings, ready);
		}

		private void RefreshNetworkKey()
		{
			lookingGlass?.RestoreInactive();
			if (networkKey != null)
			{
				NetworkModCompatibilityHelper.networkModList = NetworkModCompatibilityHelper.networkModList.Where((string k) => k != networkKey).ToArray();
			}
			networkKey = "com.t4ylor.ror2.items;1.0.0;" + settings.Fingerprint(string.Join(",", ready));
			NetworkModCompatibilityHelper.networkModList = NetworkModCompatibilityHelper.networkModList.Append<string>(networkKey).ToArray();
		}

		private void OnDestroy()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(Initialize));
			if (languageHook)
			{
				Language.GetLocalizedStringByToken -= new hook_GetLocalizedStringByToken(Language);
			}
			Array.Clear(ready, 0, ready.Length);
			for (int num = hooks.Count - 1; num >= 0; num--)
			{
				hooks[num].Dispose();
			}
			hooks.Clear();
			RestoreTornado();
			if (networkKey != null)
			{
				NetworkModCompatibilityHelper.networkModList = NetworkModCompatibilityHelper.networkModList.Where((string k) => k != networkKey).ToArray();
			}
		}
	}
	public static class Batch2Patterns
	{
		private static bool Field(Instruction i, string name)
		{
			object operand = i.Operand;
			FieldReference val = (FieldReference)((operand is FieldReference) ? operand : null);
			if (val != null)
			{
				return ((MemberReference)val).Name == name;
			}
			return false;
		}

		private static bool Call(Instruction i, string name)
		{
			object operand = i.Operand;
			MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null);
			if (val != null)
			{
				return ((MemberReference)val).Name == name;
			}
			return false;
		}

		private static int Local(Instruction i)
		{
			object operand = i.Operand;
			VariableDefinition val = (VariableDefinition)((operand is VariableDefinition) ? operand : null);
			if (val == null)
			{
				return -1;
			}
			return ((VariableReference)val).Index;
		}

		private static int One(IList<Instruction> ins, Func<int, bool> predicate, string label)
		{
			int[] array = Enumerable.Range(0, ins.Count).Where(predicate).ToArray();
			if (array.Length != 1)
			{
				throw new InvalidOperationException(label + ": expected one match, got " + array.Length);
			}
			return array[0];
		}

		public static int Seed(IList<Instruction> ins)
		{
			int n = Patterns.ItemLocal(ins, "Seed");
			return One(ins, delegate(int i)
			{
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_0048: Unknown result type (might be due to invalid IL or missing references)
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d3: 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)
				if (i + 7 < ins.Count && Local(ins[i]) == n)
				{
					OpCode opCode = ins[i].OpCode;
					if (((object)((OpCode)(ref opCode)).Code/*cast due to .constrained prefix*/).ToString().StartsWith("Ldloc") && ins[i + 1].OpCode == OpCodes.Conv_R4 && ins[i + 2].OpCode == OpCodes.Ldarg_1 && Field(ins[i + 3], "procCoefficient") && ins[i + 4].OpCode == OpCodes.Mul && ins[i + 6].OpCode == OpCodes.Ldc_I4_1)
					{
						return Call(ins[i + 7], "Heal");
					}
				}
				return false;
			}, "Seed heal amount") + 3;
		}

		public static int SingularityDamage(IList<Instruction> ins)
		{
			int n = Patterns.ItemLocal(ins, "ElementalRingVoid");
			return One(ins, (int i) => i + 3 < ins.Count && Patterns.Float(ins[i], 1f) && Local(ins[i + 1]) == n && ins[i + 2].OpCode == OpCodes.Conv_R4 && ins[i + 3].OpCode == OpCodes.Mul && ins.Skip(i).Take(13).Any((Instruction x) => Call(x, "OnHitProcDamage")), "Singularity aggregate coefficient");
		}

		public static int SingularityCooldown(IList<Instruction> ins)
		{
			return One(ins, delegate(int i)
			{
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0045: Invalid comparison between Unknown and I4
				if (i + 1 < ins.Count && Patterns.Float(ins[i], 20f))
				{
					OpCode opCode = ins[i + 1].OpCode;
					if ((int)((OpCode)(ref opCode)).Code == 48)
					{
						return ins.Skip(Math.Max(0, i - 20)).Take(20).Any((Instruction x) => Field(x, "ElementalRingVoidCooldown"));
					}
				}
				return false;
			}, "Singularity cooldown loop bound");
		}

		public static int LensesBossGate(IList<Instruction> ins)
		{
			int item = One(ins, (int i) => Field(ins[i], "CritGlassesVoid"), "Lenses item");
			if (!ins.Skip(item).Take(24).Any((Instruction x) => Patterns.Float(x, 0.5f)) || !ins.Skip(item).Take(28).Any(delegate(Instruction x)
			{
				object operand = x.Operand;
				MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null);
				return val != null && ((MemberReference)val).Name.Contains("LocalCheckRoll");
			}))
			{
				throw new InvalidOperationException("Native Lenses chance/roll changed");
			}
			return One(ins, delegate(int i)
			{
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Invalid comparison between Unknown and I4
				if (i < item && i > item - 20 && Call(ins[i], "get_isBoss"))
				{
					OpCode opCode = ins[i + 1].OpCode;
					return (int)((OpCode)(ref opCode)).Code == 44;
				}
				return false;
			}, "Lenses native boss gate");
		}

		public static int BehemothFire(IList<Instruction> ins)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			int item = One(ins, (int i) => Field(ins[i], "Behemoth"), "Behemoth item");
			int num = One(ins, (int i) => i > item && i < item + 130 && Field(ins[i], "falloffModel"), "Behemoth native falloff");
			if (ins[num - 1].OpCode != OpCodes.Ldc_I4_0)
			{
				throw new InvalidOperationException("Behemoth native falloff is no longer None");
			}
			return One(ins, delegate(int i)
			{
				if (i > item && i < item + 130)
				{
					object operand = ins[i].Operand;
					MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null);
					if (val != null && ((MemberReference)((MemberReference)val).DeclaringType).FullName == "RoR2.BlastAttack" && ((MemberReference)val).Name == "Fire" && ins.Skip(item).Take(i - item).Any((Instruction x) => Patterns.Float(x, 0.6f)))
					{
						return Field(ins[i - 1], "damageType");
					}
				}
				return false;
			}, "Native Behemoth blast call");
		}

		public static int BlastBaseDamage(IList<Instruction> ins)
		{
			return One(ins, (int i) => i + 3 < ins.Count && Field(ins[i], "baseDamage") && ins[i + 2].OpCode == OpCodes.Mul && Field(ins[i + 3], "damage"), "Blast per-hit damage");
		}

		public static void BlastDistance(IList<Instruction> ins)
		{
			One(ins, (int i) => i + 2 < ins.Count && Field(ins[i], "distanceSqr") && Call(ins[i + 1], "Sqrt") && ins[i + 2].OpCode == OpCodes.Stloc_3, "Native blast distance");
		}

		public static void ValidatePhase(MethodDefinition method, string field)
		{
			if (!((IEnumerable<Instruction>)method.Body.Instructions).Any((Instruction i) => Field(i, field)) || ((IEnumerable<Instruction>)method.Body.Instructions).Count((Instruction i) => i.OpCode == OpCodes.Ret) != 1)
			{
				throw new InvalidOperationException("Encounter phase ownership changed: " + ((MemberReference)method).FullName);
			}
		}
	}
	public static class Batch2Emitters
	{
		public static void Seed(ILContext il, Func<bool> active, float heal)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			new ILCursor(il)
			{
				Index = Batch2Patterns.Seed((IList<Instruction>)il.Body.Instructions) + 1
			}.EmitDelegate<Func<float, float>>((Func<float, float>)((float native) => Batch2Rules.SeedScale(native, active(), heal)));
		}

		public static void Singularity(ILContext il, Func<bool> active, float damage, int cooldown)
		{
			int item = Batch2Patterns.SingularityDamage((IList<Instruction>)il.Body.Instructions);
			int item2 = Batch2Patterns.SingularityCooldown((IList<Instruction>)il.Body.Instructions);
			foreach (var item3 in new(int, float)[2]
			{
				(item, damage),
				(item2, cooldown)
			}.OrderByDescending(((int, float) x) => x.Item1))
			{
				Emitters.Constant(il, item3.Item1, active, item3.Item2);
			}
		}

		public static void LensesGate<TVictim>(ILContext il, Func<bool, TVictim, bool> gate)
		{
			//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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			int num = Batch2Patterns.LensesBossGate((IList<Instruction>)il.Body.Instructions);
			ILCursor val = new ILCursor(il)
			{
				Index = num + 1
			};
			val.Emit(OpCodes.Ldarg_0);
			val.EmitDelegate<Func<bool, TVictim, bool>>(gate);
		}

		public static void BehemothMark<TBlast>(ILContext il, Func<TBlast, TBlast> mark)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			new ILCursor(il)
			{
				Index = Batch2Patterns.BehemothFire((IList<Instruction>)il.Body.Instructions)
			}.EmitDelegate<Func<TBlast, TBlast>>(mark);
		}

		public static void BehemothDamage<TBlast>(ILContext il, Func<float, TBlast, float, float> damage)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			int num = Batch2Patterns.BlastBaseDamage((IList<Instruction>)il.Body.Instructions);
			Batch2Patterns.BlastDistance((IList<Instruction>)il.Body.Instructions);
			ILCursor val = new ILCursor(il)
			{
				Index = num + 1
			};
			val.Emit(OpCodes.Ldarg_0);
			val.Emit(OpCodes.Ldloc_3);
			val.EmitDelegate<Func<float, TBlast, float, float>>(damage);
		}

		public static void AtReturn<T>(ILContext il, Action<T> callback)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			Instruction[] array = ((IEnumerable<Instruction>)il.Body.Instructions).Where((Instruction i) => i.OpCode == OpCodes.Ret).ToArray();
			if (array.Length != 1)
			{
				throw new InvalidOperationException("Expected one lifecycle return");
			}
			ILCursor val = new ILCursor(il);
			val.Goto(array[0], (MoveType)0, false);
			val.MoveAfterLabels();
			val.Emit(OpCodes.Ldarg_0);
			val.EmitDelegate<Action<T>>(callback);
		}
	}
	public enum FinalEncounter
	{
		Mithrix,
		FalseSon,
		Providence,
		Voidling,
		SolusHeart,
		Reaper,
		LunarScavenger
	}
	public static class Batch2Rules
	{
		public static readonly IReadOnlyDictionary<FinalEncounter, string[]> Bodies = new Dictionary<FinalEncounter, string[]>
		{
			{
				FinalEncounter.Mithrix,
				new string[3] { "BrotherBody", "BrotherHurtBody", "BrotherThroneBody" }
			},
			{
				FinalEncounter.FalseSon,
				new string[3] { "FalseSonBossBody", "FalseSonBossBodyLunarShard", "FalseSonBossBodyBrokenLunarShard" }
			},
			{
				FinalEncounter.Providence,
				new string[1] { "BrotherHauntBody" }
			},
			{
				FinalEncounter.Voidling,
				new string[5] { "MiniVoidRaidCrabBodyPhase1", "MiniVoidRaidCrabBodyPhase2", "MiniVoidRaidCrabBodyPhase3", "MiniVoidRaidCrabBodyBase", "VoidRaidCrabBody" }
			},
			{
				FinalEncounter.SolusHeart,
				new string[2] { "SolusHeartBody", "SolusHeartBody_Offering" }
			},
			{
				FinalEncounter.Reaper,
				new string[1] { "ReaperBossBody" }
			},
			{
				FinalEncounter.LunarScavenger,
				new string[4] { "ScavLunar1Body", "ScavLunar2Body", "ScavLunar3Body", "ScavLunar4Body" }
			}
		};

		public static bool FinalBoss(FinalEncounter encounter, string bodyName, bool member, bool summon)
		{
			if (member && !summon)
			{
				return Array.IndexOf(Bodies[encounter], bodyName) >= 0;
			}
			return false;
		}

		public static bool TeleporterBoss(bool member, bool summonedByMember)
		{
			if (member)
			{
				return !summonedByMember;
			}
			return false;
		}

		public static float BossDamage(float holderDamage, float coefficient)
		{
			return holderDamage * coefficient;
		}

		public static float SeedScale(float nativeProc, bool active, float heal)
		{
			if (!active)
			{
				return nativeProc;
			}
			return heal;
		}

		public static float LensesChance(int items, float procCoefficient)
		{
			return 0.5f * (float)items * procCoefficient;
		}

		public static float BehemothCoefficient(float distance, float radius, float edge)
		{
			float num = ((radius > 0f) ? Math.Min(1f, Math.Max(0f, distance / radius)) : 0f);
			return 0.6f + (edge - 0.6f) * num;
		}
	}
	internal sealed class KillFeature : IDisposable
	{
		private sealed class Activation
		{
			internal TimedBuff entry;

			internal float spent;

			internal float allowance;
		}

		private readonly Settings s;

		private readonly bool[] ready;

		private readonly ConditionalWeakTable<CharacterBody, Activation> activations = new ConditionalWeakTable<CharacterBody, Activation>();

		private FieldInfo timers;

		internal KillFeature(Settings s, bool[] ready)
		{
			this.s = s;
			this.ready = ready;
		}

		internal void Validate()
		{
			timers = typeof(CharacterBody).GetField("timedBuffs", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? throw new MissingFieldException("CharacterBody.timedBuffs");
			if (timers.FieldType != typeof(List<TimedBuff>))
			{
				throw new InvalidOperationException("Native timed buff list changed");
			}
		}

		private List<TimedBuff> Timers(CharacterBody body)
		{
			return (List<TimedBuff>)timers.GetValue(body);
		}

		private static int Count(CharacterBody b, ItemDef item)
		{
			if (!Object.op_Implicit((Object)(object)b) || !Object.op_Implicit((Object)(object)b.inventory))
			{
				return 0;
			}
			return b.inventory.GetItemCountEffective(item);
		}

		private static bool Alive(CharacterBody b)
		{
			if (Object.op_Implicit((Object)(object)b) && Object.op_Implicit((Object)(object)b.healthComponent))
			{
				return b.healthComponent.alive;
			}
			return false;
		}

		private Activation? Current(CharacterBody body)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (activations.TryGetValue(body, out Activation value) && value.entry.buffIndex == Buffs.WarCryBuff.buffIndex && value.entry.timer > 0f && Timers(body).Contains(value.entry) && body.HasBuff(Buffs.WarCryBuff))
			{
				return value;
			}
			activations.Remove(body);
			return null;
		}

		private void Extend(Activation a, int kills)
		{
			TimedBuff entry = a.entry;
			entry.timer += KillRules.Earn(ref a.spent, kills, s.FrenzyBonus, a.allowance);
		}

		internal void Kill(CharacterBody body, int kills)
		{
			if (!ready[14] || !NetworkServer.active)
			{
				return;
			}
			if (!Alive(body) || Count(body, Items.WarCryOnMultiKill) <= 0)
			{
				activations.Remove(body);
				return;
			}
			Activation activation = Current(body);
			if (activation != null)
			{
				Extend(activation, kills);
			}
		}

		internal void Grant(CharacterBody body, BuffDef buff, float native, int kills)
		{
			if (!ready[14])
			{
				body.AddTimedBuff(buff, native);
			}
			else if (NetworkServer.active && Alive(body) && Count(body, Items.WarCryOnMultiKill) > 0 && !body.HasBuff(buff))
			{
				activations.Remove(body);
				int items = Count(body, Items.WarCryOnMultiKill);
				body.AddTimedBuff(buff, KillRules.FrenzyBase(items, s.FrenzyFirst, s.FrenzyAdditional));
				TimedBuff val = ((IEnumerable<TimedBuff>)Timers(body)).LastOrDefault((Func<TimedBuff, bool>)((TimedBuff t) => t.buffIndex == buff.buffIndex && t.timer > 0f));
				if (val != null)
				{
					Activation activation = new Activation
					{
						entry = val,
						allowance = KillRules.FrenzyBase(items, s.FrenzyAllowance, s.FrenzyAllowanceAdditional)
					};
					activations.Add(body, activation);
					Extend(activation, KillRules.SubsequentKills(kills, body.multiKillCount - kills));
				}
			}
		}

		internal void Expire(CharacterBody body, TimedBuff entry)
		{
			if (activations.TryGetValue(body, out Activation value) && value.entry == entry)
			{
				activations.Remove(body);
			}
		}

		internal float Speed(float native, CharacterBody body)
		{
			if (!ready[15] || Count(body, Items.MoveSpeedOnKill) <= 0)
			{
				return native;
			}
			return s.HarpoonSpeed;
		}

		internal float Nectar(float native, float bonus, CharacterBody body)
		{
			if (!ready[16] || Count(body, Items.BoostAllStats) <= 0)
			{
				return native;
			}
			return KillRules.NectarAcceleration(native, bonus, body.moveSpeed);
		}

		internal void Enable()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			CharacterBody.onBodyInventoryChangedGlobal += Inventory;
			CharacterBody.onBodyDestroyGlobal += Destroyed;
			GlobalEventManager.OnCharacterDeath += new hook_OnCharacterDeath(Death);
		}

		private void ClearFrenzy(CharacterBody body)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			if (activations.TryGetValue(body, out Activation value) && value.entry.buffIndex == Buffs.WarCryBuff.buffIndex && Timers(body).Remove(value.entry))
			{
				body.RemoveBuff(value.entry.buffIndex);
			}
			activations.Remove(body);
		}

		private void Inventory(CharacterBody body)
		{
			if (NetworkServer.active)
			{
				if (ready[14] && Count(body, Items.WarCryOnMultiKill) <= 0)
				{
					ClearFrenzy(body);
				}
				if (ready[15] && Count(body, Items.MoveSpeedOnKill) <= 0)
				{
					body.ClearTimedBuffs(Buffs.KillMoveSpeed);
				}
			}
		}

		private void Destroyed(CharacterBody body)
		{
			activations.Remove(body);
		}

		private void Death(orig_OnCharacterDeath orig, GlobalEventManager manager, DamageReport report)
		{
			orig.Invoke(manager, report);
			CharacterBody victimBody = report.victimBody;
			if (Object.op_Implicit((Object)(object)victimBody) && !Alive(victimBody) && NetworkServer.active)
			{
				if (ready[14])
				{
					ClearFrenzy(victimBody);
				}
				if (ready[15])
				{
					victimBody.ClearTimedBuffs(Buffs.KillMoveSpeed);
				}
			}
		}

		public void Dispose()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			CharacterBody.onBodyInventoryChangedGlobal -= Inventory;
			CharacterBody.onBodyDestroyGlobal -= Destroyed;
			GlobalEventManager.OnCharacterDeath -= new hook_OnCharacterDeath(Death);
		}
	}
	public static class DefensePatterns
	{
		public static bool Field(Instruction i, string name)
		{
			object operand = i.Operand;
			FieldReference val = (FieldReference)((operand is FieldReference) ? operand : null);
			if (val != null)
			{
				return ((MemberReference)val).Name == name;
			}
			return false;
		}

		public static bool Call(Instruction i, string name)
		{
			object operand = i.Operand;
			MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null);
			if (val != null)
			{
				return ((MemberReference)val).Name == name;
			}
			return false;
		}

		private static int Local(Instruction i)
		{
			object operand = i.Operand;
			VariableDefinition val = (VariableDefinition)((operand is VariableDefinition) ? operand : null);
			if (val == null)
			{
				return -1;
			}
			return ((VariableReference)val).Index;
		}

		private static int One(IList<Instruction> a, Func<int, bool> match, string label)
		{
			int[] array = Enumerable.Range(0, a.Count).Where(match).ToArray();
			if (array.Length != 1)
			{
				throw new InvalidOperationException(label + ": expected one match, got " + array.Length);
			}
			return array[0];
		}

		public static (int index, int kind)[] ResourceWrites(IList<Instruction> a)
		{
			int count = One(a, (int i) => Field(a[i], "CritGlassesVoid"), "Damage resolution bound");
			List<(int, int)> list = new List<(int, int)>();
			string[] setters = new string[3] { "set_Networkhealth", "set_Networkshield", "set_Networkbarrier" };
			int kind;
			for (kind = 0; kind < 3; kind++)
			{
				int[] array = (from i in Enumerable.Range(0, count)
					where Call(a[i], setters[kind])
					select i).ToArray();
				if (array.Length != ((kind == 0) ? 1 : 2))
				{
					throw new InvalidOperationException("Resource damage writes changed: " + setters[kind]);
				}
				int[] array2 = array;
				foreach (int item in array2)
				{
					list.Add((item, kind));
				}
			}
			return list.OrderByDescending(((int, int) x) => x.Item1).ToArray();
		}

		public static int BuffDelta(IList<Instruction> a)
		{
			return One(a, (int i) => i + 3 < a.Count && Field(a[i], "timer") && a[i + 1].OpCode == OpCodes.Ldarg_1 && a[i + 2].OpCode == OpCodes.Sub && Field(a[i + 3], "timer"), "Timed-buff countdown delta") + 1;
		}

		public static int ShieldGate(IList<Instruction> a)
		{
			return One(a, (int i) => Call(a[i], "get_outOfDanger") && a.Skip(i).Take(5).Any((Instruction x) => Field(x, "isShieldRegenForced")), "Shield recharge guard");
		}

		public static int RaincoatBarrier(IList<Instruction> a)
		{
			return One(a, (int i) => Call(a[i], "AddBarrier") && a.Take(i).Any((Instruction x) => Field(x, "ImmuneToDebuffReady")), "Raincoat charge consumption barrier");
		}

		public static int MovementBonus(IList<Instruction> a)
		{
			return One(a, (int i) => i + 5 < a.Count && Local(a[i]) >= 0 && a[i].OpCode == OpCodes.Ldloc_S && a[i + 1].OpCode == OpCodes.Ldloc_S && a[i + 2].OpCode == OpCodes.Ldloc_S && a[i + 3].OpCode == OpCodes.Div && a[i + 4].OpCode == OpCodes.Mul && Local(a[i + 5]) == Local(a[i]) && a.Skip(i).Take(45).Any((Instruction x) => Call(x, "set_moveSpeed")), "Movement bonus numerator") + 1;
		}

		public static int WakeSteal(IList<Instruction> a)
		{
			int h = One(a, (int i) => Field(a[i], "HeadHunter"), "Wake item");
			return One(a, delegate(int i)
			{
				if (i > h && i < h + 60 && Call(a[i], "AddTimedBuff"))
				{
					object operand = a[i].Operand;
					MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null);
					if (val != null)
					{
						return ((MemberReference)((ParameterReference)val.Parameters[0]).ParameterType).FullName == "RoR2.BuffIndex";
					}
				}
				return false;
			}, "Wake-owned stolen buff grant");
		}

		public static int WakeDamage(IList<Instruction> a)
		{
			return One(a, (int i) => i + 3 < a.Count && Field(a[i], "damageCalculation") && a[i + 1].OpCode == OpCodes.Stloc_S && a[i + 2].OpCode == OpCodes.Ldloc_S && Local(a[i + 1]) == Local(a[i + 2]) && a[i + 3].OpCode == OpCodes.Stloc_S, "Final incoming damage calculation");
		}

		public static int DotDamage(IList<Instruction> a)
		{
			return One(a, delegate(int i)
			{
				if (Field(a[i], "damage"))
				{
					object operand = a[i].Operand;
					FieldReference val = (FieldReference)((operand is FieldReference) ? operand : null);
					if (val != null && ((MemberReference)((MemberReference)val).DeclaringType).FullName == "RoR2.DotController/DotStack")
					{
						return Field(a[i + 1], "damage");
					}
				}
				return false;
			}, "Per-stack DOT amount");
		}

		public static int DotTakeDamage(IList<Instruction> a)
		{
			return One(a, (int i) => Call(a[i], "TakeDamage"), "DOT damage dispatch");
		}
	}
	public static class DefenseEmitters
	{
		public static void ShieldSound<T>(ILContext il, Func<string, T, uint> sound)
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			Instruction[] array = ((IEnumerable<Instruction>)il.Body.Instructions).Where((Instruction i) => DefensePatterns.Call(i, "PlaySound")).ToArray();
			if (array.Length != 2 || !((IEnumerable<Instruction>)il.Body.Instructions).Any((Instruction i) => i.OpCode == OpCodes.Ldstr && (string)i.Operand == "Play_item_proc_personal_shield_recharge") || !((IEnumerable<Instruction>)il.Body.Instructions).Any((Instruction i) => i.OpCode == OpCodes.Ldstr && (string)i.Operand == "Play_item_use_shieldBooster_regen"))
			{
				throw new InvalidOperationException("Shield start sound paths changed");
			}
			Instruction[] array2 = array;
			foreach (Instruction val in array2)
			{
				ILCursor val2 = new ILCursor(il);
				val2.Goto(val, (MoveType)0, false);
				val2.MoveAfterLabels();
				val2.Remove();
				val2.EmitDelegate<Func<string, T, uint>>(sound);
			}
		}

		public static void ShieldRecharge<T>(ILContext il, Func<float, T, float> recharge)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			Instruction[] array = ((IEnumerable<Instruction>)il.Body.Instructions).Where((Instruction i) => DefensePatterns.Call(i, "set_Networkshield")).ToArray();
			if (array.Length != 1 || !((IEnumerable<Instruction>)il.Body.Instructions).Any((Instruction i) => DefensePatterns.Field(i, "isShieldRegenForced")))
			{
				throw new InvalidOperationException("Actual shield regeneration write changed");
			}
			ILCursor val = new ILCursor(il);
			val.Goto(array[0], (MoveType)0, false);
			val.MoveAfterLabels();
			val.Emit(OpCodes.Ldarg_0);
			val.EmitDelegate<Func<float, T, float>>(recharge);
		}

		public static void ResourceWrites<T>(ILContext il, Func<float, T, int, float> record)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			(int, int)[] array = DefensePatterns.ResourceWrites((IList<Instruction>)il.Body.Instructions);
			for (int i = 0; i < array.Length; i++)
			{
				(int, int) tuple = array[i];
				ILCursor val = new ILCursor(il);
				(val.Index, _) = tuple;
				val.Emit(OpCodes.Ldarg_0);
				val.Emit(OpCodes.Ldc_I4, tuple.Item2);
				val.EmitDelegate<Func<float, T, int, float>>(record);
			}
		}

		public static void BuffDelta<TBody, TBuff>(ILContext il, Func<float, TBody, TBuff, float> delta)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il)
			{
				Index = DefensePatterns.BuffDelta((IList<Instruction>)il.Body.Instructions) + 1
			};
			val.Emit(OpCodes.Ldarg_0);
			val.Emit(OpCodes.Ldloc_1);
			val.EmitDelegate<Func<float, TBody, TBuff, float>>(delta);
		}

		public static void ShieldGate<T>(ILContext il, Func<bool, T, bool> gate, Func<bool, T, bool> forcedGate)
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: 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)
			int num = DefensePatterns.ShieldGate((IList<Instruction>)il.Body.Instructions);
			int item = ((IEnumerable<Instruction>)il.Body.Instructions).Select((Instruction instruction, int index) => (instruction: instruction, index: index)).Single(((Instruction instruction, int index) x) => DefensePatterns.Field(x.instruction, "isShieldRegenForced")).index;
			ILCursor val = new ILCursor(il)
			{
				Index = item + 1
			};
			val.Emit(OpCodes.Ldarg_0);
			val.EmitDelegate<Func<bool, T, bool>>(forcedGate);
			val.Index = num + 1;
			val.Emit(OpCodes.Ldarg_0);
			val.EmitDelegate<Func<bool, T, bool>>(gate);
		}

		public static void Raincoat<T>(ILContext il, Action<T> prevention)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il)
			{
				Index = DefensePatterns.RaincoatBarrier((IList<Instruction>)il.Body.Instructions) + 1
			};
			val.Emit(OpCodes.Ldarg_0);
			val.EmitDelegate<Action<T>>(prevention);
		}

		public static void Movement<T>(ILContext il, Func<float, T, float> bonus)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il)
			{
				Index = DefensePatterns.MovementBonus((IList<Instruction>)il.Body.Instructions) + 1
			};
			val.Emit(OpCodes.Ldarg_0);
			val.EmitDelegate<Func<float, T, float>>(bonus);
		}

		public static void Decay<T>(ILContext il, Func<float, T, float> decay)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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)
			if (((IEnumerable<Instruction>)il.Body.Instructions).Count((Instruction i) => i.OpCode == OpCodes.Ret) != 1 || !((IEnumerable<Instruction>)il.Body.Instructions).Any((Instruction i) => DefensePatterns.Call(i, "get_fullBarrier")))
			{
				throw new InvalidOperationException("Barrier decay method changed");
			}
			ILCursor val = new ILCursor(il);
			val.Goto(((IEnumerable<Instruction>)il.Body.Instructions).Last(), (MoveType)0, false);
			val.MoveAfterLabels();
			val.Emit(OpCodes.Ldarg_0);
			val.EmitDelegate<Func<float, T, float>>(decay);
		}

		public static void WakeSteal<TBody, TBuff>(ILContext il, Action<TBody, TBuff, float> grant)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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)
			ILCursor val = new ILCursor(il)
			{
				Index = DefensePatterns.WakeSteal((IList<Instruction>)il.Body.Instructions)
			};
			val.Remove();
			val.EmitDelegate<Action<TBody, TBuff, float>>(grant);
		}

		public static void WakeDamage<THealth, TInfo>(ILContext il, Func<float, THealth, TInfo, float> reduce)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il)
			{
				Index = DefensePatterns.WakeDamage((IList<Instruction>)il.Body.Instructions) + 1
			};
			val.Emit(OpCodes.Ldarg_0);
			val.Emit(OpCodes.Ldarg_1);
			val.EmitDelegate<Func<float, THealth, TInfo, float>>(reduce);
		}

		public static void DotDamage<TDot, TStack>(ILContext il, Func<float, TDot, TStack, float> reduce)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			int num = DefensePatterns.DotDamage((IList<Instruction>)il.Body.Instructions);
			DefensePatterns.DotTakeDamage((IList<Instruction>)il.Body.Instructions);
			ILCursor val = new ILCursor(il)
			{
				Index = num + 1
			};
			val.Emit(OpCodes.Ldarg_0);
			val.Emit(OpCodes.Ldloc_3);
			val.EmitDelegate<Func<float, TDot, TStack, float>>(reduce);
		}

		public static void DotMark<TInfo>(ILContext il, Func<TInfo, TInfo> mark)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			new ILCursor(il)
			{
				Index = DefensePatterns.DotTakeDamage((IList<Instruction>)il.Body.Instructions)
			}.EmitDelegate<Func<TInfo, TInfo>>(mark);
		}

		public static void DotAdded<TStack>(ILContext il, Action<TStack> add)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (!((IEnumerable<Instruction>)il.Body.Instructions).Any((Instruction i) => DefensePatterns.Field(i, "dotDef")))
			{
				throw new InvalidOperationException("DOT stack lifecycle changed");
			}
			ILCursor val = new ILCursor(il);
			val.Emit(OpCodes.Ldarg_1);
			val.EmitDelegate<Action<TStack>>(add);
		}
	}
	public static class DefenseRules
	{
		public static float ExtraShieldDelay(int stacks, float first, float additional)
		{
			if (stacks <= 0)
			{
				return 0f;
			}
			return first + additional * (float)(stacks - 1);
		}

		public static bool ShieldReady(bool native, int stacks, float stopwatch, float nativeDelay, float first, float additional)
		{
			if (stacks > 0)
			{
				if (native)
				{
					return stopwatch >= nativeDelay + ExtraShieldDelay(stacks, first, additional);
				}
				return false;
			}
			return native;
		}

		public static float RaincoatBonus(int stacks, bool buff, float bonus)
		{
			if (!(stacks > 0 && buff))
			{
				return 0f;
			}
			return bonus;
		}

		public static float BarrierMultiplier(float barrier, float capacity, float threshold, float minimum, int items)
		{
			if (items > 0 && !(capacity <= 0f) && !float.IsNaN(capacity) && !float.IsInfinity(capacity))
			{
				return Math.Min(1f, Math.Max(minimum, barrier / capacity / threshold));
			}
			return 1f;
		}

		public static bool WakeProtected(int items, bool matchingSource, bool stolenActive, bool activeSlotAspect, bool aspectBuffActive)
		{
			if (items > 0 && matchingSource)
			{
				if (!stolenActive)
				{
					return activeSlotAspect && aspectBuffActive;
				}
				return true;
			}
			return false;
		}

		public static float LeaseUntil(float previous, float now, float granted, float nativeRemaining)
		{
			return Math.Max(previous, now + Math.Min(granted, nativeRemaining));
		}

		public static float PausedDelta(float delta, float now, float pauseUntil)
		{
			return Math.Max(0f, Math.Min(delta, now - pauseUntil));
		}
	}
	public sealed class QuietPeriod
	{
		public float Until { get; private set; } = float.NegativeInfinity;

		public void ResourceWrite(float previous, float next, float now, float quiet)
		{
			if (next < previous)
			{
				Until = now + quiet;
			}
		}

		public float Delta(float delta, float now)
		{
			return DefenseRules.PausedDelta(delta, now, Until);
		}
	}
	public sealed class ShieldRechargeCue
	{
		public bool Pending { get; private set; }

		public bool Played { get; private set; }

		public void SuppressEarly()
		{
			if (!Played)
			{
				Pending = true;
			}
		}

		public void Reset()
		{
			Pending = false;
			Played = false;
		}

		public bool Start(bool alive, bool holder, float before, float after)
		{
			if (!alive || (!holder && !Pending) || Played || after <= before)
			{
				return false;
			}
			Played = true;
			Pending = false;
			return true;
		}
	}
	internal sealed class DefensiveFeature : IDisposable
	{
		private readonly Settings s;

		private readonly bool[] ready;

		private readonly BuffDef speed;

		private readonly ConditionalWeakTable<CharacterBody, QuietPeriod> quiet = new ConditionalWeakTable<CharacterBody, QuietPeriod>();

		private readonly ConditionalWeakTable<CharacterBody, ShieldRechargeCue> cues = new ConditionalWeakTable<CharacterBody, ShieldRechargeCue>();

		private readonly NetworkSoundEventDef shieldSound;

		private readonly NetworkSoundEventDef boosterSound;

		internal readonly WakeFeature Wake;

		private FieldInfo? dangerWatch;

		private static float Now => FixedTimeStamp.now.t;

		internal DefensiveFeature(Settings s, bool[] ready, BuffDef speed, NetworkSoundEventDef shieldSound, NetworkSoundEventDef boosterSound)
		{
			this.s = s;
			this.ready = ready;
			this.speed = speed;
			this.shieldSound = shieldSound;
			this.boosterSound = boosterSound;
			Wake = new WakeFeature(s, () => ready[13]);
		}

		internal uint EarlyShieldSound(string name, GameObject target)
		{
			CharacterBody val = (Object.op_Implicit((Object)(object)target) ? target.GetComponent<CharacterBody>() : null);
			if (!ready[10] || !Object.op_Implicit((Object)(object)val) || !val.healthComponent.alive || Count(val, Items.ShieldOnly) <= 0)
			{
				return Util.PlaySound(name, target);
			}
			if (NetworkServer.active)
			{
				cues.GetValue(val, (CharacterBody _) => new ShieldRechargeCue()).SuppressEarly();
			}
			return 0u;
		}

		internal float ShieldResource(float next, HealthComponent health, int kind)
		{
			float num = kind switch
			{
				1 => health.shield, 
				0 => health.health, 
				_ => health.barrier, 
			};
			if (ready[10] && NetworkServer.active && Object.op_Implicit((Object)(object)health.body) && next < num)
			{
				cues.Remove(health.body);
			}
			return next;
		}

		internal float ShieldRecharge(float next, HealthComponent health)
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			if (!ready[10] || !NetworkServer.active || !Object.op_Implicit((Object)(object)health.body))
			{
				return next;
			}
			CharacterBody body = health.body;
			bool flag = Count(body, Items.ShieldOnly) > 0;
			if (!cues.TryGetValue(body, out ShieldRechargeCue value))
			{
				if (!flag)
				{
					return next;
				}
				value = cues.GetValue(body, (CharacterBody _) => new ShieldRechargeCue());
			}
			if (value.Start(health.alive, flag, health.shield, next))
			{
				if (Count(body, Items.ShieldBooster) > 0)
				{
					EffectManager.SimpleSoundEffect(boosterSound.index, body.corePosition, true);
				}
				EffectManager.SimpleSoundEffect(shieldSound.index, body.corePosition, true);
			}
			return next;
		}

		private static int Count(CharacterBody body, ItemDef item)
		{
			if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.inventory))
			{
				return 0;
			}
			return body.inventory.GetItemCountEffective(item);
		}

		internal float Resource(float next, HealthComponent health, int kind)
		{
			if (ready[9] && NetworkServer.active && health.alive && Count(health.body, Items.BearVoid) > 0)
			{
				float num = kind switch
				{
					1 => health.shield, 
					0 => health.health, 
					_ => health.barrier, 
				};
				if (next < num)
				{
					quiet.GetValue(health.body, (CharacterBody _) => new QuietPeriod()).ResourceWrite(num, next, Now, s.SpacesPause);
				}
			}
			return next;
		}

		internal float BuffDelta(float native, CharacterBody body, TimedBuff buff)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (!ready[9] || buff.buffIndex != Buffs.BearVoidCooldown.buffIndex || !body.healthComponent.alive || Count(body, Items.BearVoid) <= 0)
			{
				return native;
			}
			if (!quiet.TryGetValue(body, out QuietPeriod value))
			{
				return native;
			}
			return value.Delta(native, Now);
		}

		internal void ValidateShield()
		{
			dangerWatch = typeof(CharacterBody).GetField("outOfDangerStopwatch", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? throw new MissingFieldException("CharacterBody.outOfDangerStopwatch");
			if (dangerWatch.FieldType != typeof(float))
			{
				throw new InvalidOperationException("Shield danger stopwatch changed");
			}
		}

		private float DangerTime(CharacterBody body)
		{
			return (float)dangerWatch.GetValue(body);
		}

		internal bool ShieldGate(bool native, HealthComponent health)
		{
			int num = Count(health.body, Items.ShieldOnly);
			if (ready[10] && num > 0)
			{
				return DefenseRules.ShieldReady(native, num, DangerTime(health.body), 7f, s.ShieldDelayFirst, s.ShieldDelayAdditional);
			}
			return native;
		}

		internal bool ForcedShieldGate(bool native, HealthComponent health)
		{
			int num = Count(health.body, Items.ShieldOnly);
			if (ready[10] && num > 0)
			{
				return DefenseRules.ShieldReady(native, num, DangerTime(health.body), 0f, s.ShieldDelayFirst, s.ShieldDelayAdditional);
			}
			return native;
		}

		internal void Prevention(CharacterBody body)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if (ready[11] && NetworkServer.active && body.healthComponent.alive && Count(body, Items.ImmuneToDebuff) > 0)
			{
				body.ClearTimedBuffs(speed.buffIndex);
				body.AddTimedBuff(speed, s.RaincoatSeconds);
			}
		}

		internal float Speed(float native, CharacterBody body)
		{
			if (!ready[11])
			{
				return native;
			}
			return native + DefenseRules.RaincoatBonus(Count(body, Items.ImmuneToDebuff), body.HasBuff(speed), s.RaincoatSpeed);
		}

		internal float Decay(float native, HealthComponent health)
		{
			if (!ready[12] || !NetworkServer.active)
			{
				return native;
			}
			return native * DefenseRules.BarrierMultiplier(health.barrier, health.fullBarrier, s.AegisThreshold, s.AegisMinimum, Count(health.body, Items.BarrierOnOverHeal));
		}

		internal void Enable()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			CharacterBody.onBodyInventoryChangedGlobal += Inventory;
			CharacterBody.onBodyDestroyGlobal += Destroyed;
			GlobalEventManager.OnCharacterDeath += new hook_OnCharacterDeath(Death);
			Wake.Enable();
		}

		private void Inventory(CharacterBody body)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			if (Count(body, Items.BearVoid) <= 0)
			{
				quiet.Remove(body);
			}
			if (NetworkServer.active && Object.op_Implicit((Object)(object)speed) && Count(body, Items.ImmuneToDebuff) <= 0 && body.HasBuff(speed))
			{
				body.ClearTimedBuffs(speed.buffIndex);
			}
			if (Count(body, Items.ShieldOnly) <= 0 && cues.TryGetValue(body, out ShieldRechargeCue value) && (!value.Pending || (Object.op_Implicit((Object)(object)body.healthComponent) && body.healthComponent.shield >= body.healthComponent.fullShield)))
			{
				cues.Remove(body);
			}
		}

		private void Destroyed(CharacterBody body)
		{
			quiet.Remove(body);
			cues.Remove(body);
			Wake.Cleanup(body);
		}

		private void Death(orig_OnCharacterDeath orig, GlobalEventManager manager, DamageReport report)
		{
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			Wake.SnapshotDeath(report.victimBody);
			orig.Invoke(manager, report);
			if (Object.op_Implicit((Object)(object)report.victimBody) && !report.victimBody.healthComponent.alive)
			{
				quiet.Remove(report.victimBody);
				Wake.Cleanup(report.victimBody);
				cues.Remove(report.victimBody);
				if (NetworkServer.active && Object.op_Implicit((Object)(object)speed) && report.victimBody.HasBuff(speed))
				{
					report.victimBody.ClearTimedBuffs(speed.buffIndex);
				}
			}
		}

		public void Dispose()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or m