Decompiled source of SwitchChaosAndGesture v1.2.0

SwitchChaosAndGesture.dll

Decompiled 2 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using EntityStates.GoldGat;
using HarmonyLib;
using IL.EntityStates.GoldGat;
using IL.RoR2;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using On.RoR2;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;
using UnityEngine.ResourceManagement.AsyncOperations;

[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("Chinchi")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Gesture of the Drowned and Bottled Chaos switch item tiers.")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0+4ccb549e24130d066b5eebbde7b3d5d70ace3f4a")]
[assembly: AssemblyProduct("SwitchChaosAndGesture")]
[assembly: AssemblyTitle("SwitchChaosAndGesture")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/schinchi/SwitchChaosAndGesture")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SwitchChaosAndGesture
{
	internal class Configs
	{
		internal static ConfigEntry<bool> IsGestureAllowed { get; private set; }

		internal static ConfigEntry<bool> IsGestureBlacklisted { get; private set; }

		internal static ConfigEntry<string> BannedAutocastEquipment { get; private set; }

		internal static ConfigEntry<float> GestureScaling { get; private set; }

		internal static ConfigEntry<float> ChaosCooldownPenalty { get; private set; }

		internal static void Init(ConfigFile config, string assemblyLocation)
		{
			float num = 0.15f;
			IsGestureAllowed = config.Bind<bool>("Gesture of the Drowned", "Include In Item Pool", true, "Allow Gesture of the Drowned to be in the item pool.");
			IsGestureBlacklisted = config.Bind<bool>("Gesture of the Drowned", "AI Blacklist", false, "Blacklist the item for enemies.");
			BannedAutocastEquipment = config.Bind<string>("Gesture of the Drowned", "Banned Equipment", "Recycle,GoldGat,BossHunter,FireBallDash", "Which equipment will not be autocast with Gesture. Run the 'equipment_list' command on the console for a list of all internal name options.");
			BannedAutocastEquipment.SettingChanged += ReloadBannedAutocastEquipment;
			GestureScaling = config.Bind<float>("Gesture of the Drowned", "Stack Scaling", num, "Modify the cooldown scaling for 1+ stacks.");
			if (GestureScaling.Value < 0f)
			{
				GestureScaling.Value = 0f;
				Log.Warning("The 'Stack Scaling' config setting has a negative value. Readjusting to 0.0");
			}
			else if (GestureScaling.Value > 1f)
			{
				GestureScaling.Value = num;
				Log.Warning($"The 'Stack Scaling' config setting has a value higher than 1.0. Readjusting to the default {num}");
			}
			ChaosCooldownPenalty = config.Bind<float>("Bottled Chaos", "Cooldown Penalty", 0.2f, "The percent of the activated equipment's cooldown that will be added on due to Bottled Chaos' effect.");
			if (ChaosCooldownPenalty.Value < 0f)
			{
				ChaosCooldownPenalty.Value = 0f;
				Log.Warning("The 'Cooldown Penalty' config setting has a negative value. Readjusting to 0.0");
			}
			if (Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"))
			{
				RiskOfOptionsInit(assemblyLocation);
			}
		}

		private static void ReloadBannedAutocastEquipment(object sender, EventArgs e)
		{
			Hooks.ReloadBlacklistedEquipment();
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private static void RiskOfOptionsInit(string assemblyLocation)
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Expected O, but got Unknown
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Expected O, but got Unknown
			//IL_00df: Expected O, but got Unknown
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected O, but got Unknown
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Expected O, but got Unknown
			//IL_00fe: Expected O, but got Unknown
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Expected O, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			FileInfo fileInfo = null;
			FileInfo[] files = new DirectoryInfo(Path.GetDirectoryName(assemblyLocation)).GetFiles("icon.png", SearchOption.TopDirectoryOnly);
			if (files != null && files.Length != 0)
			{
				fileInfo = files[0];
			}
			if (fileInfo != null)
			{
				string name = "SwitchChaosAndGestureIcon";
				Texture2D val = new Texture2D(256, 256);
				((Object)val).name = name;
				if (ImageConversion.LoadImage(val, File.ReadAllBytes(fileInfo.FullName)))
				{
					Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
					((Object)obj).name = name;
					ModSettingsManager.SetModIcon(obj, "Chinchi.SwitchChaosAndGesture", "SwitchChaosAndGesture");
				}
			}
			ModSettingsManager.AddOption((BaseOption)new StringInputFieldOption(BannedAutocastEquipment, new InputFieldConfig
			{
				submitOn = (SubmitEnum)6
			}));
			ConfigEntry<float> gestureScaling = GestureScaling;
			FloatFieldConfig val2 = new FloatFieldConfig();
			((NumericFieldConfig<float>)val2).Min = 0f;
			((NumericFieldConfig<float>)val2).Max = 1f;
			ModSettingsManager.AddOption((BaseOption)new FloatFieldOption(gestureScaling, val2));
			ConfigEntry<float> chaosCooldownPenalty = ChaosCooldownPenalty;
			FloatFieldConfig val3 = new FloatFieldConfig();
			((NumericFieldConfig<float>)val3).Min = 0f;
			ModSettingsManager.AddOption((BaseOption)new FloatFieldOption(chaosCooldownPenalty, val3));
		}
	}
	internal class Hooks
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_SetEquipmentDefs <0>__CollectGestureBlacklistedEquipment;

			public static Manipulator <1>__CheckEquipmentCanBeAutocast;

			public static Manipulator <2>__CheckCrowdfunderCanBeAutocast;

			public static hook_OnEnable <3>__AddMasterToDict;

			public static hook_OnDisable <4>__RemoveMasterFromDict;

			public static Manipulator <5>__InitialiseCooldownTrackingForNewSlots;

			public static Manipulator <6>__ApplyCooldownPenaltyOnChargeGain;

			public static Manipulator <7>__ModifyGestureCooldownScaling;

			public static Manipulator <8>__ApplyOrQueueCooldownPenaltyOnExecute;

			public static Action<Inventory> <9>__EnsureNoTrackedCooldownsWithoutChaos;

			public static Action<Run> <10>__ResetMasterDict;

			public static hook_GetLocalizedStringByToken <11>__FormatBottledChaosDesc;
		}

		private static bool popNextCooldown = false;

		private static readonly Dictionary<CharacterMaster, List<float>[]> masterCooldowns = new Dictionary<CharacterMaster, List<float>[]>();

		private static readonly HashSet<EquipmentIndex> bannedAutocastEquipment = new HashSet<EquipmentIndex>();

		public static void Init()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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_007b: Expected O, but got Unknown
			//IL_0090: 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_009b: Expected O, but got Unknown
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Expected O, but got Unknown
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Expected O, but got Unknown
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Expected O, but got Unknown
			object obj = <>O.<0>__CollectGestureBlacklistedEquipment;
			if (obj == null)
			{
				hook_SetEquipmentDefs val = CollectGestureBlacklistedEquipment;
				<>O.<0>__CollectGestureBlacklistedEquipment = val;
				obj = (object)val;
			}
			EquipmentCatalog.SetEquipmentDefs += (hook_SetEquipmentDefs)obj;
			object obj2 = <>O.<1>__CheckEquipmentCanBeAutocast;
			if (obj2 == null)
			{
				Manipulator val2 = CheckEquipmentCanBeAutocast;
				<>O.<1>__CheckEquipmentCanBeAutocast = val2;
				obj2 = (object)val2;
			}
			EquipmentSlot.MyFixedUpdate += (Manipulator)obj2;
			object obj3 = <>O.<2>__CheckCrowdfunderCanBeAutocast;
			if (obj3 == null)
			{
				Manipulator val3 = CheckCrowdfunderCanBeAutocast;
				<>O.<2>__CheckCrowdfunderCanBeAutocast = val3;
				obj3 = (object)val3;
			}
			BaseGoldGatState.FixedUpdate += (Manipulator)obj3;
			object obj4 = <>O.<3>__AddMasterToDict;
			if (obj4 == null)
			{
				hook_OnEnable val4 = AddMasterToDict;
				<>O.<3>__AddMasterToDict = val4;
				obj4 = (object)val4;
			}
			CharacterMaster.OnEnable += (hook_OnEnable)obj4;
			object obj5 = <>O.<4>__RemoveMasterFromDict;
			if (obj5 == null)
			{
				hook_OnDisable val5 = RemoveMasterFromDict;
				<>O.<4>__RemoveMasterFromDict = val5;
				obj5 = (object)val5;
			}
			CharacterMaster.OnDisable += (hook_OnDisable)obj5;
			object obj6 = <>O.<5>__InitialiseCooldownTrackingForNewSlots;
			if (obj6 == null)
			{
				Manipulator val6 = InitialiseCooldownTrackingForNewSlots;
				<>O.<5>__InitialiseCooldownTrackingForNewSlots = val6;
				obj6 = (object)val6;
			}
			Inventory.SetEquipmentInternal += (Manipulator)obj6;
			object obj7 = <>O.<6>__ApplyCooldownPenaltyOnChargeGain;
			if (obj7 == null)
			{
				Manipulator val7 = ApplyCooldownPenaltyOnChargeGain;
				<>O.<6>__ApplyCooldownPenaltyOnChargeGain = val7;
				obj7 = (object)val7;
			}
			Inventory.UpdateEquipment += (Manipulator)obj7;
			object obj8 = <>O.<7>__ModifyGestureCooldownScaling;
			if (obj8 == null)
			{
				Manipulator val8 = ModifyGestureCooldownScaling;
				<>O.<7>__ModifyGestureCooldownScaling = val8;
				obj8 = (object)val8;
			}
			Inventory.CalculateEquipmentCooldownScale += (Manipulator)obj8;
			object obj9 = <>O.<8>__ApplyOrQueueCooldownPenaltyOnExecute;
			if (obj9 == null)
			{
				Manipulator val9 = ApplyOrQueueCooldownPenaltyOnExecute;
				<>O.<8>__ApplyOrQueueCooldownPenaltyOnExecute = val9;
				obj9 = (object)val9;
			}
			EquipmentSlot.OnEquipmentExecuted += (Manipulator)obj9;
			Inventory.onInventoryChangedGlobal += EnsureNoTrackedCooldownsWithoutChaos;
			Run.onRunDestroyGlobal += ResetMasterDict;
			object obj10 = <>O.<11>__FormatBottledChaosDesc;
			if (obj10 == null)
			{
				hook_GetLocalizedStringByToken val10 = FormatBottledChaosDesc;
				<>O.<11>__FormatBottledChaosDesc = val10;
				obj10 = (object)val10;
			}
			Language.GetLocalizedStringByToken += (hook_GetLocalizedStringByToken)obj10;
		}

		private static void CollectGestureBlacklistedEquipment(orig_SetEquipmentDefs orig, EquipmentDef[] newEquipmentDefs)
		{
			orig.Invoke(newEquipmentDefs);
			ReloadBlacklistedEquipment();
		}

		internal static void ReloadBlacklistedEquipment()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			bannedAutocastEquipment.Clear();
			string[] array = Configs.BannedAutocastEquipment.Value.Split(',');
			foreach (string text in array)
			{
				bannedAutocastEquipment.Add(EquipmentCatalog.FindEquipmentIndex(text.Trim()));
			}
			bannedAutocastEquipment.Remove((EquipmentIndex)(-1));
		}

		private static void CheckEquipmentCanBeAutocast(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, typeof(Items), "AutoCastEquipment"),
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Inventory>(x, "GetItemCount")
			}))
			{
				Log.PatchFail(il);
				return;
			}
			val.Emit(OpCodes.Ldarg_0);
			val.EmitDelegate<Func<int, EquipmentSlot, int>>((Func<int, EquipmentSlot, int>)((int canAutocast, EquipmentSlot equipmentSlot) => (!bannedAutocastEquipment.Contains(equipmentSlot.equipmentIndex)) ? canAutocast : 0));
		}

		private static void CheckCrowdfunderCanBeAutocast(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			ILLabel val2 = default(ILLabel);
			if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[5]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Inventory>(x, "GetItemCount"),
				(Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, 0),
				(Instruction x) => ILPatternMatchingExt.MatchBle(x, ref val2),
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0),
				(Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, 1)
			}))
			{
				Log.PatchFail(il);
				return;
			}
			val.Emit(OpCodes.Ldarg_0);
			val.EmitDelegate<Func<bool, BaseGoldGatState, bool>>((Func<bool, BaseGoldGatState, bool>)((bool autocast, BaseGoldGatState state) => state.shouldFire || (autocast && !bannedAutocastEquipment.Contains(Equipment.GoldGat.equipmentIndex))));
		}

		private static void AddMasterToDict(orig_OnEnable orig, CharacterMaster self)
		{
			orig.Invoke(self);
			if (NetworkServer.active && !masterCooldowns.ContainsKey(self))
			{
				masterCooldowns[self] = Array.Empty<List<float>>();
			}
		}

		private static void RemoveMasterFromDict(orig_OnDisable orig, CharacterMaster self)
		{
			orig.Invoke(self);
			if (NetworkServer.active && masterCooldowns.ContainsKey(self))
			{
				masterCooldowns.Remove(self);
			}
		}

		private static void InitialiseCooldownTrackingForNewSlots(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[4]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<Inventory>(x, "equipmentStateSlots"),
				(Instruction x) => ILPatternMatchingExt.MatchLdlen(x),
				(Instruction x) => ILPatternMatchingExt.MatchConvI4(x)
			}))
			{
				Log.PatchFail(il);
				return;
			}
			val.Emit(OpCodes.Ldarg_0);
			val.Emit(OpCodes.Ldarg_2);
			val.EmitDelegate<Func<int, Inventory, uint, int>>((Func<int, Inventory, uint, int>)delegate(int num, Inventory inventory, uint slot)
			{
				if (NetworkServer.active)
				{
					CharacterMaster component = ((Component)inventory).GetComponent<CharacterMaster>();
					if ((Object)(object)component != (Object)null && masterCooldowns.TryGetValue(component, out var value) && value.Length <= slot)
					{
						Array.Resize(ref value, (int)(slot + 1));
						for (int i = num; i < value.Length; i++)
						{
							value[i] = new List<float>();
						}
						masterCooldowns[component] = value;
					}
				}
				return num;
			});
		}

		private static void ApplyCooldownPenaltyOnChargeGain(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<EquipmentState>(x, "equipmentDef"),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<EquipmentDef>(x, "cooldown")
			}))
			{
				Log.PatchFail(il);
				return;
			}
			val.Emit(OpCodes.Ldarg_0);
			val.Emit(OpCodes.Ldloc_1);
			val.Emit(OpCodes.Ldloc_2);
			val.EmitDelegate<Func<float, Inventory, uint, byte, float>>((Func<float, Inventory, uint, byte, float>)delegate(float equipmentCooldown, Inventory inventory, uint maxCharges, byte slot)
			{
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				CharacterMaster component = ((Component)inventory).GetComponent<CharacterMaster>();
				if ((Object)(object)component != (Object)null && masterCooldowns.TryGetValue(component, out var value))
				{
					if (value.Length <= slot)
					{
						Log.Warning("Inventory.UpdateEquipment cooldown array not resized properly.");
						return equipmentCooldown;
					}
					List<float> list = value[slot];
					if (list.Count > 0 && popNextCooldown)
					{
						EquipmentState val2 = inventory.equipmentStateSlots[slot];
						if (val2.charges + 1 < maxCharges || ((FixedTimeStamp)(ref val2.chargeFinishTime)).isPositiveInfinity)
						{
							float num = list[0];
							list.RemoveAt(0);
							return equipmentCooldown + num * Configs.ChaosCooldownPenalty.Value;
						}
					}
				}
				return equipmentCooldown;
			});
		}

		private static void ModifyGestureCooldownScaling(ILContext il)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			ILCursor val = new ILCursor(il);
			int gestureStacksVar = -1;
			float num2 = default(float);
			float num = default(float);
			if (!val.TryGotoNext(new Func<Instruction, bool>[3]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, typeof(Items), "AutoCastEquipment"),
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Inventory>(x, "GetItemCount"),
				(Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref gestureStacksVar)
			}) || !val.TryGotoNext(new Func<Instruction, bool>[3]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, ref num2),
				(Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, ref num),
				(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, gestureStacksVar)
			}))
			{
				Log.PatchFail(il);
				return;
			}
			val.Index += 2;
			val.EmitDelegate<Func<float, float>>((Func<float, float>)((float scaling) => 1f - Configs.GestureScaling.Value));
		}

		private static void ApplyOrQueueCooldownPenaltyOnExecute(ILContext il)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			Inventory inventory = null;
			CharacterMaster master = null;
			byte slot = 0;
			bool addCooldownNow = false;
			ILCursor val = new ILCursor(il);
			if (!val.TryGotoNext(new Func<Instruction, bool>[2]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0),
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)AccessTools.PropertyGetter(typeof(EquipmentSlot), "equipmentIndex"))
			}))
			{
				Log.PatchFail(((MemberReference)il.Method).Name + " #1");
				return;
			}
			val.Index += 1;
			val.EmitDelegate<Func<EquipmentSlot, EquipmentSlot>>((Func<EquipmentSlot, EquipmentSlot>)delegate(EquipmentSlot equipmentSlot)
			{
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				popNextCooldown = false;
				inventory = equipmentSlot.inventory;
				master = ((Component)inventory).GetComponent<CharacterMaster>();
				slot = inventory.activeEquipmentSlot;
				EquipmentState val2 = inventory.equipmentStateSlots[slot];
				bool flag = inventory.GetItemCount(Items.RandomEquipmentTrigger) > 0;
				if (flag)
				{
					masterCooldowns[master][slot].Add(0f);
				}
				addCooldownNow = ((FixedTimeStamp)(ref val2.chargeFinishTime)).isPositiveInfinity && flag;
				return equipmentSlot;
			});
			if (!val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<EquipmentSlot>(x, "PerformEquipmentAction")
			}))
			{
				Log.PatchFail(((MemberReference)il.Method).Name + " #2");
				return;
			}
			val.Index += 3;
			val.EmitDelegate<Func<EquipmentIndex, EquipmentIndex>>((Func<EquipmentIndex, EquipmentIndex>)delegate(EquipmentIndex equipmentIndex)
			{
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				List<float> list = masterCooldowns[master][slot];
				if (list.Count == 0)
				{
					Log.Error("EquipmentSlot.OnEquipmentExecuted: Empty cooldown queue");
				}
				else
				{
					list[list.Count - 1] += EquipmentCatalog.GetEquipmentDef(equipmentIndex).cooldown;
				}
				return equipmentIndex;
			});
			if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, typeof(EffectManager), "SpawnEffect")
			}))
			{
				Log.PatchFail(((MemberReference)il.Method).Name + " #3");
				return;
			}
			val.EmitDelegate<Action>((Action)delegate
			{
				//IL_0069: Unknown result type (might be due to invalid IL or missing references)
				//IL_006e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_0076: Unknown result type (might be due to invalid IL or missing references)
				//IL_007b: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0082: Unknown result type (might be due to invalid IL or missing references)
				//IL_0087: Unknown result type (might be due to invalid IL or missing references)
				//IL_008e: Unknown result type (might be due to invalid IL or missing references)
				if (addCooldownNow)
				{
					float num = masterCooldowns[master][slot][0] * inventory.CalculateEquipmentCooldownScale() * Configs.ChaosCooldownPenalty.Value;
					masterCooldowns[master][slot].RemoveAt(0);
					EquipmentState equipment = inventory.GetEquipment((uint)slot);
					inventory.SetEquipment(new EquipmentState(equipment.equipmentIndex, equipment.chargeFinishTime + num, equipment.charges, false), (uint)slot);
				}
				popNextCooldown = true;
			});
		}

		private static void EnsureNoTrackedCooldownsWithoutChaos(Inventory inventory)
		{
			if (!NetworkServer.active || inventory.GetItemCount(Items.RandomEquipmentTrigger) > 0)
			{
				return;
			}
			CharacterMaster component = ((Component)inventory).GetComponent<CharacterMaster>();
			if (Object.op_Implicit((Object)(object)component) && masterCooldowns.TryGetValue(component, out var value))
			{
				List<float>[] array = value;
				for (int i = 0; i < array.Length; i++)
				{
					array[i].Clear();
				}
			}
		}

		private static void ResetMasterDict(Run obj)
		{
			masterCooldowns.Clear();
		}

		private static string FormatBottledChaosDesc(orig_GetLocalizedStringByToken orig, Language self, string token)
		{
			string text = orig.Invoke(self, token);
			if (token == "ITEM_RANDOMEQUIPMENTTRIGGER_DESC")
			{
				text = string.Format(text, Configs.ChaosCooldownPenalty.Value * 100f);
			}
			return text;
		}
	}
	internal static class Log
	{
		private static ManualLogSource _logger;

		internal static void Init(ManualLogSource logger)
		{
			_logger = logger;
		}

		internal static void Info(object data)
		{
			_logger.LogInfo(data);
		}

		internal static void Debug(object data)
		{
			_logger.LogDebug(data);
		}

		internal static void Message(object data)
		{
			_logger.LogMessage(data);
		}

		internal static void Warning(object data)
		{
			_logger.LogWarning(data);
		}

		internal static void Error(object data)
		{
			_logger.LogError(data);
		}

		internal static void Fatal(object data)
		{
			_logger.LogFatal(data);
		}

		internal static void PatchFail(string message)
		{
			_logger.LogError((object)("Failed to patch " + message));
		}

		internal static void PatchFail(ILContext il)
		{
			PatchFail(((MemberReference)il.Method).Name);
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Chinchi.SwitchChaosAndGesture", "SwitchChaosAndGesture", "1.2.0")]
	public class SwitchChaosAndGesture : BaseUnityPlugin
	{
		public const string PluginGUID = "Chinchi.SwitchChaosAndGesture";

		public const string PluginAuthor = "Chinchi";

		public const string PluginName = "SwitchChaosAndGesture";

		public const string PluginVersion = "1.2.0";

		internal const string RiskOfOptionsGUID = "com.rune580.riskofoptions";

		private static AssetBundle assetBundle;

		public void Awake()
		{
			Log.Init(((BaseUnityPlugin)this).Logger);
			Configs.Init(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Info.Location);
			LoadBundle(((BaseUnityPlugin)this).Info.Location);
			ModifyItems();
			Hooks.Init();
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(ApplyModelChanges));
		}

		private void LoadBundle(string directory)
		{
			string text = "assetdata.bundle";
			assetBundle = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(directory), text));
			if ((Object)(object)assetBundle == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Failed to load '" + text + "'"));
			}
		}

		private static void ModifyItems()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			AsyncOperationHandle<ItemDef> val = Addressables.LoadAssetAsync<ItemDef>((object)"RoR2/Base/AutoCastEquipment/AutoCastEquipment.asset");
			val.Completed += Modify;
			val = Addressables.LoadAssetAsync<ItemDef>((object)"RoR2/DLC1/RandomEquipmentTrigger/RandomEquipmentTrigger.asset");
			val.Completed += Modify;
			static void Modify(AsyncOperationHandle<ItemDef> handle)
			{
				ItemDef result = handle.Result;
				if (((Object)result).name == "RandomEquipmentTrigger")
				{
					UpdateItemDef(result, (ItemTier)3, "texBottledChaosIcon", isDroppable: true);
				}
				else if (((Object)result).name == "AutoCastEquipment")
				{
					UpdateItemDef(result, (ItemTier)2, "texFossilIcon", Configs.IsGestureAllowed.Value);
					ModifyItemTag(result, (ItemTag)4, Configs.IsGestureBlacklisted.Value);
				}
			}
		}

		private static void UpdateItemDef(ItemDef itemDef, ItemTier tier, string sprite, bool isDroppable)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			itemDef.deprecatedTier = tier;
			AssetBundle val = assetBundle;
			if (Object.op_Implicit((Object)(object)val))
			{
				itemDef.pickupIconSprite = val.LoadAsset<Sprite>(sprite);
			}
			ModifyItemTag(itemDef, (ItemTag)9, !isDroppable);
		}

		private static void ModifyItemTag(ItemDef itemDef, ItemTag tag, bool include)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (!include)
			{
				if (itemDef.tags.Contains(tag))
				{
					List<ItemTag> list = itemDef.tags.ToList();
					list.Remove(tag);
					itemDef.tags = list.ToArray();
				}
			}
			else if (!itemDef.tags.Contains(tag))
			{
				List<ItemTag> list2 = itemDef.tags.ToList();
				list2.Add(tag);
				itemDef.tags = list2.ToArray();
			}
		}

		private void ApplyModelChanges()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			AsyncOperationHandle<Material> val = Addressables.LoadAssetAsync<Material>((object)"RoR2/DLC1/RandomEquipmentTrigger/matBottledChaos.mat");
			val.Completed += delegate(AsyncOperationHandle<Material> material)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_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)
				AsyncOperationHandle<Texture2D> val3 = Addressables.LoadAssetAsync<Texture2D>((object)"RoR2/Base/Common/ColorRamps/texLunarWispTracer 1.png");
				val3.Completed += delegate(AsyncOperationHandle<Texture2D> texture)
				{
					material.Result.mainTexture = (Texture)(object)texture.Result;
				};
			};
			AsyncOperationHandle<GameObject> val2 = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/DLC1/RandomEquipmentTrigger/RandomEquipmentTriggerProcEffect.prefab");
			val2.Completed += delegate(AsyncOperationHandle<GameObject> effect)
			{
				SetMaterial(((Component)effect.Result.transform.Find("Vase")).gameObject, "RoR2/Base/LunarWisp/matLunarWispStones.mat", 0);
				SetMaterial(((Component)effect.Result.transform.Find("Trails")).gameObject, "RoR2/Base/LunarWisp/matLunarWispMinigunTracer.mat", 1);
			};
		}

		private void SetMaterial(GameObject go, string material, int index)
		{
			//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)
			AsyncOperationHandle<Material> val = Addressables.LoadAssetAsync<Material>((object)material);
			val.Completed += delegate(AsyncOperationHandle<Material> obj)
			{
				ParticleSystemRenderer component = go.GetComponent<ParticleSystemRenderer>();
				Material[] sharedMaterials = ((Renderer)component).sharedMaterials;
				sharedMaterials[index] = obj.Result;
				((Renderer)component).sharedMaterials = sharedMaterials;
			};
		}
	}
}