Decompiled source of ItemStatistics v1.2.1

patchers/ItemStatisticsPatcher.dll

Decompiled 2 days 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 BepInEx;
using BepInEx.Logging;
using Mono.Cecil;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyVersion("1.2.0.0")]
public static class ItemStatisticsPatcher
{
	private static ManualLogSource _log;

	private static ManualLogSource log
	{
		get
		{
			if (_log == null)
			{
				_log = Logger.CreateLogSource("ItemStatisticsPatcher");
			}
			return _log;
		}
	}

	public static IEnumerable<string> TargetDLLs => new string[1] { "RoR2.dll" };

	public static void Patch(AssemblyDefinition assembly)
	{
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Expected O, but got Unknown
		ModuleDefinition mainModule = assembly.MainModule;
		string[] files = Directory.GetFiles(Paths.PluginPath, "ItemStatistics.dll", SearchOption.AllDirectories);
		if (files.Length == 0)
		{
			log.LogFatal((object)"Failed to find ItemStatistics.dll");
			return;
		}
		AssemblyDefinition val = AssemblyDefinition.ReadAssembly(files[0]);
		TypeReference fieldType = mainModule.ImportReference((TypeReference)(object)val.MainModule.GetType("ItemStatistics.Components.TrackedInventory"));
		TypeReference val2 = mainModule.ImportReference((TypeReference)(object)val.MainModule.GetType("ItemStatistics.ProcChain"));
		GenericInstanceType val3 = new GenericInstanceType(mainModule.ImportReference(typeof(List<>)));
		val3.GenericArguments.Add(val2);
		TypeReference fieldType2 = mainModule.ImportReference((TypeReference)(object)val.MainModule.GetType("ItemStatistics.Index"));
		ModuleDefinition mainModule2 = AssemblyDefinition.ReadAssembly(Path.Combine(Paths.ManagedPath, "UnityEngine.CoreModule.dll")).MainModule;
		TypeReference fieldType3 = mainModule.ImportReference((TypeReference)(object)mainModule2.GetType("UnityEngine.GameObject"));
		AddField(mainModule.GetType("RoR2.CharacterMaster"), fieldType, "trackedInventory");
		AddField(mainModule.GetType("RoR2.DotController/DotStack"), val2, "dotStackChain");
		AddField(mainModule.GetType("RoR2.DotController/PendingDamage"), (TypeReference)(object)val3, "pendingDotChainList");
		AddField(mainModule.GetType("RoR2.Orbs.GenericDamageOrb"), fieldType3, "inflictor");
		AddField(mainModule.GetType("RoR2.Orbs.DevilOrb"), fieldType3, "inflictor");
		AddField(mainModule.GetType("RoR2.Orbs.BounceOrb"), fieldType3, "inflictor");
		AddField(mainModule.GetType("RoR2.Orbs.LunarDetonatorOrb"), fieldType3, "inflictor");
		AddField(mainModule.GetType("RoR2.Orbs.HealOrb"), fieldType2, "inflictor");
		AddField(mainModule.GetType("EntityStates.FrozenState"), fieldType2, "freezeInflictor");
		AddField(mainModule.GetType("EntityStates.FrozenState"), (TypeReference)(object)mainModule.GetType("RoR2.CharacterMaster"), "freezeInflictorMaster");
		AddField(mainModule.GetType("RoR2.Orbs.VineOrb/SplitDebuffInformation"), val2, "procChain");
	}

	private static FieldDefinition AddField(TypeDefinition target, TypeReference fieldType, string fieldName)
	{
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Expected O, but got Unknown
		if (target == null || fieldType == null)
		{
			log.LogError((object)("Null types in AddField: " + fieldName));
			return null;
		}
		if (((IEnumerable<FieldDefinition>)target.Fields).FirstOrDefault((Func<FieldDefinition, bool>)((FieldDefinition a) => ((MemberReference)a).Name == fieldName)) != null)
		{
			log.LogWarning((object)(((MemberReference)target).Name + "." + fieldName + " already exists"));
			return null;
		}
		FieldDefinition val = new FieldDefinition(fieldName, (FieldAttributes)6, fieldType);
		target.Fields.Add(val);
		return val;
	}
}

plugins/ItemStatistics.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Dolso;
using EntityStates;
using EntityStates.CaptainDefenseMatrixItem;
using EntityStates.GlobalSkills.LunarDetonator;
using EntityStates.GummyClone;
using EntityStates.Headstompers;
using EntityStates.Toolbot;
using HG;
using HG.GeneralSerializer;
using HG.Reflection;
using ItemStatistics;
using ItemStatistics.Components;
using ItemStatistics.Hooks;
using ItemStatistics.Networking;
using ItemStatistics.Trackers;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using MonoMod.Utils;
using Rewired.Integration.UnityUI;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.Items;
using RoR2.Networking;
using RoR2.Orbs;
using RoR2.Projectile;
using RoR2.Skills;
using RoR2.Stats;
using RoR2.UI;
using TMPro;
using Unity;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.EventSystems;
using UnityEngine.Networking;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.UI;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: CompilationRelaxations(8)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: OptIn]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.1.0")]
[module: UnverifiableCode]
namespace Dolso
{
	internal static class log
	{
		private static ManualLogSource logger;

		internal static void start(ManualLogSource logSource)
		{
			logger = logSource;
		}

		internal static void start(string name)
		{
			logger = Logger.CreateLogSource(name);
		}

		internal static void info(object data)
		{
			logger.LogInfo(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 LogError(this ILCursor c, object data)
		{
			logger.LogError((object)string.Format($"ILCursor failure, skipping: {data}\n{c}"));
		}

		internal static void LogErrorCaller(this ILCursor c, object data)
		{
			logger.LogError((object)string.Format($"ILCursor failed in {new StackFrame(1).GetMethod().Name}, skipping: {data}\n{c}"));
		}
	}
	internal static class HookManager
	{
		internal delegate bool ConfigEnabled<T>(T configValue);

		internal const BindingFlags allFlags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		private static readonly ConfigEnabled<bool> boolConfigEnabled = (bool configValue) => configValue;

		private static ILHookConfig ilHookConfig = new ILHookConfig
		{
			ManualApply = true
		};

		private static HookConfig onHookConfig = new HookConfig
		{
			ManualApply = true
		};

		internal static void Hook(Type typeFrom, string methodFrom, Manipulator ilHook)
		{
			HookInternal(GetMethod(typeFrom, methodFrom), ilHook);
		}

		internal static void Hook(MethodBase methodFrom, Manipulator ilHook)
		{
			HookInternal(methodFrom, ilHook);
		}

		internal static void Hook(Delegate from, Manipulator ilHook)
		{
			HookInternal(from.Method, ilHook);
		}

		internal static void Hook(Type typeFrom, string methodFrom, Delegate onHook)
		{
			HookInternal(GetMethod(typeFrom, methodFrom), onHook.Method, onHook.Target);
		}

		internal static void Hook(MethodBase methodFrom, MethodInfo onHook)
		{
			HookInternal(methodFrom, onHook, null);
		}

		internal static void Hook(MethodBase methodFrom, Delegate onHook)
		{
			HookInternal(methodFrom, onHook.Method, onHook.Target);
		}

		internal static void Hook(Delegate from, Delegate onHook)
		{
			HookInternal(from.Method, onHook.Method, onHook.Target);
		}

		internal static void Hook(Type typeFrom, string methodFrom, Delegate onHook, object instance)
		{
			HookInternal(GetMethod(typeFrom, methodFrom), onHook.Method, instance);
		}

		internal static void Hook(MethodBase methodFrom, MethodInfo onHook, object target)
		{
			HookInternal(methodFrom, onHook, target);
		}

		private static void HookInternal(MethodBase methodFrom, Manipulator ilHook)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if (methodFrom == null)
			{
				log.error("null methodFrom for hook: " + ((Delegate)(object)ilHook).Method.Name);
				return;
			}
			try
			{
				new ILHook(methodFrom, ilHook, ref ilHookConfig).Apply();
			}
			catch (Exception ex)
			{
				log.error($"Failed to apply ILHook: {methodFrom.DeclaringType}::{methodFrom.Name} - {((Delegate)(object)ilHook).Method.Name}\n{ex}");
			}
		}

		private static void HookInternal(MethodBase methodFrom, MethodInfo onHook, object target)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (methodFrom == null)
			{
				log.error("null methodFrom for hook: " + onHook.Name);
				return;
			}
			try
			{
				new Hook(methodFrom, onHook, target, ref onHookConfig).Apply();
			}
			catch (Exception ex)
			{
				log.error($"Failed to apply Hook: {methodFrom.DeclaringType}::{methodFrom.Name} - {onHook.Name}\n{ex}");
			}
		}

		internal static void HookConfig(this ConfigEntry<bool> configEntry, Type typeFrom, string methodFrom, Manipulator ilHook)
		{
			configEntry.HookConfigInternal(boolConfigEnabled, GetMethod(typeFrom, methodFrom), (Delegate)(object)ilHook);
		}

		internal static void HookConfig(this ConfigEntry<bool> configEntry, MethodBase methodFrom, Manipulator ilHook)
		{
			configEntry.HookConfigInternal(boolConfigEnabled, methodFrom, (Delegate)(object)ilHook);
		}

		internal static void HookConfig(this ConfigEntry<bool> configEntry, Type typeFrom, string methodFrom, Delegate onHook)
		{
			configEntry.HookConfigInternal(boolConfigEnabled, GetMethod(typeFrom, methodFrom), onHook);
		}

		internal static void HookConfig(this ConfigEntry<bool> configEntry, MethodBase methodFrom, Delegate onHook)
		{
			configEntry.HookConfigInternal(boolConfigEnabled, methodFrom, onHook);
		}

		internal static void HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, Type typeFrom, string methodFrom, Manipulator ilHook)
		{
			configEntry.HookConfigInternal(enabled, GetMethod(typeFrom, methodFrom), (Delegate)(object)ilHook);
		}

		internal static void HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, MethodBase methodFrom, Manipulator ilHook)
		{
			configEntry.HookConfigInternal(enabled, methodFrom, (Delegate)(object)ilHook);
		}

		internal static void HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, Type typeFrom, string methodFrom, Delegate onHook)
		{
			configEntry.HookConfigInternal(enabled, GetMethod(typeFrom, methodFrom), onHook);
		}

		internal static void HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, MethodBase methodFrom, Delegate onHook)
		{
			configEntry.HookConfigInternal(enabled, methodFrom, onHook);
		}

		private static void HookConfigInternal<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, MethodBase methodFrom, Delegate hook)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			try
			{
				IDetour detour = ManualDetour(methodFrom, hook);
				EventHandler eventHandler = delegate(object sender, EventArgs _)
				{
					UpdateHook(detour, enabled((sender as ConfigEntry<T>).Value));
				};
				configEntry.SettingChanged += eventHandler;
				eventHandler(configEntry, (EventArgs)new SettingChangedEventArgs((ConfigEntryBase)(object)configEntry));
			}
			catch (Exception ex)
			{
				log.error($"Failed to do config hook {methodFrom.DeclaringType}::{methodFrom.Name} - {hook.Method.Name}\n{ex}");
			}
		}

		private static void UpdateHook(IDetour hook, bool enabled)
		{
			if (enabled)
			{
				if (!hook.IsApplied)
				{
					hook.Apply();
				}
			}
			else if (hook.IsApplied)
			{
				hook.Undo();
			}
		}

		internal static IDetour ManualDetour(Type typeFrom, string methodFrom, Delegate hook)
		{
			return ManualDetour(GetMethod(typeFrom, methodFrom), hook);
		}

		internal static IDetour ManualDetour(MethodBase methodFrom, Delegate hook)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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
			if (methodFrom == null)
			{
				log.error("null methodFrom for detour: " + hook.Method.Name);
			}
			else
			{
				try
				{
					Manipulator val = (Manipulator)(object)((hook is Manipulator) ? hook : null);
					if (val != null)
					{
						return (IDetour)new ILHook(methodFrom, val, ref ilHookConfig);
					}
					return (IDetour)new Hook(methodFrom, hook, ref onHookConfig);
				}
				catch (Exception ex)
				{
					log.error($"Failed to create detour {methodFrom.DeclaringType}::{methodFrom} - {hook.Method.Name}\n{ex}");
				}
			}
			return null;
		}

		internal static MethodInfo GetMethod(Type typeFrom, string methodName)
		{
			if (typeFrom == null || methodName == null)
			{
				log.error($"Null argument in GetMethod: type={typeFrom}, name={methodName}");
				return null;
			}
			MethodInfo[] array = (from predicate in typeFrom.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
				where predicate.Name == methodName
				select predicate).ToArray();
			switch (array.Length)
			{
			case 1:
				return array[0];
			case 0:
				log.error($"Failed to find method: {typeFrom}::{methodName}");
				return null;
			default:
			{
				log.error($"{array.Length} ambiguous matches found for: {typeFrom}::{methodName}");
				MethodInfo[] array2 = array;
				for (int i = 0; i < array2.Length; i++)
				{
					log.error(array2[i]);
				}
				return null;
			}
			}
		}

		internal static MethodInfo GetMethod(Type typeFrom, string methodName, params Type[] parameters)
		{
			if (typeFrom == null || methodName == null)
			{
				log.error($"Null argument in GetMethod: type={typeFrom}, name={methodName}");
				return null;
			}
			MethodInfo? method = typeFrom.GetMethod(methodName, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, parameters, null);
			if (method == null)
			{
				log.error($"Failed to find method: {typeFrom}::{methodName}_{parameters.Length}");
			}
			return method;
		}

		internal static void SetPriority(string[] before = null, string[] after = null)
		{
			ilHookConfig.Before = before;
			onHookConfig.Before = before;
			ilHookConfig.After = after;
			onHookConfig.After = after;
		}
	}
	internal static class Utilities
	{
		private static GameObject _prefabParent;

		internal static GameObject CreatePrefab(GameObject gameObject, string name = null)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)_prefabParent))
			{
				_prefabParent = new GameObject("DolsoPrefabs");
				Object.DontDestroyOnLoad((Object)(object)_prefabParent);
				((Object)_prefabParent).hideFlags = (HideFlags)61;
				_prefabParent.SetActive(false);
			}
			GameObject val = Object.Instantiate<GameObject>(gameObject, _prefabParent.transform);
			if (name != null)
			{
				((Object)val).name = name;
			}
			return val;
		}

		internal static Task<Obj> GetAddressableAsync<Obj>(string addressable) where Obj : Object
		{
			//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)
			return Addressables.LoadAssetAsync<Obj>((object)addressable).Task;
		}

		internal static Task<GameObject> GetAddressableAsync(string addressable)
		{
			//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)
			return Addressables.LoadAssetAsync<GameObject>((object)addressable).Task;
		}

		internal static void DoAddressable<Obj>(string addressable, Action<Obj> callback) where Obj : Object
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			AsyncOperationHandle<Obj> val = Addressables.LoadAssetAsync<Obj>((object)addressable);
			val.Completed += delegate(AsyncOperationHandle<Obj> a)
			{
				callback(a.Result);
			};
		}

		internal static void DoAddressable(string addressable, Action<GameObject> callback)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			AsyncOperationHandle<GameObject> val = Addressables.LoadAssetAsync<GameObject>((object)addressable);
			val.Completed += delegate(AsyncOperationHandle<GameObject> a)
			{
				callback(a.Result);
			};
		}

		internal static void AddressableAddComp<Comp>(string addressable) where Comp : Component
		{
			//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)
			AsyncOperationHandle<GameObject> val = Addressables.LoadAssetAsync<GameObject>((object)addressable);
			val.Completed += delegate(AsyncOperationHandle<GameObject> a)
			{
				a.Result.AddComponent<Comp>();
			};
		}

		internal static void AddressableAddComp<Comp>(string addressable, Action<Comp> callback) where Comp : Component
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			AsyncOperationHandle<GameObject> val = Addressables.LoadAssetAsync<GameObject>((object)addressable);
			val.Completed += delegate(AsyncOperationHandle<GameObject> a)
			{
				callback(a.Result.AddComponent<Comp>());
			};
		}

		internal static void AddressableAddCompSingle<Comp>(string addressable) where Comp : Component
		{
			//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)
			AsyncOperationHandle<GameObject> val = Addressables.LoadAssetAsync<GameObject>((object)addressable);
			val.Completed += delegate(AsyncOperationHandle<GameObject> a)
			{
				if (!Object.op_Implicit((Object)(object)a.Result.GetComponent<Comp>()))
				{
					a.Result.AddComponent<Comp>();
				}
			};
		}

		internal static void ModifyStateConfig(this EntityStateConfiguration stateConfig, string fieldName, object newValue)
		{
			SerializedField[] serializedFields = stateConfig.serializedFieldsCollection.serializedFields;
			for (int i = 0; i < serializedFields.Length; i++)
			{
				if (serializedFields[i].fieldName == fieldName)
				{
					Object val = (Object)((newValue is Object) ? newValue : null);
					if (val != null)
					{
						serializedFields[i].fieldValue.objectValue = val;
					}
					else if (newValue != null && StringSerializer.CanSerializeType(newValue.GetType()))
					{
						serializedFields[i].fieldValue.stringValue = StringSerializer.Serialize(newValue.GetType(), newValue);
					}
					else
					{
						log.error("Invalid value for SerializedField: " + newValue);
					}
					return;
				}
			}
			log.error("Failed to find " + fieldName + " for " + ((Object)stateConfig).name);
		}

		internal static bool IsKeyDown(this ConfigEntry<KeyboardShortcut> key, bool onlyPressed)
		{
			//IL_0004: 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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value;
			if (onlyPressed)
			{
				value = key.Value;
				if (!Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey))
				{
					goto IL_0030;
				}
			}
			if (!onlyPressed)
			{
				value = key.Value;
				if (!Input.GetKey(((KeyboardShortcut)(ref value)).MainKey))
				{
					goto IL_0030;
				}
			}
			value = key.Value;
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers)
			{
				if (!Input.GetKey(modifier))
				{
					return false;
				}
			}
			return true;
			IL_0030:
			return false;
		}
	}
	internal static class RiskofOptions
	{
		internal const string rooGuid = "com.rune580.riskofoptions";

		internal static bool enabled => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions");

		internal static void SetSprite(Sprite sprite)
		{
			ModSettingsManager.SetModIcon(sprite);
		}

		internal static void SetSpriteDefaultIcon()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_005b: 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)
			try
			{
				string fullName = new DirectoryInfo(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)).FullName;
				Texture2D val = new Texture2D(256, 256);
				if (ImageConversion.LoadImage(val, File.ReadAllBytes(Path.Combine(fullName, "icon.png"))))
				{
					ModSettingsManager.SetModIcon(Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)));
				}
				else
				{
					log.error("Failed to load icon.png");
				}
			}
			catch (Exception ex)
			{
				log.error("Failed to load icon.png\n" + ex);
			}
		}

		internal static void AddOption<T>(ConfigEntry<T> entry)
		{
			AddOption<T>(entry, "", "", restartRequired: false);
		}

		internal static void AddOption<T>(ConfigEntry<T> entry, string categoryName = "", string name = "", bool restartRequired = false)
		{
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Expected O, but got Unknown
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Expected O, but got Unknown
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Expected O, but got Unknown
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Expected O, but got Unknown
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Expected O, but got Unknown
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Expected O, but got Unknown
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Expected O, but got Unknown
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected O, but got Unknown
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			object obj;
			if (!(typeof(T) == typeof(float)))
			{
				obj = ((!(typeof(T) == typeof(string))) ? ((!(typeof(T) == typeof(bool))) ? ((!(typeof(T) == typeof(int))) ? ((!(typeof(T) == typeof(Color))) ? ((!(typeof(T) == typeof(KeyboardShortcut))) ? ((object)((!typeof(T).IsEnum) ? ((ChoiceOption)null) : new ChoiceOption((ConfigEntryBase)(object)entry, new ChoiceConfig()))) : ((object)new KeyBindOption(entry as ConfigEntry<KeyboardShortcut>, new KeyBindConfig()))) : ((object)new ColorOption(entry as ConfigEntry<Color>, new ColorOptionConfig()))) : ((object)new IntFieldOption(entry as ConfigEntry<int>, new IntFieldConfig()))) : ((object)new CheckBoxOption(entry as ConfigEntry<bool>, new CheckBoxConfig()))) : ((object)new StringInputFieldOption(entry as ConfigEntry<string>, new InputFieldConfig
				{
					submitOn = (SubmitEnum)6,
					lineType = (LineType)0
				})));
			}
			else
			{
				ConfigEntry<float> obj2 = entry as ConfigEntry<float>;
				FloatFieldConfig val = new FloatFieldConfig();
				((NumericFieldConfig<float>)val).FormatString = "{0:f2}";
				((BaseOptionConfig)val).description = ((ConfigEntryBase)(object)entry).DescWithDefault("{0:f2}");
				obj = (object)new FloatFieldOption(obj2, val);
			}
			BaseOption val2 = (BaseOption)obj;
			if (val2 != null)
			{
				BaseOptionConfig config = val2.GetConfig();
				config.category = categoryName;
				config.name = name;
				config.restartRequired = restartRequired;
				if (config.description == "")
				{
					config.description = ((ConfigEntryBase)(object)entry).DescWithDefault();
				}
				ModSettingsManager.AddOption(val2);
			}
		}

		internal static void AddOption(ConfigEntry<float> entry, float min, float max, string format = "{0:f2}")
		{
			AddFloatSlider(entry, min, max, format);
		}

		internal static void AddFloatSlider(ConfigEntry<float> entry, float min, float max, string format = "{0:f2}", string categoryName = "")
		{
			//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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_0035: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new SliderOption(entry, new SliderConfig
			{
				min = min,
				max = max,
				FormatString = format,
				category = categoryName,
				description = ((ConfigEntryBase)(object)entry).DescWithDefault(format)
			}));
		}

		internal static void AddIntSlider(ConfigEntry<int> entry, int min, int max, string categoryName = "")
		{
			//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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new IntSliderOption(entry, new IntSliderConfig
			{
				min = min,
				max = max,
				category = categoryName,
				description = ((ConfigEntryBase)(object)entry).DescWithDefault()
			}));
		}

		private static string DescWithDefault(this ConfigEntryBase entry)
		{
			return $"{entry.Description.Description}\n[Default: {entry.DefaultValue}]";
		}

		private static string DescWithDefault(this ConfigEntryBase entry, string format)
		{
			return string.Format("{1}\n[Default: " + format + "]", entry.DefaultValue, entry.Description.Description);
		}
	}
}
namespace ItemStatistics
{
	public readonly struct ChainContext : IDisposable
	{
		private readonly ProcChain prevProcChain;

		private static readonly List<ChainContext> chains;

		public static ConstructorInfo constructor0 => typeof(ChainContext).GetConstructor(Type.EmptyTypes);

		public static ConstructorInfo constructor1 => typeof(ChainContext).GetConstructor(new Type[1] { typeof(ProcChain) });

		public ChainContext(ProcChain procChain)
		{
			prevProcChain = CurrentContext.procChain;
			chains.Add(this);
			CurrentContext.procChain = procChain;
		}

		public ChainContext()
			: this(null)
		{
		}

		public void Dispose()
		{
			CurrentContext.procChain = prevProcChain;
			chains.RemoveAt(chains.Count - 1);
		}

		static ChainContext()
		{
			chains = new List<ChainContext>();
			Stage.onStageStartGlobal += SafetyCheck;
		}

		private static void SafetyCheck(Stage stage)
		{
			if (chains.Count != 0)
			{
				log.error("ChainContext has leaked chains: " + string.Join(", ", chains));
				chains.Clear();
			}
		}

		public override string ToString()
		{
			if (prevProcChain != null)
			{
				return prevProcChain.ToString();
			}
			return "null chain";
		}
	}
	internal static class Config
	{
		internal enum ResetMode
		{
			Never,
			WhenNotInInventory,
			EveryPickup
		}

		private static ConfigFile configFile;

		internal static ConfigEntry<ResetMode> resetOnStackChanged;

		internal static ConfigEntry<KeyboardShortcut> resetSpamKey;

		internal static void DoConfig(ConfigFile bepConfigFile)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			configFile = bepConfigFile;
			resetOnStackChanged = configFile.Bind<ResetMode>(string.Empty, "Reset on Stack Changed", ResetMode.Never, "When item stack changes, should its stats automatically be reset? Can right click on item to force a reset. Warning: having this enabled will cause stats to be reset during Mithrix's item steal phase");
			resetSpamKey = configFile.Bind<KeyboardShortcut>(string.Empty, "Reset Spam Key", new KeyboardShortcut((KeyCode)306, Array.Empty<KeyCode>()), "Hold this key down to easily reset icons you hover over");
			if (Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"))
			{
				DoRiskOfOptions();
			}
		}

		internal static void DoRiskOfOptions()
		{
			RiskofOptions.SetSpriteDefaultIcon();
			RiskofOptions.AddOption<ResetMode>(resetOnStackChanged);
			RiskofOptions.AddOption<KeyboardShortcut>(resetSpamKey);
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void ReloadConfig(ConCommandArgs args)
		{
			configFile.Reload();
			Debug.Log((object)"ItemStatistics config reloaded");
		}
	}
	public static class CurrentContext
	{
		public static TrackedInventory attackerTrackedInventory;

		public static Inventory attackerInventory;

		public static TrackedInventory victimTrackedInventory;

		public static Inventory victimInventory;

		public static ProcChain procChain;

		private static (DamageInfo, ProcChain) cachedInfoChain;

		internal static ProcChain FindProcChain(DamageInfo damageInfo)
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			if (damageInfo == cachedInfoChain.Item1)
			{
				return cachedInfoChain.Item2;
			}
			ProcComponent procComponent = default(ProcComponent);
			if (Object.op_Implicit((Object)(object)damageInfo.inflictor) && damageInfo.inflictor.TryGetComponent<ProcComponent>(ref procComponent))
			{
				cachedInfoChain = (damageInfo, procComponent.procChain);
				return cachedInfoChain.Item2;
			}
			if (((DamageTypeCombo)(ref damageInfo.damageType)).IsDamageSourceSkillBased && (!Object.op_Implicit((Object)(object)damageInfo.attacker) || !Object.op_Implicit((Object)(object)damageInfo.attacker.GetComponent<MinionComponent>())))
			{
				cachedInfoChain = (damageInfo, SkillChainFromCombo(damageInfo.damageType));
				return cachedInfoChain.Item2;
			}
			cachedInfoChain = (damageInfo, null);
			return null;
		}

		internal static ProcChain SkillChainFromCombo(DamageTypeCombo damageType)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			Index index = damageType.damageSource;
			if (index.isNotNone)
			{
				return ProcChain.TryGetCachedSkillChain(index);
			}
			return null;
		}
	}
	public readonly struct HitContext : IDisposable
	{
		private readonly ProcChain prevProcChain;

		private readonly TrackedInventory prevAttackerTrackedInventory;

		private readonly Inventory prevAttackerInventory;

		private readonly TrackedInventory prevVictimTrackedInventory;

		private readonly Inventory prevVictimInventory;

		private static readonly List<HitContext> hits;

		public HitContext(ProcChain procChain, TrackedInventory attackerTrackedInventory, Inventory attackerInventory, TrackedInventory victimTrackedInventory, Inventory victimInventory)
		{
			prevProcChain = CurrentContext.procChain;
			prevAttackerTrackedInventory = CurrentContext.attackerTrackedInventory;
			prevAttackerInventory = CurrentContext.attackerInventory;
			prevVictimTrackedInventory = CurrentContext.victimTrackedInventory;
			prevVictimInventory = CurrentContext.victimInventory;
			hits.Add(this);
			CurrentContext.procChain = procChain;
			CurrentContext.attackerTrackedInventory = attackerTrackedInventory;
			CurrentContext.attackerInventory = attackerInventory;
			CurrentContext.victimTrackedInventory = victimTrackedInventory;
			CurrentContext.victimInventory = victimInventory;
		}

		public HitContext()
			: this(null, null, null, null, null)
		{
		}

		public void Dispose()
		{
			CurrentContext.procChain = prevProcChain;
			CurrentContext.attackerTrackedInventory = prevAttackerTrackedInventory;
			CurrentContext.attackerInventory = prevAttackerInventory;
			CurrentContext.victimTrackedInventory = prevVictimTrackedInventory;
			CurrentContext.victimInventory = prevVictimInventory;
			hits.RemoveAt(hits.Count - 1);
		}

		static HitContext()
		{
			hits = new List<HitContext>();
			Stage.onStageStartGlobal += SafetyCheck;
		}

		private static void SafetyCheck(Stage stage)
		{
			if (hits.Count != 0)
			{
				log.error("HitContext has leaked hits: " + string.Join(",\n", hits));
				hits.Clear();
			}
		}

		public override string ToString()
		{
			return string.Join(", ", prevProcChain, prevAttackerTrackedInventory, prevAttackerInventory, prevVictimTrackedInventory, prevVictimInventory);
		}
	}
	[Serializable]
	public struct Index : IEquatable<Index>
	{
		[SerializeField]
		private int _value;

		public readonly IndexType type => (IndexType)(_value >> 16);

		public readonly int index => (short)_value;

		public readonly bool isNotNone => _value != 0;

		public Index(ItemIndex index)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected I4, but got Unknown
			_value = (index & 0xFFFF) + 65536;
		}

		public Index(EquipmentIndex index)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected I4, but got Unknown
			_value = (index & 0xFFFF) + 131072;
		}

		public Index(SkillSlot index)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected I4, but got Unknown
			_value = (index & 0xFFFF) + 196608;
		}

		public Index(MiscIndex index)
		{
			_value = (int)((index & (MiscIndex)65535) + 262144);
		}

		public Index(short type, short index)
		{
			_value = (index & 0xFFFF) + (type << 16);
		}

		public static implicit operator Index(ItemIndex index)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return new Index(index);
		}

		public static implicit operator Index(ItemDef itemDef)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return new Index(itemDef.itemIndex);
		}

		public static implicit operator Index(EquipmentIndex index)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return new Index(index);
		}

		public static implicit operator Index(EquipmentDef equipDef)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return new Index(equipDef.equipmentIndex);
		}

		public static implicit operator Index(SkillSlot index)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return new Index(index);
		}

		public static implicit operator Index(MiscIndex index)
		{
			return new Index(index);
		}

		public static implicit operator Index(DamageSource damageSource)
		{
			//IL_0000: 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)
			//IL_002c: Expected I4, but got Unknown
			switch (damageSource - 1)
			{
			case 0:
				return new Index((SkillSlot)0);
			case 1:
			case 2:
				return new Index((SkillSlot)1);
			case 3:
			case 4:
				return new Index((SkillSlot)2);
			case 7:
			case 8:
				return new Index((SkillSlot)3);
			default:
				return new Index(0, 0);
			}
		}

		public static bool operator ==(Index a, Index b)
		{
			return a._value == b._value;
		}

		public static bool operator !=(Index a, Index b)
		{
			return a._value != b._value;
		}

		public override readonly bool Equals(object obj)
		{
			if (obj is Index)
			{
				return _value == ((Index)obj)._value;
			}
			return false;
		}

		public readonly bool Equals(Index index)
		{
			return _value == index._value;
		}

		public override readonly int GetHashCode()
		{
			return _value;
		}

		public override readonly string ToString()
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			switch (type)
			{
			case IndexType.None:
				return "None" + ((index == 0) ? "" : ("." + index));
			case IndexType.Item:
				return Language.GetString(ItemCatalog.GetItemDef((ItemIndex)index).nameToken);
			case IndexType.Equip:
				return Language.GetString(EquipmentCatalog.GetEquipmentDef((EquipmentIndex)index).nameToken);
			case IndexType.SkillSlot:
			{
				SkillSlot val = (SkillSlot)(sbyte)index;
				return "Skill." + ((object)(SkillSlot)(ref val)).ToString();
			}
			case IndexType.Misc:
				return "Misc." + (MiscIndex)index;
			default:
				return $"Unknown Index {type}.{index}";
			}
		}

		internal static void Serialize(NetworkWriter writer, Index value)
		{
			writer.WritePackedUInt32((uint)value._value);
		}

		internal static Index Deserialize(NetworkReader reader)
		{
			Index result = default(Index);
			result._value = (int)reader.ReadPackedUInt32();
			return result;
		}

		static Index()
		{
			//IL_0011: 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_002a: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			StringSerializer.serializationHandlers[typeof(Index)] = new SerializationHandler
			{
				serializer = new SerializerDelegate(SerializeToString),
				deserializer = new DeserializerDelegate(DeserializeFromString)
			};
		}

		private static string SerializeToString(object obj)
		{
			Index index = (Index)obj;
			return $"{((int)index.type).ToString(CultureInfo.InvariantCulture)} {index.index.ToString(CultureInfo.InvariantCulture)}";
		}

		private static object DeserializeFromString(string str)
		{
			string[] array = StringSerializer.SplitToComponents(str, typeof(Index), 2);
			return new Index(short.Parse(array[0], CultureInfo.InvariantCulture), short.Parse(array[1], CultureInfo.InvariantCulture));
		}
	}
	public enum IndexType
	{
		None,
		Item,
		Equip,
		SkillSlot,
		Misc
	}
	public enum MiscIndex
	{
		NeverInInventory = -1,
		Ignore,
		Regen,
		Barrier,
		MinionDamage
	}
	public static class ItemStatisticsAPI
	{
		public static void AddTrackerToPrefab(GameObject prefab, Index indexToCredit)
		{
			prefab.AddComponent<ProcComponent>().index = indexToCredit;
		}

		public static void AddMinionTrackerToPrefab(GameObject prefab, Index indexToCredit)
		{
			prefab.AddComponent<MinionComponent>().index = indexToCredit;
		}

		public static void AddTrackedIndex(Index indexToAdd, TrackedDef trackedDef)
		{
			if (trackedDef != null)
			{
				ItemStatisticsPlugin.indexToDef.Add(indexToAdd, trackedDef);
			}
			else
			{
				log.error($"Attempted to give {indexToAdd} a null tracker type");
			}
		}

		public static TrackedInventory GetTrackedInventory(CharacterMaster master, bool includeFromMinion)
		{
			return TrackedInventory.GetTrackedInventory(master, includeFromMinion);
		}

		public static bool TryGetTrackedInventory(CharacterMaster master, bool includeFromMinion, out TrackedInventory trackedInventory)
		{
			return TrackedInventory.TryGetTrackedInventory(master, includeFromMinion, out trackedInventory);
		}

		public static GameObject CreateNewInflictor(Index index, ProcChain parentChain = null)
		{
			return ProcComponent.CreateInflictor(index, parentChain);
		}

		public static void CreditNextHeal(Index indexToCredit)
		{
			HCHeal.healIndex = indexToCredit;
		}

		public static void CreditDamage(TrackedInventory trackedInventory, Index index, float damage)
		{
			trackedInventory.AddDamage(index, damage);
		}

		public static void CreditGold(TrackedInventory trackedInventory, Index index, float gold)
		{
			trackedInventory.AddGold(index, gold);
		}

		public static void CreditProcAttempt(TrackedInventory trackedInventory, Index index)
		{
			trackedInventory.AddAttempt(index);
		}

		public static void CreditProcSuccess(TrackedInventory trackedInventory, Index index)
		{
			trackedInventory.AddSuccess(index);
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("dolso.ItemStatistics", "ItemStatistics", "1.2.1")]
	public class ItemStatisticsPlugin : BaseUnityPlugin
	{
		public const string ModGuid = "dolso.ItemStatistics";

		public const string Version = "1.2.1";

		internal static readonly Dictionary<Index, TrackedDef> indexToDef = new Dictionary<Index, TrackedDef>();

		internal static GameObject missileLauncher;

		internal static GameObject hhOverloading;

		internal static GameObject hhFireTrail;

		internal static GameObject hhGoldOuter;

		internal static GameObject hhGoldInner;

		internal static GameObject hhBead;

		internal static int crocoDiseaseProjectileIndex;

		internal static BodyIndex falseSonCharacterBodyIndex;

		private void Awake()
		{
			log.start(((BaseUnityPlugin)this).Logger);
			Config.DoConfig(((BaseUnityPlugin)this).Config);
			ModifyAddressablesAsync();
			Stopwatch stopwatch = Stopwatch.StartNew();
			GeneralHooks.Apply();
			HCDamage.Apply();
			HCHeal.Apply();
			GEMHooks.Apply();
			ItemHooks.Apply();
			OrbHooks.Apply();
			DotTracking.Apply();
			EquipmentHooks.Apply();
			SurvivorHooks.Apply();
			NetworkHooks.Apply();
			FreezeHooks.Apply();
			Language.collectLanguageRootFolders += CollectLanguageRootFolders;
			log.info($"Hooks completed in {stopwatch.Elapsed.TotalSeconds:f2}s");
		}

		private static void ModifyAddressablesAsync()
		{
			try
			{
				Utilities.AddressableAddComp<IconBehaviour>("RoR2/Base/UI/ItemIcon.prefab", (Action<IconBehaviour>)delegate(IconBehaviour a)
				{
					a.type = IndexType.Item;
				});
				Utilities.AddressableAddComp<IconBehaviour>("RoR2/Base/UI/ItemIconScoreboard_InGame.prefab", (Action<IconBehaviour>)delegate(IconBehaviour a)
				{
					a.type = IndexType.Item;
				});
				Utilities.AddressableAddComp<TrackedInventory>("RoR2/Base/Core/PlayerMaster.prefab", (Action<TrackedInventory>)delegate(TrackedInventory a)
				{
					((Component)a).GetComponent<CharacterMaster>().trackedInventory = a;
				});
				Utilities.DoAddressable("RoR2/Base/UI/HUDSimple.prefab", delegate(GameObject hudsimple)
				{
					EquipmentIcon[] componentsInChildren = hudsimple.GetComponentsInChildren<EquipmentIcon>();
					for (int i = 0; i < componentsInChildren.Length; i++)
					{
						((Component)componentsInChildren[i]).gameObject.AddComponent<IconBehaviour>().type = IndexType.Equip;
					}
					SkillIcon[] componentsInChildren2 = hudsimple.GetComponentsInChildren<SkillIcon>();
					for (int i = 0; i < componentsInChildren2.Length; i++)
					{
						((Component)componentsInChildren2[i]).gameObject.AddComponent<IconBehaviour>().type = IndexType.SkillSlot;
					}
				});
				Utilities.DoAddressable("RoR2/Base/UI/ScoreboardStrip.prefab", delegate(GameObject scoreboardStrip)
				{
					((Component)scoreboardStrip.GetComponentInChildren<EquipmentIcon>()).gameObject.AddComponent<IconBehaviour>().type = IndexType.Equip;
					PlayerTooltip.CreateTooltipPrefab(scoreboardStrip);
				});
				ToolbotStance.DoSetup();
			}
			catch (Exception ex)
			{
				log.error("Failed to do addressables\n" + ex);
			}
		}

		[SystemInitializer(new Type[]
		{
			typeof(PickupCatalog),
			typeof(SurvivorCatalog),
			typeof(ProjectileCatalog)
		})]
		private static void Init()
		{
			//IL_0b89: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b8e: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<Index, TrackedDef> dictionary = indexToDef;
			dictionary.Add((SkillSlot)0, TrackedDef.Skill);
			dictionary.Add((SkillSlot)1, TrackedDef.Skill);
			dictionary.Add((SkillSlot)2, TrackedDef.Skill);
			dictionary.Add((SkillSlot)3, TrackedDef.Skill);
			dictionary.Add(MiscIndex.Regen, new TrackedDef(typeof(HealTracker), TrackedDef.regenPortionTooltip));
			dictionary.Add(MiscIndex.Barrier, new TrackedDef(typeof(ArmorTracker), TrackedDef.barrierBlockedTooltip));
			dictionary.Add(MiscIndex.MinionDamage, new TrackedDef(typeof(DamageTracker), TrackedDef.minionPortionTooltip));
			dictionary.Add(Items.Bear, TrackedDef.ArmorCount);
			dictionary.Add(Items.BearVoid, TrackedDef.ArmorCount);
			dictionary.Add(Items.Crowbar, TrackedDef.Damage);
			dictionary.Add(Items.ExplodeOnDeathVoid, TrackedDef.Damage);
			dictionary.Add(Items.NearbyDamageBonus, TrackedDef.Damage);
			dictionary.Add(Items.FragileDamageBonus, TrackedDef.Damage);
			dictionary.Add(Items.FragileDamageBonusConsumed, new TrackedDef(typeof(WatchTracker), TrackedDef.damageTooltip));
			dictionary.Add(Items.BossDamageBonus, TrackedDef.Damage);
			dictionary.Add(Items.CritGlasses, new TrackedDef(typeof(DamageTracker), TrackedDef.totalCritTooltip));
			dictionary.Add(Items.CritDamage, TrackedDef.Damage);
			dictionary.Add(Items.DeathMark, TrackedDef.Damage);
			dictionary.Add(Items.CritGlassesVoid, TrackedDef.DamageChance);
			dictionary.Add(Items.ExecuteLowHealthElite, TrackedDef.Damage);
			dictionary.Add(Items.OutOfCombatArmor, TrackedDef.ArmorCount);
			dictionary.Add(Items.SprintArmor, TrackedDef.Armor);
			dictionary.Add(Items.ArmorPlate, TrackedDef.Armor);
			dictionary.Add(Items.ParentEgg, TrackedDef.Heal);
			dictionary.Add(Items.GoldOnHit, TrackedDef.Gold);
			dictionary.Add(Items.GoldOnHurt, TrackedDef.Gold);
			dictionary.Add(Items.Thorns, TrackedDef.Damage);
			dictionary.Add(Items.Seed, TrackedDef.Heal);
			dictionary.Add(Items.BleedOnHit, TrackedDef.DamageChance);
			dictionary.Add(Items.BleedOnHitVoid, TrackedDef.DamageChance);
			dictionary.Add(Items.SlowOnHitVoid, TrackedDef.Chance);
			dictionary.Add(Items.Missile, TrackedDef.DamageChance);
			dictionary.Add(Items.MissileVoid, TrackedDef.DamageChance);
			dictionary.Add(Items.ChainLightning, TrackedDef.DamageChance);
			dictionary.Add(Items.ChainLightningVoid, TrackedDef.DamageChance);
			dictionary.Add(Items.BounceNearby, TrackedDef.DamageChance);
			dictionary.Add(Items.StickyBomb, TrackedDef.DamageChance);
			dictionary.Add(Items.IceRing, TrackedDef.Damage);
			dictionary.Add(Items.FireRing, TrackedDef.Damage);
			dictionary.Add(Items.ElementalRingVoid, TrackedDef.Damage);
			dictionary.Add(Items.FireballsOnHit, TrackedDef.DamageChance);
			dictionary.Add(Items.LightningStrikeOnHit, TrackedDef.DamageChance);
			dictionary.Add(Items.HealOnCrit, TrackedDef.Heal);
			dictionary.Add(Items.Behemoth, TrackedDef.Damage);
			dictionary.Add(Items.IgniteOnKill, TrackedDef.DamageChance);
			dictionary.Add(Items.ExplodeOnDeath, TrackedDef.DamageChance);
			dictionary.Add(Items.Dagger, TrackedDef.Damage);
			dictionary.Add(Items.Tooth, TrackedDef.Heal);
			dictionary.Add(Items.Bandolier, TrackedDef.Chance);
			dictionary.Add(Items.BonusGoldPackOnKill, TrackedDef.Gold);
			dictionary.Add(Items.BleedOnHitAndExplode, new TrackedDef(typeof(DamageChanceTracker), TrackedDef.hit_damageTooltip));
			dictionary.Add(Items.BarrierOnKill, new TrackedDef(typeof(HealTracker), TrackedDef.barrierGainedTooltip));
			dictionary.Add(Items.Plant, TrackedDef.Heal);
			dictionary.Add(Items.Mushroom, TrackedDef.Heal);
			dictionary.Add(Items.MushroomVoid, TrackedDef.Heal);
			dictionary.Add(Items.Medkit, TrackedDef.Heal);
			dictionary.Add(Items.TPHealingNova, TrackedDef.Heal);
			dictionary.Add(Items.HealingPotionConsumed, TrackedDef.Heal);
			dictionary.Add(Items.BarrierOnOverHeal, new TrackedDef(typeof(HealTracker), TrackedDef.barrierGainedTooltip));
			dictionary.Add(Items.ShockNearby, TrackedDef.DamagePortion);
			dictionary.Add(Items.PrimarySkillShuriken, new TrackedDef(typeof(DamageChanceTracker), TrackedDef.hit_damageTooltip));
			dictionary.Add(Items.StrengthenBurn, TrackedDef.Damage);
			dictionary.Add(Items.LaserTurbine, TrackedDef.Damage);
			dictionary.Add(Items.CaptainDefenseMatrix, TrackedDef.Count);
			dictionary.Add(Items.Icicle, TrackedDef.Damage);
			dictionary.Add(Items.NovaOnLowHealth, TrackedDef.DamagePortion);
			dictionary.Add(Items.ImmuneToDebuff, new TrackedDef(typeof(HealChanceTracker), TrackedDef.chance_barrierTooltip));
			dictionary.Add(Items.NovaOnHeal, TrackedDef.Damage);
			dictionary.Add(Items.SprintWisp, TrackedDef.DamagePortion);
			dictionary.Add(Items.RandomlyLunar, TrackedDef.Chance);
			dictionary.Add(Items.Firework, TrackedDef.Damage);
			dictionary.Add(Items.Phasing, TrackedDef.Count);
			dictionary.Add(Items.FallBoots, TrackedDef.DamagePortion);
			dictionary.Add(Items.SiphonOnLowHealth, TrackedDef.Heal);
			dictionary.Add(Items.LunarSun, TrackedDef.DamagePortion);
			dictionary.Add(Items.Infusion, TrackedDef.Count);
			dictionary.Add(Items.HeadHunter, TrackedDef.Damage);
			dictionary.Add(Items.RoboBallBuddy, TrackedDef.Damage);
			dictionary.Add(Items.VoidMegaCrabItem, TrackedDef.Damage);
			dictionary.Add(Items.BeetleGland, TrackedDef.Damage);
			dictionary.Add(Items.DroneWeapons, TrackedDef.Damage);
			dictionary.Add(Items.GhostOnKill, TrackedDef.Damage);
			dictionary.Add(Items.MinorConstructOnKill, TrackedDef.Damage);
			dictionary.Add(Items.Squid, TrackedDef.Damage);
			dictionary.Add(Items.TitanGoldDuringTP, TrackedDef.Damage);
			dictionary.Add(Items.ExtraShrineItem, TrackedDef.Chance);
			dictionary.Add(Items.IncreasePrimaryDamage, TrackedDef.Damage);
			dictionary.Add(Items.MeteorAttackOnHighDamage, TrackedDef.DamageChance);
			dictionary.Add(Items.KnockBackHitEnemies, TrackedDef.Damage);
			dictionary.Add(Items.StunAndPierce, TrackedDef.DamageChance);
			dictionary.Add(Items.LowerPricedChests, TrackedDef.Count);
			dictionary.Add(Items.LowerPricedChestsConsumed, TrackedDef.Count);
			dictionary.Add(Items.ResetChests, TrackedDef.Chance);
			dictionary.Add(Items.GoldOnStageStart, TrackedDef.Damage);
			dictionary.Add(Items.TeleportOnLowHealth, TrackedDef.Damage);
			dictionary.Add(Items.TriggerEnemyDebuffs, TrackedDef.Damage);
			dictionary.Add(Items.WardOnLevel, TrackedDef.StackCombat);
			dictionary.Add(Items.WarCryOnMultiKill, TrackedDef.StackCombat);
			dictionary.Add(Items.EnergizedOnEquipmentUse, TrackedDef.StackCombat);
			dictionary.Add(Items.KillEliteFrenzy, TrackedDef.StackCombat);
			dictionary.Add(Items.MoveSpeedOnKill, TrackedDef.StackCombat);
			dictionary.Add(Items.SpeedBoostPickup, TrackedDef.StackCombat);
			dictionary.Add(Items.BoostAllStats, TrackedDef.StackCombat);
			dictionary.Add(Items.SprintBonus, TrackedDef.Stack);
			dictionary.Add(Items.SprintOutOfCombat, TrackedDef.Stack);
			dictionary.Add(Items.ArmorReductionOnHit, TrackedDef.StackHit);
			dictionary.Add(Items.PermanentDebuffOnHit, TrackedDef.StackHit);
			dictionary.Add(Items.RandomDamageZone, TrackedDef.StackHit);
			dictionary.Add(Items.IncreaseDamageOnMultiKill, TrackedDef.StackHit);
			dictionary.Add(Items.LowerHealthHigherDamage, new TrackedDef(typeof(ChanceTracker), TrackedDef.stackHitSkillTooltip));
			dictionary.Add(Equipment.Saw, TrackedDef.DamagePortion);
			dictionary.Add(Equipment.GoldGat, TrackedDef.Damage);
			dictionary.Add(Equipment.BFG, TrackedDef.Damage);
			dictionary.Add(Equipment.PassiveHealing, TrackedDef.Heal);
			dictionary.Add(Equipment.CommandMissile, TrackedDef.Damage);
			dictionary.Add(Equipment.Fruit, TrackedDef.Heal);
			dictionary.Add(Equipment.DroneBackup, TrackedDef.Damage);
			dictionary.Add(Equipment.Lightning, TrackedDef.Damage);
			dictionary.Add(Equipment.Recycle, new TrackedDef(typeof(CountTracker), TrackedDef.recycledTooltip));
			dictionary.Add(Equipment.LifestealOnHit, TrackedDef.Heal);
			dictionary.Add(Equipment.Molotov, TrackedDef.Damage);
			dictionary.Add(Equipment.VendingMachine, TrackedDef.Heal);
			dictionary.Add(Equipment.GummyClone, TrackedDef.Damage);
			dictionary.Add(Equipment.MultiShopCard, TrackedDef.Gold);
			dictionary.Add(Equipment.GainArmor, TrackedDef.Armor);
			dictionary.Add(Equipment.Meteor, TrackedDef.Damage);
			dictionary.Add(Equipment.BurnNearby, TrackedDef.Damage);
			dictionary.Add(Equipment.AffixRed, TrackedDef.Damage);
			dictionary.Add(Equipment.AffixBlue, TrackedDef.Damage);
			dictionary.Add(Equipment.AffixWhite, TrackedDef.Damage);
			dictionary.Add(Equipment.EliteAurelioniteEquipment, TrackedDef.Damage);
			dictionary.Add(Equipment.EliteBeadEquipment, TrackedDef.Damage);
			ModifyPrefabs();
			crocoDiseaseProjectileIndex = ProjectileCatalog.FindProjectileIndex("CrocoDiseaseProjectile");
			falseSonCharacterBodyIndex = BodyCatalog.FindBodyIndex("FalseSonBody");
		}

		private static void ModifyPrefabs()
		{
			AddProcComponent("RoR2/Base/StickyBomb/StickyBomb.prefab", Items.StickyBomb);
			AddProcComponent("RoR2/Base/ElementalRings/FireTornado.prefab", Items.FireRing);
			AddProcComponent("RoR2/DLC1/ElementalRingVoid/ElementalRingVoidBlackHole.prefab", Items.ElementalRingVoid);
			AddProcComponent("RoR2/Base/FireballsOnHit/FireMeatBall.prefab", Items.FireballsOnHit);
			AddProcComponent("RoR2/DLC1/PrimarySkillShuriken/ShurikenProjectile.prefab", Items.PrimarySkillShuriken);
			AddProcComponent("RoR2/Base/LaserTurbine/LaserTurbineController.prefab", Items.LaserTurbine);
			AddProcComponent("RoR2/Base/LaserTurbine/LaserTurbineBomb.prefab", Items.LaserTurbine);
			AddProcComponent("RoR2/Base/Icicle/IcicleAura.prefab", Items.Icicle);
			AddProcComponent("RoR2/Base/NovaOnLowHealth/VagrantNovaItemBodyAttachment.prefab", Items.NovaOnLowHealth);
			AddProcComponent("RoR2/Base/Firework/FireworkProjectile.prefab", Items.Firework);
			AddProcComponent("RoR2/DLC1/LunarSun/LunarSunProjectile.prefab", Items.LunarSun);
			AddProcComponent("RoR2/Base/Dagger/DaggerProjectile.prefab", Items.Dagger);
			AddProcComponent("RoR2/Base/BleedOnHitAndExplode/BleedOnHitAndExplodeDelay.prefab", Items.BleedOnHitAndExplode);
			AddProcComponent("RoR2/DLC2/Items/StunAndPierce/StunAndPierceBoomerang.prefab", Items.StunAndPierce);
			AddProcComponent("RoR2/DLC2/Items/GoldOnStageStart/BossMissileProjectile.prefab", Items.GoldOnStageStart);
			AddProcComponent("RoR2/Base/BonusGoldPackOnKill/BonusMoneyPack.prefab", Items.BonusGoldPackOnKill);
			AddProcComponent("RoR2/Base/Mushroom/MushroomWard.prefab", Items.Mushroom);
			AddProcComponent("RoR2/Base/Plant/DeskplantWard.prefab", Items.Plant);
			AddMinionComponent("RoR2/Base/RoboBallBuddy/RoboBallGreenBuddyBody.prefab", Items.RoboBallBuddy);
			AddMinionComponent("RoR2/Base/RoboBallBuddy/RoboBallRedBuddyBody.prefab", Items.RoboBallBuddy);
			AddMinionComponent("RoR2/DLC1/VoidJailer/VoidJailerAllyBody.prefab", Items.VoidMegaCrabItem);
			AddMinionComponent("RoR2/Base/Nullifier/NullifierAllyBody.prefab", Items.VoidMegaCrabItem);
			AddMinionComponent("RoR2/DLC1/VoidMegaCrab/VoidMegaCrabAllyBody.prefab", Items.VoidMegaCrabItem);
			AddMinionComponent("RoR2/Base/BeetleGland/BeetleGuardAllyBody.prefab", Items.BeetleGland);
			AddMinionComponent("RoR2/Base/Squid/SquidTurretBody.prefab", Items.Squid);
			AddMinionComponent("RoR2/DLC1/MajorAndMinorConstruct/MinorConstructOnKillBody.prefab", Items.MinorConstructOnKill);
			AddMinionComponent("RoR2/Base/Titan/TitanGoldBody.prefab", Items.TitanGoldDuringTP);
			AddMinionComponent("RoR2/Base/Drones/BackupDroneBody.prefab", Equipment.DroneBackup);
			Utilities.AddressableAddComp<ProjectileBehaviour>("RoR2/Base/Nullifier/NullifierDeathBombProjectile.prefab", (Action<ProjectileBehaviour>)delegate(ProjectileBehaviour a)
			{
				a.projectile = ProjectileBehaviour.Projectile.ZoeaDeath;
			});
			Utilities.AddressableAddComp<ProjectileBehaviour>("RoR2/DLC1/VoidJailer/VoidJailerDeathBombProjectile.prefab", (Action<ProjectileBehaviour>)delegate(ProjectileBehaviour a)
			{
				a.projectile = ProjectileBehaviour.Projectile.ZoeaDeath;
			});
			Utilities.AddressableAddComp<ProjectileBehaviour>("RoR2/DLC1/VoidMegaCrab/VoidMegaCrabDeathBombProjectile.prefab", (Action<ProjectileBehaviour>)delegate(ProjectileBehaviour a)
			{
				a.projectile = ProjectileBehaviour.Projectile.ZoeaDeathChilder;
			});
			Utilities.AddressableAddComp<ProjectileBehaviour>("RoR2/DLC1/VoidMegaCrab/VoidMegaCrabDeathBombletsProjectile.prefab", (Action<ProjectileBehaviour>)delegate(ProjectileBehaviour a)
			{
				a.projectile = ProjectileBehaviour.Projectile.ZoeaDeath;
			});
			AddProcComponent("RoR2/Base/Saw/Sawmerang.prefab", Equipment.Saw);
			AddProcComponent("RoR2/Base/GoldGat/GoldGatController.prefab", Equipment.GoldGat);
			AddProcComponent("RoR2/Base/BFG/BeamSphere.prefab", Equipment.BFG);
			AddProcComponent("RoR2/Base/Meteor/MeteorStorm.prefab", Equipment.Meteor);
			AddProcComponent("RoR2/DLC1/Molotov/MolotovClusterProjectile.prefab", Equipment.Molotov);
			AddProcComponent("RoR2/DLC1/Molotov/MolotovSingleProjectile.prefab", Equipment.Molotov);
			AddProcComponent("RoR2/DLC1/Molotov/MolotovProjectileDotZone.prefab", Equipment.Molotov);
			AddProcComponent("RoR2/Base/Mage/MageFireboltBasic.prefab", (SkillSlot)0);
			AddProcComponent("RoR2/Base/Mage/MageLightningboltBasic.prefab", (SkillSlot)0);
			AddProcComponent("RoR2/Base/Mage/MageIceBombProjectile.prefab", (SkillSlot)1);
			AddProcComponent("RoR2/Base/Mage/MageLightningBombProjectile.prefab", (SkillSlot)1);
			AddProcComponent("RoR2/Base/Mage/MageIcewallPillarProjectile.prefab", (SkillSlot)2);
			AddProcComponent("RoR2/Base/Merc/EvisProjectile.prefab", (SkillSlot)3);
			AddProcComponent("RoR2/Base/Merc/EvisOverlapProjectile.prefab", (SkillSlot)3);
			AddProcComponent("RoR2/Base/Commando/FMJRamping.prefab", (SkillSlot)1);
			AddProcComponent("RoR2/Base/Commando/CommandoGrenadeProjectile.prefab", (SkillSlot)3);
			AddProcComponent("RoR2/Base/Captain/CaptainAirstrikeProjectile1.prefab", (SkillSlot)2);
			AddProcComponent("RoR2/Base/Captain/CaptainAirstrikeAltProjectile.prefab", (SkillSlot)2);
			AddProcComponent("RoR2/Base/Captain/CaptainSupplyDrop, Base.prefab", (SkillSlot)3);
			AddProcComponent("RoR2/Base/Captain/CaptainSupplyDrop, EquipmentRestock.prefab", (SkillSlot)3);
			AddProcComponent("RoR2/Base/Captain/CaptainSupplyDrop, Hacking.prefab", (SkillSlot)3);
			AddProcComponent("RoR2/Base/Captain/CaptainSupplyDrop, Healing.prefab", (SkillSlot)3);
			AddProcComponent("RoR2/Base/Captain/CaptainSupplyDrop, Shocking.prefab", (SkillSlot)3);
			AddProcComponent("RoR2/Base/Captain/CaptainTazer.prefab", (SkillSlot)1);
			AddProcComponent("RoR2/Base/Huntress/HuntressArrowRain.prefab", (SkillSlot)3);
			AddProcComponent("RoR2/Base/Loader/LoaderYankHook.prefab", (SkillSlot)1);
			AddProcComponent("RoR2/Base/Loader/LoaderZapCone.prefab", (SkillSlot)2);
			AddProcComponent("RoR2/Base/Loader/LoaderPylon.prefab", (SkillSlot)3);
			AddProcComponent("RoR2/Base/Engi/EngiGrenadeProjectile.prefab", (SkillSlot)0);
			AddProcComponent("RoR2/Base/Engi/EngiHarpoon.prefab", (SkillSlot)2);
			AddMinionComponent("RoR2/Base/Engi/EngiTurretBody.prefab", (SkillSlot)3);
			AddMinionComponent("RoR2/Base/Engi/EngiWalkerTurretBody.prefab", (SkillSlot)3);
			AddProcComponent("RoR2/Base/Croco/CrocoSpit.prefab", (SkillSlot)1);
			AddProcComponent("RoR2/Base/Croco/CrocoLeapAcid.prefab", (SkillSlot)2);
			AddProcComponent("RoR2/Base/Croco/CrocoDiseaseProjectile.prefab", (SkillSlot)3);
			AddProcComponent("RoR2/Base/Toolbot/CryoCanisterProjectile.prefab", (SkillSlot)1);
			AddProcComponent("RoR2/Base/Toolbot/CryoCanisterBombletsProjectile.prefab", (SkillSlot)1);
			AddProcComponent("RoR2/Base/Bandit2/Bandit2ShivProjectile.prefab", (SkillSlot)1);
			AddProcComponent("RoR2/DLC1/Railgunner/RailgunnerPistolProjectile.prefab", (SkillSlot)0);
			AddProcComponent("RoR2/Base/Treebot/SyringeProjectile.prefab", (SkillSlot)0);
			AddProcComponent("RoR2/Base/Treebot/SyringeProjectileHealing.prefab", (SkillSlot)0);
			AddProcComponent("RoR2/Base/Treebot/TreebotMortar2.prefab", (SkillSlot)1);
			AddProcComponent("RoR2/Base/Treebot/TreebotMortarRain.prefab", (SkillSlot)1);
			AddProcComponent("RoR2/Base/Treebot/TreebotFlowerSeed.prefab", (SkillSlot)3);
			AddProcComponent("RoR2/Base/Treebot/TreebotFruitSeedProjectile.prefab", (SkillSlot)3);
			Utilities.DoAddressable<GameObject>("RoR2/Base/Treebot/TreebotFruitPack.prefab", (Action<GameObject>)delegate(GameObject a)
			{
				((Component)a.GetComponentInChildren<HealthPickup>()).gameObject.AddComponent<ProcComponent>().index = (SkillSlot)3;
			});
			AddProcComponent("RoR2/DLC1/VoidSurvivor/VoidSurvivorMegaBlasterSmallProjectile.prefab", (SkillSlot)1);
			AddProcComponent("RoR2/DLC1/VoidSurvivor/VoidSurvivorMegaBlasterBigProjectile.prefab", (SkillSlot)1);
			AddProcComponent("RoR2/DLC1/VoidSurvivor/VoidSurvivorMegaBlasterBigProjectileCorrupted.prefab", (SkillSlot)1);
			AddProcComponent("RoR2/Base/LunarSkillReplacements/LunarNeedleProjectile.prefab", (SkillSlot)0);
			AddProcComponent("RoR2/Base/LunarSkillReplacements/LunarSecondaryProjectile.prefab", (SkillSlot)1);
			AddProcComponent("RoR2/DLC2/Seeker/SpiritPunchProjectile.prefab", (SkillSlot)0);
			AddProcComponent("RoR2/DLC2/Seeker/SpiritPunchFinisherProjectile.prefab", (SkillSlot)0);
			AddProcComponent("RoR2/DLC2/Seeker/SoulSpiralProjectile.prefab", (SkillSlot)1);
			AddProcComponent("RoR2/DLC2/Seeker/UnseenHandMovingProjectile.prefab", (SkillSlot)1);
			AddProcComponent("RoR2/DLC2/Seeker/SojournVehicle/SojournVehicle.prefab", (SkillSlot)2);
			AddProcComponent("RoR2/DLC2/FalseSon/LunarSpike.prefab", (SkillSlot)1);
			AddProcComponent("RoR2/DLC2/Chef/ChefCleaver.prefab", (SkillSlot)0);
			AddProcComponent("RoR2/DLC2/Chef/ChefDiceEnhanced.prefab", (SkillSlot)3);
			AddProcComponent("RoR2/DLC2/Chef/BoostedSearFireballProjectile.prefab", (SkillSlot)3);
			AddProcComponent("RoR2/DLC2/Chef/BoostedRolyPolyProjectile.prefab", (SkillSlot)3);
			AddProcComponent("RoR2/DLC2/Chef/ChefGlazeProjectile.prefab", (SkillSlot)3);
			Utilities.DoAddressable("RoR2/Base/Common/MissileProjectile.prefab", DoMissilePrefab);
			DoElites();
		}

		private static void AddProcComponent(string addressable, Index index)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			AsyncOperationHandle<GameObject> val = Addressables.LoadAssetAsync<GameObject>((object)addressable);
			val.Completed += delegate(AsyncOperationHandle<GameObject> a)
			{
				a.Result.AddComponent<ProcComponent>().index = index;
			};
		}

		private static void AddMinionComponent(string addressable, Index index)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			AsyncOperationHandle<GameObject> val = Addressables.LoadAssetAsync<GameObject>((object)addressable);
			val.Completed += delegate(AsyncOperationHandle<GameObject> a)
			{
				a.Result.AddComponent<MinionComponent>().index = index;
			};
		}

		private static void DoMissilePrefab(GameObject missilePrefab)
		{
			missileLauncher = Utilities.CreatePrefab(missilePrefab, "DisposableMissileProjectile");
			missileLauncher.AddComponent<ProcComponent>().index = Equipment.CommandMissile;
			CommonAssets.missilePrefab = Utilities.CreatePrefab(missilePrefab, "ATGMissileProjectile");
			CommonAssets.missilePrefab.AddComponent<ProcComponent>().index = Items.Missile;
		}

		private static async void DoElites()
		{
			Task<GameObject>[] tasks = new Task<GameObject>[5]
			{
				Utilities.GetAddressableAsync("RoR2/Base/EliteLightning/LightningStake.prefab"),
				Utilities.GetAddressableAsync("RoR2/Base/Common/FireTrail.prefab"),
				Utilities.GetAddressableAsync("RoR2/DLC2/Elites/EliteAurelionite/AffixAurelionitePreStrikeProjectile.prefab"),
				Utilities.GetAddressableAsync("RoR2/DLC2/Elites/EliteAurelionite/AffixAurelioniteCenterProjectile.prefab"),
				Utilities.GetAddressableAsync("RoR2/DLC2/Elites/EliteBead/BeadProjectileTrackingBomb.prefab")
			};
			await Task.WhenAll(tasks);
			DoDualElitePrefab(tasks[0].Result, Equipment.AffixBlue.equipmentIndex, out hhOverloading);
			DoDualElitePrefab(tasks[1].Result, Equipment.AffixRed.equipmentIndex, out hhFireTrail);
			DoDualElitePrefab(tasks[2].Result, Equipment.EliteAurelioniteEquipment.equipmentIndex, out hhGoldOuter);
			DoDualElitePrefab(tasks[3].Result, Equipment.EliteAurelioniteEquipment.equipmentIndex, out hhGoldInner);
			DoDualElitePrefab(tasks[4].Result, Equipment.EliteBeadEquipment.equipmentIndex, out hhBead);
		}

		private static void DoDualElitePrefab(GameObject prefab, EquipmentIndex eliteIndex, out GameObject hhPrefab)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			prefab.AddComponent<ProcComponent>().index = eliteIndex;
			hhPrefab = Utilities.CreatePrefab(prefab);
			hhPrefab.GetComponent<ProcComponent>().index = Items.HeadHunter;
		}

		private void CollectLanguageRootFolders(List<string> list)
		{
			list.Add(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "Language"));
		}
	}
	public class ProcChain
	{
		public readonly Index index;

		public readonly ProcChain parent;

		private static readonly ProcChain[] cachedSkillChains = new ProcChain[4]
		{
			new ProcChain((SkillSlot)0),
			new ProcChain((SkillSlot)1),
			new ProcChain((SkillSlot)2),
			new ProcChain((SkillSlot)3)
		};

		public ProcChain(Index index, ProcChain parent = null)
		{
			this.index = index;
			this.parent = parent;
		}

		public static ProcChain TryGetCachedSkillChain(Index index)
		{
			int num = index.index;
			if (index.type == IndexType.SkillSlot && num >= 0 && num < cachedSkillChains.Length)
			{
				return cachedSkillChains[num];
			}
			return new ProcChain(index);
		}

		public void AddDamageToChain(TrackedInventory trackedInventory, float damage)
		{
			for (ProcChain procChain = this; procChain != null; procChain = procChain.parent)
			{
				if (trackedInventory.inventory.HasIndex(procChain.index) && trackedInventory.GetTracker(procChain.index) is IDamageTracker damageTracker)
				{
					damageTracker.AddDamage(damage);
				}
			}
		}

		public override string ToString()
		{
			string text = index.ToString();
			for (ProcChain procChain = parent; procChain != null; procChain = procChain.parent)
			{
				text = procChain.index.ToString() + " -> " + text;
			}
			return text;
		}
	}
	[Serializable]
	public struct Totals
	{
		public static float allDamageDealt;

		public float damageDealt;

		public float minionDamageDealt;

		public float damageTaken;

		public float healed;

		public uint goldEarned;
	}
	public class TrackedDef
	{
		private static readonly string tooltipPrefix = "ITEMSTATISTICS_TOOLTIPS_";

		public static readonly string damageTooltip = tooltipPrefix + "DAMAGE";

		public static readonly string chanceTooltip = tooltipPrefix + "CHANCE";

		public static readonly string countTooltip = tooltipPrefix + "COUNT";

		public static readonly string healTooltip = tooltipPrefix + "HEAL";

		public static readonly string goldTooltip = tooltipPrefix + "GOLD";

		public static readonly string reductionTooltip = tooltipPrefix + "REDUCTION";

		public static readonly string portionTooltip = tooltipPrefix + "DAMAGEPORTION";

		public static readonly string recycledTooltip = tooltipPrefix + "RECYCLED";

		public static readonly string barrierGainedTooltip = tooltipPrefix + "BARRIERGAINED";

		public static readonly string totalCritTooltip = tooltipPrefix + "CRITDAMAGE";

		public static readonly string stackTooltip = tooltipPrefix + "STACK";

		public static readonly string stackCombatTooltip = tooltipPrefix + "STACKCOMBAT";

		public static readonly string stackHitTooltip = tooltipPrefix + "STACKHIT";

		public static readonly string stackHitSkillTooltip = tooltipPrefix + "STACKHITSKILL";

		public static readonly string globalPortionTooltip = tooltipPrefix + "GLOBALPORTION";

		public static readonly string minionPortionTooltip = tooltipPrefix + "MINIONPORTION";

		public static readonly string regenPortionTooltip = tooltipPrefix + "REGENPORTION";

		public static readonly string barrierBlockedTooltip = tooltipPrefix + "BARRIERBLOCKED";

		public static readonly string chance_barrierTooltip = tooltipPrefix + "CHANCE_BARRIER";

		public static readonly string chance_healedTooltip = tooltipPrefix + "CHANCE_HEALED";

		public static readonly string chance_damageTooltip = tooltipPrefix + "CHANCE_DAMAGE";

		public static readonly string hit_damageTooltip = tooltipPrefix + "HIT_DAMAGE";

		public static readonly string count_chanceTooltip = tooltipPrefix + "COUNT_CHANCE";

		public static readonly string reduction_countTooltip = tooltipPrefix + "REDUCTION_COUNT";

		public static readonly TrackedDef ArmorCount = new TrackedDef(typeof(ArmorCountTracker), reduction_countTooltip);

		public static readonly TrackedDef Armor = new TrackedDef(typeof(ArmorTracker), reductionTooltip);

		public static readonly TrackedDef Chance = new TrackedDef(typeof(ChanceTracker), count_chanceTooltip);

		public static readonly TrackedDef Count = new TrackedDef(typeof(CountTracker), countTooltip);

		public static readonly TrackedDef DamageChance = new TrackedDef(typeof(DamageChanceTracker), chance_damageTooltip);

		public static readonly TrackedDef DamagePortion = new TrackedDef(typeof(DamageTracker), portionTooltip);

		public static readonly TrackedDef Damage = new TrackedDef(typeof(DamageTracker), damageTooltip);

		public static readonly TrackedDef Gold = new TrackedDef(typeof(GoldTracker), goldTooltip);

		public static readonly TrackedDef Heal = new TrackedDef(typeof(HealTracker), healTooltip);

		public static readonly TrackedDef Skill = new TrackedDef(typeof(SkillTracker), null);

		public static readonly TrackedDef Stack = new TrackedDef(typeof(ChanceTracker), stackTooltip);

		public static readonly TrackedDef StackCombat = new TrackedDef(typeof(ChanceTracker), stackCombatTooltip);

		public static readonly TrackedDef StackHit = new TrackedDef(typeof(ChanceTracker), stackHitTooltip);

		private readonly Type trackerType;

		private readonly string tooltipToken;

		public TrackedDef(Type trackerType, string tooltipToken)
		{
			if (!typeof(ITracker).IsAssignableFrom(trackerType))
			{
				throw new ArgumentException(trackerType?.ToString() + " is not a valid tracker type");
			}
			this.trackerType = trackerType;
			this.tooltipToken = tooltipToken;
		}

		public string GetTooltip(ITracker tracker, in Totals totals)
		{
			string[] tooltipArgs = tracker.GetTooltipArgs(in totals);
			if (tooltipArgs == null)
			{
				return "";
			}
			if (tooltipToken == null)
			{
				return string.Concat(tooltipArgs);
			}
			string text = tooltipToken;
			object[] array = tooltipArgs;
			return Language.GetStringFormatted(text, array);
		}

		internal ITracker CreateTracker()
		{
			return (ITracker)Activator.CreateInstance(trackerType);
		}
	}
}
namespace ItemStatistics.Trackers
{
	public class ArmorCountTracker : ITracker, IReductionTracker, IChanceTracker
	{
		private float globalDamageTakenWhenSet;

		private float damageBlocked;

		private uint attempted;

		private uint succedded;

		public int itemCount { get; set; }

		public bool dirtyBit { get; set; }

		public void Attempted()
		{
			log.warning("Called Attempted on ArmorChanceTracker");
		}

		public void Succedded()
		{
			succedded++;
			dirtyBit = true;
		}

		public void AddBlockedDamage(float blocked)
		{
			damageBlocked += blocked;
			dirtyBit = true;
		}

		string[] ITracker.GetTooltipArgs(in Totals totals)
		{
			return new string[2]
			{
				TrackerStatics.ReductionToString(damageBlocked, totals.damageTaken - globalDamageTakenWhenSet),
				succedded.ToString()
			};
		}

		void ITracker.Reset(in Totals totals)
		{
			attempted = 0u;
			succedded = 0u;
			damageBlocked = 0f;
			globalDamageTakenWhenSet = totals.damageTaken;
		}

		void ITracker.Serialize(SerializationBuffer data)
		{
			data.Add(attempted);
			data.Add(succedded);
			data.Add(damageBlocked);
		}

		void ITracker.Deserialize(SerializationBuffer data)
		{
			attempted = data.nextInt;
			succedded = data.nextInt;
			damageBlocked = data.nextFloat;
		}
	}
	public class ArmorTracker : ITracker, IReductionTracker
	{
		private float globalDamageTakenWhenSet;

		private float damageBlocked;

		public int itemCount { get; set; }

		public bool dirtyBit { get; set; }

		public void AddBlockedDamage(float blocked)
		{
			damageBlocked += blocked;
			dirtyBit = true;
		}

		string[] ITracker.GetTooltipArgs(in Totals totals)
		{
			return new string[2]
			{
				TrackerStatics.ReductionToString(damageBlocked, totals.damageTaken - globalDamageTakenWhenSet),
				TrackerStatics.PortionToString(damageBlocked, totals.damageTaken - globalDamageTakenWhenSet)
			};
		}

		void ITracker.Reset(in Totals totals)
		{
			damageBlocked = 0f;
			globalDamageTakenWhenSet = totals.damageTaken;
		}

		void ITracker.Serialize(SerializationBuffer data)
		{
			data.Add(damageBlocked);
		}

		void ITracker.Deserialize(SerializationBuffer data)
		{
			damageBlocked = data.nextFloat;
		}
	}
	public class ChanceTracker : ITracker, IChanceBatchTracker, IChanceTracker
	{
		private uint attempted;

		private uint succedded;

		public int itemCount { get; set; }

		public bool dirtyBit { get; set; }

		public void Attempted()
		{
			attempted++;
			dirtyBit = true;
		}

		public void Succedded()
		{
			succedded++;
			dirtyBit = true;
		}

		public void Succedded(uint count)
		{
			succedded += count;
			dirtyBit = true;
		}

		string[] ITracker.GetTooltipArgs(in Totals totals)
		{
			return new string[3]
			{
				succedded.ToString("n0"),
				TrackerStatics.ChanceToString(attempted, succedded),
				TrackerStatics.RateToString(attempted, succedded)
			};
		}

		void ITracker.Reset(in Totals totals)
		{
			attempted = 0u;
			succedded = 0u;
		}

		void ITracker.Serialize(SerializationBuffer data)
		{
			data.Add(attempted);
			data.Add(succedded);
		}

		void ITracker.Deserialize(SerializationBuffer data)
		{
			attempted = data.nextInt;
			succedded = data.nextInt;
		}
	}
	public class CountTracker : ITracker, IChanceBatchTracker, IChanceTracker
	{
		private uint succedded;

		public int itemCount { get; set; }

		public bool dirtyBit { get; set; }

		public void Attempted()
		{
			log.warning("Called Attempted on CountTracker");
		}

		public void Succedded()
		{
			succedded++;
			dirtyBit = true;
		}

		public void Succedded(uint count)
		{
			succedded += count;
			dirtyBit = true;
		}

		string[] ITracker.GetTooltipArgs(in Totals totals)
		{
			return new string[1] { succedded.ToString("n0") };
		}

		void ITracker.Reset(in Totals totals)
		{
			succedded = 0u;
		}

		void ITracker.Serialize(SerializationBuffer data)
		{
			data.Add(succedded);
		}

		void ITracker.Deserialize(SerializationBuffer data)
		{
			succedded = data.nextInt;
		}
	}
	public class DamageChanceTracker : ITracker, IChanceTracker, IDamageTracker
	{
		private uint attempted;

		private uint succedded;

		private float globalDamageWhenSet;

		private float itemDamage;

		public int itemCount { get; set; }

		public bool dirtyBit { get; set; }

		public void Attempted()
		{
			attempted++;
			dirtyBit = true;
		}

		public void Succedded()
		{
			succedded++;
			dirtyBit = true;
		}

		public void AddDamage(float damage)
		{
			itemDamage += damage;
			dirtyBit = true;
		}

		string[] ITracker.GetTooltipArgs(in Totals totals)
		{
			return new string[2]
			{
				TrackerStatics.ChanceToString(attempted, succedded),
				TrackerStatics.IncreaseToString(itemDamage, totals.damageDealt - globalDamageWhenSet)
			};
		}

		void ITracker.Reset(in Totals totals)
		{
			attempted = 0u;
			succedded = 0u;
			itemDamage = 0f;
			globalDamageWhenSet = totals.damageDealt;
		}

		void ITracker.Serialize(SerializationBuffer data)
		{
			data.Add(attempted);
			data.Add(succedded);
			data.Add(itemDamage);
		}

		void ITracker.Deserialize(SerializationBuffer data)
		{
			attempted = data.nextInt;
			succedded = data.nextInt;
			itemDamage = data.nextFloat;
		}
	}
	public class DamageTracker : ITracker, IDamageTracker
	{
		internal float globalDamageWhenSet;

		internal float itemDamage;

		public int itemCount { get; set; }

		public bool dirtyBit { get; set; }

		public void AddDamage(float damage)
		{
			itemDamage += damage;
			dirtyBit = true;
		}

		string[] ITracker.GetTooltipArgs(in Totals totals)
		{
			return new string[2]
			{
				TrackerStatics.IncreaseToString(itemDamage, totals.damageDealt - globalDamageWhenSet),
				TrackerStatics.PortionToString(itemDamage, totals.damageDealt - globalDamageWhenSet)
			};
		}

		public virtual void Reset(in Totals totals)
		{
			itemDamage = 0f;
			globalDamageWhenSet = totals.damageDealt;
		}

		public virtual void Serialize(SerializationBuffer data)
		{
			data.Add(itemDamage);
		}

		public virtual void Deserialize(SerializationBuffer data)
		{
			itemDamage = data.nextFloat;
		}
	}
	public class GoldTracker : ITracker, IGoldTracker
	{
		private float globalEarnedWhenSet;

		private float itemEarned;

		public int itemCount { get; set; }

		public bool dirtyBit { get; set; }

		public void AddGold(float gold)
		{
			itemEarned += gold;
			dirtyBit = true;
		}

		string[] ITracker.GetTooltipArgs(in Totals totals)
		{
			return new string[1] { TrackerStatics.IncreaseToString(itemEarned, (float)totals.goldEarned - globalEarnedWhenSet) };
		}

		void ITracker.Reset(in Totals totals)
		{
			itemEarned = 0f;
			globalEarnedWhenSet = totals.goldEarned;
		}

		void ITracker.Serialize(SerializationBuffer data)
		{
			data.Add(itemEarned);
		}

		void ITracker.Deserialize(SerializationBuffer data)
		{
			itemEarned = data.nextFloat;
		}
	}
	public class HealChanceTracker : ITracker, IChanceTracker, IHealTracker
	{
		private uint attempted;

		private uint succedded;

		private float itemHealed;

		private float globalHealedWhenSet;

		public int itemCount { get; set; }

		public bool dirtyBit { get; set; }

		public void Attempted()
		{
			attempted++;
			dirtyBit = true;
		}

		public void Succedded()
		{
			succedded++;
			dirtyBit = true;
		}

		public void AddHealing(float heal)
		{
			itemHealed += heal;
			dirtyBit = true;
		}

		string[] ITracker.GetTooltipArgs(in Totals totals)
		{
			return new string[3]
			{
				TrackerStatics.ChanceToString(attempted, succedded),
				TrackerStatics.PortionToString(itemHealed, totals.healed - globalHealedWhenSet),
				itemHealed.ToString("n0")
			};
		}

		void ITracker.Reset(in Totals totals)
		{
			attempted = 0u;
			succedded = 0u;
			itemHealed = 0f;
			globalHealedWhenSet = totals.healed;
		}

		void ITracker.Serialize(SerializationBuffer data)
		{
			data.Add(attempted);
			data.Add(succedded);
			data.Add(itemHealed);
		}

		void ITracker.Deserialize(SerializationBuffer data)
		{
			attempted = data.nextInt;
			succedded = data.nextInt;
			itemHealed = data.nextFloat;
		}
	}
	public class HealTracker : ITracker, IHealTracker
	{
		private float itemHealed;

		private float globalHealedWhenSet;

		public int itemCount { get; set; }

		public bool dirtyBit { get; set; }

		public void AddHealing(float heal)
		{
			itemHealed += heal;
			dirtyBit = true;
		}

		string[] ITracker.GetTooltipArgs(in Totals totals)
		{
			return new string[2]
			{
				TrackerStatics.PortionToString(itemHealed, totals.healed - globalHealedWhenSet),
				itemHealed.ToString("n0")
			};
		}

		void ITracker.Reset(in Totals totals)
		{
			itemHealed = 0f;
			globalHealedWhenSet = totals.healed;
		}

		void ITracker.Serialize(SerializationBuffer data)
		{
			data.Add(itemHealed);
		}

		void ITracker.Deserialize(SerializationBuffer data)
		{
			itemHealed = data.nextFloat;
		}
	}
	public interface IChanceTracker
	{
		void Attempted();

		void Succedded();
	}
	public interface IChanceBatchTracker : IChanceTracker
	{
		void Succedded(uint count);
	}
	public interface IDamageTracker
	{
		void AddDamage(float damage);
	}
	public interface IHealTracker
	{
		void AddHealing(float heal);
	}
	public interface IReductionTracker
	{
		void AddBlockedDamage(float blocked);
	}
	public interface IGoldTracker
	{
		void AddGold(float gold);
	}
	public interface ITracker
	{
		int itemCount { get; set; }

		bool dirtyBit { get; set; }

		string[] GetTooltipArgs(in Totals totals);

		void Reset(in Totals totals);

		void Serialize(SerializationBuffer data);

		void Deserialize(SerializationBuffer data);
	}
	public class SkillTracker : ITracker, IDamageTracker, IHealTracker
	{
		private float itemDamage;

		private float itemHealed;

		private float globalDamageWhenSet;

		private float globalHealedWhenSet;

		public int itemCount { get; set; }

		public bool dirtyBit { get; set; }

		public void AddDamage(float damage)
		{
			itemDamage += damage;
			dirtyBit = true;
		}

		public void AddHealing(float heal)
		{
			itemHealed += heal;
			dirtyBit = true;
		}

		string[] ITracker.GetTooltipArgs(in Totals totals)
		{
			bool flag = itemDamage != 0f;
			bool flag2 = itemHealed != 0f;
			string text = null;
			if (flag)
			{
				text = Language.GetStringFormatted(TrackedDef.portionTooltip, new object[2]
				{
					null,
					TrackerStatics.PortionToString(itemDamage, totals.damageDealt - globalDamageWhenSet)
				});
			}
			if (flag2)
			{
				if (flag)
				{
					text += "\n";
				}
				text += Language.GetStringFormatted(TrackedDef.healTooltip, new object[2]
				{
					TrackerStatics.PortionToString(itemHealed, totals.healed - globalHealedWhenSet),
					null
				});
			}
			if (text != null)
			{
				return new string[1] { text };
			}
			return null;
		}

		void ITracker.Reset(in Totals totals)
		{
			itemDamage = 0f;
			itemHealed = 0f;
			globalDamageWhenSet = totals.damageDealt;
			globalHealedWhenSet = totals.healed;
		}

		void ITracker.Serialize(SerializationBuffer data)
		{
			data.Add(itemDamage);
			data.Add(itemHealed);
		}

		void ITracker.Deserialize(SerializationBuffer data)
		{
			itemDamage = data.nextFloat;
			itemHealed = data.nextFloat;
		}
	}
	public static class TrackerStatics
	{
		public static string IncreaseToString(float localNum, float totalNum)
		{
			if (totalNum == 0f)
			{
				return "NaN";
			}
			if (localNum >= 0.999999f * totalNum)
			{
				return "Max";
			}
			if (localNum < 0f)
			{
				return (100f * localNum / totalNum).ToString("f0") + "%";
			}
			return (100f / (1f - localNum / totalNum) - 100f).ToString("f0") + "%";
		}

		public static string ChanceToString(uint attempted, uint succedded)
		{
			if (attempted == 0)
			{
				return "NaN";
			}
			float num = 100f * (float)succedded / (float)attempted;
			return num.ToString((num < 10f) ? "f1" : "f0") + "%";
		}

		public static string ReductionToString(float localNum, float totalNum)
		{
			if (totalNum == 0f)
			{
				if (!(localNum > 0f))
				{
					return "NaN";
				}
				return "100%";
			}
			if (localNum <= -0.999999f * totalNum)
			{
				return "Min";
			}
			return (100f - 100f / (1f + localNum / totalNum)).ToString("f0") + "%";
		}

		public static string PortionToString(float localNum, float totalNum)
		{
			if (totalNum == 0f)
			{
				return "NaN";
			}
			return (100f * localNum / totalNum).ToString("f0") + "%";
		}

		public static string RateToString(uint attempted, uint succedded)
		{
			if (attempted == 0)
			{
				return "NaN";
			}
			return ((float)succedded / (float)attempted).ToString("f1");
		}

		internal static void LogInvalid(Index index, ITracker tracker, string requiredTracker, [CallerMemberName] string caller = "")
		{
			log.error($"Invalid call '{caller}' on {index} ({tracker}). Has to be a {requiredTracker} tracker");
		}
	}
	public class WatchTracker : DamageTracker
	{
		private bool globalset;

		public void AddBrokenDamage(DamageTracker notBrokenWatchTracker)
		{
			AddDamage(notBrokenWatchTracker.itemDamage);
			if (!globalset)
			{
				globalDamageWhenSet = notBrokenWatchTracker.globalDamageWhenSet;
				globalset = true;
			}
		}

		public override void Reset(in Totals totals)
		{
			base.Reset(in totals);
			globalset = false;
		}

		public override void Serialize(SerializationBuffer data)
		{
			base.Serialize(data);
			data.Add(globalDamageWhenSet);
		}

		public override void Deserialize(SerializationBuffer data)
		{
			base.Deserialize(data);
			globalDamageWhenSet = data.nextFloat;
		}
	}
}
namespace ItemStatistics.Networking
{
	public class BlastMessage
	{
		private Index inflictorIndex;

		internal BlastAttackDamageInfo blastAttack;

		public BlastMessage()
		{
		}

		public BlastMessage(in BlastAttackDamageInfo blastAttack, Index inflictorIndex)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			this.inflictorIndex = inflictorIndex;
			this.blastAttack = blastAttack;
		}

		internal static void Serialize(NetworkWriter writer, BlastMessage value)
		{
			Index.Serialize(writer, value.inflictorIndex);
			((BlastAttackDamageInfo)(ref value.blastAttack)).Write(writer);
		}

		internal static BlastMessage Deserialize(NetworkReader reader)
		{
			BlastMessage blastMessage = new BlastMessage();
			blastMessage.inflictorIndex = Index.Deserialize(reader);
			((BlastAttackDamageInfo)(ref blastMessage.blastAttack)).Read(reader);
			blastMessage.blastAttack.inflictor = ProcComponent.CreateInflictor(blastMessage.inflictorIndex);
			return blastMessage;
		}
	}
	internal static class NetworkHooks
	{
		private delegate void BlastAttack_ClientReportDamage(in BlastAttackDamageInfo blastAttack);

		private static Index inflictorIndex;

		private static bool shouldClientSendMessage
		{
			get
			{
				if (TrackModdedUsers.isModdedServer)
				{
					return inflictorIndex.isNotNone;
				}
				return false;
			}
		}

		internal static void Apply()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			HookManager.Hook(MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/), (Delegate)new <>A{00000018}<BlastAttack_ClientReportDamage, BlastAttackDamageInfo>(NetworkMessage_On_BlastAttack_ClientReportDamage));
			HookManager.Hook(MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/), new Manipulator(HeadStompers_IL_HeadstompersFall_DoStompExplosionAuthority));
		}

		private static void NetworkMessage_On_BlastAttack_ClientReportDamage(BlastAttack_ClientReportDamage orig, in BlastAttackDamageInfo blastAttack)
		{
			if (!shouldClientSendMessage)
			{
				orig(in blastAttack);
			}
			else if (Object.op_Implicit((Object)(object)blastAttack.hitHealthComponent))
			{
				TrackModdedUsers.localUser.CallCmdBlastAttack(new BlastMessage(in blastAttack, inflictorIndex));
			}
		}

		private static void HeadStompers_IL_HeadstompersFall_DoStompExplosionAuthority(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			if (val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction a) => ILPatternMatchingExt.MatchStfld<BlastAttack>(a, "inflictor")
			}))
			{
				val.Emit(OpCodes.Pop);
				val.Emit(OpCodes.Ldarg_0);
				val.EmitDelegate<Func<HeadstompersFall, GameObject>>((Func<HeadstompersFall, GameObject>)delegate
				{
					//IL_001d: Unknown result type (might be due to invalid IL or missing references)
					if (NetworkServer.active)
					{
						return ProcComponent.CreateInflictor(Items.FallBoots);
					}
					inflictorIndex = Items.FallBoots.itemIndex;
					return null;
				});
				if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
				{
					(Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt(a, typeof(BlastAttack), "Fire")
				}))
				{
					val.Emit(OpCodes.Ldsflda, typeof(NetworkHooks).GetField("inflictorIndex", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic));
					val.Emit(OpCodes.Initobj, typeof(Index));
					return;
				}
			}
			val.LogErrorCaller("Headstompers");
		}
	}
	public class SerializationBuffer : IEnumerable<Index>, IEnumerable
	{
		[StructLayout(LayoutKind.Explicit)]
		private struct IntFloat
		{
			[FieldOffset(0)]
			private float floatValue;

			[FieldOffset(0)]
			private uint intValue;

			internal static float IntToFloat(uint value)
			{
				IntFloat intFloat = default(IntFloat);
				intFloat.intValue = value;
				return intFloat.floatValue;
			}

			internal static uint FloatToInt(float value)
			{
				IntFloat intFloat = default(IntFloat);
				intFloat.floatValue = value;
				return intFloat.intValue;
			}
		}

		private static readonly SerializationBuffer staticBuffer = new SerializationBuffer(4u, 4u);

		private Index[] indexes;

		private uint[] bits;

		private uint indexSize;

		private uint bitsSize;

		private uint bitPos;

		public uint nextInt => bits[bitPos++];

		public float nextFloat => IntFloat.IntToFloat(nextInt);

		public bool hasSomething => indexSize != 0;

		public void Add(float num)
		{
			Add(IntFloat.FloatToInt(num));
		}

		public void Add(uint num)
		{
			uint num2 = bitsSize + 1;
			if (num2 >= bits.Length)
			{
				int num3 = ((bits.Length == 0) ? 4 : (2 * bits.Length));
				if (num3 < num2)
				{
					num3 = (int)num2;
				}
				Array.Resize(ref bits, num3);
			}
			bits[bitsSize] = num;
			bitsSize = num2;
		}

		internal void Add(Index index)
		{
			uint num = indexSize + 1;
			if (num >= indexes.Length)
			{
				int num2 = ((indexes.Length == 0) ? 4 : (2 * indexes.Length));
				if (num2 < num)
				{
					num2 = (int)num;
				}
				Array.Resize(ref indexes, num2);
			}
			indexes[indexSize] = index;
			indexSize = num;
		}

		internal static void Serialize(NetworkWriter writer, SerializationBuffer value)
		{
			writer.WritePackedUInt32(value.indexSize);
			writer.WritePackedUInt32(value.bitsSize);
			for (uint num = 0u; num < value.indexSize; num++)
			{
				Index.Serialize(writer, value.indexes[num]);
			}
			for (uint num2 = 0u; num2 < value.bitsSize; num2++)
			{
				writer.WritePackedUInt32(value.bits[num2]);
			}
		}

		internal static SerializationBuffer Deserialize(NetworkReader reader)
		{
			SerializationBuffer serializationBuffer = staticBuffer;
			serializationBuffer.Clear();
			uint num = reader.ReadPackedUInt32();
			uint num2 = reader.ReadPackedUInt32();
			for (uint num3 = 0u; num3 < num; num3++)
			{
				serializationBuffer.Add(Index.Deserialize(reader));
			}
			for (uint num4 = 0u; num4 < num2; num4++)
			{
				serializationBuffer.Add(reader.ReadPackedUInt32());
			}
			return serializationBuffer;
		}

		internal void Clear()
		{
			indexSize = 0u;
			bitsSize = 0u;
			bitPos = 0u;
		}

		internal static SerializationBuffer GetBuffer()
		{
			return staticBuffer;
		}

		public IEnumerator<Index> GetEnumerator()
		{
			int i = 0;
			while (i < indexSize)
			{
				yield return indexes[i];
				int num = i + 1;
				i = num;
			}
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}

		private SerializationBuffer(uint initialIndexCapacity, uint initialBitsCapacity)
		{
			indexes = new Index[initialIndexCapacity];
			bits = new uint[initialBitsCapacity];
		}
	}
}
namespace ItemStatistics.Hooks
{
	public static class DotTracking
	{
		internal static List<ProcChain> dotChainListParameter;

		private static ProcChain dotChainParameter;

		private static MethodInfo modifiedGetDotStackTotalDurationForIndex;

		internal static void Apply()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			HookManager.Hook(MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/), (Delegate)new Action<Action<DotController, DotStack>, DotController, DotStack>(AddTree_On_DotController_OnDotStackAddedServer));
			HookManager.Hook(MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/), new Manipulator(Passer_IL_DotController_EvaluateDotStacksForType));
			HookManager.Hook(MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/), new Manipulator(CollectProcChain_IL_DotController_AddPendingDamageEntry));
			HookManager.Hook(MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/), (Delegate)new Action<Action<DotStack>, DotStack>(On_DotStack_Reset));
			HookManager.Hook(MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/), (Delegate)new Action<Action<PendingDamage>, PendingDamage>(On_PendingDamage_Reset));
			DoNoxious();
		}

		private static void AddTree_On_DotController_OnDotStackAddedServer(Action<DotController, DotStack> orig, DotController self, DotStack dotStack)
		{
			orig(self, dotStack);
			if (CurrentContext.procChain != null)
			{
				dotStack.dotStackChain = CurrentContext.procChain;
			}
		}

		private static void Passer_IL_DotController_EvaluateDotStacksForType(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: 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_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			if (val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction a) => ILPatternMatchingExt.MatchLdfld<DotStack>(a, "timer")
			}))
			{
				val.Emit(OpCodes.Dup);
				val.Emit(OpCodes.Ldfld, typeof(DotStack).GetField("dotStackChain"));
				val.Emit(OpCodes.Stsfld, typeof(DotTracking).GetField("dotChainParameter", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic));
				if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
				{
					(Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt<DotController>(a, "AddPendingDamageEntry")
				}))
				{
					val.Emit(OpCodes.Ldnull);
					val.Emit(OpCodes.Stsfld, typeof(DotTracking).GetField("dotChainParameter", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic));
					if (val.TryGotoNext(new Func<Instruction, bool>[1]
					{
						(Instruction a) => ILPatternMatchingExt.MatchLdfld<PendingDamage>(a, "totalDamage")
					}))
					{
						val.Emit(OpCodes.Dup);
						val.Emit(OpCodes.Ldfld, typeof(PendingDamage).GetField("pendingDotChainList"));
						val.Emit(OpCodes.Stsfld, typeof(DotTracking).GetField("dotChainListParameter", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic));
						if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
						{
							(Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt<HealthComponent>(a, "TakeDamage")
						}))
						{
							val.Emit(OpCodes.Ldnull);
							val.Emit(OpCodes.Stsfld, typeof(DotTracking).GetField("dotChainListParameter", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic));
							return;
						}
					}
				}
			}
			val.LogErrorCaller("");
		}

		private static void CollectProcChain_IL_DotController_AddPendingDamageEntry(ILContext il)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_0084: 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)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			int iIndex = 1;
			ILCursor[] array = default(ILCursor[]);
			val.FindNext(ref array, new Func<Instruction, bool>[2]
			{
				(Instruction a) => ILPatternMatchingExt.MatchLdloc(a, ref iIndex),
				(Instruction a) => ILPatternMatchingExt.MatchLdcI4(a, 1)
			});
			if (val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction a) => ILPatternMatchingExt.MatchStfld<PendingDamage>(a, "totalDamage")
			}))
			{
				val.Emit(OpCodes.Ldarg, 0);
				val.Emit(OpCodes.Ldloc, iIndex);
				val.Emit<List<PendingDamage>>(OpCodes.Callvirt, "get_Item");
				val.EmitDelegate<Action<PendingDamage>>((Action<PendingDamage>)delegate(PendingDamage pending)
				{
					if (dotChainParameter != null)
					{
						pending.pendingDotChainList.Add(dotChainParameter);
					}
				});
			}
			else
			{
				val.LogErrorCaller("1");
			}
			MethodReference val2 = default(MethodReference);
			if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
			{
				(Instruction a) => ILPatternMatchingExt.MatchLdsfld<DotController>(a, "pendingDamagePool"),
				(Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt(a, ref val2)
			}))
			{
				val.Emit(OpCodes.Dup);
				val.EmitDelegate<Action<PendingDamage>>((Action<PendingDamage>)delegate(PendingDamage pending)
				{
					List<ProcChain> list = (pending.pendingDotChainList = CollectionPool<ProcChain, List<ProcChain>>.RentCollection());
					if (dotChainParameter != null)
					{
						list.Add(dotChainParameter);
					}
				});
			}
			else
			{
				val.LogErrorCaller("2");
			}
		}

		private static void On_DotStack_Reset(Action<DotStack> orig, DotStack self)
		{
			orig(self);
			self.dotStackChain = null;
		}

		private static void On_PendingDamage_Reset(Action<PendingDamage> orig, PendingDamage self)
		{
			orig(self);
			List<ProcChain> pendingDotChainList = self.pendingDotChainList;
			if (pendingDotChainList != null)
			{
				CollectionPool<ProcChain, List<ProcChain>>.ReturnCollection(pendingDotChainList);
			}
			self.pendingDotChainList = null;
		}

		private static void DoNoxious()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Expected O, but got Unknown
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Expected O, but got Unknown
			try
			{
				DynamicMethodDefinition val = new DynamicMethodDefinition((MethodBase)HookManager.GetMethod(typeof(DotController), "GetDotStackTotalDurationForIndex"));
				((MethodReference)val.Definition).Parameters.Add(new ParameterDefinition("procChain", (ParameterAttributes)2, (TypeReference)new ByReferenceType(val.Module.ImportReference(typeof(ProcChain)))));
				typeof(DynamicMethodDefinition).GetProperty("OriginalMethod").SetValue(val, null);
				ILContext val2 = new ILContext(val.Definition);
				ILCursor val3 = new ILCursor(val2);
				val3.Emit(OpCodes.Ldarg_3);
				val3.Emit(OpCodes.Ldnull);
				val3.Emit(OpCodes.Stind_Ref);
				VariableDefinition val4 = val3.AddNewVariable<DotStack>();
				val3.GotoNext(new Func<Instruction, bool>[1]
				{
					(Instruction a) => ILPatternMatchingExt.MatchLdfld<DotStack>(a, "totalDuration")
				});
				val3.Emit(OpCodes.Stloc, val4);
				val3.Emit(OpCodes.Ldarg_3);
				val3.Emit(OpCodes.Ldloc, val4);
				val3.Emit<DotStack>(OpCodes.Ldfld, "dotStackChain");
				val3.Emit(OpCodes.Stind_Ref);
				val3.Emit(OpCodes.Ldloc, val4);
				val2.Dispose();
				modifiedGetDotStackTotalDurationForIndex = val.Generate();
				HookManager.Hook(MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/), new Manipulator(GetChain_IL_CharacterBody_TriggerEnemyDebuffs));
				HookManager.Hook(MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/), new Manipulator(ApplyChain_IL_VineOrb_OnArrival));
			}
			catch (Exception ex)
			{
				log.error("Failed Noxious Thorn\n" + ex);
			}
		}

		private static void GetChain_IL_CharacterBody_TriggerEnemyDebuffs(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing