Decompiled source of ArtificerExtended v4.0.18

ArtificerExtended.dll

Decompiled 2 weeks ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using AncientScepter;
using ArtificerExtended.Components;
using ArtificerExtended.Helpers;
using ArtificerExtended.Modules;
using ArtificerExtended.Passive;
using ArtificerExtended.Skills;
using ArtificerExtended.States;
using ArtificerExtended.Unlocks;
using Assets.RoR2.Scripts.Platform;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using EntityStates;
using EntityStates.Huntress;
using EntityStates.Mage;
using EntityStates.Mage.Weapon;
using EntityStates.Seeker;
using EntityStates.Toolbot;
using JetBrains.Annotations;
using JetHack;
using KinematicCharacterController;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using On.EntityStates;
using On.EntityStates.Mage;
using On.EntityStates.Mage.Weapon;
using On.RoR2;
using On.RoR2.Skills;
using On.RoR2.UI;
using R2API;
using R2API.Utils;
using RainrotSharedUtils;
using RainrotSharedUtils.Components;
using RainrotSharedUtils.Frost;
using Rewired.ComponentControls.Effects;
using RiskyMod.Survivors.Mage.Components;
using RoR2;
using RoR2.Achievements;
using RoR2.ContentManagement;
using RoR2.EntityLogic;
using RoR2.ExpansionManagement;
using RoR2.Networking;
using RoR2.Orbs;
using RoR2.Projectile;
using RoR2.Skills;
using RoR2.Stats;
using RoR2.UI;
using RoR2BepInExPack.GameAssetPaths;
using ThreeEyedGames;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.ResourceManagement.AsyncOperations;
using VRAPI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("ArtificerExtended")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ArtificerExtended")]
[assembly: AssemblyTitle("ArtificerExtended")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: UnverifiableCode]
[module: UnverifiableCode]
namespace ArtificerExtended
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[R2APISubmoduleDependency(new string[] { "LanguageAPI", "LoadoutAPI", "PrefabAPI", "UnlockableAPI", "SkillsAPI", "DamageAPI", "RecalculateStatsAPI", "DeployableAPI" })]
	[BepInPlugin("com.Borbo.ArtificerExtended", "ArtificerExtended", "4.0.18")]
	public class ArtificerExtendedPlugin : BaseUnityPlugin
	{
		public delegate TCheese GiveCheese<TCheese>();

		private class FlamethrowerContext
		{
			public AltArtiPassive passive;

			public float timer;

			public FlamethrowerContext(AltArtiPassive passive)
			{
				this.passive = passive;
				timer = 0f;
			}
		}

		private class PrepWallContext
		{
			public AltArtiPassive passive;

			public AltArtiPassive.BatchHandle handle;

			public PrepWallContext(AltArtiPassive passive, AltArtiPassive.BatchHandle handle)
			{
				this.passive = passive;
				this.handle = handle;
			}
		}

		private class NanoBombContext
		{
			public AltArtiPassive passive;

			public AltArtiPassive.BatchHandle handle;

			public float timer;

			public NanoBombContext(AltArtiPassive passive, AltArtiPassive.BatchHandle handle)
			{
				this.passive = passive;
				this.handle = handle;
				timer = 0f;
			}
		}

		public const string guid = "com.Borbo.ArtificerExtended";

		public const string modName = "ArtificerExtended";

		public const string teamName = "Borbo";

		public const string version = "4.0.18";

		public static ArtificerExtendedPlugin instance;

		public const string iconsPath = "Assets/Icons/";

		public const string DEVELOPER_PREFIX = "AE_";

		public const string achievementIdentifier = "_ACHIEVEMENT_NAME";

		public static bool isJethackLoaded = Tools.isLoaded("JetHack.JetHackPlugin.guid");

		public static bool isScepterLoaded = Tools.isLoaded("com.DestroyedClone.AncientScepter");

		public static bool autosprintLoaded = Tools.isLoaded("com.johnedwa.RTAutoSprintEx");

		public static bool is2r4rLoaded = Tools.isLoaded("com.HouseOfFruits.RiskierRain");

		public static bool isRiskyModLoaded = Tools.isLoaded("com.RiskyLives.RiskyMod");

		public static GameObject mageObject;

		public static CharacterBody mageBody;

		public static SkillLocator mageSkillLocator;

		public static GenericSkill magePassive;

		public static SkillFamily magePassiveFamily;

		public static SkillFamily magePrimary;

		public static SkillFamily mageSecondary;

		public static SkillFamily mageUtility;

		public static SkillFamily mageSpecial;

		public static float artiBoltDamage = 2.8f;

		public static float artiNanoDamage = 20f;

		public static float artiUtilCooldown = 12f;

		public static float meleeRangeChannel = 21f;

		public static float meleeRangeSingle = meleeRangeChannel + 7f;

		public static List<Type> entityStates = new List<Type>();

		public static List<SkillBase> Skills = new List<SkillBase>();

		public static Dictionary<SkillBase, bool> SkillStatusDictionary = new Dictionary<SkillBase, bool>();

		private readonly Dictionary<Flamethrower, FlamethrowerContext> flamethrowerContext = new Dictionary<Flamethrower, FlamethrowerContext>();

		private readonly Dictionary<PrepWall, PrepWallContext> prepWallContext = new Dictionary<PrepWall, PrepWallContext>();

		private readonly Dictionary<BaseChargeBombState, NanoBombContext> nanoBombContext = new Dictionary<BaseChargeBombState, NanoBombContext>();

		public const string ThunderSurgeHitBoxGroupName = "IonCharge";

		public static Material ionSurgePowerOverlay;

		public static BuffDef ionSurgePower;

		public static GameObject muzzleflashIonSurgeTrail;

		public static string surgeFullDesc = "<style=cIsDamage>Stunning</style>. Surge forward, dealing <style=cIsDamage>" + Tools.ConvertDecimal(SurgeExtendedDash.grazeDamageCoefficient) + " damage</style> to enemies in your path. Upon impact, create an explosion for <style=cIsDamage>" + Tools.ConvertDecimal(SurgeExtendedDash.impactDamageCoefficient) + " damage</style>.";

		public static AssetBundle iconBundle => Tools.mainAssetBundle;

		internal static ConfigFile CustomConfigFile { get; set; }

		public static ConfigEntry<bool> RecolorMeteor { get; set; }

		public static bool ShouldReworkIonSurge { get; set; }

		private void Awake()
		{
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Expected O, but got Unknown
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Expected O, but got Unknown
			instance = this;
			Config.Init();
			Log.Init(((BaseUnityPlugin)this).Logger);
			InitializeConfig();
			Language.Init();
			CommonAssets.Init();
			AddHooks();
			mageObject = LegacyResourcesAPI.Load<GameObject>("prefabs/characterbodies/MageBody");
			mageObject.AddComponent<ElementCounter>();
			mageBody = mageObject.GetComponent<CharacterBody>();
			mageSkillLocator = mageObject.GetComponent<SkillLocator>();
			if (Object.op_Implicit((Object)(object)mageObject) && Object.op_Implicit((Object)(object)mageBody) && Object.op_Implicit((Object)(object)mageSkillLocator))
			{
				ArtificerExtended.Modules.Skills.characterSkillLocators.Add("MageBody", mageSkillLocator);
				Log.Debug("AE Skill Setup succeeded!");
			}
			magePassive = CreateMagePassiveSlot(mageObject, mageSkillLocator);
			magePassiveFamily = magePassive.skillFamily;
			magePrimary = mageSkillLocator.primary.skillFamily;
			mageSecondary = mageSkillLocator.secondary.skillFamily;
			mageUtility = mageSkillLocator.utility.skillFamily;
			mageSpecial = mageSkillLocator.special.skillFamily;
			Log.Debug("ArtificerExtended setup succeeded!");
			CreateMagePassives(magePassiveFamily);
			DoSurgeReworkAssetSetup();
			SkillCatalog.Init += new hook_Init(ReplaceSkillDefs);
			if (is2r4rLoaded)
			{
				artiNanoDamage = 12f;
				artiUtilCooldown = 8f;
			}
			ArtiChanges();
			InitializeContent();
			CharacterMaster.OnBodyStart += new hook_OnBodyStart(AddAEBodyFX);
			new ContentPacks().Initialize();
		}

		public static bool BodyHasAncientScepterItem(CharacterBody body)
		{
			if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.inventory))
			{
				return false;
			}
			if (!isScepterLoaded)
			{
				return false;
			}
			return _BodyHasAncientScepterItem(body);
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private static bool _BodyHasAncientScepterItem(CharacterBody body)
		{
			return body.inventory.GetItemCount(((ItemBase)ItemBase<AncientScepterItem>.instance).ItemDef) > 0;
		}

		private void InitializeContent()
		{
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			BeginInitializing<SkillBase>(types, "SwanSongSkills.txt");
		}

		private void BeginInitializing<T>(Type[] allTypes, string fileName = "") where T : SharedBase
		{
			Type baseType = typeof(T);
			if (!baseType.IsAbstract)
			{
				Log.Error(Log.Combine() + "Incorrect BaseType: " + baseType.Name);
				return;
			}
			IEnumerable<Type> enumerable = allTypes.Where((Type type) => !type.IsAbstract && type.IsSubclassOf(baseType));
			if (enumerable.Count() <= 0)
			{
				return;
			}
			Log.Debug(Log.Combine(baseType.Name) + "Initializing");
			foreach (Type item in enumerable)
			{
				string text = Log.Combine(baseType.Name, item.Name);
				Log.Debug(text);
				T obj = (T)Activator.CreateInstance(item);
				if (ValidateBaseType(obj))
				{
					Log.Debug(text + "Validated");
					InitializeBaseType(obj);
					Log.Debug(text + "Initialized");
				}
			}
			if (!string.IsNullOrEmpty(fileName))
			{
				Language.TryPrintOutput(fileName);
			}
		}

		private bool ValidateBaseType(SharedBase obj)
		{
			bool isEnabled = obj.isEnabled;
			if (obj.lockEnabled)
			{
				return isEnabled;
			}
			return obj.Bind(isEnabled, "Should This Content Be Enabled");
		}

		private void InitializeBaseType(SharedBase obj)
		{
			obj.Init();
		}

		private GenericSkill CreateMagePassiveSlot(GameObject body, SkillLocator skillLocator)
		{
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			GenericSkill[] components = body.GetComponents<GenericSkill>();
			foreach (GenericSkill val in components)
			{
				if (((Object)val.skillFamily).name.ToLower().Contains("passive"))
				{
					return val;
				}
			}
			SkillFamily val2 = ScriptableObject.CreateInstance<SkillFamily>();
			val2.variants = (Variant[])(object)new Variant[1];
			GenericSkill val3 = body.gameObject.AddComponent<GenericSkill>();
			val3._skillFamily = val2;
			SkillsAPI.SetOrderPriority(val3, -1);
			SkillsAPI.SetLoadoutTitleTokenOverride(val3, "MAGE_LOADOUT_PASSIVE");
			val3._skillFamily = val2;
			((Object)val3.skillFamily).name = "MageBodyPassive";
			LanguageAPI.Add("MAGE_LOADOUT_PASSIVE", "Passive");
			Content.AddSkillFamily(val2);
			skillLocator.passiveSkill.enabled = false;
			EntityStateMachine[] components2 = body.GetComponents<EntityStateMachine>();
			foreach (EntityStateMachine val4 in components2)
			{
				if (val4.customName == "Body")
				{
					val4.mainStateType = new SerializableEntityStateType(typeof(GenericCharacterMain));
				}
			}
			return val3;
		}

		private void CharacterSelectController_BuildSkillStripDisplayData(orig_BuildSkillStripDisplayData orig, CharacterSelectController self, Loadout loadout, ValueType bodyInfo, object dest)
		{
			throw new NotImplementedException();
		}

		public void CreateMagePassives(SkillFamily passiveFamily)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Expected O, but got Unknown
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Expected O, but got Unknown
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			PassiveSkillDef passiveSkillDef = ScriptableObject.CreateInstance<PassiveSkillDef>();
			((SkillDef)passiveSkillDef).skillNameToken = mageSkillLocator.passiveSkill.skillNameToken;
			((Object)passiveSkillDef).name = mageSkillLocator.passiveSkill.skillNameToken;
			((SkillDef)passiveSkillDef).skillDescriptionToken = mageSkillLocator.passiveSkill.skillDescriptionToken;
			((SkillDef)passiveSkillDef).icon = mageSkillLocator.passiveSkill.icon;
			((SkillDef)passiveSkillDef).canceledFromSprinting = false;
			((SkillDef)passiveSkillDef).cancelSprintingOnActivation = false;
			passiveSkillDef.stateMachineDefaults = new PassiveSkillDef.StateMachineDefaults[1]
			{
				new PassiveSkillDef.StateMachineDefaults
				{
					machineName = "Body",
					initalState = new SerializableEntityStateType(typeof(MageCharacterMain)),
					mainState = new SerializableEntityStateType(typeof(MageCharacterMain)),
					defaultInitalState = new SerializableEntityStateType(typeof(GenericCharacterMain)),
					defaultMainState = new SerializableEntityStateType(typeof(GenericCharacterMain))
				}
			};
			LanguageAPI.Add("MAGE_PASSIVE_ENERGY_NAME", "Energetic Resonance");
			Sprite icon = iconBundle.LoadAsset<Sprite>("Assets/Icons/passiveilyborbo.png");
			PassiveSkillDef passiveSkillDef2 = ScriptableObject.CreateInstance<PassiveSkillDef>();
			((SkillDef)passiveSkillDef2).skillNameToken = "MAGE_PASSIVE_ENERGY_NAME";
			((SkillDef)passiveSkillDef2).skillDescriptionToken = CommonAssets.magePassiveDescToken;
			((SkillDef)passiveSkillDef2).icon = icon;
			((SkillDef)passiveSkillDef2).canceledFromSprinting = false;
			((SkillDef)passiveSkillDef2).cancelSprintingOnActivation = false;
			passiveSkillDef2.stateMachineDefaults = new PassiveSkillDef.StateMachineDefaults[1]
			{
				new PassiveSkillDef.StateMachineDefaults
				{
					machineName = "Jet",
					initalState = new SerializableEntityStateType(typeof(AltArtiPassive)),
					mainState = new SerializableEntityStateType(typeof(AltArtiPassive)),
					defaultInitalState = new SerializableEntityStateType(typeof(Idle)),
					defaultMainState = new SerializableEntityStateType(typeof(Idle))
				}
			};
			((SkillDef)passiveSkillDef2).keywordTokens = new string[3]
			{
				CommonAssets.meltKeywordToken,
				CommonAssets.arcticBlastKeywordToken,
				CommonAssets.lightningBoltKeywordToken
			};
			Variant[] array = new Variant[2];
			Variant val = new Variant
			{
				skillDef = (SkillDef)(object)passiveSkillDef,
				unlockableName = ""
			};
			((Variant)(ref val)).viewableNode = new Node(((SkillDef)passiveSkillDef).skillNameToken, false, (Node)null);
			array[0] = val;
			val = new Variant
			{
				skillDef = (SkillDef)(object)passiveSkillDef2,
				unlockableDef = UnlockBase.CreateUnlockDef(typeof(FullKitElementUnlock), icon)
			};
			((Variant)(ref val)).viewableNode = new Node(((SkillDef)passiveSkillDef2).skillNameToken, false, (Node)null);
			array[1] = val;
			passiveFamily.variants = (Variant[])(object)array;
			Content.AddSkillDef((SkillDef)(object)passiveSkillDef);
			Content.AddSkillDef((SkillDef)(object)passiveSkillDef2);
		}

		private void ReplaceSkillDefs(orig_Init orig)
		{
			orig.Invoke();
			ReplaceVanillaIonSurge(shouldReworkSurge: true);
		}

		private void AddAEBodyFX(orig_OnBodyStart orig, CharacterMaster self, CharacterBody body)
		{
			orig.Invoke(self, body);
			AEBodyEffects aEBodyEffects = ((Component)body).gameObject.AddComponent<AEBodyEffects>();
			aEBodyEffects.body = body;
		}

		private void InitializeConfig()
		{
		}

		private void ArtiChanges()
		{
			LanguageAPI.Add("MAGE_OUTRO_FLAVOR", "..and so she left, still searching for a heaven that no longer exists.");
			GameObject val = LegacyResourcesAPI.Load<GameObject>("prefabs/projectiles/MageIcewallPillarProjectile");
			ProjectileImpactExplosion componentInChildren = val.GetComponentInChildren<ProjectileImpactExplosion>();
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				componentInChildren.destroyOnEnemy = false;
			}
			LanguageAPI.Add("MAGE_UTILITY_ICE_DESCRIPTION", "<style=cIsUtility>Freezing</style>. Create a barrier that hurts enemies for up to <style=cIsDamage>12x100% damage</style>.");
			SkillDef skillDef = mageSpecial.variants[0].skillDef;
			if ((Object)(object)skillDef != (Object)null)
			{
				skillDef.mustKeyPress = true;
			}
		}

		public static SkillDef CloneSkillDef(SkillDef oldDef)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			SkillDef val = ScriptableObject.CreateInstance<SkillDef>();
			val.skillName = oldDef.skillName;
			val.skillNameToken = oldDef.skillNameToken;
			val.skillDescriptionToken = oldDef.skillDescriptionToken;
			val.icon = oldDef.icon;
			val.activationStateMachineName = oldDef.activationStateMachineName;
			val.activationState = oldDef.activationState;
			val.interruptPriority = oldDef.interruptPriority;
			val.baseRechargeInterval = oldDef.baseRechargeInterval;
			val.baseMaxStock = oldDef.baseMaxStock;
			val.rechargeStock = oldDef.rechargeStock;
			val.requiredStock = oldDef.requiredStock;
			val.stockToConsume = oldDef.stockToConsume;
			val.beginSkillCooldownOnSkillEnd = oldDef.beginSkillCooldownOnSkillEnd;
			val.fullRestockOnAssign = oldDef.fullRestockOnAssign;
			val.dontAllowPastMaxStocks = oldDef.dontAllowPastMaxStocks;
			val.resetCooldownTimerOnUse = oldDef.resetCooldownTimerOnUse;
			val.isCombatSkill = oldDef.isCombatSkill;
			val.cancelSprintingOnActivation = oldDef.cancelSprintingOnActivation;
			val.canceledFromSprinting = oldDef.canceledFromSprinting;
			val.forceSprintDuringState = oldDef.forceSprintDuringState;
			val.mustKeyPress = oldDef.mustKeyPress;
			val.keywordTokens = oldDef.keywordTokens;
			return val;
		}

		public void DoHooks()
		{
			AddHooks();
		}

		private void RemoveHooks()
		{
		}

		private void AddHooks()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Expected O, but got Unknown
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Expected O, but got Unknown
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected O, but got Unknown
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Expected O, but got Unknown
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Expected O, but got Unknown
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Expected O, but got Unknown
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Expected O, but got Unknown
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Expected O, but got Unknown
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: 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_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			FireFireBolt.FireGauntlet += new hook_FireGauntlet(FireFireBolt_FireGauntlet);
			BaseChargeBombState.OnEnter += new hook_OnEnter(BaseChargeBombState_OnEnter);
			BaseChargeBombState.FixedUpdate += new hook_FixedUpdate(BaseChargeBombState_FixedUpdate);
			BaseChargeBombState.OnExit += new hook_OnExit(BaseChargeBombState_OnExit);
			PrepWall.OnEnter += new hook_OnEnter(PrepWall_OnEnter);
			PrepWall.OnExit += new hook_OnExit(PrepWall_OnExit);
			Flamethrower.OnEnter += new hook_OnEnter(Flamethrower_OnEnter);
			Flamethrower.FixedUpdate += new hook_FixedUpdate(Flamethrower_FixedUpdate);
			Flamethrower.OnExit += new hook_OnExit(Flamethrower_OnExit);
			HealthComponent.TakeDamage += new hook_TakeDamage(HealthComponent_TakeDamage);
			GlobalEventManager.onCharacterDeathGlobal += GlobalEventManager_OnCharacterDeath;
			CharacterMaster.OnBodyStart += new hook_OnBodyStart(CharacterMaster_OnBodyStart);
			CharacterMaster.OnBodyDestroyed += new hook_OnBodyDestroyed(CharacterMaster_OnBodyDestroyed);
			RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(MeltAttackSpeedBuff);
			FrozenState.OnEnter += new hook_OnEnter(FrostNovaOnFreeze);
			FrozenState.FixedUpdate += new hook_FixedUpdate(RemoveFrostWhileFrozen);
			SetStateOnHurt.SetFrozenInternal += new hook_SetFrozenInternal(FixSetFrozen);
			CharacterBody.AddTimedBuff_BuffIndex_float += new hook_AddTimedBuff_BuffIndex_float(FixFrostStacks);
			CharacterBody.AddTimedBuff_BuffDef_float += new hook_AddTimedBuff_BuffDef_float(FixFrostStacks2);
			GlobalEventManager.OnHitAll += new hook_OnHitAll(ChainLightningHook);
			AssetReferenceT<GameObject> val = new AssetReferenceT<GameObject>(RoR2_Base_Mage.MageIceBombProjectile_prefab);
			AsyncOperationHandle<GameObject> val2 = AssetAsyncReferenceManager<GameObject>.LoadAsset(val, (AsyncReferenceHandleUnloadType)2);
			val2.Completed += FixIceSpear;
			AssetReferenceT<GameObject> val3 = new AssetReferenceT<GameObject>(RoR2_Base_Lightning.LightningStrikeImpact_prefab);
			val2 = AssetAsyncReferenceManager<GameObject>.LoadAsset(val3, (AsyncReferenceHandleUnloadType)2);
			val2.Completed += delegate(AsyncOperationHandle<GameObject> ctx)
			{
				FixLightningStrike(ctx.Result);
			};
			AssetReferenceT<GameObject> val4 = new AssetReferenceT<GameObject>(RoR2_Base_LightningStrikeOnHit.SimpleLightningStrikeImpact_prefab);
			val2 = AssetAsyncReferenceManager<GameObject>.LoadAsset(val4, (AsyncReferenceHandleUnloadType)2);
			val2.Completed += delegate(AsyncOperationHandle<GameObject> ctx)
			{
				FixLightningStrike(ctx.Result);
			};
		}

		private void FixLightningStrike(GameObject lightningStrikeImpactPrefab)
		{
			EffectComponent val = default(EffectComponent);
			if (!lightningStrikeImpactPrefab.TryGetComponent<EffectComponent>(ref val))
			{
				Log.Error("Lightning strike impact is missing EffectComponent");
			}
			else if (string.IsNullOrEmpty(val.soundName))
			{
				val.soundName = "Play_item_use_lighningArm";
			}
		}

		private void RemoveFrostWhileFrozen(orig_FixedUpdate orig, FrozenState self)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)((EntityState)self).characterBody))
			{
				((EntityState)self).characterBody.SetBuffCount(Buffs.Frost.buffIndex, 0);
			}
			orig.Invoke(self);
		}

		private void FixFrostStacks2(orig_AddTimedBuff_BuffDef_float orig, CharacterBody self, BuffDef buffDef, float duration)
		{
			if (!self.healthComponent.isInFrozenState || !((Object)(object)buffDef == (Object)(object)Buffs.Frost))
			{
				orig.Invoke(self, buffDef, duration);
			}
		}

		private void FixFrostStacks(orig_AddTimedBuff_BuffIndex_float orig, CharacterBody self, BuffIndex buffDef, float duration)
		{
			//IL_000e: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			if (!self.healthComponent.isInFrozenState || buffDef != Buffs.Frost.buffIndex)
			{
				orig.Invoke(self, buffDef, duration);
			}
		}

		private void FixSoulSpiralNRE(orig_DiscoverUnassignedSpirals orig, SeekerSoulSpiralManager self)
		{
			if (self == null || (Object)(object)self.seekerController == (Object)null || SoulSpiralProjectile.unassignedSoulSpirals == null || SoulSpiralProjectile.unassignedSoulSpirals.Count <= 0)
			{
				self.StopListeningForUnassignedSpirals();
			}
			else
			{
				orig.Invoke(self);
			}
		}

		private void FixIceSpear(AsyncOperationHandle<GameObject> iceSpearPrefab)
		{
			iceSpearPrefab.Result.layer = LayerIndex.projectileWorldOnly.intVal;
		}

		private void FixSetFrozen(orig_SetFrozenInternal orig, SetStateOnHurt self, float duration)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			if (Object.op_Implicit((Object)(object)self.targetStateMachine))
			{
				FrozenState val = new FrozenState();
				val.freezeDuration = duration;
				self.targetStateMachine.SetInterruptState((EntityState)(object)val, (InterruptPriority)5);
			}
			EntityStateMachine[] idleStateMachine = self.idleStateMachine;
			for (int i = 0; i < idleStateMachine.Length; i++)
			{
				idleStateMachine[i].SetNextStateToMain();
			}
		}

		private void FrostNovaOnFreeze(orig_OnEnter orig, FrozenState self)
		{
			if (NetworkServer.active)
			{
				CharacterBody val = null;
				GameObject lastHitAttacker = ((EntityState)self).healthComponent.lastHitAttacker;
				bool isCrit = false;
				if (Object.op_Implicit((Object)(object)lastHitAttacker))
				{
					val = lastHitAttacker.GetComponent<CharacterBody>();
				}
				if (Object.op_Implicit((Object)(object)val))
				{
					isCrit = Util.CheckRoll(val.crit, val.master);
				}
				FrostNovaOnMaxChill(val, ((EntityState)self).characterBody, isCrit);
			}
			orig.Invoke(self);
		}

		private static void ChainLightningHook(orig_OnHitAll orig, GlobalEventManager self, DamageInfo damageInfo, GameObject hitObject)
		{
			//IL_0002: 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_001a: Expected O, but got Unknown
			//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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			if (DamageAPI.HasModdedDamageType(damageInfo, CommonAssets.ChainLightningDamageType))
			{
				LightningOrb val = new LightningOrb();
				((Orb)val).origin = damageInfo.position;
				val.damageValue = damageInfo.damage * CommonAssets.chainLightningZapDamageFraction;
				val.isCrit = damageInfo.crit;
				val.teamIndex = TeamComponent.GetObjectTeam(damageInfo.attacker);
				val.attacker = damageInfo.attacker;
				val.bouncesRemaining = 0;
				val.canBounceOnSameTarget = false;
				val.bouncedObjects = new List<HealthComponent>();
				HurtBox component = hitObject.GetComponent<HurtBox>();
				if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.healthComponent))
				{
					val.bouncedObjects.Add(component.healthComponent);
				}
				else
				{
					HealthComponent component2 = hitObject.GetComponent<HealthComponent>();
					if (Object.op_Implicit((Object)(object)component2))
					{
						val.bouncedObjects.Add(component2);
					}
				}
				val.procChainMask = damageInfo.procChainMask;
				val.procCoefficient = CommonAssets.chainLightningZapDamageCoefficient;
				val.lightningType = (LightningType)0;
				val.damageColorIndex = (DamageColorIndex)0;
				val.range = CommonAssets.chainLightningZapDistance;
				HurtBox val2 = val.PickNextTarget(damageInfo.position);
				if (Object.op_Implicit((Object)(object)val2))
				{
					((Orb)val).target = val2;
					OrbManager.instance.AddOrb((Orb)(object)val);
				}
			}
			orig.Invoke(self, damageInfo, hitObject);
		}

		private void MeltAttackSpeedBuff(CharacterBody sender, StatHookEventArgs args)
		{
			int buffCount = sender.GetBuffCount(CommonAssets.meltBuff);
			if (buffCount > 0)
			{
				args.baseAttackSpeedAdd += AltArtiPassive.meltAspdIncrease * (float)buffCount;
			}
		}

		private void CharacterMaster_OnBodyStart(orig_OnBodyStart orig, CharacterMaster self, CharacterBody body)
		{
			ElementCounter component = ((Component)body).GetComponent<ElementCounter>();
			if ((Object)(object)component != (Object)null)
			{
				component.OnBodyStart(body.skillLocator);
			}
			orig.Invoke(self, body);
		}

		private void CharacterMaster_OnBodyDestroyed(orig_OnBodyDestroyed orig, CharacterMaster self, CharacterBody body)
		{
			ElementCounter component = ((Component)body).GetComponent<ElementCounter>();
			if ((Object)(object)component != (Object)null)
			{
				component.OnBodyEnd();
			}
			orig.Invoke(self, body);
		}

		private void GlobalEventManager_OnCharacterDeath(DamageReport damageReport)
		{
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active || damageReport == null)
			{
				return;
			}
			CharacterBody attackerBody = damageReport.attackerBody;
			CharacterBody victimBody = damageReport.victimBody;
			if (!Object.op_Implicit((Object)(object)victimBody) || !Object.op_Implicit((Object)(object)attackerBody) || !Object.op_Implicit((Object)(object)victimBody.healthComponent) || !AltArtiPassive.instanceLookup.TryGetValue(((Component)attackerBody).gameObject, out var value))
			{
				return;
			}
			ElementCounter.Power powerLevelFromBody = ElementCounter.GetPowerLevelFromBody(((Component)attackerBody).gameObject, (MageElement)2, value);
			int num = victimBody.GetBuffCount(Buffs.Frost);
			if (victimBody.healthComponent.isInFrozenState)
			{
				num = Mathf.Min(num + 3, 5);
			}
			int num2 = 0;
			int num3 = ((num2 <= 0) ? 1 : 3);
			if (num >= num3 && powerLevelFromBody > ElementCounter.Power.None)
			{
				float num4 = (float)num / 6f;
				float num5 = 1f - num4;
				float num6 = Mathf.Pow(num5, 2f);
				float num7 = 1f - num6;
				if (Util.CheckRoll(num7 * 100f, damageReport.attackerMaster))
				{
					AltArtiPassive.DoArcticBlast(attackerBody, powerLevelFromBody, ((Component)damageReport.victim).transform.position, damageReport.damageInfo.crit, num);
				}
			}
		}

		private void HealthComponent_TakeDamage(orig_TakeDamage orig, HealthComponent self, DamageInfo damageInfo)
		{
			orig.Invoke(self, damageInfo);
		}

		private void MaxFrostHook(ILContext il)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<DamageTypeCombo>(x, "IsChefFrostDamage")
			}) || !val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<SetStateOnHurt>(x, "SetFrozen")
			}))
			{
				return;
			}
			val.Emit(OpCodes.Ldarg_0, 0);
			val.Emit(OpCodes.Ldloc, 0);
			val.Emit(OpCodes.Ldloc, 1);
			val.EmitDelegate<Action<DamageInfo, CharacterBody, CharacterBody>>((Action<DamageInfo, CharacterBody, CharacterBody>)delegate(DamageInfo damageInfo, CharacterBody attackerBody, CharacterBody victimBody)
			{
				if (NetworkServer.active)
				{
					FrostNovaOnMaxChill(attackerBody, victimBody, damageInfo.crit);
				}
			});
		}

		private static void FrostNovaOnMaxChill(CharacterBody aBody, CharacterBody vBody, bool isCrit)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)aBody != (Object)null && AltArtiPassive.instanceLookup.TryGetValue(((Component)aBody).gameObject, out var value))
			{
				ElementCounter.Power powerLevelFromBody = ElementCounter.GetPowerLevelFromBody(((Component)aBody).gameObject, (MageElement)2, value);
				if (powerLevelFromBody > ElementCounter.Power.None)
				{
					AltArtiPassive.DoArcticBlast(aBody, powerLevelFromBody, vBody.corePosition, isCrit);
				}
			}
		}

		private void Flamethrower_OnEnter(orig_OnEnter orig, Flamethrower self)
		{
			orig.Invoke(self);
			GameObject gameObject = ((Component)((EntityState)self).outer).gameObject;
			if (AltArtiPassive.instanceLookup.ContainsKey(gameObject))
			{
				AltArtiPassive altArtiPassive = AltArtiPassive.instanceLookup[gameObject];
				FlamethrowerContext value = new FlamethrowerContext(altArtiPassive);
				altArtiPassive.SkillCast(null, isFire: true);
				flamethrowerContext[self] = value;
			}
		}

		private void Flamethrower_FixedUpdate(orig_FixedUpdate orig, Flamethrower self)
		{
			orig.Invoke(self);
			if (this.flamethrowerContext.ContainsKey(self))
			{
				FlamethrowerContext flamethrowerContext = this.flamethrowerContext[self];
				flamethrowerContext.timer += Time.fixedDeltaTime * ((BaseState)flamethrowerContext.passive).attackSpeedStat;
				int num = 0;
				while (flamethrowerContext.timer >= flamethrowerContext.passive.ext_flamethrowerInterval && num <= flamethrowerContext.passive.ext_flamethrowerMaxPerTick)
				{
					flamethrowerContext.passive.SkillCast(null, isFire: true);
					num++;
					flamethrowerContext.timer -= flamethrowerContext.passive.ext_flamethrowerInterval;
				}
			}
		}

		private void Flamethrower_OnExit(orig_OnExit orig, Flamethrower self)
		{
			orig.Invoke(self);
			if (this.flamethrowerContext.ContainsKey(self))
			{
				FlamethrowerContext flamethrowerContext = this.flamethrowerContext[self];
				flamethrowerContext.passive.SkillCast(null, isFire: true);
				this.flamethrowerContext.Remove(self);
			}
		}

		private void PrepWall_OnEnter(orig_OnEnter orig, PrepWall self)
		{
			orig.Invoke(self);
			GameObject gameObject = ((Component)((EntityState)self).outer).gameObject;
			if (AltArtiPassive.instanceLookup.ContainsKey(gameObject))
			{
				AltArtiPassive altArtiPassive = AltArtiPassive.instanceLookup[gameObject];
				AltArtiPassive.BatchHandle handle = new AltArtiPassive.BatchHandle();
				altArtiPassive.SkillCast(handle);
				PrepWallContext value = new PrepWallContext(altArtiPassive, handle);
				prepWallContext[self] = value;
			}
		}

		private void PrepWall_OnExit(orig_OnExit orig, PrepWall self)
		{
			orig.Invoke(self);
			if (this.prepWallContext.ContainsKey(self))
			{
				PrepWallContext prepWallContext = this.prepWallContext[self];
				prepWallContext.handle.Fire(prepWallContext.passive.ext_prepWallMinDelay, prepWallContext.passive.ext_prepWallMaxDelay);
				this.prepWallContext.Remove(self);
			}
		}

		private void BaseChargeBombState_OnEnter(orig_OnEnter orig, BaseChargeBombState self)
		{
			orig.Invoke(self);
			GameObject gameObject = ((Component)((EntityState)self).outer).gameObject;
			if (AltArtiPassive.instanceLookup.ContainsKey(gameObject))
			{
				AltArtiPassive altArtiPassive = AltArtiPassive.instanceLookup[gameObject];
				AltArtiPassive.BatchHandle handle = new AltArtiPassive.BatchHandle();
				NanoBombContext value = new NanoBombContext(altArtiPassive, handle);
				nanoBombContext[self] = value;
				altArtiPassive.SkillCast(handle, self is ChargeSolarFlare);
			}
		}

		private void BaseChargeBombState_FixedUpdate(orig_FixedUpdate orig, BaseChargeBombState self)
		{
			orig.Invoke(self);
			if (this.nanoBombContext.ContainsKey(self))
			{
				NanoBombContext nanoBombContext = this.nanoBombContext[self];
				nanoBombContext.timer += Time.fixedDeltaTime * nanoBombContext.passive.ext_attackSpeedStat;
				int num = 0;
				while (nanoBombContext.timer >= nanoBombContext.passive.ext_nanoBombInterval && num <= nanoBombContext.passive.ext_nanoBombMaxPerTick)
				{
					num++;
					nanoBombContext.passive.SkillCast(nanoBombContext.handle, self is ChargeSolarFlare);
					nanoBombContext.timer -= nanoBombContext.passive.ext_nanoBombInterval;
				}
			}
		}

		private void BaseChargeBombState_OnExit(orig_OnExit orig, BaseChargeBombState self)
		{
			orig.Invoke(self);
			if (this.nanoBombContext.ContainsKey(self))
			{
				NanoBombContext nanoBombContext = this.nanoBombContext[self];
				int num = 0;
				while (nanoBombContext.timer >= nanoBombContext.passive.ext_nanoBombInterval && num <= nanoBombContext.passive.ext_nanoBombMaxPerTick)
				{
					num++;
					nanoBombContext.passive.SkillCast(nanoBombContext.handle, self is ChargeSolarFlare);
					nanoBombContext.timer -= nanoBombContext.passive.ext_nanoBombInterval;
				}
				nanoBombContext.handle.Fire(nanoBombContext.passive.ext_nanoBombMinDelay, nanoBombContext.passive.ext_nanoBombMaxDelay);
				this.nanoBombContext.Remove(self);
			}
		}

		private void FireFireBolt_FireGauntlet(orig_FireGauntlet orig, FireFireBolt self)
		{
			orig.Invoke(self);
			GameObject gameObject = ((Component)((EntityState)self).outer).gameObject;
			if (AltArtiPassive.instanceLookup.TryGetValue(gameObject, out var value))
			{
				value.SkillCast(null, !(self is FireLightningBolt) && !(self is FireSnowBall));
			}
		}

		public void ReplaceVanillaIonSurge(bool shouldReworkSurge)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			SkillDef val = Addressables.LoadAssetAsync<SkillDef>((object)"RoR2/Base/Mage/MageBodyFlyUp.asset").WaitForCompletion();
			if ((Object)(object)val != (Object)null)
			{
				Debug.Log((object)"Changing ion surge");
				if (shouldReworkSurge)
				{
					ModifyVanillaIonSurge(val);
				}
				else
				{
					Content.AddEntityState(typeof(VanillaIonSurge));
					val.activationState = new SerializableEntityStateType(typeof(VanillaIonSurge));
				}
			}
			if (isScepterLoaded)
			{
				ReplaceScepterIonSurge(shouldReworkSurge, val);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public void ReplaceScepterIonSurge(bool shouldReworkSurge, SkillDef surgeSkillDef)
		{
			if (!shouldReworkSurge || (Object)(object)surgeSkillDef == (Object)null)
			{
				Debug.LogError((object)"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\nArtificerExtended could not replace Ancient Scepter's Antimatter Surge. Antimatter Surge WILL break Artificer Extended's alt passives. \nEither turn on ArtificerExtended's Ion Surge rework to use ArtificerExtended's Antimatter Surge, avoid using Antimatter Surge with ArtificerExtended's alt passive, or tell the Ancient Scepter developers to get in contact to fix Antimatter Surge. \nThis is NOT an error that can be fixed on the ArtificerExtended side.\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
				return;
			}
			SkillDef skillDef = SkillCatalog.GetSkillDef(SkillCatalog.FindSkillIndexByName(surgeSkillDef.skillName + "Scepter"));
			if ((Object)(object)skillDef != (Object)null)
			{
				ModifyScepterSurge(skillDef);
			}
		}

		private void DoSurgeReworkAssetSetup()
		{
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Expected O, but got Unknown
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			ModelLocator component = ((Component)mageBody).GetComponent<ModelLocator>();
			Transform val = ((component != null) ? component.modelTransform : null);
			if (Object.op_Implicit((Object)(object)val))
			{
				HitBoxGroup val2 = ((Component)val).gameObject.AddComponent<HitBoxGroup>();
				val2.groupName = "IonCharge";
				ChildLocator component2 = ((Component)val).GetComponent<ChildLocator>();
				if (Object.op_Implicit((Object)(object)component2))
				{
					Transform obj = component2.FindChild("Base");
					Transform val3 = ((obj != null) ? obj.parent : null);
					if (Object.op_Implicit((Object)(object)val3))
					{
						GameObject val4 = new GameObject();
						HitBox val5 = val4.AddComponent<HitBox>();
						val4.transform.parent = val3;
						val4.layer = LayerIndex.projectile.intVal;
						val4.transform.localPosition = new Vector3(0f, 1.5f, 0f);
						val4.transform.localRotation = Quaternion.identity;
						val4.transform.localScale = new Vector3(4f, 4f, 4f);
						val2.hitBoxes = (HitBox[])(object)new HitBox[1] { val5 };
					}
				}
			}
			ionSurgePower = Content.CreateAndAddBuff("bdIonSurgePower", null, Color.black, canStack: false, isDebuff: false);
			ionSurgePower.isHidden = true;
			ionSurgePowerOverlay = Object.Instantiate<Material>(Addressables.LoadAssetAsync<Material>((object)"RoR2/DLC1/VoidSurvivor/matVoidSurvivorCorruptOverlay.mat").WaitForCompletion());
			((Object)ionSurgePowerOverlay).name = "matIonSurgePowerOverlay";
			ionSurgePowerOverlay.SetColor("_TintColor", Color32.op_Implicit(new Color32((byte)0, (byte)210, byte.MaxValue, byte.MaxValue)));
			CharacterModel.UpdateOverlays += new hook_UpdateOverlays(SurgeOverlay);
			muzzleflashIonSurgeTrail = PrefabAPI.InstantiateClone(Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Mage/MuzzleflashMageLightningLargeWithTrail.prefab").WaitForCompletion(), "MuzzleflashIonSurgeTrail");
			ParticleSystem[] componentsInChildren = muzzleflashIonSurgeTrail.GetComponentsInChildren<ParticleSystem>();
			ParticleSystem[] array = componentsInChildren;
			foreach (ParticleSystem val6 in array)
			{
				Debug.Log((object)((Object)((Component)val6).gameObject).name);
				MainModule main = val6.main;
				((MainModule)(ref main)).duration = SurgeExtendedDash.flightDuration;
			}
			TrailRenderer componentInChildren = muzzleflashIonSurgeTrail.GetComponentInChildren<TrailRenderer>();
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				componentInChildren.time = SurgeExtendedDash.flightDuration + 0.5f;
			}
			Transform val7 = muzzleflashIonSurgeTrail.transform.Find("Trail");
			if (Object.op_Implicit((Object)(object)val7))
			{
				TrailRenderer component3 = ((Component)val7).GetComponent<TrailRenderer>();
				component3.time = SurgeExtendedDash.flightDuration + 0.5f;
			}
			else
			{
				Debug.LogError((object)"A");
			}
			Transform val8 = muzzleflashIonSurgeTrail.transform.Find("Matrix, Mesh");
			if (Object.op_Implicit((Object)(object)val8))
			{
				ParticleSystem component4 = ((Component)val8).GetComponent<ParticleSystem>();
				MainModule main2 = component4.main;
				((MainModule)(ref main2)).duration = SurgeExtendedDash.flightDuration;
				((MainModule)(ref main2)).loop = true;
			}
			else
			{
				Debug.LogError((object)"nb");
			}
			Transform val9 = muzzleflashIonSurgeTrail.transform.Find("Point Light");
			if (Object.op_Implicit((Object)(object)val9))
			{
				LightIntensityCurve component5 = ((Component)val9).GetComponent<LightIntensityCurve>();
				component5.timeMax = 2f;
			}
			else
			{
				Debug.LogError((object)"c");
			}
			Transform val10 = muzzleflashIonSurgeTrail.transform.Find("Smoke");
			if (Object.op_Implicit((Object)(object)val10))
			{
				ParticleSystem component6 = ((Component)val10).GetComponent<ParticleSystem>();
				MainModule main3 = component6.main;
				((MainModule)(ref main3)).duration = SurgeExtendedDash.flightDuration;
				((MainModule)(ref main3)).loop = true;
			}
			else
			{
				Debug.LogError((object)"d");
			}
		}

		private void SurgeOverlay(orig_UpdateOverlays orig, CharacterModel self)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			orig.Invoke(self);
			if ((int)self.visibility != 0 && !((Object)(object)self.body == (Object)null))
			{
				AddOverlay(ionSurgePowerOverlay, self.body.HasBuff(ionSurgePower));
			}
			void AddOverlay(Material overlayMaterial, bool condition)
			{
				if (self.activeOverlayCount < CharacterModel.maxOverlays && condition)
				{
					Material[] currentOverlays = self.currentOverlays;
					CharacterModel obj = self;
					int activeOverlayCount = obj.activeOverlayCount;
					obj.activeOverlayCount = activeOverlayCount + 1;
					currentOverlays[activeOverlayCount] = overlayMaterial;
				}
			}
		}

		public void ModifyVanillaIonSurge(SkillDef surge)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			Content.AddEntityState(typeof(SurgeExtendedDash));
			Content.AddEntityState(typeof(SurgeExtendedImpact));
			LanguageAPI.Add("MAGE_SPECIAL_LIGHTNING_DESCRIPTION", surgeFullDesc);
			surge.activationState = new SerializableEntityStateType(typeof(SurgeExtendedDash));
			surge.baseRechargeInterval = 8f;
		}

		public void ModifyScepterSurge(SkillDef surge2)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			LanguageAPI.Add("MAGE_ANTISURGE_LIGHTNING_DESC", surgeFullDesc + "\n<color=#d299ff>SCEPTER: 30% longer flight time, 200% impact damage.</color>");
			surge2.activationState = new SerializableEntityStateType(typeof(SurgeExtendedDash));
		}
	}
	public class AEBodyEffects : MonoBehaviour
	{
		public CharacterBody body;

		private TemporaryVisualEffect blizzardArmorTempEffect;

		private void Update()
		{
			UpdateSingleTemporaryVisualEffect(ref blizzardArmorTempEffect, _1FrostbiteSkill.blizzardArmorVFX, body.radius * 0.5f, body.GetBuffCount(_1FrostbiteSkill.artiIceShield));
		}

		private void UpdateSingleTemporaryVisualEffect(ref TemporaryVisualEffect tempEffect, GameObject obj, float effectRadius, int count, string childLocatorOverride = "")
		{
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			bool flag = (Object)(object)tempEffect != (Object)null;
			if (flag == count > 0)
			{
				return;
			}
			if (count > 0)
			{
				if (flag)
				{
					return;
				}
				GameObject val = Object.Instantiate<GameObject>(obj, body.corePosition, Quaternion.identity);
				tempEffect = val.GetComponent<TemporaryVisualEffect>();
				tempEffect.parentTransform = body.coreTransform;
				tempEffect.visualState = (VisualState)0;
				tempEffect.healthComponent = body.healthComponent;
				tempEffect.radius = effectRadius;
				LocalCameraEffect component = val.GetComponent<LocalCameraEffect>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.targetCharacter = ((Component)this).gameObject;
				}
				if (string.IsNullOrEmpty(childLocatorOverride))
				{
					return;
				}
				ModelLocator modelLocator = body.modelLocator;
				ChildLocator val2;
				if ((Object)(object)modelLocator == (Object)null)
				{
					val2 = null;
				}
				else
				{
					Transform modelTransform = modelLocator.modelTransform;
					val2 = (((Object)(object)modelTransform != (Object)null) ? ((Component)modelTransform).GetComponent<ChildLocator>() : null);
				}
				ChildLocator val3 = val2;
				if (Object.op_Implicit((Object)(object)val3))
				{
					Transform val4 = val3.FindChild(childLocatorOverride);
					if (Object.op_Implicit((Object)(object)val4))
					{
						tempEffect.parentTransform = val4;
					}
				}
			}
			else if (Object.op_Implicit((Object)(object)tempEffect))
			{
				tempEffect.visualState = (VisualState)1;
			}
		}
	}
	public abstract class SharedBase
	{
		public virtual string BASE_TOKEN => TOKEN_PREFIX + TOKEN_IDENTIFIER;

		public abstract string TOKEN_IDENTIFIER { get; }

		public abstract string TOKEN_PREFIX { get; }

		public virtual bool lockEnabled { get; } = false;


		public abstract string ConfigName { get; }

		public virtual bool isEnabled { get; } = true;


		public virtual ConfigFile configFile { get; } = Config.MyConfig;


		public static ManualLogSource Logger => Log._logSource;

		public abstract AssetBundle assetBundle { get; }

		public virtual Type RequiredUnlock { get; }

		public abstract void Hooks();

		public abstract void Lang();

		public virtual void Init()
		{
			ConfigManager.HandleConfigAttributes(GetType(), ConfigName, configFile);
			Hooks();
			Lang();
		}

		public T Bind<T>(T defaultValue, string configName, string configDesc = "")
		{
			return ConfigManager.DualBindToConfig(ConfigName, configFile, configName, defaultValue, configDesc);
		}

		public static float GetHyperbolic(float firstStack, float cap, float chance)
		{
			if (firstStack >= cap)
			{
				return cap * (chance / firstStack);
			}
			float num = chance / firstStack;
			float num2 = 100f * firstStack / (cap - firstStack);
			return cap * (1f - 100f / (num * num2 + 100f));
		}
	}
	internal static class Log
	{
		public static bool enableDebugging;

		internal static ManualLogSource _logSource;

		internal static void Init(ManualLogSource logSource)
		{
			enableDebugging = ConfigManager.DualBindToConfig("Artificer Extended", Config.MyConfig, "Enable Debugging", defaultValue: false, "Enable debug outputs to the log for troubleshooting purposes. Enabling this will slow down the game.");
			_logSource = logSource;
		}

		internal static string Combine(params string[] parameters)
		{
			string text = "ArtificerExtended : ";
			foreach (string text2 in parameters)
			{
				text = text + text2 + " : ";
			}
			return text;
		}

		internal static void Debug(object data)
		{
			if (enableDebugging)
			{
				_logSource.LogDebug(data);
			}
		}

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

		internal static void ErrorAssetBundle(string assetName, string bundleName)
		{
			Error("failed to load asset, " + assetName + ", because it does not exist in asset bundle, " + bundleName);
		}

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

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

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

		internal static void Warning(object data)
		{
			_logSource.LogWarning(data);
		}
	}
	public static class Tools
	{
		internal static Dictionary<string, AssetBundle> loadedBundles = new Dictionary<string, AssetBundle>();

		private static AssetBundle _mainAssetBundle;

		public static string modPrefix = string.Format("@{0}+{1}", "ArtificerExtended", "artiskillicons");

		public static AssetBundle mainAssetBundle
		{
			get
			{
				if ((Object)(object)_mainAssetBundle == (Object)null)
				{
					_mainAssetBundle = LoadAssetBundle("artiextended");
				}
				return _mainAssetBundle;
			}
			set
			{
				_mainAssetBundle = value;
			}
		}

		internal static AssetBundle LoadAssetBundle(string bundleName)
		{
			if (loadedBundles.ContainsKey(bundleName))
			{
				return loadedBundles[bundleName];
			}
			AssetBundle val = null;
			val = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)ArtificerExtendedPlugin.instance).Info.Location), bundleName));
			loadedBundles[bundleName] = val;
			return val;
		}

		public static string GetModPrefix(this BaseUnityPlugin plugin, string bundleName)
		{
			return $"@{plugin.Info.Metadata.Name}+{bundleName}";
		}

		public static string ConvertDecimal(float f)
		{
			return f * 100f + "%";
		}

		internal static bool isLoaded(string modguid)
		{
			foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
			{
				string key = pluginInfo.Key;
				PluginInfo value = pluginInfo.Value;
				if (key == modguid)
				{
					return true;
				}
			}
			return false;
		}

		internal static void GetMaterial(GameObject model, string childObject, Color color, ref Material material, float scaleMultiplier = 1f, bool replaceAll = false)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			Renderer[] componentsInChildren = model.GetComponentsInChildren<Renderer>();
			Renderer[] array = componentsInChildren;
			foreach (Renderer val in array)
			{
				Renderer val2 = val;
				if (string.Equals(((Object)val).name, childObject))
				{
					if (color == Color.clear)
					{
						Object.Destroy((Object)(object)val);
						break;
					}
					if ((Object)(object)material == (Object)null)
					{
						material = new Material(val.material);
						material.mainTexture = val.material.mainTexture;
						material.shader = val.material.shader;
						material.color = color;
					}
					val.material = material;
					Transform transform = ((Component)val).transform;
					transform.localScale *= scaleMultiplier;
					if (!replaceAll)
					{
						break;
					}
				}
			}
		}

		internal static void DebugMaterial(GameObject model)
		{
			Renderer[] componentsInChildren = model.GetComponentsInChildren<Renderer>();
			Renderer[] array = componentsInChildren;
			foreach (Renderer val in array)
			{
				Renderer val2 = val;
				Debug.Log((object)("Material: " + ((Object)val2).name.ToString()));
			}
		}

		internal static void GetParticle(GameObject model, string childObject, Color color, float sizeMultiplier = 1f, bool replaceAll = false)
		{
			//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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			ParticleSystem[] componentsInChildren = model.GetComponentsInChildren<ParticleSystem>();
			ParticleSystem[] array = componentsInChildren;
			foreach (ParticleSystem val in array)
			{
				ParticleSystem val2 = val;
				MainModule main = val2.main;
				ColorOverLifetimeModule colorOverLifetime = val2.colorOverLifetime;
				ColorBySpeedModule colorBySpeed = val2.colorBySpeed;
				if (string.Equals(((Object)val2).name, childObject))
				{
					((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(color);
					((MainModule)(ref main)).startSizeMultiplier = ((MainModule)(ref main)).startSizeMultiplier * sizeMultiplier;
					((ColorOverLifetimeModule)(ref colorOverLifetime)).color = MinMaxGradient.op_Implicit(color);
					((ColorBySpeedModule)(ref colorBySpeed)).color = MinMaxGradient.op_Implicit(color);
					if (!replaceAll)
					{
						break;
					}
				}
			}
		}

		internal static void DebugParticleSystem(GameObject model)
		{
			ParticleSystem[] componentsInChildren = model.GetComponentsInChildren<ParticleSystem>();
			ParticleSystem[] array = componentsInChildren;
			foreach (ParticleSystem val in array)
			{
				ParticleSystem val2 = val;
				Debug.Log((object)("Particle: " + ((Object)val2).name.ToString()));
			}
		}

		internal static void GetLight(GameObject model, string childObject, Color color, bool replaceAll = false)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			Light[] componentsInChildren = model.GetComponentsInChildren<Light>();
			Light[] array = componentsInChildren;
			foreach (Light val in array)
			{
				Light val2 = val;
				if (string.Equals(((Object)val2).name, childObject))
				{
					val2.color = color;
					if (!replaceAll)
					{
						break;
					}
				}
			}
		}

		internal static void DebugLight(GameObject model)
		{
			Light[] componentsInChildren = model.GetComponentsInChildren<Light>();
			Light[] array = componentsInChildren;
			foreach (Light val in array)
			{
				Light val2 = val;
				Debug.Log((object)("Light: " + ((Object)val2).name.ToString()));
			}
		}
	}
	public static class VRStuff
	{
		public static bool VRInstalled;

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void SetupVR()
		{
			if (Chainloader.PluginInfos.ContainsKey("com.DrBibop.VRAPI"))
			{
				VRInstalled = VR.enabled && MotionControls.enabled;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static Ray GetVRHandAimRay(bool dominant)
		{
			//IL_0015: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			return dominant ? MotionControls.dominantHand.aimRay : MotionControls.nonDominantHand.aimRay;
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AnimateVRHand(bool dominant, string triggerName)
		{
			HandController val = (dominant ? MotionControls.dominantHand : MotionControls.nonDominantHand);
			val.animator.SetTrigger(triggerName);
		}
	}
}
namespace ArtificerExtended.Unlocks
{
	[RegisterAchievement("AbsoluteZeroUnlock", "AbsoluteZeroUnlock", "FreeMage", 5u, null)]
	public class AbsoluteZeroUnlock : UnlockBase
	{
		public override string TOKEN_IDENTIFIER => "AbsoluteZeroUnlock".ToUpperInvariant();

		public override string AchievementName => "Artificer: Absolute Zero";

		public override string AchievementDesc => "As Artificer, freeze and execute the King of Nothing.";

		private void ExecuteMithrixCheck(orig_TakeDamage orig, HealthComponent self, DamageInfo damageInfo)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			CharacterBody body = self.body;
			BodyIndex bodyIndex = body.bodyIndex;
			if ((bodyIndex == BodyCatalog.FindBodyIndex("BrotherBody") || bodyIndex == BodyCatalog.FindBodyIndex("BrotherGlassBody") || bodyIndex == BodyCatalog.FindBodyIndex("BrotherHauntBody") || bodyIndex == BodyCatalog.FindBodyIndex("BrotherHurtBody")) && self.isInFrozenState)
			{
				flag = true;
			}
			orig.Invoke(self, damageInfo);
			if (!flag || self.alive)
			{
				return;
			}
			GameObject attacker = damageInfo.attacker;
			CharacterBody val = ((attacker != null) ? attacker.GetComponent<CharacterBody>() : null);
			if ((Object)(object)val != (Object)null)
			{
				BodyIndex bodyIndex2 = val.bodyIndex;
				if (bodyIndex2 == ((BaseAchievement)this).LookUpRequiredBodyIndex())
				{
					((BaseAchievement)this).Grant();
				}
			}
		}

		public override void OnInstall()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			HealthComponent.TakeDamage += new hook_TakeDamage(ExecuteMithrixCheck);
			((BaseAchievement)this).OnInstall();
		}

		public override void OnUninstall()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			HealthComponent.TakeDamage -= new hook_TakeDamage(ExecuteMithrixCheck);
			((BaseAchievement)this).OnUninstall();
		}
	}
	[RegisterAchievement("FastHellUnlock", "FastHellUnlock", "FreeMage", 5u, null)]
	internal class FastHellUnlock : UnlockBase
	{
		private static readonly string[] requiredScenes = new string[2] { "dampcavesimple", "helminthroost" };

		private SceneDef depthsSceneDef;

		private SceneDef hatcherySceneDef;

		public static float timeInMinutes = 3f;

		private bool stageOk = false;

		private float stageEnterTime;

		public override string TOKEN_IDENTIFIER => "FastHellUnlock".ToUpperInvariant();

		public override string AchievementName => "Artificer: God, It’s Pretty Hot Down Here";

		public override string AchievementDesc => $"As Artificer, leave the Abyssal Depths or Helminth Hatchery within {timeInMinutes} minutes of entering.";

		public override void OnInstall()
		{
			((BaseAchievement)this).OnInstall();
			depthsSceneDef = SceneCatalog.GetSceneDefFromSceneName("dampcavesimple");
			hatcherySceneDef = SceneCatalog.GetSceneDefFromSceneName("helminthroost");
		}

		public override void OnBodyRequirementMet()
		{
			((BaseAchievement)this).OnBodyRequirementMet();
			SceneCatalog.onMostRecentSceneDefChanged += HandleMostRecentSceneDefChanged;
		}

		public override void OnBodyRequirementBroken()
		{
			((BaseAchievement)this).OnBodyRequirementBroken();
			SceneCatalog.onMostRecentSceneDefChanged -= HandleMostRecentSceneDefChanged;
			stageOk = false;
			stageEnterTime = float.NegativeInfinity;
		}

		private bool CheckSceneRequirement(SceneDef sceneDef)
		{
			Debug.Log((object)sceneDef.baseSceneName);
			return requiredScenes.Contains(sceneDef.baseSceneName);
		}

		private void OnStageStart(Stage obj)
		{
			if (CheckSceneRequirement(obj.sceneDef))
			{
				stageOk = true;
				stageEnterTime = Run.instance.GetRunStopwatch();
			}
		}

		private void HandleMostRecentSceneDefChanged(SceneDef newSceneDef)
		{
			if (stageOk && stageEnterTime >= 0f)
			{
				float num = Run.instance.GetRunStopwatch() - stageEnterTime;
				Debug.Log((object)("seconds this stage: " + num));
				if (num <= timeInMinutes)
				{
				}
				((BaseAchievement)this).Grant();
				stageOk = false;
				stageEnterTime = float.NegativeInfinity;
			}
			else if (CheckSceneRequirement(newSceneDef))
			{
				stageOk = true;
				stageEnterTime = Run.instance.GetRunStopwatch();
			}
			else
			{
				stageOk = false;
				stageEnterTime = float.NegativeInfinity;
			}
		}
	}
	[RegisterAchievement("FreezeManySimultaneousUnlock", "FreezeManySimultaneousUnlock", "FreeMage", 5u, typeof(FreezeManySimultaneousServerAchievement))]
	internal class FreezeManySimultaneousUnlock : UnlockBase<FreezeManySimultaneousUnlock>
	{
		private class FreezeManySimultaneousServerAchievement : BaseServerAchievement
		{
			private Dictionary<SetStateOnHurt, float> avalancheUnlockTrackers;

			private CharacterBody trackedBody;

			public override void OnInstall()
			{
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Expected O, but got Unknown
				((BaseServerAchievement)this).OnInstall();
				avalancheUnlockTrackers = new Dictionary<SetStateOnHurt, float>();
				RoR2Application.onFixedUpdate += SetTrackedBody;
				SetStateOnHurt.SetFrozenInternal += new hook_SetFrozenInternal(AddFreezeTracker);
			}

			private void AddFreezeTracker(orig_SetFrozenInternal orig, SetStateOnHurt self, float duration)
			{
				orig.Invoke(self, duration);
				CharacterBody val = default(CharacterBody);
				if (!((Component)self).TryGetComponent<CharacterBody>(ref val))
				{
					return;
				}
				HealthComponent healthComponent = val.healthComponent;
				GameObject val2 = ((healthComponent != null) ? healthComponent.lastHitAttacker : null);
				CharacterBody val3 = default(CharacterBody);
				if (!Object.op_Implicit((Object)(object)val2) || !val2.TryGetComponent<CharacterBody>(ref val3) || (Object)(object)val3 != (Object)(object)trackedBody)
				{
					return;
				}
				int num = 1;
				bool flag = false;
				foreach (KeyValuePair<SetStateOnHurt, float> avalancheUnlockTracker in avalancheUnlockTrackers)
				{
					if (!((Object)(object)avalancheUnlockTracker.Key == (Object)null) && !(Time.time > avalancheUnlockTracker.Value))
					{
						num++;
						if (num >= freezeRequirementTotal)
						{
							flag = true;
							break;
						}
					}
				}
				if (flag)
				{
					((BaseServerAchievement)this).Grant();
					((BaseServerAchievement)this).ServerTryToCompleteActivity();
				}
				else if (avalancheUnlockTrackers.ContainsKey(self))
				{
					avalancheUnlockTrackers[self] = Time.time + duration;
				}
				else
				{
					avalancheUnlockTrackers.Add(self, Time.time + duration);
				}
			}

			private void SetTrackedBody()
			{
				trackedBody = ((BaseServerAchievement)this).GetCurrentBody();
			}

			public override void OnUninstall()
			{
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Expected O, but got Unknown
				((BaseServerAchievement)this).OnUninstall();
				RoR2Application.onFixedUpdate -= SetTrackedBody;
				SetStateOnHurt.SetFrozenInternal += new hook_SetFrozenInternal(AddFreezeTracker);
			}
		}

		public static int freezeRequirementTotal = 5;

		public override string AchievementName => "Artificer: Ice V Has Arrived";

		public override string AchievementDesc => $"As Artificer, have {freezeRequirementTotal} monsters frozen at once.";

		public override string TOKEN_IDENTIFIER => "FreezeManySimultaneousUnlock".ToUpperInvariant();

		public override void TryToCompleteActivity()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			bool flag = ((BaseAchievement)this).localUser.id == LocalUserManager.GetFirstLocalUser().id;
			if (((BaseAchievement)this).shouldGrant && flag)
			{
				BaseActivitySelector val = new BaseActivitySelector();
				val.activityAchievementID = "FreezeManySimultaneousUnlock";
				PlatformSystems.activityManager.TryToCompleteActivity(val, true, true);
			}
		}

		public override void OnBodyRequirementMet()
		{
			((BaseAchievement)this).OnBodyRequirementMet();
			((BaseAchievement)this).SetServerTracked(true);
		}

		public override void OnBodyRequirementBroken()
		{
			((BaseAchievement)this).OnBodyRequirementBroken();
			((BaseAchievement)this).SetServerTracked(false);
		}

		public override void OnInstall()
		{
			((BaseAchievement)this).OnInstall();
		}

		public override void OnUninstall()
		{
			((BaseAchievement)this).OnUninstall();
		}
	}
	[RegisterAchievement("FullKitElementUnlock", "FullKitElementUnlock", "FreeMage", 5u, null)]
	internal class FullKitElementUnlock : UnlockBase
	{
		public override string TOKEN_IDENTIFIER => "FullKitElementUnlock".ToUpperInvariant();

		public override string AchievementName => "Artificer: Elemental Intensity";

		public override string AchievementDesc => "As Artificer, win with 4 abilities of a single element equipped at once.";

		public override void OnInstall()
		{
			Run.onClientGameOverGlobal += ClearCheck;
			((BaseAchievement)this).OnInstall();
		}

		private void ClearCheck(Run run, RunReport runReport)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if (run == null || runReport == null || !Object.op_Implicit((Object)(object)runReport.gameEnding) || !runReport.gameEnding.isWin)
			{
				return;
			}
			CharacterBody cachedBody = ((BaseAchievement)this).localUser.cachedBody;
			if (cachedBody.bodyIndex == ((BaseAchievement)this).requiredBodyIndex)
			{
				ElementCounter component = ((Component)cachedBody).GetComponent<ElementCounter>();
				if ((Object)(object)component != (Object)null && (component.firePower >= ElementCounter.Power.Extreme || component.icePower >= ElementCounter.Power.Extreme || component.lightningPower >= ElementCounter.Power.Extreme))
				{
					((BaseAchievement)this).Grant();
				}
			}
		}

		public override void OnUninstall()
		{
			Run.onClientGameOverGlobal -= ClearCheck;
			((BaseAchievement)this).OnUninstall();
		}

		private void PowerCheck(orig_OnEnter orig, MageCharacterMain self)
		{
			orig.Invoke(self);
			CharacterBody characterBody = ((EntityState)self).characterBody;
			ElementCounter elementCounter = ((characterBody != null) ? ((Component)characterBody).GetComponent<ElementCounter>() : null);
			if ((Object)(object)elementCounter != (Object)null && (elementCounter.firePower >= ElementCounter.Power.Extreme || elementCounter.icePower >= ElementCounter.Power.Extreme || elementCounter.lightningPower >= ElementCounter.Power.Extreme))
			{
				((BaseAchievement)this).Grant();
			}
		}
	}
	[RegisterAchievement("KillBlazingWithFireUnlock", "KillBlazingWithFireUnlock", "FreeMage", 5u, null)]
	internal class KillBlazingWithFireUnlock : UnlockBase
	{
		public static int burnRequirementTotal = 15;

		public int burnCounter = 0;

		public override string TOKEN_IDENTIFIER => "KillBlazingWithFireUnlock".ToUpperInvariant();

		public override string AchievementName => "Artificer: Sinners For Dinner";

		public override string AchievementDesc => $"As Artificer, kill {burnRequirementTotal} Blazing Elites with burn damage in a single run.";

		public override void OnInstall()
		{
			GlobalEventManager.onCharacterDeathGlobal += AddBurnCounter;
			Run.onRunStartGlobal += ResetBurnCounter;
			((BaseAchievement)this).OnInstall();
		}

		public override void OnUninstall()
		{
			GlobalEventManager.onCharacterDeathGlobal -= AddBurnCounter;
			Run.onRunStartGlobal -= ResetBurnCounter;
			((BaseAchievement)this).OnUninstall();
		}

		private void ResetBurnCounter(Run obj)
		{
			burnCounter = 0;
		}

		private void AddBurnCounter(DamageReport obj)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Invalid comparison between Unknown and I4
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Invalid comparison between Unknown and I4
			CharacterBody attackerBody = obj.attackerBody;
			CharacterBody victimBody = obj.victimBody;
			if (!Object.op_Implicit((Object)(object)attackerBody) || !Object.op_Implicit((Object)(object)victimBody) || attackerBody.bodyIndex != ((BaseAchievement)this).LookUpRequiredBodyIndex() || !victimBody.HasBuff(Buffs.AffixRed))
			{
				return;
			}
			DamageInfo damageInfo = obj.damageInfo;
			bool flag = ((Enum)damageInfo.damageType.damageType).HasFlag((Enum)(object)(DamageType)128) || ((Enum)damageInfo.damageType.damageType).HasFlag((Enum)(object)(DamageType)8192);
			bool flag2 = (int)damageInfo.dotIndex == 1 || (int)damageInfo.dotIndex == 3 || (int)damageInfo.dotIndex == 7;
			if (flag || flag2)
			{
				burnCounter++;
				if (burnCounter >= burnRequirementTotal)
				{
					((BaseAchievement)this).Grant();
				}
			}
		}
	}
	[RegisterAchievement("MeteoriteDeathUnlock", "MeteoriteDeathUnlock", "FreeMage", 5u, null)]
	internal class MeteoriteDeathUnlock : UnlockBase
	{
		private GameObject meteorGameObject = LegacyResourcesAPI.Load<GameObject>("Prefabs/NetworkedObjects/MeteorStorm");

		public override string TOKEN_IDENTIFIER => "MeteoriteDeathUnlock".ToUpperInvariant();

		public override string AchievementName => "Artificer: Cloudy, With A Risk Of...";

		public override string AchievementDesc => "As Artificer, kill yourself with a meteor strike.";

		public override void OnInstall()
		{
			GlobalEventManager.onCharacterDeathGlobal += MeteorCheck;
			((BaseAchievement)this).OnInstall();
		}

		public override void OnUninstall()
		{
			GlobalEventManager.onCharacterDeathGlobal -= MeteorCheck;
			((BaseAchievement)this).OnUninstall();
		}

		private void MeteorCheck(DamageReport obj)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			CharacterBody attackerBody = obj.attackerBody;
			CharacterBody victimBody = obj.victimBody;
			if ((Object)(object)attackerBody == (Object)(object)victimBody && attackerBody.bodyIndex == ((BaseAchievement)this).LookUpRequiredBodyIndex())
			{
				GameObject inflictor = obj.damageInfo.inflictor;
				MeteorStormController component = inflictor.GetComponent<MeteorStormController>();
				if ((Object)(object)component != (Object)null && attackerBody.equipmentSlot.equipmentIndex == Equipment.Meteor.equipmentIndex)
				{
					((BaseAchievement)this).Grant();
				}
			}
		}
	}
	[RegisterAchievement("NoDamageUnlock", "NoDamageUnlock", "FreeMage", 5u, null)]
	internal class NoDamageUnlock : UnlockBase
	{
		public static float maxHealthFraction = 0.8f;

		private HealthComponent healthComponent;

		private bool failed;

		private bool characterOk;

		private ToggleAction healthCheck;

		private ToggleAction teleporterCheck;

		public override string TOKEN_IDENTIFIER => "NoDamageUnlock".ToUpperInvariant();

		public override string AchievementName => "Artificer: Flawless Execution";

		public override string AchievementDesc => "As Artificer, start and finish any stage without falling below " + Tools.ConvertDecimal(maxHealthFraction) + " health.";

		private void SubscribeHealthCheck()
		{
			RoR2Application.onFixedUpdate += CheckHealth;
		}

		private void UnsubscribeHealthCheck()
		{
			RoR2Application.onFixedUpdate -= CheckHealth;
		}

		private void SubscribeTeleporterCheck()
		{
			TeleporterInteraction.onTeleporterChargedGlobal += CheckTeleporter;
		}

		private void UnsubscribeTeleporterCheck()
		{
			TeleporterInteraction.onTeleporterChargedGlobal -= CheckTeleporter;
		}

		private void CheckTeleporter(TeleporterInteraction teleporterInteraction)
		{
			if (characterOk && !failed)
			{
				((BaseAchievement)this).Grant();
			}
		}

		public override void OnInstall()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			((BaseAchievement)this).OnInstall();
			healthCheck = new ToggleAction((Action)SubscribeHealthCheck, (Action)UnsubscribeHealthCheck);
			teleporterCheck = new ToggleAction((Action)SubscribeTeleporterCheck, (Action)UnsubscribeTeleporterCheck);
			SceneCatalog.onMostRecentSceneDefChanged += OnMostRecentSceneDefChanged;
			((BaseAchievement)this).localUser.onBodyChanged += OnBodyChanged;
		}

		public override void OnUninstall()
		{
			((BaseAchievement)this).localUser.onBodyChanged -= OnBodyChanged;
			SceneCatalog.onMostRecentSceneDefChanged -= OnMostRecentSceneDefChanged;
			healthCheck.Dispose();
			teleporterCheck.Dispose();
			((BaseAchievement)this).OnUninstall();
		}

		private void OnBodyChanged()
		{
			if (characterOk && !failed && Object.op_Implicit((Object)(object)((BaseAchievement)this).localUser.cachedBody))
			{
				healthComponent = ((BaseAchievement)this).localUser.cachedBody.healthComponent;
				healthCheck.SetActive(true);
				teleporterCheck.SetActive(true);
			}
		}

		private void OnMostRecentSceneDefChanged(SceneDef sceneDef)
		{
			failed = false;
		}

		public override void OnBodyRequirementMet()
		{
			((BaseAchievement)this).OnBodyRequirementMet();
			characterOk = true;
		}

		public override void OnBodyRequirementBroken()
		{
			characterOk = false;
			Fail();
			((BaseAchievement)this).OnBodyRequirementBroken();
		}

		private void Fail()
		{
			failed = true;
			healthCheck.SetActive(false);
			teleporterCheck.SetActive(false);
		}

		private void CheckHealth()
		{
			if (Object.op_Implicit((Object)(object)healthComponent) && healthComponent.combinedHealth < healthComponent.fullCombinedHealth * maxHealthFraction)
			{
				Fail();
			}
		}
	}
	[RegisterAchievement("OverkillOverloadingUnlock", "OverkillOverloadingUnlock", "FreeMage", 5u, typeof(OverkillOverloadingServerAchievement))]
	internal class OverkillOverloadingUnlock : UnlockBase
	{
		private class OverkillOverloadingServerAchievement : BaseServerAchievement
		{
			public override void OnInstall()
			{
				((BaseServerAchievement)this).OnInstall();
				GlobalEventManager.onCharacterDeathGlobal += OnDeathOverkillCheck;
				GlobalEventManager.onServerCharacterExecuted += OnExecuteOverkillCheck;
			}

			public override void OnUninstall()
			{
				((BaseServerAchievement)this).OnUninstall();
				GlobalEventManager.onCharacterDeathGlobal -= OnDeathOverkillCheck;
				GlobalEventManager.onServerCharacterExecuted -= OnExecuteOverkillCheck;
			}

			private void OnDeathOverkillCheck(DamageReport damageReport)
			{
				OnExecuteOverkillCheck(damageReport, 0f);
			}

			private void OnExecuteOverkillCheck(DamageReport damageReport, float executionHealthLost)
			{
				if ((Object)(object)damageReport.attackerBody != (Object)(object)((BaseServerAchievement)this).GetCurrentBody())
				{
					return;
				}
				CharacterBody victimBody = damageReport.victimBody;
				HealthComponent healthComponent = victimBody.healthComponent;
				bool flag = victimBody.HasBuff(Buffs.AffixBlue);
				float num = healthComponent.fullCombinedHealth - executionHealthLost;
				if (flag)
				{
					float num2 = damageReport.damageDealt - damageReport.combinedHealthBeforeDamage;
					if (num2 >= num * overkillAmount)
					{
						((BaseServerAchievement)this).Grant();
						((BaseServerAchievement)this).ServerTryToCompleteActivity();
					}
				}
			}
		}

		private static float overkillAmount = 1f;

		public override string TOKEN_IDENTIFIER => "OverkillOverloadingUnlock".ToUpperInvariant();

		public override string AchievementName => "Artificer: Powertrippin’";

		public override string AchievementDesc => $"As Artificer, overkill an Overloading Elite enemy by more than {overkillAmount * 100f}% of its combined maximum health.";

		public override void TryToCompleteActivity()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			bool flag = ((BaseAchievement)this).localUser.id == LocalUserManager.GetFirstLocalUser().id;
			if (((BaseAchievement)this).shouldGrant && flag)
			{
				BaseActivitySelector val = new BaseActivitySelector();
				val.activityAchievementID = "FreezeManySimultaneousUnlock";
				PlatformSystems.activityManager.TryToCompleteActivity(val, true, true);
			}
		}

		public override void OnInstall()
		{
			((BaseAchievement)this).OnInstall();
		}

		public override void OnUninstall()
		{
			((BaseAchievement)this).OnUninstall();
		}

		public override void OnBodyRequirementMet()
		{
			((BaseAchievement)this).OnBodyRequirementMet();
			((BaseAchievement)this).SetServerTracked(true);
		}

		public override void OnBodyRequirementBroken()
		{
			((BaseAchievement)this).OnBodyRequirementBroken();
			((BaseAchievement)this).SetServerTracked(false);
		}

		private void OverkillCheck(orig_TakeDamage orig, HealthComponent self, DamageInfo damageInfo)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			CharacterBody body = self.body;
			bool flag = body.HasBuff(Buffs.AffixBlue);
			float combinedHealth = self.combinedHealth;
			float num = self.fullHealth;
			orig.Invoke(self, damageInfo);
			if (!(!self.alive && flag))
			{
				return;
			}
			CharacterBody val = null;
			if ((Object)(object)damageInfo.attacker != (Object)null)
			{
				val = damageInfo.attacker.GetComponent<CharacterBody>();
			}
			if ((Object)(object)val != (Object)null && val.bodyIndex == ((BaseAchievement)this).LookUpRequiredBodyIndex())
			{
				if (self.isInFrozenState)
				{
					num *= 0.7f;
				}
				float num2 = damageInfo.damage - combinedHealth;
				if (num2 > num * overkillAmount)
				{
					((BaseAchievement)this).Grant();
				}
			}
		}
	}
	[RegisterAchievement("StackBurnUnlock", "StackBurnUnlock", "FreeMage", 5u, null)]
	internal class StackBurnUnlock : UnlockBase
	{
		public static int burnRequirementTotal = 25;

		public override string TOKEN_IDENTIFIER => "StackBurnUnlock".ToUpperInvariant();

		public override string AchievementName => "Artificer: The Ultimate Stonecutter";

		public override string AchievementDesc => $"As Artificer, apply {burnRequirementTotal} stacks of burn to a single target.";

		public override void OnInstall()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			GlobalEventManager.OnHitEnemy += new hook_OnHitEnemy(CountBurn);
			((BaseAchievement)this).OnInstall();
		}

		public override void OnUninstall()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			GlobalEventManager.OnHitEnemy -= new hook_OnHitEnemy(CountBurn);
			((BaseAchievement)this).OnUninstall();
		}

		private void CountBurn(orig_OnHitEnemy orig, GlobalEventManager self, DamageInfo damageInfo, GameObject victim)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			if (damageInfo.procCoefficient == 0f || damageInfo.rejected || !NetworkServer.active)
			{
				return;
			}
			CharacterBody component = victim.GetComponent<CharacterBody>();
			CharacterBody val = null;
			if ((Object)(object)damageInfo.attacker != (Object)null)
			{
				val = damageInfo.attacker.GetComponent<CharacterBody>();
			}
			if ((Object)(object)component != (Object)null && (Object)(object)val != (Object)null && val.bodyIndex == ((BaseAchievement)this).LookUpRequiredBodyIndex())
			{
				int num = component.GetBuffCount(Buffs.OnFire) + component.GetBuffCount(Buffs.StrongerBurn) + 1;
				if (num >= burnRequirementTotal)
				{
					((BaseAchievement)this).Grant();
				}
			}
			orig.Invoke(self, damageInfo, victim);
		}
	}
	[RegisterAchievement("TankDamageUnlock", "TankDamageUnlock", "FreeMage", 5u, null)]
	internal class TankDamageUnlock : UnlockBase
	{
		public static int damageRequirementTotal = 5000;

		private float damageTakenCount = 0f;

		public ulong killRequirementTotal = 5uL;

		public StatDef postmortemKillCounter = UnlockBase.GetCareerStatTotal("artificerKillsPostMortem");

		public override string TOKEN_IDENTIFIER => "TankDamageUnlock".ToUpperInvariant();

		public override string AchievementName => "Artificer: Cold Hearted";

		public override string AchievementDesc => $"As Artificer, take more than {damageRequirementTotal} points of damage in a single life.";

		private void ResetDamageCount()
		{
			damageTakenCount = 0f;
		}

		public override void OnBodyRequirementMet()
		{
			((BaseAchievement)this).OnBodyRequirementMet();
			GlobalEventManager.onServerDamageDealt += DamageCounter;
			Run.onClientGameOverGlobal += ClearCheck;
		}

		private void ClearCheck(Run run, RunReport runReport)
		{
			ResetDamageCount();
		}

		public override void OnBodyRequirementBroken()
		{
			((BaseAchievement)this).OnBodyRequirementBroken();
			GlobalEventManager.onServerDamageDealt -= DamageCounter;
		}

		private void DamageCounter(DamageReport damageReport)
		{
			if (!((Object)(object)damageReport.victimBody == (Object)(object)((BaseAchievement)this).localUser.cachedBody))
			{
				return;
			}
			if (!damageReport.victimBody.healthComponent.alive)
			{
				ResetDamageCount();
				return;
			}
			damageTakenCount += damageReport.damageDealt;
			if (damageTakenCount > (float)damageRequirementTotal)
			{
				((BaseAchievement)this).Grant();
			}
		}

		private void ColdFusionKillCounter(DamageReport damageReport)
		{
			//IL_0002: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Invalid comparison between Unknown and I4
			BodyIndex attackerBodyIndex = damageReport.attackerBodyIndex;
			CharacterMaster attackerMaster = damageReport.attackerMaster;
			string? text = ((object)(BodyIndex)(ref attackerBodyIndex)).ToString();
			BodyIndex val = ((BaseAchievement)this).LookUpRequiredBodyIndex();
			Debug.Log((object)(text + " + " + ((object)(BodyIndex)(ref val)).ToString()));
			if (!Object.op_Implicit((Object)(object)attackerMaster) || (attackerBodyIndex != ((BaseAchievement)this).LookUpRequiredBodyIndex() && (int)attackerBodyIndex != -1))
			{
				return;
			}
			CharacterBody attackerBody = damageReport.attackerBody;
			if ((Object)(object)attackerBody == (Object)null || !attackerBody.healthComponent.alive)
			{
				StatSheet currentStats = attackerMaster.playerStatsComponent.currentStats;
				currentStats.PushStatValue(postmortemKillCounter, 1uL);
				ulong statValueULong = ((BaseAchievement)this).userProfile.statSheet.GetStatValueULong(postmortemKillCounter);
				Debug.Log((object)statValueULong);
				if (statValueULong >= killRequirementTotal)
				{
					((BaseAchievement)this).Grant();
				}
			}
		}
	}
	[RegisterAchievement("UgornsMusicUnlock", "UgornsMusicUnlock", "FreeMage", 5u, typeof(UgornsMusicServerAchievement))]
	internal class UgornsMusicUnlock : UnlockBase
	{
		private class UgornsMusicServerAchievement : BaseServerAchievement
		{
			private CharacterBody trackedBody;

			public override void OnInstall()
			{
				((BaseServerAchievement)this).OnInstall();
				GlobalEventManager.onCharacterDeathGlobal += OnDeathResonanceCheck;
			}

			public override void OnUninstall()
			{
				((BaseServerAchievement)this).OnUninstall();
				GlobalEventManager.onCharacterDeathGlobal -= OnDeathResonanceCheck;
			}

			private void OnDeathResonanceCheck(DamageReport damageReport)
			{
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				CharacterBody currentBody = ((BaseServerAchievement)this).networkUser.GetCurrentBody();
				if (Object.op_Implicit((Object)(object)currentBody))
				{
					CharacterBody victimBody = damageReport.victimBody;
					if (victimBody.bodyIndex == BodyCatalog.FindBodyIndex("ElectricWormBody") && ElementCounter.GetPowerLevelFromBody(((Component)currentBody).gameObject, (MageElement)3) >= ElementCounter.Power.Low)
					{
						((BaseServerAchievement)this).Grant();
						((BaseServerAchievement)this).ServerTryToCompleteActivity();
					}
				}
			}
		}

		private Inventory currentInventory;

		public override string TOKEN_IDENTIFIER => "UgornsMusicUnlock".ToUpperInvariant();

		public override string AchievementName => "Artificer: Ugorn’s Music";

		public override string AchievementDesc => "As Artificer, with at least one Lightning ability equipped, triumph over an Overloading Worm.";

		public override void TryToCompleteActivity()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			bool flag = ((BaseAchievement)this).localUser.id == LocalUserManager.GetFirstLocalUser().id;
			if (((BaseAchievement)this).shouldGrant && flag)
			{
				BaseActivitySelector val = new BaseActivitySelector();
				val.activityAchievementID = "FreezeManySimultaneousUnlock";
				PlatformSystems.activityManager.TryToCompleteActivity(val, true, true);
			}
		}

		public override void OnBodyRequirementMet()
		{
			((BaseAchievement)this).OnBodyRequirementMet();
			((BaseAchievement)this).SetServerTracked(true);
		}

		public override void OnBodyRequirementBroken()
		{
			((BaseAchievement)this).OnBodyRequirementBroken();
			((BaseAchievement)this).SetServerTracked(false);
		}

		public override void OnInstall()
		{
			((BaseAchievement)this).OnInstall();
		}

		public override void OnUninstall()
		{
			((BaseAchievement)this).OnUninstall();
		}

		private void UpdateInventory()
		{
			Inventory val = null;
			if (Object.op_Implicit((Object)(object)((BaseAchievement)this).localUser.cachedMasterController))
			{
				val = ((BaseAchievement)this).localUser.cachedMasterController.master.inventory;
			}
			SetCurrentInventory(val);
		}

		private void SetCurrentInventory(Inventory newInventory)
		{
			if (!((Object)(object)currentInventory == (Object)(object)newInventory))
			{
				if ((Object)(object)currentInventory != (Object)null)
				{
					currentInventory.onInventoryChanged -= OnInventoryChanged;
				}
				currentInventory = newInventory;
				if ((Object)(object)currentInventory != (Object)null)
				{
					currentInventory.onInventoryChanged += OnInventoryChanged;
					OnInventoryChanged();
				}
			}
		}

		private void OnInventoryChanged()
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			GameObject cachedBodyObject = ((BaseAchievement)this).localUser.cachedBodyObject;
			if (!((Object)(object)((Component)currentInventory).gameObject == (Object)(object)cachedBodyObject) || !((BaseAchievement)this).meetsBodyRequirement)
			{
				return;
			}
			ElementCounter component = cachedBodyObject.GetComponent<ElementCounter>();
			if ((Object)(object)component != (Object)null && component.lightningPower >= ElementCounter.Power.Low)
			{
				if (currentInventory.currentEquipmentIndex == Equipment.AffixBlue.equipmentIndex)
				{
					((BaseAchievement)this).Grant();
				}
				else if (currentInventory.currentEquipmentIndex == Equipment.Lightning.equipmentIndex && currentInventory.GetItemCount(Items.LightningStrikeOnHit) > 0)
				{
					((BaseAchievement)this).Grant();
				}
			}
		}

		private void ImpBossSmiteCheck(DamageReport obj)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			CharacterBody attackerBody = obj.attackerBody;
			CharacterBody victimBody = obj.victimBody;
			DamageInfo damageInfo = obj.damageInfo;
			if (Object.op_Implicit((Object)(object)attackerBody) && Object.op_Implicit((Object)(object)victimBody) && damageInfo != null)
			{
				bool flag = victimBody.bodyIndex == BodyCatalog.FindBodyIndex("ImpBossBody");
				if (attackerBody.bodyIndex == ((BaseAchievement)this).LookUpRequiredBodyIndex() && flag && (damageInfo.force == Vector3.down * 1500f || (damageInfo.force == Vector3.down * 3000f && ((Enum)damageInfo.damageType.damageType).HasFlag((Enum)(object)(DamageType)32))) && (Object)(object)damageInfo.inflictor == (Object)null)
				{
					((BaseAchievement)this).Grant();
				}
			}
		}
	}
	public abstract class UnlockBase<T> : UnlockBase where T : UnlockBase<T>
	{
		public static T instance { get; private set; }

		public UnlockBase()
		{
			if (instance != null)
			{
				Log.Error("Singleton class \"" + typeof(T).Name + "\" inheriting UnlockBase was instantiated twice");
			}
			else
			{
				instance = this as T;
			}
		}
	}
	public abstract class UnlockBase : BaseAchievement
	{
		public static Dictionary<string, UnlockableDef> allUnlockDefs = new Dictionary<string, UnlockableDef>();

		public abstract string TOKEN_IDENTIFIER { get; }

		public abstract string AchievementName { get; }

		public abstract string AchievementDesc { get; }

		public static UnlockableDef CreateUnlockDef(Type RequiredUnlock, Sprite icon)
		{
			string name = RequiredUnlock.Name;
			if (allUnlockDefs.ContainsKey(name))
			{
				return allUnlockDefs[name];
			}
			string text = name.ToUpperInvariant();
			UnlockableDef val = Content.CreateAndAddUnlockbleDef(name, name, icon);
			string nameToken = "ACHIEVEMENT_" + text + "_NAME";
			string descToken = "ACHIEVEMENT_" + text + "_DESCRIPTION";
			LanguageAPI.Add(nameToken, Reflection.GetPropertyValue<string>(RequiredUnlock, "AchievementName"));
			LanguageAPI.Add(descToken, Reflection.GetPropertyValue<string>(RequiredUnlock, "AchievementDesc"));
			val.getHowToUnlockString = () => Language.GetStringFormatted("UNLOCK_VIA_ACHIEVEMENT_FORMAT", new object[2]
			{
				Language.GetString(nameToken),
				Language.GetString(descToken)
			});
			val.getUnlockedString = () => Language.GetStringFormatted("UNLOCKED_FORMAT", new object[2]
			{
				Language.GetString(nameToken),
				Language.GetString(descToken)
			});
			allUnlockDefs[name] = val;
			return val;
		}

		public void AddLang()
		{
			LanguageAPI.Add("ACHIEVEMENT_" + TOKEN_IDENTIFIER + "_NAME", AchievementName);
			LanguageAPI.Add("ACHIEVEMENT_" + TOKEN_IDENTIFIER + "_DESCRI