Decompiled source of HexedRisk v1.0.4

plugins/HexedRisk/HexedRisk.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using On.RoR2;
using R2API;
using R2API.Networking;
using R2API.Networking.Interfaces;
using RoR2;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace HexedRisk
{
	internal enum HexId : byte
	{
		GlassCannon,
		GetExcited,
		Minionmancer,
		Earthwake,
		Dropkick,
		TapDancer,
		DoubleTap,
		MagicMissile,
		InfernalConduit,
		CircleOfDeath,
		ShrinkEngine,
		ToothFairy,
		Goliath,
		NearDeathInsight,
		TankEngine,
		EtherealWeapon,
		Vulnerability,
		BackToBasics,
		GiantSlayer,
		Firebrand,
		PandorasBox,
		MysticPunch,
		Archmage,
		TransmuteChaos,
		TransmutePrismatic,
		TransmuteGold,
		Eureka,
		JeweledGauntlet,
		DontBlink,
		FinalForm,
		SlapAround,
		CelestialBody,
		Recursion,
		SkilledSniper,
		Erosion,
		Typhoon,
		VeilOfWarding,
		HeavyHitter,
		CritDefense,
		ShadowRunner,
		BurningInterest
	}
	internal sealed class HexDefinition
	{
		internal HexId Id { get; }

		internal string Name { get; }

		internal string Description { get; }

		internal string Accent { get; }

		internal HexDefinition(HexId id, string name, string description, string accent)
		{
			Id = id;
			Name = name;
			Description = description;
			Accent = accent;
		}
	}
	internal static class HexCatalog
	{
		internal static readonly IReadOnlyList<HexDefinition> All = new HexDefinition[41]
		{
			new HexDefinition(HexId.GlassCannon, "玻璃大炮", "最大生命值降低 30%,所有伤害提高 25%", "#e879f9"),
			new HexDefinition(HexId.GetExcited, "罪恶快感", "击杀后获得 40% 移速和 20% 攻速,持续 4 秒;击杀精英持续 8 秒", "#facc15"),
			new HexDefinition(HexId.Minionmancer, "仆从大师", "无人机、炮塔和召唤物获得 40% 生命与伤害,体型增大 150%", "#facc15"),
			new HexDefinition(HexId.Earthwake, "大地苏醒", "使用位移技能后在原地留下震点,1 秒后爆炸,造成 300% 基础伤害", "#e879f9"),
			new HexDefinition(HexId.Dropkick, "飞身踢", "处决阈值为 10% 加最大生命值成长:每 200 最大生命值提高 1%;Boss 不会被处决", "#e879f9"),
			new HexDefinition(HexId.TapDancer, "踢踏舞", "普攻获得 1 米/秒移速,持续 4 秒;额外移速的 75% 转为攻速,第一关最多 20 层,此后每关上限增加 10 层", "#e879f9"),
			new HexDefinition(HexId.DoubleTap, "双发快射", "暴击会额外触发一次攻击特效,不会递归触发自身", "#facc15"),
			new HexDefinition(HexId.MagicMissile, "魔法飞弹", "技能命中发射 3 枚追踪弹;每枚造成目标最大生命值 1% 的伤害,Boss 有伤害上限", "#facc15"),
			new HexDefinition(HexId.InfernalConduit, "炼狱导管", "技能命中施加灼烧;灼烧伤害每 0.25 秒最多缩短全部技能冷却 0.2 秒", "#e879f9"),
			new HexDefinition(HexId.CircleOfDeath, "死亡之环", "获得治疗时对最近敌人造成治疗量 150% 的伤害,每秒最多触发 4 次", "#e879f9"),
			new HexDefinition(HexId.ShrinkEngine, "缩小引擎", "击杀精英后体型缩小 5%,获得 5% 冷却缩减和 5% 移速;冷却缩减上限 80%,死亡损失 65% 层数", "#facc15"),
			new HexDefinition(HexId.ToothFairy, "牙仙子", "4 秒内对同一目标造成其 25% 最大生命伤害时自动吸收牙齿;每层增加 10% 无视护甲几率,本关最多 10 层", "#facc15"),
			new HexDefinition(HexId.Goliath, "歌利亚巨人", "体型增大 50%,最大生命值提高 50%,伤害提高 25%,移动速度降低 10%", "#e879f9"),
			new HexDefinition(HexId.NearDeathInsight, "濒死悟道", "受到致命伤时免疫该次伤害并恢复至 35% 生命,冷却 240 秒", "#e879f9"),
			new HexDefinition(HexId.TankEngine, "坦克引擎", "击杀精英或 Boss 获得 1 层:体型提高 4%,最大生命值提高 6%;死亡损失 65% 层数", "#facc15"),
			new HexDefinition(HexId.EtherealWeapon, "虚幻武器", "伤害技能额外触发一次攻击特效,同一目标冷却 0.5 秒", "#facc15"),
			new HexDefinition(HexId.Vulnerability, "易损", "获得 25% 暴击率;主动装备伤害和持续伤害可以暴击", "#facc15"),
			new HexDefinition(HexId.BackToBasics, "回归基本功", "封印特殊技能;其他三类技能伤害和治疗提高 50%,冷却缩短 40%", "#e879f9"),
			new HexDefinition(HexId.GiantSlayer, "巨人杀手", "体型缩小 25% 并获得 25% 移速;对更大敌人造成 25%-75% 额外伤害", "#e879f9"),
			new HexDefinition(HexId.Firebrand, "火上浇油", "攻击施加持续 5 秒的灼烧,每次攻击累计目标最大生命值 0.5% 的总伤害", "#facc15"),
			new HexDefinition(HexId.PandorasBox, "潘朵拉的盒子", "消耗自身,将当前全部海克斯随机重铸为不重复的棱彩海克斯", "#e879f9"),
			new HexDefinition(HexId.MysticPunch, "秘术冲拳", "攻击特效命中时使全部技能冷却缩短 0.25 秒,每秒最多 4 次", "#e879f9"),
			new HexDefinition(HexId.Archmage, "大法师", "施放技能时,随机使另一个技能返还本次技能基础冷却的 30%", "#e879f9"),
			new HexDefinition(HexId.TransmuteChaos, "质变:混沌", "消耗自身,按等级权重随机获得 2 个不重复海克斯", "#e879f9"),
			new HexDefinition(HexId.TransmutePrismatic, "质变:棱彩阶", "消耗自身,随机获得 1 个未拥有的棱彩海克斯", "#facc15"),
			new HexDefinition(HexId.TransmuteGold, "质变:黄金阶", "消耗自身,随机获得 1 个未拥有的黄金海克斯", "#c0c0c0"),
			new HexDefinition(HexId.Eureka, "尤里卡", "额外伤害加成的 30% 转化为技能冷却缩减,最多 40%", "#e879f9"),
			new HexDefinition(HexId.JeweledGauntlet, "珠光护手", "获得 25% 暴击率;技能可以暴击,技能暴击造成 145% 总伤害", "#e879f9"),
			new HexDefinition(HexId.DontBlink, "唯快不破", "每比目标快 10% 造成 1% 额外伤害,最多 30%", "#c0c0c0"),
			new HexDefinition(HexId.FinalForm, "最终形态", "施放特殊技能后获得 30% 最大生命屏障、10% 吸血和 30% 移速,持续 10 秒;20 秒冷却", "#e879f9"),
			new HexDefinition(HexId.SlapAround, "扇巴掌", "硬控精英或 Boss 后永久获得 5% 基础伤害;同一目标 5 秒冷却,死亡损失 50% 层数", "#c0c0c0"),
			new HexDefinition(HexId.CelestialBody, "星界躯体", "最大生命提高 60%,造成的伤害降低 10%", "#facc15"),
			new HexDefinition(HexId.Recursion, "循环往复", "所有技能冷却时间降低 35%", "#facc15"),
			new HexDefinition(HexId.SkilledSniper, "老练狙神", "50 米外用非特殊技能命中时返还该技能 50% 冷却;低 Proc 持续伤害返还 30%", "#facc15"),
			new HexDefinition(HexId.Erosion, "侵蚀", "直接伤害施加持续 4 秒的 1.5 护甲削减,最多 20 层", "#c0c0c0"),
			new HexDefinition(HexId.Typhoon, "台风", "攻击时向额外目标发射造成 30% 伤害的飞弹,并以 30% 效能触发攻击特效", "#c0c0c0"),
			new HexDefinition(HexId.VeilOfWarding, "防护面纱", "每 30 秒无条件格挡下一次伤害,包括坠落、自伤和环境伤害", "#c0c0c0"),
			new HexDefinition(HexId.HeavyHitter, "重量级打击手", "普攻附加生命区间伤害:floor(最大生命/100)×100×3.5%", "#c0c0c0"),
			new HexDefinition(HexId.CritDefense, "会心防御", "获得 25% 暴击率;受伤时以至多 50% 暴击率概率使伤害降低 20%", "#c0c0c0"),
			new HexDefinition(HexId.ShadowRunner, "暗影疾奔", "使用位移技能后获得 100% 移速,持续 2 秒", "#c0c0c0"),
			new HexDefinition(HexId.BurningInterest, "炽燃利息", "持续伤害的 0.2% 转化为金币;每秒最多 5 金,每关最多 100 金", "#facc15")
		};

		internal static readonly HexId[] PrismaticPool = new HexId[15]
		{
			HexId.GlassCannon,
			HexId.Earthwake,
			HexId.Dropkick,
			HexId.TapDancer,
			HexId.InfernalConduit,
			HexId.CircleOfDeath,
			HexId.Goliath,
			HexId.NearDeathInsight,
			HexId.BackToBasics,
			HexId.GiantSlayer,
			HexId.MysticPunch,
			HexId.Archmage,
			HexId.Eureka,
			HexId.JeweledGauntlet,
			HexId.FinalForm
		};

		internal static readonly HexId[] GoldPool = new HexId[14]
		{
			HexId.GetExcited,
			HexId.Minionmancer,
			HexId.DoubleTap,
			HexId.MagicMissile,
			HexId.ShrinkEngine,
			HexId.ToothFairy,
			HexId.TankEngine,
			HexId.EtherealWeapon,
			HexId.Vulnerability,
			HexId.Firebrand,
			HexId.CelestialBody,
			HexId.Recursion,
			HexId.SkilledSniper,
			HexId.BurningInterest
		};

		internal static readonly HexId[] SilverPool = new HexId[8]
		{
			HexId.DontBlink,
			HexId.SlapAround,
			HexId.Erosion,
			HexId.Typhoon,
			HexId.VeilOfWarding,
			HexId.HeavyHitter,
			HexId.CritDefense,
			HexId.ShadowRunner
		};

		private static readonly Dictionary<HexId, HexDefinition> ById = BuildIndex();

		internal static HexDefinition Get(HexId id)
		{
			return ById[id];
		}

		internal static bool HasAvailable(CharacterMaster master)
		{
			return All.Any((HexDefinition hex) => HexRunState.GetStacks(master, hex.Id) == 0);
		}

		internal static HexDefinition[] RollThree(CharacterMaster master, Random random)
		{
			HexDefinition[] array = All.Where((HexDefinition hex) => HexRunState.GetStacks(master, hex.Id) == 0).ToArray();
			int[] array2 = new int[array.Length];
			for (int num = 0; num < array.Length; num++)
			{
				array2[num] = num;
			}
			int num2 = Math.Min(3, array2.Length);
			for (int num3 = 0; num3 < num2; num3++)
			{
				int num4 = random.Next(num3, array2.Length);
				ref int reference = ref array2[num3];
				ref int reference2 = ref array2[num4];
				int num5 = array2[num4];
				int num6 = array2[num3];
				reference = num5;
				reference2 = num6;
			}
			HexDefinition[] array3 = new HexDefinition[num2];
			for (int num7 = 0; num7 < num2; num7++)
			{
				array3[num7] = array[array2[num7]];
			}
			return array3;
		}

		internal static HexDefinition? RollOne(CharacterMaster master, IReadOnlyList<HexDefinition> visibleChoices, Random random)
		{
			HexDefinition[] array = All.Where((HexDefinition candidate) => HexRunState.GetStacks(master, candidate.Id) == 0 && visibleChoices.All((HexDefinition visible) => visible.Id != candidate.Id)).ToArray();
			if (array.Length != 0)
			{
				return array[random.Next(array.Length)];
			}
			return null;
		}

		private static Dictionary<HexId, HexDefinition> BuildIndex()
		{
			Dictionary<HexId, HexDefinition> dictionary = new Dictionary<HexId, HexDefinition>();
			foreach (HexDefinition item in All)
			{
				dictionary.Add(item.Id, item);
			}
			return dictionary;
		}
	}
	internal sealed class HexPickerUI
	{
		private readonly Action<CharacterMaster, HexId> _onSelected;

		private readonly ConfigEntry<bool> _showOverlay;

		private readonly Random _random = new Random();

		private HexDefinition[] _choices = Array.Empty<HexDefinition>();

		private CharacterMaster? _owner;

		private int[] _rerollsLeft = Array.Empty<int>();

		private bool _visible;

		private bool _overlayVisible = true;

		private CursorLockMode _previousLockMode;

		private bool _previousCursorVisible;

		private Font? _font;

		private GUIStyle? _titleStyle;

		private GUIStyle? _subtitleStyle;

		private GUIStyle? _cardStyle;

		private GUIStyle? _buttonStyle;

		private GUIStyle? _overlayStyle;

		internal bool IsVisible => _visible;

		internal HexPickerUI(Action<CharacterMaster, HexId> onSelected, ConfigEntry<bool> showOverlay)
		{
			_onSelected = onSelected;
			_showOverlay = showOverlay;
		}

		internal void Open(CharacterMaster owner, int rerolls)
		{
			//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)
			if (!_visible)
			{
				_owner = owner;
				_choices = HexCatalog.RollThree(owner, _random);
				_rerollsLeft = new int[_choices.Length];
				for (int i = 0; i < _rerollsLeft.Length; i++)
				{
					_rerollsLeft[i] = Math.Max(0, rerolls);
				}
				_previousLockMode = Cursor.lockState;
				_previousCursorVisible = Cursor.visible;
				_visible = true;
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
			}
		}

		internal void Close()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (_visible)
			{
				_visible = false;
				_owner = null;
				Cursor.lockState = _previousLockMode;
				Cursor.visible = _previousCursorVisible;
			}
		}

		internal void Update()
		{
			if (Input.GetKeyDown((KeyCode)288))
			{
				_overlayVisible = !_overlayVisible;
			}
			if (_visible)
			{
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
			}
		}

		internal void Draw()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			EnsureStyles();
			if (_showOverlay.Value && _overlayVisible)
			{
				DrawActiveHexes();
			}
			if (!_visible)
			{
				return;
			}
			Color color = GUI.color;
			GUI.color = new Color(0f, 0f, 0f, 0.72f);
			GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)Texture2D.whiteTexture);
			GUI.color = color;
			float num = Mathf.Min(1120f, (float)Screen.width - 60f);
			float num2 = Mathf.Min(590f, (float)Screen.height - 60f);
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(((float)Screen.width - num) / 2f, ((float)Screen.height - num2) / 2f, num, num2);
			GUI.Box(val, GUIContent.none, _overlayStyle);
			GUI.Label(new Rect(((Rect)(ref val)).x + 30f, ((Rect)(ref val)).y + 22f, ((Rect)(ref val)).width - 60f, 48f), "选择一个海克斯", _titleStyle);
			GUI.Label(new Rect(((Rect)(ref val)).x + 30f, ((Rect)(ref val)).y + 69f, ((Rect)(ref val)).width - 60f, 30f), "仅对你的角色生效,并持续至本局结束", _subtitleStyle);
			float num3 = 18f;
			float num4 = (((Rect)(ref val)).width - 60f - num3 * 2f) / 3f;
			Rect val2 = default(Rect);
			for (int i = 0; i < _choices.Length; i++)
			{
				HexDefinition hexDefinition = _choices[i];
				string text = "<size=26><color=" + hexDefinition.Accent + ">" + hexDefinition.Name + "</color></size>\n\n<size=18>" + hexDefinition.Description + "</size>";
				((Rect)(ref val2))..ctor(((Rect)(ref val)).x + 30f + (float)i * (num4 + num3), ((Rect)(ref val)).y + 118f, num4, ((Rect)(ref val)).height - 240f);
				if (GUI.Button(val2, text, _cardStyle))
				{
					if ((Object)(object)_owner != (Object)null)
					{
						_onSelected(_owner, hexDefinition.Id);
					}
					Close();
					break;
				}
				GUI.enabled = _rerollsLeft[i] > 0 && (Object)(object)_owner != (Object)null && HexCatalog.All.Count - HexRunState.Enumerate(_owner).Count() > _choices.Length;
				if (GUI.Button(new Rect(((Rect)(ref val2)).x, ((Rect)(ref val)).yMax - 92f, num4, 44f), $"单独刷新(剩余 {_rerollsLeft[i]} 次)", _buttonStyle))
				{
					HexDefinition hexDefinition2 = HexCatalog.RollOne(_owner, _choices, _random);
					if (hexDefinition2 != null)
					{
						_choices[i] = hexDefinition2;
						_rerollsLeft[i]--;
					}
				}
				GUI.enabled = true;
			}
		}

		private void DrawActiveHexes()
		{
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			string text = "<b>海克斯</b>  <size=13>[F7 隐藏]</size>";
			int num = 0;
			LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
			CharacterMaster val = ((firstLocalUser != null) ? firstLocalUser.cachedMaster : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			foreach (KeyValuePair<HexId, int> item in HexRunState.Enumerate(val))
			{
				HexDefinition hexDefinition = HexCatalog.Get(item.Key);
				text += $"\n<color={hexDefinition.Accent}>{hexDefinition.Name}</color> ×{item.Value}";
				num++;
			}
			if (num != 0)
			{
				float num2 = 42f + (float)num * 24f;
				GUI.Box(new Rect(18f, 90f, 245f, num2), text, _overlayStyle);
			}
		}

		private void EnsureStyles()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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)
			//IL_007b: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			//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_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Expected O, but got Unknown
			//IL_011b: Expected O, but got Unknown
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Expected O, but got Unknown
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Expected O, but got Unknown
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Expected O, but got Unknown
			if (_titleStyle == null)
			{
				_font = Font.CreateDynamicFontFromOSFont(new string[3] { "Microsoft YaHei UI", "Microsoft YaHei", "Arial" }, 22);
				GUIStyle val = new GUIStyle(GUI.skin.label)
				{
					font = _font,
					fontSize = 34,
					alignment = (TextAnchor)4,
					fontStyle = (FontStyle)1
				};
				val.normal.textColor = Color.white;
				_titleStyle = val;
				GUIStyle val2 = new GUIStyle(GUI.skin.label)
				{
					font = _font,
					fontSize = 17,
					alignment = (TextAnchor)4
				};
				val2.normal.textColor = new Color(0.78f, 0.82f, 0.88f);
				_subtitleStyle = val2;
				_cardStyle = new GUIStyle(GUI.skin.button)
				{
					font = _font,
					fontSize = 18,
					alignment = (TextAnchor)4,
					wordWrap = true,
					richText = true,
					padding = new RectOffset(20, 20, 20, 20)
				};
				_buttonStyle = new GUIStyle(GUI.skin.button)
				{
					font = _font,
					fontSize = 17,
					alignment = (TextAnchor)4
				};
				GUIStyle val3 = new GUIStyle(GUI.skin.box)
				{
					font = _font,
					fontSize = 16,
					alignment = (TextAnchor)0,
					richText = true,
					padding = new RectOffset(14, 14, 12, 12)
				};
				val3.normal.textColor = Color.white;
				_overlayStyle = val3;
			}
		}
	}
	internal static class HexRunState
	{
		internal const int MaxSelectionsPerPlayer = 6;

		private static readonly Dictionary<CharacterMaster, Dictionary<HexId, int>> PlayerStacks = new Dictionary<CharacterMaster, Dictionary<HexId, int>>();

		private static readonly Dictionary<CharacterMaster, int> SelectionCounts = new Dictionary<CharacterMaster, int>();

		private static readonly Dictionary<CharacterBody, float> ExcitedUntil = new Dictionary<CharacterBody, float>();

		private static readonly Dictionary<CharacterBody, TimedStackState> TapDancerStates = new Dictionary<CharacterBody, TimedStackState>();

		private static readonly Dictionary<CharacterBody, float> InfernalNextRecharge = new Dictionary<CharacterBody, float>();

		private static readonly Dictionary<CharacterBody, TriggerWindow> CircleTriggerWindows = new Dictionary<CharacterBody, TriggerWindow>();

		private static readonly Dictionary<CharacterMaster, int> ShrinkEngineStacks = new Dictionary<CharacterMaster, int>();

		private static readonly Dictionary<CharacterMaster, int> TankEngineStacks = new Dictionary<CharacterMaster, int>();

		private static readonly Dictionary<CharacterMaster, int> ToothStacks = new Dictionary<CharacterMaster, int>();

		private static readonly Dictionary<(CharacterMaster, HealthComponent), ToothProgress> ToothProgresses = new Dictionary<(CharacterMaster, HealthComponent), ToothProgress>();

		private static readonly Dictionary<CharacterMaster, float> NearDeathReadyAt = new Dictionary<CharacterMaster, float>();

		private static readonly Dictionary<(CharacterBody, HealthComponent), float> EtherealReadyAt = new Dictionary<(CharacterBody, HealthComponent), float>();

		private static readonly Dictionary<CharacterBody, TriggerWindow> MysticPunchWindows = new Dictionary<CharacterBody, TriggerWindow>();

		private static readonly HashSet<HealthComponent> DropkickExecuting = new HashSet<HealthComponent>();

		private static readonly Dictionary<CharacterBody, float> FinalFormUntil = new Dictionary<CharacterBody, float>();

		private static readonly Dictionary<CharacterMaster, float> FinalFormReadyAt = new Dictionary<CharacterMaster, float>();

		private static readonly Dictionary<CharacterBody, float> ShadowRunnerUntil = new Dictionary<CharacterBody, float>();

		private static readonly Dictionary<(CharacterMaster, HealthComponent), float> SlapReadyAt = new Dictionary<(CharacterMaster, HealthComponent), float>();

		private static readonly Dictionary<CharacterMaster, int> SlapStacks = new Dictionary<CharacterMaster, int>();

		private static readonly Dictionary<HealthComponent, ErosionState> ErosionStates = new Dictionary<HealthComponent, ErosionState>();

		private static readonly Dictionary<CharacterBody, float> SkilledSniperReadyAt = new Dictionary<CharacterBody, float>();

		private static readonly Dictionary<CharacterMaster, float> VeilReadyAt = new Dictionary<CharacterMaster, float>();

		private static readonly Dictionary<CharacterMaster, InterestState> InterestStates = new Dictionary<CharacterMaster, InterestState>();

		private static GameObject? _missileProjectilePrefab;

		internal static event Action? Changed;

		internal static int GetStacks(CharacterMaster? master, HexId id)
		{
			if (!((Object)(object)master != (Object)null) || !PlayerStacks.TryGetValue(master, out Dictionary<HexId, int> value) || !value.TryGetValue(id, out var value2))
			{
				return 0;
			}
			return value2;
		}

		internal static IEnumerable<KeyValuePair<HexId, int>> Enumerate(CharacterMaster master)
		{
			if (!PlayerStacks.TryGetValue(master, out Dictionary<HexId, int> value))
			{
				return Array.Empty<KeyValuePair<HexId, int>>();
			}
			return value;
		}

		internal static IEnumerable<KeyValuePair<CharacterMaster, IEnumerable<KeyValuePair<HexId, int>>>> EnumeratePlayers()
		{
			foreach (KeyValuePair<CharacterMaster, Dictionary<HexId, int>> playerStack in PlayerStacks)
			{
				if ((Object)(object)playerStack.Key != (Object)null)
				{
					yield return new KeyValuePair<CharacterMaster, IEnumerable<KeyValuePair<HexId, int>>>(playerStack.Key, playerStack.Value);
				}
			}
		}

		internal static bool CanSelectHex(CharacterMaster? master)
		{
			if ((Object)(object)master != (Object)null && (!SelectionCounts.TryGetValue(master, out var value) || value < 6))
			{
				return HexCatalog.HasAvailable(master);
			}
			return false;
		}

		internal static void Reset()
		{
			ClearRuntimeEffects();
			PlayerStacks.Clear();
			SelectionCounts.Clear();
			HexRunState.Changed?.Invoke();
			RefreshAllBodies();
		}

		internal static void Add(CharacterMaster master, HexId id)
		{
			if (CanSelectHex(master))
			{
				SelectionCounts[master] = ((!SelectionCounts.TryGetValue(master, out var value)) ? 1 : (value + 1));
				Dictionary<HexId, int> orCreateStacks = GetOrCreateStacks(master);
				switch (id)
				{
				case HexId.PandorasBox:
				{
					int count = orCreateStacks.Count;
					orCreateStacks.Clear();
					AddRandomUnique(orCreateStacks, HexCatalog.PrismaticPool, count);
					break;
				}
				case HexId.TransmuteChaos:
					AddChaosReward(orCreateStacks);
					AddChaosReward(orCreateStacks);
					break;
				case HexId.TransmutePrismatic:
					AddRandomUnique(orCreateStacks, HexCatalog.PrismaticPool, 1);
					break;
				case HexId.TransmuteGold:
					AddRandomUnique(orCreateStacks, HexCatalog.GoldPool, 1);
					break;
				default:
					orCreateStacks[id] = 1;
					break;
				}
				HexRunState.Changed?.Invoke();
				RefreshAllBodies();
			}
		}

		private static void AddChaosReward(Dictionary<HexId, int> stacks)
		{
			int num = Random.Range(0, 100);
			AddRandomUnique(stacks, (num < 30) ? HexCatalog.SilverPool : ((num < 80) ? HexCatalog.GoldPool : HexCatalog.PrismaticPool), 1);
		}

		private static void AddRandomUnique(Dictionary<HexId, int> stacks, IReadOnlyList<HexId> pool, int count)
		{
			List<HexId> list = new List<HexId>();
			foreach (HexId item in pool)
			{
				if (!stacks.ContainsKey(item))
				{
					list.Add(item);
				}
			}
			while (count-- > 0 && list.Count > 0)
			{
				int index = Random.Range(0, list.Count);
				stacks[list[index]] = 1;
				list.RemoveAt(index);
			}
		}

		internal static void Replace(CharacterMaster master, IEnumerable<KeyValuePair<HexId, int>> values)
		{
			Dictionary<HexId, int> orCreateStacks = GetOrCreateStacks(master);
			orCreateStacks.Clear();
			foreach (KeyValuePair<HexId, int> value in values)
			{
				if (value.Value > 0 && Enum.IsDefined(typeof(HexId), value.Key))
				{
					orCreateStacks[value.Key] = 1;
				}
			}
			HexRunState.Changed?.Invoke();
			RefreshAllBodies();
		}

		private static Dictionary<HexId, int> GetOrCreateStacks(CharacterMaster master)
		{
			if (!PlayerStacks.TryGetValue(master, out Dictionary<HexId, int> value))
			{
				value = new Dictionary<HexId, int>();
				PlayerStacks[master] = value;
			}
			return value;
		}

		internal static void ApplyStats(CharacterBody body, StatHookEventArgs args)
		{
			if ((Object)(object)body == (Object)null)
			{
				return;
			}
			CharacterMaster master = body.master;
			if (IsPlayerBody(body))
			{
				if (GetStacks(master, HexId.GlassCannon) > 0)
				{
					args.healthMultAdd -= 0.3f;
					args.damageMultAdd += 0.25f;
				}
				if (ExcitedUntil.TryGetValue(body, out var value) && value > Time.fixedTime)
				{
					args.moveSpeedMultAdd += 0.4f;
					args.attackSpeedMultAdd += 0.2f;
				}
				if (TapDancerStates.TryGetValue(body, out var value2) && value2.EndTime > Time.fixedTime)
				{
					float num = 1f * (float)value2.Stacks;
					args.baseMoveSpeedAdd += num;
					float num2 = Mathf.Max(body.moveSpeed, body.baseMoveSpeed + num);
					args.attackSpeedMultAdd += Mathf.Max(0f, num2 / Mathf.Max(1f, body.baseMoveSpeed) - 1f) * 0.75f;
				}
				if ((Object)(object)master != (Object)null && ShrinkEngineStacks.TryGetValue(master, out var value3))
				{
					args.allSkills.cooldownMultAdd -= Mathf.Min(0.8f, (float)value3 * 0.05f);
					args.moveSpeedMultAdd += (float)value3 * 0.05f;
				}
				if (GetStacks(master, HexId.Goliath) > 0)
				{
					args.healthMultAdd += 0.5f;
					args.damageMultAdd += 0.25f;
					args.moveSpeedMultAdd -= 0.1f;
				}
				if ((Object)(object)master != (Object)null && TankEngineStacks.TryGetValue(master, out var value4))
				{
					args.healthMultAdd += (float)value4 * 0.06f;
				}
				if (GetStacks(master, HexId.Vulnerability) > 0)
				{
					args.critAdd += 25f;
				}
				if (GetStacks(master, HexId.BackToBasics) > 0)
				{
					args.primarySkill.cooldownMultAdd -= 0.4f;
					args.secondarySkill.cooldownMultAdd -= 0.4f;
					args.utilitySkill.cooldownMultAdd -= 0.4f;
				}
				if (GetStacks(master, HexId.GiantSlayer) > 0)
				{
					args.moveSpeedMultAdd += 0.25f;
				}
				if (GetStacks(master, HexId.Eureka) > 0)
				{
					float num3 = Mathf.Max(0f, body.damage / Mathf.Max(1f, body.baseDamage) - 1f);
					args.allSkills.cooldownMultAdd -= Mathf.Min(0.4f, num3 * 0.3f);
				}
				if (GetStacks(master, HexId.JeweledGauntlet) > 0)
				{
					args.critAdd += 25f;
				}
				if (FinalFormUntil.TryGetValue(body, out var value5) && value5 > Time.fixedTime)
				{
					args.moveSpeedMultAdd += 0.3f;
				}
				if (GetStacks(master, HexId.CelestialBody) > 0)
				{
					args.healthMultAdd += 0.6f;
					args.damageMultAdd -= 0.1f;
				}
				if (GetStacks(master, HexId.Recursion) > 0)
				{
					args.allSkills.cooldownMultAdd -= 0.35f;
				}
				if (GetStacks(master, HexId.CritDefense) > 0)
				{
					args.critAdd += 25f;
				}
				if (ShadowRunnerUntil.TryGetValue(body, out var value6) && value6 > Time.fixedTime)
				{
					args.moveSpeedMultAdd += 1f;
				}
			}
			if ((Object)(object)body.healthComponent != (Object)null && ErosionStates.TryGetValue(body.healthComponent, out var value7) && value7.EndTime > Time.fixedTime)
			{
				args.armorAdd -= (float)value7.Stacks * 1.5f;
			}
			CharacterMaster master2 = body.master;
			object master3;
			if (master2 == null)
			{
				master3 = null;
			}
			else
			{
				MinionOwnership minionOwnership = master2.minionOwnership;
				master3 = ((minionOwnership != null) ? minionOwnership.ownerMaster : null);
			}
			if (GetStacks((CharacterMaster?)master3, HexId.Minionmancer) > 0 && IsPlayerMinion(body))
			{
				args.healthMultAdd += 0.4f;
				args.damageMultAdd += 0.4f;
			}
		}

		internal static void OnCharacterDeath(DamageReport report)
		{
			if (!NetworkServer.active)
			{
				return;
			}
			CharacterBody val = report.attackerBody;
			if (!IsPlayerBody(val))
			{
				CharacterMaster attackerOwnerMaster = report.attackerOwnerMaster;
				val = ((attackerOwnerMaster != null) ? attackerOwnerMaster.GetBody() : null);
			}
			if (IsPlayerBody(val))
			{
				if (GetStacks(val.master, HexId.GetExcited) > 0)
				{
					float duration = ((report.victimIsElite || report.victimIsBoss) ? 8f : 4f);
					ActivateGetExcited(val, duration);
					NetMessageExtensions.Send((INetMessage)(object)new GetExcitedMessage(((Component)val).gameObject, duration), (NetworkDestination)1);
				}
				if (GetStacks(val.master, HexId.ShrinkEngine) > 0 && report.victimIsElite && (Object)(object)val.master != (Object)null)
				{
					SetAndBroadcastShrinkStacks(val.master, GetShrinkStacks(val.master) + 1);
				}
				if (GetStacks(val.master, HexId.TankEngine) > 0 && (report.victimIsElite || report.victimIsBoss) && (Object)(object)val.master != (Object)null)
				{
					SetAndBroadcastTankStacks(val.master, GetTankStacks(val.master) + 1);
				}
			}
			CharacterMaster val2 = (IsPlayerBody(report.victimBody) ? report.victimBody.master : null);
			if (GetStacks(val2, HexId.ShrinkEngine) > 0 && (Object)(object)val2 != (Object)null)
			{
				SetAndBroadcastShrinkStacks(val2, Mathf.FloorToInt((float)GetShrinkStacks(val2) * 0.35f));
			}
			if (GetStacks(val2, HexId.TankEngine) > 0 && (Object)(object)val2 != (Object)null)
			{
				SetAndBroadcastTankStacks(val2, Mathf.FloorToInt((float)GetTankStacks(val2) * 0.35f));
			}
			if (GetStacks(val2, HexId.SlapAround) > 0 && (Object)(object)val2 != (Object)null && SlapStacks.TryGetValue(val2, out var value))
			{
				SlapStacks[val2] = Mathf.FloorToInt((float)value * 0.5f);
			}
		}

		internal static bool OnSkillExecute(orig_ExecuteIfReady orig, GenericSkill self)
		{
			CharacterBody characterBody = self.characterBody;
			if (GetStacks((characterBody != null) ? characterBody.master : null, HexId.BackToBasics) > 0 && IsPlayerBody(characterBody) && (Object)(object)characterBody.skillLocator != (Object)null && (Object)(object)self == (Object)(object)characterBody.skillLocator.special)
			{
				return false;
			}
			bool flag = orig.Invoke(self);
			if (!flag || !NetworkServer.active)
			{
				return flag;
			}
			if (GetStacks((characterBody != null) ? characterBody.master : null, HexId.Earthwake) > 0 && IsPlayerBody(characterBody) && (Object)(object)characterBody.skillLocator != (Object)null && (Object)(object)self == (Object)(object)characterBody.skillLocator.utility)
			{
				Plugin.Instance.StartManagedCoroutine(DetonateEarthwake(characterBody));
			}
			if (GetStacks((characterBody != null) ? characterBody.master : null, HexId.Archmage) > 0 && IsPlayerBody(characterBody))
			{
				RechargeRandomOtherSkill(characterBody, self, self.baseRechargeInterval * 0.3f);
			}
			if (IsPlayerBody(characterBody) && (Object)(object)characterBody.skillLocator != (Object)null && (Object)(object)self == (Object)(object)characterBody.skillLocator.special && GetStacks(characterBody.master, HexId.FinalForm) > 0 && (Object)(object)characterBody.master != (Object)null && (!FinalFormReadyAt.TryGetValue(characterBody.master, out var value) || value <= Time.fixedTime))
			{
				FinalFormReadyAt[characterBody.master] = Time.fixedTime + 20f;
				FinalFormUntil[characterBody] = Time.fixedTime + 10f;
				HealthComponent healthComponent = characterBody.healthComponent;
				if (healthComponent != null)
				{
					healthComponent.AddBarrier(characterBody.healthComponent.fullCombinedHealth * 0.3f);
				}
				characterBody.RecalculateStats();
			}
			if (IsPlayerBody(characterBody) && (Object)(object)characterBody.skillLocator != (Object)null && (Object)(object)self == (Object)(object)characterBody.skillLocator.utility && GetStacks(characterBody.master, HexId.ShadowRunner) > 0)
			{
				ShadowRunnerUntil[characterBody] = Time.fixedTime + 2f;
				characterBody.RecalculateStats();
			}
			return flag;
		}

		internal static void OnServerDamageDealt(DamageReport report)
		{
			if (NetworkServer.active && !((Object)(object)report.attackerBody == (Object)null) && !((Object)(object)report.victim == (Object)null) && !((Object)(object)report.victimBody == (Object)null))
			{
				CharacterBody attackerBody = report.attackerBody;
				if (IsPlayerBody(attackerBody))
				{
					HandleTapDancer(report, attackerBody);
					HandleDoubleTap(report, attackerBody);
					HandleMagicMissile(report, attackerBody);
					HandleInfernalConduit(report, attackerBody);
					HandleDropkick(report, attackerBody);
					HandleToothFairy(report, attackerBody);
					HandleEtherealWeapon(report, attackerBody);
					HandleFirebrand(report, attackerBody);
					HandleMysticPunch(report, attackerBody);
					HandleFinalForm(report, attackerBody);
					HandleSlapAround(report, attackerBody);
					HandleSkilledSniper(report, attackerBody);
					HandleErosion(report, attackerBody);
					HandleTyphoon(report, attackerBody);
					HandleBurningInterest(report, attackerBody);
				}
			}
		}

		private static void HandleTapDancer(DamageReport report, CharacterBody attacker)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			if (GetStacks(attacker.master, HexId.TapDancer) != 0 && (int)report.damageInfo.damageType.damageSource == 1)
			{
				TimedStackState value;
				int num = ((TapDancerStates.TryGetValue(attacker, out value) && value.EndTime > Time.fixedTime) ? value.Stacks : 0);
				int stacks = Mathf.Min(GetTapDancerStackLimit(), num + 1);
				ActivateTapDancer(attacker, stacks, 4f);
				NetMessageExtensions.Send((INetMessage)(object)new TapDancerMessage(((Component)attacker).gameObject, stacks, 4f), (NetworkDestination)1);
			}
		}

		private static void HandleDoubleTap(DamageReport report, CharacterBody attacker)
		{
			//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_004f: 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)
			ProcChainMask procChainMask = report.damageInfo.procChainMask;
			if (GetStacks(attacker.master, HexId.DoubleTap) != 0 && report.damageInfo.crit && !((ProcChainMask)(ref procChainMask)).HasProc((ProcType)15) && !((ProcChainMask)(ref procChainMask)).HasProc((ProcType)26))
			{
				((ProcChainMask)(ref procChainMask)).AddProc((ProcType)15);
				DamageInfo damageInfo = report.damageInfo;
				damageInfo.procChainMask = procChainMask;
				GlobalEventManager.instance.OnHitEnemy(damageInfo, ((Component)report.victimBody).gameObject);
			}
		}

		private static void HandleMagicMissile(DamageReport report, CharacterBody attacker)
		{
			//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_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			ProcChainMask procChainMask = report.damageInfo.procChainMask;
			if (GetStacks(attacker.master, HexId.MagicMissile) == 0 || !IsNonPrimarySkillDamage(report.damageInfo) || ((ProcChainMask)(ref procChainMask)).HasProc((ProcType)1))
			{
				return;
			}
			if (_missileProjectilePrefab == null)
			{
				_missileProjectilePrefab = LegacyResourcesAPI.Load<GameObject>("Prefabs/Projectiles/MissileProjectile");
			}
			if (!((Object)(object)_missileProjectilePrefab == (Object)null))
			{
				((ProcChainMask)(ref procChainMask)).AddProc((ProcType)1);
				float num = report.victimBody.maxHealth * 0.01f;
				if (report.victimIsBoss)
				{
					num = Mathf.Min(num, attacker.damage * 3f);
				}
				for (int i = 0; i < 3; i++)
				{
					MissileUtils.FireMissile(attacker.corePosition, attacker, procChainMask, ((Component)report.victimBody).gameObject, num, Util.CheckRoll(attacker.crit, attacker.master), _missileProjectilePrefab, (DamageColorIndex)3, true);
				}
			}
		}

		private static void HandleInfernalConduit(DamageReport report, CharacterBody attacker)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Invalid comparison between Unknown and I4
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: 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)
			if (GetStacks(attacker.master, HexId.InfernalConduit) == 0)
			{
				return;
			}
			DotIndex dotIndex = report.damageInfo.dotIndex;
			if ((int)dotIndex == 1 || (int)dotIndex == 7)
			{
				if (!InfernalNextRecharge.TryGetValue(attacker, out var value) || value <= Time.fixedTime)
				{
					InfernalNextRecharge[attacker] = Time.fixedTime + 0.25f;
					RechargeAllSkills(attacker, 0.2f);
				}
			}
			else if (IsSkillDamage(report.damageInfo) && !((ProcChainMask)(ref report.damageInfo.procChainMask)).HasProc((ProcType)1))
			{
				InflictDotInfo val = new InflictDotInfo
				{
					victimObject = ((Component)report.victimBody).gameObject,
					attackerObject = ((Component)attacker).gameObject,
					dotIndex = (DotIndex)1,
					duration = 3f,
					damageMultiplier = 0.5f
				};
				DotController.InflictDot(ref val);
			}
		}

		private static void HandleDropkick(DamageReport report, CharacterBody attacker)
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: 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_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			int num = ((!((Object)(object)attacker.master == (Object)null)) ? GetTankStacks(attacker.master) : 0);
			float num2 = attacker.maxHealth / (1f + (float)num * 0.06f);
			float num3 = 0.1f + Mathf.Floor(num2 / 200f) * 0.01f;
			if (GetStacks(attacker.master, HexId.Dropkick) == 0 || report.victimIsBoss || !report.victim.alive || report.victim.combinedHealthFraction > num3 || !DropkickExecuting.Add(report.victim))
			{
				return;
			}
			try
			{
				CharacterBody victimBody = report.victimBody;
				Vector3 corePosition = victimBody.corePosition;
				if ((Object)(object)victimBody.characterMotor != (Object)null)
				{
					Vector3 val = victimBody.corePosition - attacker.corePosition;
					Vector3 normalized = ((Vector3)(ref val)).normalized;
					victimBody.characterMotor.ApplyForce(normalized * 2800f + Vector3.up * 900f, true, false);
				}
				report.victim.Suicide(((Component)attacker).gameObject, ((Component)attacker).gameObject, DamageTypeCombo.op_Implicit((DamageType)0));
				FireBlast(attacker, corePosition, 2f, 8f, 0f);
			}
			finally
			{
				DropkickExecuting.Remove(report.victim);
			}
		}

		private static void HandleToothFairy(DamageReport report, CharacterBody attacker)
		{
			if (GetStacks(attacker.master, HexId.ToothFairy) == 0 || (Object)(object)attacker.master == (Object)null || (Object)(object)report.victim == (Object)null || report.damageDealt <= 0f)
			{
				return;
			}
			(CharacterMaster, HealthComponent) key = (attacker.master, report.victim);
			float fixedTime = Time.fixedTime;
			ToothProgress value;
			ToothProgress toothProgress = ((ToothProgresses.TryGetValue(key, out value) && value.EndTime > fixedTime) ? value : new ToothProgress(0f, fixedTime + 4f, awarded: false));
			if (!toothProgress.Awarded)
			{
				float num = toothProgress.Damage + report.damageDealt;
				if (num < report.victim.fullCombinedHealth * 0.25f)
				{
					ToothProgresses[key] = new ToothProgress(num, toothProgress.EndTime, awarded: false);
					return;
				}
				ToothProgresses[key] = new ToothProgress(num, toothProgress.EndTime, awarded: true);
				ToothStacks[attacker.master] = Mathf.Min(10, (!ToothStacks.TryGetValue(attacker.master, out var value2)) ? 1 : (value2 + 1));
			}
		}

		private static void HandleEtherealWeapon(DamageReport report, CharacterBody attacker)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: 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)
			if (GetStacks(attacker.master, HexId.EtherealWeapon) != 0 && IsSkillDamage(report.damageInfo) && !((ProcChainMask)(ref report.damageInfo.procChainMask)).HasProc((ProcType)26))
			{
				(CharacterBody, HealthComponent) key = (attacker, report.victim);
				if (!EtherealReadyAt.TryGetValue(key, out var value) || !(value > Time.fixedTime))
				{
					EtherealReadyAt[key] = Time.fixedTime + 0.5f;
					DamageInfo damageInfo = report.damageInfo;
					ProcChainMask procChainMask = damageInfo.procChainMask;
					((ProcChainMask)(ref procChainMask)).AddProc((ProcType)26);
					damageInfo.procChainMask = procChainMask;
					damageInfo.procCoefficient = Mathf.Max(1f, damageInfo.procCoefficient);
					GlobalEventManager.instance.OnHitEnemy(damageInfo, ((Component)report.victimBody).gameObject);
				}
			}
		}

		private static void HandleFirebrand(DamageReport report, CharacterBody attacker)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: 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)
			if (GetStacks(attacker.master, HexId.Firebrand) != 0 && !(report.damageInfo.procCoefficient <= 0f) && (int)report.damageInfo.dotIndex == -1 && !((ProcChainMask)(ref report.damageInfo.procChainMask)).HasProc((ProcType)26))
			{
				InflictDotInfo val = new InflictDotInfo
				{
					victimObject = ((Component)report.victimBody).gameObject,
					attackerObject = ((Component)attacker).gameObject,
					dotIndex = (DotIndex)1,
					duration = 5f,
					totalDamage = report.victim.fullCombinedHealth * 0.005f
				};
				DotController.InflictDot(ref val);
			}
		}

		private static void HandleMysticPunch(DamageReport report, CharacterBody attacker)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Invalid comparison between Unknown and I4
			bool flag = report.damageInfo.procChainMask.mask != 0 || (report.damageInfo.procCoefficient < 1f && (int)report.damageInfo.damageType.damageSource == 0);
			if (GetStacks(attacker.master, HexId.MysticPunch) != 0 && flag)
			{
				float fixedTime = Time.fixedTime;
				TriggerWindow value;
				TriggerWindow triggerWindow = ((MysticPunchWindows.TryGetValue(attacker, out value) && value.EndTime > fixedTime) ? value : new TriggerWindow(0, fixedTime + 1f));
				if (triggerWindow.Count < 4)
				{
					MysticPunchWindows[attacker] = new TriggerWindow(triggerWindow.Count + 1, triggerWindow.EndTime);
					RechargeAllSkills(attacker, 0.25f);
				}
			}
		}

		private static void HandleFinalForm(DamageReport report, CharacterBody attacker)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (report.damageDealt > 0f && FinalFormUntil.TryGetValue(attacker, out var value) && value > Time.fixedTime)
			{
				HealthComponent healthComponent = attacker.healthComponent;
				if (healthComponent != null)
				{
					healthComponent.Heal(report.damageDealt * 0.1f, default(ProcChainMask), true);
				}
			}
		}

		private static void HandleSlapAround(DamageReport report, CharacterBody attacker)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (GetStacks(attacker.master, HexId.SlapAround) != 0 && !((Object)(object)attacker.master == (Object)null) && (report.victimIsElite || report.victimIsBoss))
			{
				bool num = (report.damageInfo.damageType.damageType & 0x120) != 0 || ((Vector3)(ref report.damageInfo.force)).sqrMagnitude >= 40000f;
				(CharacterMaster, HealthComponent) key = (attacker.master, report.victim);
				if (num && (!SlapReadyAt.TryGetValue(key, out var value) || !(value > Time.fixedTime)))
				{
					SlapReadyAt[key] = Time.fixedTime + 5f;
					SlapStacks[attacker.master] = ((!SlapStacks.TryGetValue(attacker.master, out var value2)) ? 1 : (value2 + 1));
				}
			}
		}

		private static void HandleSkilledSniper(DamageReport report, CharacterBody attacker)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if (GetStacks(attacker.master, HexId.SkilledSniper) != 0 && !(Vector3.Distance(attacker.corePosition, report.victimBody.corePosition) < 50f) && (!SkilledSniperReadyAt.TryGetValue(attacker, out var value) || !(value > Time.fixedTime)))
			{
				GenericSkill skillForSource = GetSkillForSource(attacker, report.damageInfo.damageType.damageSource);
				if (!((Object)(object)skillForSource == (Object)null) && !((Object)(object)skillForSource == (Object)(object)attacker.skillLocator?.special))
				{
					SkilledSniperReadyAt[attacker] = Time.fixedTime + 0.25f;
					float num = ((report.damageInfo.procCoefficient < 1f) ? 0.3f : 0.5f);
					skillForSource.RunRecharge(skillForSource.baseRechargeInterval * num);
				}
			}
		}

		private static void HandleErosion(DamageReport report, CharacterBody attacker)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			if (GetStacks(attacker.master, HexId.Erosion) != 0 && (int)report.damageInfo.dotIndex == -1 && !(report.damageInfo.procCoefficient <= 0f) && !((ProcChainMask)(ref report.damageInfo.procChainMask)).HasProc((ProcType)26))
			{
				HealthComponent victim = report.victim;
				ErosionState value;
				int num = ((ErosionStates.TryGetValue(victim, out value) && value.EndTime > Time.fixedTime) ? value.Stacks : 0);
				ErosionStates[victim] = new ErosionState(Mathf.Min(20, num + 1), Time.fixedTime + 4f);
				report.victimBody.RecalculateStats();
			}
		}

		private static void HandleTyphoon(DamageReport report, CharacterBody attacker)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: 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_00e2: Expected O, but got Unknown
			if (GetStacks(attacker.master, HexId.Typhoon) != 0 && !(report.damageInfo.procCoefficient <= 0f) && !((ProcChainMask)(ref report.damageInfo.procChainMask)).HasProc((ProcType)26))
			{
				CharacterBody val = FindClosestEnemy(report.victimBody.corePosition, report.victimBody);
				if (!((Object)(object)((val != null) ? val.healthComponent : null) == (Object)null))
				{
					ProcChainMask procChainMask = report.damageInfo.procChainMask;
					((ProcChainMask)(ref procChainMask)).AddProc((ProcType)26);
					val.healthComponent.TakeDamage(new DamageInfo
					{
						attacker = ((Component)attacker).gameObject,
						inflictor = ((Component)attacker).gameObject,
						damage = report.damageDealt * 0.3f,
						position = val.corePosition,
						procCoefficient = 0.3f,
						procChainMask = procChainMask,
						damageType = DamageTypeCombo.op_Implicit((DamageType)0),
						damageColorIndex = (DamageColorIndex)3
					});
				}
			}
		}

		private static void HandleBurningInterest(DamageReport report, CharacterBody attacker)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Invalid comparison between Unknown and I4
			if (GetStacks(attacker.master, HexId.BurningInterest) == 0 || (Object)(object)attacker.master == (Object)null || (int)report.damageInfo.dotIndex == -1 || report.damageDealt <= 0f)
			{
				return;
			}
			float fixedTime = Time.fixedTime;
			InterestState value;
			InterestState interestState = (InterestStates.TryGetValue(attacker.master, out value) ? value : default(InterestState));
			if (interestState.WindowEnd <= fixedTime)
			{
				interestState = new InterestState(interestState.StageGold, 0f, fixedTime + 1f, interestState.Fraction);
			}
			float num = Mathf.Min(report.damageDealt * 0.002f, Mathf.Min(5f - interestState.WindowGold, 100f - interestState.StageGold));
			if (!(num <= 0f))
			{
				float num2 = interestState.Fraction + num;
				int num3 = Mathf.FloorToInt(num2);
				if (num3 > 0)
				{
					attacker.master.GiveMoney((uint)num3);
				}
				InterestStates[attacker.master] = new InterestState(interestState.StageGold + num, interestState.WindowGold + num, interestState.WindowEnd, num2 - (float)num3);
			}
		}

		internal static void OnTakeDamageProcess(orig_TakeDamageProcess orig, HealthComponent self, DamageInfo damageInfo)
		{
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Invalid comparison between Unknown and I4
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Invalid comparison between Unknown and I4
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Invalid comparison between Unknown and I4
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Invalid comparison between Unknown and I4
			//IL_0444: Unknown result type (might be due to invalid IL or missing references)
			//IL_044a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Invalid comparison between Unknown and I4
			//IL_0386: Unknown result type (might be due to invalid IL or missing references)
			//IL_038c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkServer.active)
			{
				CharacterBody body = self.body;
				if (GetStacks((body != null) ? body.master : null, HexId.VeilOfWarding) > 0 && (Object)(object)body.master != (Object)null && damageInfo.damage > 0f && (!VeilReadyAt.TryGetValue(body.master, out var value) || value <= Time.fixedTime))
				{
					VeilReadyAt[body.master] = Time.fixedTime + 30f;
					damageInfo.rejected = true;
					orig.Invoke(self, damageInfo);
					return;
				}
				if (GetStacks((body != null) ? body.master : null, HexId.CritDefense) > 0 && (Object)(object)body.master != (Object)null && damageInfo.damage > 0f && Util.CheckRoll(Mathf.Min(50f, body.crit), body.master))
				{
					damageInfo.damage *= 0.8f;
				}
				CharacterBody val = ResolveAttackerBody(damageInfo.attacker);
				if (IsPlayerBody(val))
				{
					DamageSource damageSource = damageInfo.damageType.damageSource;
					if (GetStacks(val.master, HexId.Vulnerability) > 0 && ((damageSource & 0x40) != 0 || (int)damageInfo.dotIndex != -1))
					{
						damageInfo.crit = Util.CheckRoll(val.crit, val.master);
					}
					if (GetStacks(val.master, HexId.BackToBasics) > 0 && ((int)damageSource == 1 || (int)damageSource == 2 || (int)damageSource == 4))
					{
						damageInfo.damage *= 1.5f;
					}
					if (GetStacks(val.master, HexId.GiantSlayer) > 0 && (Object)(object)self.body != (Object)null)
					{
						float num = self.body.bestFitRadius / Mathf.Max(0.1f, val.bestFitRadius);
						if (num > 1f)
						{
							damageInfo.damage *= 1f + Mathf.Clamp(0.25f + (num - 1f) * 0.25f, 0.25f, 0.75f);
						}
					}
					if (GetStacks(val.master, HexId.JeweledGauntlet) > 0 && IsSkillDamage(damageInfo) && damageInfo.crit)
					{
						damageInfo.crit = false;
						damageInfo.damage *= 1.45f;
					}
					if (GetStacks(val.master, HexId.DontBlink) > 0 && (Object)(object)self.body != (Object)null)
					{
						float num2 = val.moveSpeed / Mathf.Max(0.1f, self.body.moveSpeed);
						damageInfo.damage *= 1f + Mathf.Clamp(Mathf.Floor((num2 - 1f) / 0.1f) * 0.01f, 0f, 0.3f);
					}
					if (GetStacks(val.master, HexId.SlapAround) > 0 && (Object)(object)val.master != (Object)null && SlapStacks.TryGetValue(val.master, out var value2))
					{
						damageInfo.damage *= 1f + (float)value2 * 0.05f;
					}
					if (GetStacks(val.master, HexId.HeavyHitter) > 0 && (int)damageSource == 1 && !((ProcChainMask)(ref damageInfo.procChainMask)).HasProc((ProcType)26))
					{
						damageInfo.damage += Mathf.Floor(val.maxHealth / 100f) * 100f * 0.035f;
					}
					if (GetStacks(val.master, HexId.ToothFairy) > 0 && (Object)(object)val.master != (Object)null && ToothStacks.TryGetValue(val.master, out var value3) && Util.CheckRoll((float)value3 * 10f, val.master))
					{
						damageInfo.damageType |= DamageTypeCombo.op_Implicit((DamageType)2);
					}
				}
				if (GetStacks((body != null) ? body.master : null, HexId.NearDeathInsight) > 0 && IsPlayerBody(body) && (Object)(object)body.master != (Object)null && damageInfo.damage >= self.combinedHealth && (!NearDeathReadyAt.TryGetValue(body.master, out var value4) || value4 <= Time.fixedTime))
				{
					NearDeathReadyAt[body.master] = Time.fixedTime + 240f;
					damageInfo.rejected = true;
					orig.Invoke(self, damageInfo);
					self.Heal(Mathf.Max(0f, self.fullCombinedHealth * 0.35f - self.combinedHealth), default(ProcChainMask), true);
					return;
				}
			}
			orig.Invoke(self, damageInfo);
		}

		internal static float OnHeal(orig_Heal orig, HealthComponent self, float amount, ProcChainMask procChainMask, bool nonRegen)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Expected O, but got Unknown
			CharacterBody body = self.body;
			if (GetStacks((body != null) ? body.master : null, HexId.BackToBasics) > 0 && IsPlayerBody(self.body))
			{
				amount *= 1.5f;
			}
			float num = orig.Invoke(self, amount, procChainMask, nonRegen);
			if (NetworkServer.active && !(num <= 0f))
			{
				CharacterBody body2 = self.body;
				if (GetStacks((body2 != null) ? body2.master : null, HexId.CircleOfDeath) != 0 && IsPlayerBody(self.body))
				{
					CharacterBody body3 = self.body;
					float fixedTime = Time.fixedTime;
					TriggerWindow value;
					TriggerWindow triggerWindow = ((CircleTriggerWindows.TryGetValue(body3, out value) && value.EndTime > fixedTime) ? value : new TriggerWindow(0, fixedTime + 1f));
					if (triggerWindow.Count >= 4)
					{
						return num;
					}
					CircleTriggerWindows[body3] = new TriggerWindow(triggerWindow.Count + 1, triggerWindow.EndTime);
					CharacterBody val = FindClosestEnemy(body3.corePosition);
					if ((Object)(object)((val != null) ? val.healthComponent : null) != (Object)null)
					{
						val.healthComponent.TakeDamage(new DamageInfo
						{
							attacker = ((Component)body3).gameObject,
							inflictor = ((Component)body3).gameObject,
							damage = num * 1.5f,
							position = val.corePosition,
							procCoefficient = 0f,
							damageType = DamageTypeCombo.op_Implicit((DamageType)0),
							damageColorIndex = (DamageColorIndex)3
						});
					}
					return num;
				}
			}
			return num;
		}

		internal static void OnBodyStart(CharacterBody body)
		{
			UpdateMinionScale(body);
			UpdatePlayerScale(body);
		}

		internal static void FixedUpdate()
		{
			List<CharacterBody> list = new List<CharacterBody>();
			foreach (KeyValuePair<CharacterBody, float> item in ExcitedUntil)
			{
				if ((Object)(object)item.Key == (Object)null || item.Value <= Time.fixedTime)
				{
					list.Add(item.Key);
				}
			}
			foreach (CharacterBody item2 in list)
			{
				ExcitedUntil.Remove(item2);
				if ((Object)(object)item2 != (Object)null)
				{
					item2.RecalculateStats();
				}
			}
			list.Clear();
			foreach (KeyValuePair<CharacterBody, TimedStackState> tapDancerState in TapDancerStates)
			{
				if ((Object)(object)tapDancerState.Key == (Object)null || tapDancerState.Value.EndTime <= Time.fixedTime)
				{
					list.Add(tapDancerState.Key);
				}
			}
			foreach (CharacterBody item3 in list)
			{
				TapDancerStates.Remove(item3);
				if ((Object)(object)item3 != (Object)null)
				{
					item3.RecalculateStats();
				}
			}
			ExpireTimedBodies(FinalFormUntil);
			ExpireTimedBodies(ShadowRunnerUntil);
			List<HealthComponent> list2 = new List<HealthComponent>();
			foreach (KeyValuePair<HealthComponent, ErosionState> erosionState in ErosionStates)
			{
				if ((Object)(object)erosionState.Key == (Object)null || erosionState.Value.EndTime <= Time.fixedTime)
				{
					list2.Add(erosionState.Key);
				}
			}
			foreach (HealthComponent item4 in list2)
			{
				ErosionStates.Remove(item4);
				if ((Object)(object)item4?.body != (Object)null)
				{
					item4.body.RecalculateStats();
				}
			}
		}

		internal static void ActivateGetExcited(CharacterBody body, float duration)
		{
			ExcitedUntil[body] = Time.fixedTime + duration;
			body.RecalculateStats();
		}

		internal static void ActivateTapDancer(CharacterBody body, int stacks, float duration)
		{
			TapDancerStates[body] = new TimedStackState(Mathf.Clamp(stacks, 1, GetTapDancerStackLimit()), Time.fixedTime + duration);
			body.RecalculateStats();
		}

		private static int GetTapDancerStackLimit()
		{
			return 20 + (Run.instance?.stageClearCount ?? 0) * 10;
		}

		internal static void OnStageBegin()
		{
			ToothStacks.Clear();
			ToothProgresses.Clear();
			InterestStates.Clear();
			RefreshAllBodies();
		}

		internal static void SetShrinkEngineStacks(CharacterMaster master, int stacks)
		{
			ShrinkEngineStacks[master] = Mathf.Max(0, stacks);
			CharacterBody body = master.GetBody();
			if ((Object)(object)body != (Object)null)
			{
				UpdatePlayerScale(body);
				body.RecalculateStats();
			}
		}

		private static int GetShrinkStacks(CharacterMaster master)
		{
			if (!ShrinkEngineStacks.TryGetValue(master, out var value))
			{
				return 0;
			}
			return value;
		}

		private static void SetAndBroadcastShrinkStacks(CharacterMaster master, int stacks)
		{
			SetShrinkEngineStacks(master, stacks);
			NetMessageExtensions.Send((INetMessage)(object)new ShrinkEngineMessage(((Component)master).gameObject, stacks), (NetworkDestination)1);
		}

		internal static void SetTankEngineStacks(CharacterMaster master, int stacks)
		{
			TankEngineStacks[master] = Mathf.Max(0, stacks);
			CharacterBody body = master.GetBody();
			if ((Object)(object)body != (Object)null)
			{
				UpdatePlayerScale(body);
				body.RecalculateStats();
			}
		}

		private static int GetTankStacks(CharacterMaster master)
		{
			if (!TankEngineStacks.TryGetValue(master, out var value))
			{
				return 0;
			}
			return value;
		}

		private static void SetAndBroadcastTankStacks(CharacterMaster master, int stacks)
		{
			SetTankEngineStacks(master, stacks);
			NetMessageExtensions.Send((INetMessage)(object)new TankEngineMessage(((Component)master).gameObject, stacks), (NetworkDestination)1);
		}

		private static IEnumerator DetonateEarthwake(CharacterBody body)
		{
			GameObject attackerObject = ((Component)body).gameObject;
			Vector3 position = body.corePosition;
			yield return (object)new WaitForSeconds(1f);
			if ((Object)(object)attackerObject != (Object)null && (Object)(object)body != (Object)null && (Object)(object)body.healthComponent != (Object)null && body.healthComponent.alive)
			{
				FireBlast(body, position, 3f, 8f, 0.5f);
			}
		}

		private static void FireBlast(CharacterBody attacker, Vector3 position, float damageCoefficient, float radius, float procCoefficient)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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_001d: 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_0024: 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_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)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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)
			new BlastAttack
			{
				attacker = ((Component)attacker).gameObject,
				inflictor = ((Component)attacker).gameObject,
				teamIndex = (TeamIndex)1,
				position = position,
				radius = radius,
				falloffModel = (FalloffModel)0,
				baseDamage = attacker.damage * damageCoefficient,
				baseForce = 1200f,
				crit = Util.CheckRoll(attacker.crit, attacker.master),
				damageType = DamageTypeCombo.op_Implicit((DamageType)0),
				procCoefficient = procCoefficient
			}.Fire();
		}

		private static bool IsSkillDamage(DamageInfo damageInfo)
		{
			//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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Invalid comparison between Unknown and I4
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Invalid comparison between Unknown and I4
			DamageSource damageSource = damageInfo.damageType.damageSource;
			if ((int)damageSource != 1 && (int)damageSource != 2 && (int)damageSource != 4)
			{
				return (int)damageSource == 8;
			}
			return true;
		}

		private static bool IsNonPrimarySkillDamage(DamageInfo damageInfo)
		{
			//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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Invalid comparison between Unknown and I4
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			DamageSource damageSource = damageInfo.damageType.damageSource;
			if ((int)damageSource != 2 && (int)damageSource != 4)
			{
				return (int)damageSource == 8;
			}
			return true;
		}

		private static void RechargeAllSkills(CharacterBody body, float seconds)
		{
			SkillLocator skillLocator = body.skillLocator;
			if (!((Object)(object)skillLocator == (Object)null))
			{
				GenericSkill primary = skillLocator.primary;
				if (primary != null)
				{
					primary.RunRecharge(seconds);
				}
				GenericSkill secondary = skillLocator.secondary;
				if (secondary != null)
				{
					secondary.RunRecharge(seconds);
				}
				GenericSkill utility = skillLocator.utility;
				if (utility != null)
				{
					utility.RunRecharge(seconds);
				}
				GenericSkill special = skillLocator.special;
				if (special != null)
				{
					special.RunRecharge(seconds);
				}
			}
		}

		private static void RechargeRandomOtherSkill(CharacterBody body, GenericSkill usedSkill, float seconds)
		{
			SkillLocator skillLocator = body.skillLocator;
			if ((Object)(object)skillLocator == (Object)null || seconds <= 0f)
			{
				return;
			}
			List<GenericSkill> list = new List<GenericSkill>();
			GenericSkill[] array = (GenericSkill[])(object)new GenericSkill[4] { skillLocator.primary, skillLocator.secondary, skillLocator.utility, skillLocator.special };
			foreach (GenericSkill val in array)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)usedSkill && val.cooldownRemaining > 0f)
				{
					list.Add(val);
				}
			}
			if (list.Count > 0)
			{
				list[Random.Range(0, list.Count)].RunRecharge(seconds);
			}
		}

		private static GenericSkill? GetSkillForSource(CharacterBody body, DamageSource source)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Invalid comparison between Unknown and I4
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			SkillLocator skillLocator = body.skillLocator;
			if ((Object)(object)skillLocator == (Object)null)
			{
				return null;
			}
			if ((int)source != 1)
			{
				if ((int)source != 2)
				{
					if ((int)source != 4)
					{
						if ((int)source != 8)
						{
							return null;
						}
						return skillLocator.special;
					}
					return skillLocator.utility;
				}
				return skillLocator.secondary;
			}
			return skillLocator.primary;
		}

		private static void ExpireTimedBodies(Dictionary<CharacterBody, float> states)
		{
			List<CharacterBody> list = new List<CharacterBody>();
			foreach (KeyValuePair<CharacterBody, float> state in states)
			{
				if ((Object)(object)state.Key == (Object)null || state.Value <= Time.fixedTime)
				{
					list.Add(state.Key);
				}
			}
			foreach (CharacterBody item in list)
			{
				states.Remove(item);
				if ((Object)(object)item != (Object)null)
				{
					item.RecalculateStats();
				}
			}
		}

		private static CharacterBody? FindClosestEnemy(Vector3 origin, CharacterBody? excluded = null)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			CharacterBody result = null;
			float num = float.PositiveInfinity;
			TeamMask enemyTeams = TeamMask.GetEnemyTeams((TeamIndex)1);
			foreach (CharacterBody readOnlyInstances in CharacterBody.readOnlyInstancesList)
			{
				if (!((Object)(object)readOnlyInstances == (Object)null) && !((Object)(object)readOnlyInstances == (Object)(object)excluded) && !((Object)(object)readOnlyInstances.healthComponent == (Object)null) && readOnlyInstances.healthComponent.alive && !((Object)(object)readOnlyInstances.teamComponent == (Object)null) && ((TeamMask)(ref enemyTeams)).HasTeam(readOnlyInstances.teamComponent.teamIndex))
				{
					Vector3 val = readOnlyInstances.corePosition - origin;
					float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
					if (!(sqrMagnitude >= num))
					{
						result = readOnlyInstances;
						num = sqrMagnitude;
					}
				}
			}
			return result;
		}

		private static bool IsPlayerBody(CharacterBody? body)
		{
			if ((Object)(object)body != (Object)null && (Object)(object)body.master != (Object)null)
			{
				return (Object)(object)body.master.playerCharacterMasterController != (Object)null;
			}
			return false;
		}

		private static CharacterBody? ResolveAttackerBody(GameObject? attackerObject)
		{
			if ((Object)(object)attackerObject == (Object)null)
			{
				return null;
			}
			CharacterBody obj = attackerObject.GetComponent<CharacterBody>();
			if (obj == null)
			{
				obj = attackerObject.GetComponentInParent<CharacterBody>();
				if (obj == null)
				{
					CharacterMaster component = attackerObject.GetComponent<CharacterMaster>();
					if (component == null)
					{
						return null;
					}
					obj = component.GetBody();
				}
			}
			return obj;
		}

		private static bool IsPlayerMinion(CharacterBody body)
		{
			CharacterMaster master = body.master;
			object obj;
			if (master == null)
			{
				obj = null;
			}
			else
			{
				MinionOwnership minionOwnership = master.minionOwnership;
				obj = ((minionOwnership != null) ? minionOwnership.ownerMaster : null);
			}
			CharacterMaster val = (CharacterMaster)obj;
			if ((Object)(object)val != (Object)null)
			{
				return (Object)(object)val.playerCharacterMasterController != (Object)null;
			}
			return false;
		}

		private static void RefreshAllBodies()
		{
			foreach (CharacterBody readOnlyInstances in CharacterBody.readOnlyInstancesList)
			{
				if (!((Object)(object)readOnlyInstances == (Object)null))
				{
					UpdateMinionScale(readOnlyInstances);
					UpdatePlayerScale(readOnlyInstances);
					readOnlyInstances.RecalculateStats();
				}
			}
		}

		private static void UpdateMinionScale(CharacterBody body)
		{
			ModelLocator modelLocator = body.modelLocator;
			Transform val = ((modelLocator != null) ? modelLocator.modelTransform : null);
			if (!((Object)(object)val == (Object)null))
			{
				MinionScaleMarker component = ((Component)val).GetComponent<MinionScaleMarker>();
				CharacterMaster master = body.master;
				object master2;
				if (master == null)
				{
					master2 = null;
				}
				else
				{
					MinionOwnership minionOwnership = master.minionOwnership;
					master2 = ((minionOwnership != null) ? minionOwnership.ownerMaster : null);
				}
				bool flag = GetStacks((CharacterMaster?)master2, HexId.Minionmancer) > 0 && IsPlayerMinion(body);
				if (flag && (Object)(object)component == (Object)null)
				{
					((Component)val).gameObject.AddComponent<MinionScaleMarker>();
				}
				else if (!flag && (Object)(object)component != (Object)null)
				{
					Object.Destroy((Object)(object)component);
				}
			}
		}

		private static void UpdatePlayerScale(CharacterBody body)
		{
			if (!IsPlayerBody(body))
			{
				return;
			}
			ModelLocator modelLocator = body.modelLocator;
			Transform val = ((modelLocator != null) ? modelLocator.modelTransform : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			float num = 1f;
			if (GetStacks(body.master, HexId.Goliath) > 0)
			{
				num *= 1.5f;
			}
			if ((Object)(object)body.master != (Object)null && ShrinkEngineStacks.TryGetValue(body.master, out var value))
			{
				num *= Mathf.Max(0.35f, Mathf.Pow(0.95f, (float)value));
			}
			if ((Object)(object)body.master != (Object)null && TankEngineStacks.TryGetValue(body.master, out var value2))
			{
				num *= 1f + (float)value2 * 0.04f;
			}
			if (GetStacks(body.master, HexId.GiantSlayer) > 0)
			{
				num *= 0.75f;
			}
			PlayerScaleMarker playerScaleMarker = ((Component)val).GetComponent<PlayerScaleMarker>();
			if (Mathf.Approximately(num, 1f))
			{
				if ((Object)(object)playerScaleMarker != (Object)null)
				{
					Object.Destroy((Object)(object)playerScaleMarker);
				}
				return;
			}
			if (playerScaleMarker == null)
			{
				playerScaleMarker = ((Component)val).gameObject.AddComponent<PlayerScaleMarker>();
			}
			playerScaleMarker.SetScale(num);
		}

		private static void ClearRuntimeEffects()
		{
			ExcitedUntil.Clear();
			TapDancerStates.Clear();
			InfernalNextRecharge.Clear();
			CircleTriggerWindows.Clear();
			ShrinkEngineStacks.Clear();
			TankEngineStacks.Clear();
			ToothStacks.Clear();
			ToothProgresses.Clear();
			NearDeathReadyAt.Clear();
			EtherealReadyAt.Clear();
			MysticPunchWindows.Clear();
			DropkickExecuting.Clear();
			FinalFormUntil.Clear();
			FinalFormReadyAt.Clear();
			ShadowRunnerUntil.Clear();
			SlapReadyAt.Clear();
			SlapStacks.Clear();
			ErosionStates.Clear();
			SkilledSniperReadyAt.Clear();
			VeilReadyAt.Clear();
			InterestStates.Clear();
			foreach (CharacterBody readOnlyInstances in CharacterBody.readOnlyInstancesList)
			{
				object obj;
				if (readOnlyInstances == null)
				{
					obj = null;
				}
				else
				{
					ModelLocator modelLocator = readOnlyInstances.modelLocator;
					if (modelLocator == null)
					{
						obj = null;
					}
					else
					{
						Transform modelTransform = modelLocator.modelTransform;
						obj = ((modelTransform != null) ? ((Component)modelTransform).GetComponent<MinionScaleMarker>() : null);
					}
				}
				MinionScaleMarker minionScaleMarker = (MinionScaleMarker)obj;
				if ((Object)(object)minionScaleMarker != (Object)null)
				{
					Object.Destroy((Object)(object)minionScaleMarker);
				}
				object obj2;
				if (readOnlyInstances == null)
				{
					obj2 = null;
				}
				else
				{
					ModelLocator modelLocator2 = readOnlyInstances.modelLocator;
					if (modelLocator2 == null)
					{
						obj2 = null;
					}
					else
					{
						Transform modelTransform2 = modelLocator2.modelTransform;
						obj2 = ((modelTransform2 != null) ? ((Component)modelTransform2).GetComponent<PlayerScaleMarker>() : null);
					}
				}
				PlayerScaleMarker playerScaleMarker = (PlayerScaleMarker)obj2;
				if ((Object)(object)playerScaleMarker != (Object)null)
				{
					Object.Destroy((Object)(object)playerScaleMarker);
				}
			}
		}
	}
	internal sealed class MinionScaleMarker : MonoBehaviour
	{
		private Vector3 _originalScale;

		private void Awake()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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)
			_originalScale = ((Component)this).transform.localScale;
			((Component)this).transform.localScale = _originalScale * 2.5f;
		}

		private void OnDestroy()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)((Component)this).transform != (Object)null)
			{
				((Component)this).transform.localScale = _originalScale;
			}
		}
	}
	internal sealed class PlayerScaleMarker : MonoBehaviour
	{
		private Vector3 _originalScale;

		private void Awake()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			_originalScale = ((Component)this).transform.localScale;
		}

		internal void SetScale(float multiplier)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).transform.localScale = _originalScale * multiplier;
		}

		private void OnDestroy()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)((Component)this).transform != (Object)null)
			{
				((Component)this).transform.localScale = _originalScale;
			}
		}
	}
	internal readonly struct TimedStackState
	{
		internal int Stacks { get; }

		internal float EndTime { get; }

		internal TimedStackState(int stacks, float endTime)
		{
			Stacks = stacks;
			EndTime = endTime;
		}
	}
	internal readonly struct TriggerWindow
	{
		internal int Count { get; }

		internal float EndTime { get; }

		internal TriggerWindow(int count, float endTime)
		{
			Count = count;
			EndTime = endTime;
		}
	}
	internal readonly struct ToothProgress
	{
		internal float Damage { get; }

		internal float EndTime { get; }

		internal bool Awarded { get; }

		internal ToothProgress(float damage, float endTime, bool awarded)
		{
			Damage = damage;
			EndTime = endTime;
			Awarded = awarded;
		}
	}
	internal readonly struct ErosionState
	{
		internal int Stacks { get; }

		internal float EndTime { get; }

		internal ErosionState(int stacks, float endTime)
		{
			Stacks = stacks;
			EndTime = endTime;
		}
	}
	internal readonly struct InterestState
	{
		internal float StageGold { get; }

		internal float WindowGold { get; }

		internal float WindowEnd { get; }

		internal float Fraction { get; }

		internal InterestState(float stageGold, float windowGold, float windowEnd, float fraction)
		{
			StageGold = stageGold;
			WindowGold = windowGold;
			WindowEnd = windowEnd;
			Fraction = fraction;
		}
	}
	internal sealed class HexStateMessage : INetMessage, ISerializableObject
	{
		private GameObject? _masterObject;

		private readonly List<KeyValuePair<HexId, int>> _values = new List<KeyValuePair<HexId, int>>();

		public HexStateMessage()
		{
		}

		internal HexStateMessage(GameObject masterObject, IEnumerable<KeyValuePair<HexId, int>> values)
		{
			_masterObject = masterObject;
			_values.AddRange(values);
		}

		public void Serialize(NetworkWriter writer)
		{
			writer.Write(_masterObject);
			writer.Write((byte)_values.Count);
			foreach (KeyValuePair<HexId, int> value in _values)
			{
				writer.Write((byte)value.Key);
				writer.Write(value.Value);
			}
		}

		public void Deserialize(NetworkReader reader)
		{
			_masterObject = reader.ReadGameObject();
			_values.Clear();
			byte b = reader.ReadByte();
			for (int i = 0; i < b; i++)
			{
				_values.Add(new KeyValuePair<HexId, int>((HexId)reader.ReadByte(), reader.ReadInt32()));
			}
		}

		public void OnReceived()
		{
			CharacterMaster val = (((Object)(object)_masterObject != (Object)null) ? _masterObject.GetComponent<CharacterMaster>() : null);
			if ((Object)(object)val != (Object)null)
			{
				HexRunState.Replace(val, _values);
			}
		}
	}
	internal sealed class OpenHexPickerMessage : INetMessage, ISerializableObject
	{
		private GameObject? _masterObject;

		private int _rerolls;

		public OpenHexPickerMessage()
		{
		}

		internal OpenHexPickerMessage(GameObject masterObject, int rerolls)
		{
			_masterObject = masterObject;
			_rerolls = rerolls;
		}

		public void Serialize(NetworkWriter writer)
		{
			writer.Write(_masterObject);
			writer.Write(_rerolls);
		}

		public void Deserialize(NetworkReader reader)
		{
			_masterObject = reader.ReadGameObject();
			_rerolls = reader.ReadInt32();
		}

		public void OnReceived()
		{
			CharacterMaster val = (((Object)(object)_masterObject != (Object)null) ? _masterObject.GetComponent<CharacterMaster>() : null);
			if ((Object)(object)val != (Object)null)
			{
				Plugin.Instance.OpenPicker(val, _rerolls);
			}
		}
	}
	internal sealed class SelectHexMessage : INetMessage, ISerializableObject
	{
		private GameObject? _masterObject;

		private HexId _hexId;

		public SelectHexMessage()
		{
		}

		internal SelectHexMessage(GameObject masterObject, HexId hexId)
		{
			_masterObject = masterObject;
			_hexId = hexId;
		}

		public void Serialize(NetworkWriter writer)
		{
			writer.Write(_masterObject);
			writer.Write((byte)_hexId);
		}

		public void Deserialize(NetworkReader reader)
		{
			_masterObject = reader.ReadGameObject();
			_hexId = (HexId)reader.ReadByte();
		}

		public void OnReceived()
		{
			if (NetworkServer.active)
			{
				CharacterMaster val = (((Object)(object)_masterObject != (Object)null) ? _masterObject.GetComponent<CharacterMaster>() : null);
				if ((Object)(object)val != (Object)null)
				{
					Plugin.Instance.SelectHex(val, _hexId);
				}
			}
		}
	}
	internal sealed class GetExcitedMessage : INetMessage, ISerializableObject
	{
		private GameObject? _bodyObject;

		private float _duration;

		public GetExcitedMessage()
		{
		}

		internal GetExcitedMessage(GameObject bodyObject, float duration)
		{
			_bodyObject = bodyObject;
			_duration = duration;
		}

		public void Serialize(NetworkWriter writer)
		{
			writer.Write(_bodyObject);
			writer.Write(_duration);
		}

		public void Deserialize(NetworkReader reader)
		{
			_bodyObject = reader.ReadGameObject();
			_duration = reader.ReadSingle();
		}

		public void OnReceived()
		{
			CharacterBody val = (((Object)(object)_bodyObject != (Object)null) ? _bodyObject.GetComponent<CharacterBody>() : null);
			if ((Object)(object)val != (Object)null)
			{
				HexRunState.ActivateGetExcited(val, _duration);
			}
		}
	}
	internal sealed class TapDancerMessage : INetMessage, ISerializableObject
	{
		private GameObject? _bodyObject;

		private int _stacks;

		private float _duration;

		public TapDancerMessage()
		{
		}

		internal TapDancerMessage(GameObject bodyObject, int stacks, float duration)
		{
			_bodyObject = bodyObject;
			_stacks = stacks;
			_duration = duration;
		}

		public void Serialize(NetworkWriter writer)
		{
			writer.Write(_bodyObject);
			writer.Write(_stacks);
			writer.Write(_duration);
		}

		public void Deserialize(NetworkReader reader)
		{
			_bodyObject = reader.ReadGameObject();
			_stacks = reader.ReadInt32();
			_duration = reader.ReadSingle();
		}

		public void OnReceived()
		{
			CharacterBody val = (((Object)(object)_bodyObject != (Object)null) ? _bodyObject.GetComponent<CharacterBody>() : null);
			if ((Object)(object)val != (Object)null)
			{
				HexRunState.ActivateTapDancer(val, _stacks, _duration);
			}
		}
	}
	internal sealed class ShrinkEngineMessage : INetMessage, ISerializableObject
	{
		private GameObject? _masterObject;

		private int _stacks;

		public ShrinkEngineMessage()
		{
		}

		internal ShrinkEngineMessage(GameObject masterObject, int stacks)
		{
			_masterObject = masterObject;
			_stacks = stacks;
		}

		public void Serialize(NetworkWriter writer)
		{
			writer.Write(_masterObject);
			writer.Write(_stacks);
		}

		public void Deserialize(NetworkReader reader)
		{
			_masterObject = reader.ReadGameObject();
			_stacks = reader.ReadInt32();
		}

		public void OnReceived()
		{
			CharacterMaster val = (((Object)(object)_masterObject != (Object)null) ? _masterObject.GetComponent<CharacterMaster>() : null);
			if ((Object)(object)val != (Object)null)
			{
				HexRunState.SetShrinkEngineStacks(val, _stacks);
			}
		}
	}
	internal sealed class TankEngineMessage : INetMessage, ISerializableObject
	{
		private GameObject? _masterObject;

		private int _stacks;

		public TankEngineMessage()
		{
		}

		internal TankEngineMessage(GameObject masterObject, int stacks)
		{
			_masterObject = masterObject;
			_stacks = stacks;
		}

		public void Serialize(NetworkWriter writer)
		{
			writer.Write(_masterObject);
			writer.Write(_stacks);
		}

		public void Deserialize(NetworkReader reader)
		{
			_masterObject = reader.ReadGameObject();
			_stacks = reader.ReadInt32();
		}

		public void OnReceived()
		{
			CharacterMaster val = (((Object)(object)_masterObject != (Object)null) ? _masterObject.GetComponent<CharacterMaster>() : null);
			if ((Object)(object)val != (Object)null)
			{
				HexRunState.SetTankEngineStacks(val, _stacks);
			}
		}
	}
	[BepInPlugin("com.dmh.hexedrisk", "HexedRisk", "1.0.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static StatHookEventHandler <0>__ApplyStats;

			public static Action<DamageReport> <1>__OnCharacterDeath;

			public static Action<DamageReport> <2>__OnServerDamageDealt;

			public static Action<CharacterBody> <3>__OnBodyStart;

			public static hook_ExecuteIfReady <4>__OnSkillExecute;

			public static hook_Heal <5>__OnHeal;

			public static hook_TakeDamageProcess <6>__OnTakeDamageProcess;
		}

		public const string PluginGuid = "com.dmh.hexedrisk";

		public const string PluginName = "HexedRisk";

		public const string PluginVersion = "1.0.4";

		private ConfigEntry<int> _rerollsPerStage;

		private ConfigEntry<bool> _showActiveHexes;

		private HexPickerUI _picker;

		private int _lastBossGroupId = int.MinValue;

		private bool _hexChoicePending;

		private bool _waitingForSelection;

		private bool _continuationScheduled;

		private readonly HashSet<CharacterMaster> _pendingPlayers = new HashSet<CharacterMaster>();

		private Stage? _pendingStage;

		private SceneDef? _pendingDestination;

		internal static ManualLogSource Log { get; private set; }

		internal static Plugin Instance { get; private set; }

		private void Awake()
		{
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Expected O, but got Unknown
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Expected O, but got Unknown
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Expected O, but got Unknown
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Expected O, but got Unknown
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Expected O, but got Unknown
			//IL_01bf: 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_01ca: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			_rerollsPerStage = ((BaseUnityPlugin)this).Config.Bind<int>("General", "RerollsPerStage", 3, "每关每张海克斯卡片可单独刷新的次数。范围 0-99。");
			_showActiveHexes = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "ShowActiveHexes", true, "在屏幕左上角显示本局已选海克斯;游戏内按 F7 临时隐藏。");
			_picker = new HexPickerUI(SubmitHex, _showActiveHexes);
			NetworkingAPI.RegisterMessageType<HexStateMessage>();
			NetworkingAPI.RegisterMessageType<OpenHexPickerMessage>();
			NetworkingAPI.RegisterMessageType<SelectHexMessage>();
			NetworkingAPI.RegisterMessageType<GetExcitedMessage>();
			NetworkingAPI.RegisterMessageType<TapDancerMessage>();
			NetworkingAPI.RegisterMessageType<ShrinkEngineMessage>();
			NetworkingAPI.RegisterMessageType<TankEngineMessage>();
			Run.onRunStartGlobal += OnRunStart;
			Run.onRunDestroyGlobal += OnRunDestroy;
			Stage.onServerStageBegin += OnServerStageBegin;
			BossGroup.onBossGroupDefeatedServer += OnBossGroupDefeatedServer;
			NetworkUser.onNetworkUserDiscovered += new NetworkUserGenericDelegate(OnNetworkUserDiscovered);
			object obj = <>O.<0>__ApplyStats;
			if (obj == null)
			{
				StatHookEventHandler val = HexRunState.ApplyStats;
				<>O.<0>__ApplyStats = val;
				obj = (object)val;
			}
			RecalculateStatsAPI.GetStatCoefficients += (StatHookEventHandler)obj;
			GlobalEventManager.onCharacterDeathGlobal += HexRunState.OnCharacterDeath;
			GlobalEventManager.onServerDamageDealt += HexRunState.OnServerDamageDealt;
			CharacterBody.onBodyStartGlobal += HexRunState.OnBodyStart;
			object obj2 = <>O.<4>__OnSkillExecute;
			if (obj2 == null)
			{
				hook_ExecuteIfReady val2 = HexRunState.OnSkillExecute;
				<>O.<4>__OnSkillExecute = val2;
				obj2 = (object)val2;
			}
			GenericSkill.ExecuteIfReady += (hook_ExecuteIfReady)obj2;
			object obj3 = <>O.<5>__OnHeal;
			if (obj3 == null)
			{
				hook_Heal val3 = HexRunState.OnHeal;
				<>O.<5>__OnHeal = val3;
				obj3 = (object)val3;
			}
			HealthComponent.Heal += (hook_Heal)obj3;
			object obj4 = <>O.<6>__OnTakeDamageProcess;
			if (obj4 == null)
			{
				hook_TakeDamageProcess val4 = HexRunState.OnTakeDamageProcess;
				<>O.<6>__OnTakeDamageProcess = val4;
				obj4 = (object)val4;
			}
			HealthComponent.TakeDamageProcess += (hook_TakeDamageProcess)obj4;
			Stage.BeginAdvanceStage += new hook_BeginAdvanceStage(OnBeginAdvanceStage);
			Log.LogInfo((object)"HexedRisk 1.0.4 loaded.");
		}

		private void OnDestroy()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Expected O, but got Unknown
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Expected O, but got Unknown
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Expected O, but got Unknown
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Expected O, but got Unknown
			Run.onRunStartGlobal -= OnRunStart;
			Run.onRunDestroyGlobal -= OnRunDestroy;
			Stage.onServerStageBegin -= OnServerStageBegin;
			BossGroup.onBossGroupDefeatedServer -= OnBossGroupDefeatedServer;
			NetworkUser.onNetworkUserDiscovered -= new NetworkUserGenericDelegate(OnNetworkUserDiscovered);
			object obj = <>O.<0>__ApplyStats;
			if (obj == null)
			{
				StatHookEventHandler val = HexRunState.ApplyStats;
				<>O.<0>__ApplyStats = val;
				obj = (object)val;
			}
			RecalculateStatsAPI.GetStatCoefficients -= (StatHookEventHandler)obj;
			GlobalEventManager.onCharacterDeathGlobal -= HexRunState.OnCharacterDeath;
			GlobalEventManager.onServerDamageDealt -= HexRunState.OnServerDamageDealt;
			CharacterBody.onBodyStartGlobal -= HexRunState.OnBodyStart;
			object obj2 = <>O.<4>__OnSkillExecute;
			if (obj2 == null)
			{
				hook_ExecuteIfReady val2 = HexRunState.OnSkillExecute;
				<>O.<4>__OnSkillExecute = val2;
				obj2 = (object)val2;
			}
			GenericSkill.ExecuteIfReady -= (hook_ExecuteIfReady)obj2;
			object obj3 = <>O.<5>__OnHeal;
			if (obj3 == null)
			{
				hook_Heal val3 = HexRunState.OnHeal;
				<>O.<5>__OnHeal = val3;
				obj3 = (object)val3;
			}
			HealthComponent.Heal -= (hook_Heal)obj3;
			object obj4 = <>O.<6>__OnTakeDamageProcess;
			if (obj4 == null)
			{
				hook_TakeDamageProcess val4 = HexRunState.OnTakeDamageProcess;
				<>O.<6>__OnTakeDamageProcess = val4;
				obj4 = (object)val4;
			}
			HealthComponent.TakeDamageProcess -= (hook_TakeDamageProcess)obj4;
			Stage.BeginAdvanceStage -= new hook_BeginAdvanceStage(OnBeginAdvanceStage);
			_picker?.Close();
		}

		private void Update()
		{
			_picker.Update();
		}

		private void FixedUpdate()
		{
			HexRunState.FixedUpdate();
			if (_waitingForSelection && NetworkServer.active)
			{
				_pendingPlayers.RemoveWhere((CharacterMaster master) => (Object)(object)master == (Object)null);
				if (_pendingPlayers.Count == 0)
				{
					ScheduleContinueToNextStage();
				}
			}
		}

		private void OnGUI()
		{
			_picker.Draw();
		}

		private void OnRunStart(Run run)
		{
			_lastBossGroupId = int.MinValue;
			ClearPendingChoice();
			_picker.Close();
			HexRunState.Reset();
		}

		private void OnRunDestroy(Run run)
		{
			ClearPendingChoice();
			_picker.Close();
			HexRunState.Reset();
		}

		private void OnServerStageBegin(Stage stage)
		{
			_lastBossGroupId = int.MinValue;
			ClearPendingChoice();
			HexRunState.OnStageBegin();
			foreach (KeyValuePair<CharacterMaster, IEnumerable<KeyValuePair<HexId, in