Decompiled source of MixKickingFightingStyle v1.1.1

BepInEx/plugins/MixKickingFightingStyle/MixKickingFightingStyle.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.Playables;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MixKickingFightingStyle")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MixKickingFightingStyle")]
[assembly: AssemblyTitle("MixKickingFightingStyle")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MixKickingFightingStyle
{
	internal static class ArmorStandSupport
	{
		private static readonly FieldInfo Equipment = AccessTools.Field(typeof(ArmorStand), "m_visEquipment");

		internal static void EnsureAttachMarker(GameObject prefab)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)prefab.transform.Find("attach")) && !Object.op_Implicit((Object)(object)prefab.transform.Find("attach_skin")))
			{
				new GameObject("attach").transform.SetParent(prefab.transform, false);
			}
		}

		internal static void Ensure(ArmorStand stand)
		{
			object? value = Equipment.GetValue(stand);
			VisEquipment val = (VisEquipment)((value is VisEquipment) ? value : null);
			if (Object.op_Implicit((Object)(object)val))
			{
				FightingArmorVisuals.Ensure(val);
				KickBootVisualDriver kickBootVisualDriver = ((Component)val).GetComponent<KickBootVisualDriver>();
				if (!Object.op_Implicit((Object)(object)kickBootVisualDriver))
				{
					kickBootVisualDriver = ((Component)val).gameObject.AddComponent<KickBootVisualDriver>();
				}
				kickBootVisualDriver.StandEquipment = val;
			}
		}
	}
	[HarmonyPatch(typeof(ArmorStand), "Awake")]
	internal static class FightingArmorStandAwake
	{
		private static void Postfix(ArmorStand __instance)
		{
			ArmorStandSupport.Ensure(__instance);
		}
	}
	[HarmonyPatch(typeof(ArmorStand), "SetVisualItem")]
	internal static class FightingArmorStandVisual
	{
		private static void Postfix(ArmorStand __instance)
		{
			ArmorStandSupport.Ensure(__instance);
		}
	}
	[HarmonyPatch(typeof(ArmorStand), "CanAttach")]
	internal static class FightingArmorStandSlot
	{
		private static bool Prefix(object __0, ItemData __1, ref bool __result)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (!KickBootVisuals.TryGetTier(__1, out var _))
			{
				return true;
			}
			List<ItemType> list = AccessTools.Field(__0.GetType(), "m_supportedTypes").GetValue(__0) as List<ItemType>;
			__result = list != null && (list.Count == 0 || list.Contains(__1.m_shared.m_itemType));
			return false;
		}
	}
	internal static class BalanceConfig
	{
		internal sealed class FiniteMultiplierRange : AcceptableValueBase
		{
			private readonly float minimum;

			internal FiniteMultiplierRange(float minimum)
				: base(typeof(float))
			{
				this.minimum = minimum;
			}

			internal static float Normalize(float value, float minimum)
			{
				if (!float.IsNaN(value) && !float.IsInfinity(value))
				{
					return Math.Max(minimum, Math.Min(20f, value));
				}
				return 1f;
			}

			public override object Clamp(object value)
			{
				return Normalize((float)value, minimum);
			}

			public override bool IsValid(object value)
			{
				if (value is float num && !float.IsNaN(num) && !float.IsInfinity(num) && num >= minimum)
				{
					return num <= 20f;
				}
				return false;
			}

			public override string ToDescriptionString()
			{
				return "# Acceptable value range: From " + minimum.ToString(CultureInfo.InvariantCulture) + " to 20; non-finite values reset to 1";
			}
		}

		internal static ConfigEntry<float> FeetExperienceMultiplier;

		internal static ConfigEntry<float> KickDamageMultiplier;

		internal static ConfigEntry<float> HeavyDamageMultiplier;

		internal static ConfigEntry<float> KickStaggerMultiplier;

		internal static ConfigEntry<float> HeavyStaggerMultiplier;

		internal static ConfigEntry<float> StaminaCostMultiplier;

		internal static ConfigEntry<float> DurabilityDrainMultiplier;

		internal static void Initialize(ConfigFile config)
		{
			FeetExperienceMultiplier = Bind(config, "Combat Skills", "FeetExperienceMultiplier", 0.1f, "Feet XP only; does not multiply Path of Valheiman XP. Ignored when UseFeetSkill is false.");
			KickDamageMultiplier = Bind(config, "Combat", "KickDamageMultiplier", 0.1f, "All kicking weapon damage, including upgrades, normal combos and Heavy attacks.");
			HeavyDamageMultiplier = Bind(config, "Combat", "HeavyDamageMultiplier", 0.1f, "Additional Heavy damage multiplier. Stacks with KickDamageMultiplier; both set to 20 gives 400 times current Heavy damage.");
			KickStaggerMultiplier = Bind(config, "Combat", "KickStaggerMultiplier", 0.1f, "Normal kick stagger multiplier. Damage changes also affect stagger through the game's normal rules.");
			HeavyStaggerMultiplier = Bind(config, "Combat", "HeavyStaggerMultiplier", 0.1f, "Heavy stagger multiplier, independent of the normal kick stagger setting.");
			StaminaCostMultiplier = Bind(config, "Combat", "StaminaCostMultiplier", 0.1f, "Stamina cost of normal and Heavy kicks, retaining native skill and status-effect adjustments.");
			DurabilityDrainMultiplier = Bind(config, "Equipment", "DurabilityDrainMultiplier", 0f, "Kicking weapon durability lost on melee use. Zero disables that wear; maximum durability and armor wear are unchanged.");
		}

		private static ConfigEntry<float> Bind(ConfigFile config, string section, string key, float minimum, string detail)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			return config.Bind<float>(section, key, 1f, new ConfigDescription(detail + " Default 1 preserves the current balance. Maximum 20. Server-synced; admins only. In-game configuration changes apply immediately; restart after editing the file externally.", (AcceptableValueBase)(object)new FiniteMultiplierRange(minimum), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			} }));
		}

		internal static float Value(ConfigEntry<float> entry)
		{
			if (entry != null)
			{
				return FiniteMultiplierRange.Normalize(entry.Value, (entry == DurabilityDrainMultiplier) ? 0f : 0.1f);
			}
			return 1f;
		}

		internal static float ScaleFeetExperience(float amount)
		{
			return amount * Value(FeetExperienceMultiplier);
		}

		internal static float ScaleStamina(float amount, ItemData weapon)
		{
			if (!KickBootVisuals.TryGetTier(weapon, out var _))
			{
				return amount;
			}
			return amount * Value(StaminaCostMultiplier);
		}

		internal static float ScaleWear(float amount, Attack attack)
		{
			if (!KickBootVisuals.TryGetTier(attack.GetWeapon(), out var _))
			{
				return amount;
			}
			return amount * Value(DurabilityDrainMultiplier);
		}
	}
	[HarmonyPatch(typeof(ItemData), "GetDamage", new Type[]
	{
		typeof(int),
		typeof(float)
	})]
	internal static class KickConfiguredDamage
	{
		[HarmonyPriority(0)]
		private static void Postfix(ItemData __instance, ref DamageTypes __result)
		{
			if (KickBootVisuals.TryGetTier(__instance, out var _))
			{
				float num = BalanceConfig.Value(BalanceConfig.KickDamageMultiplier);
				if (num != 1f)
				{
					((DamageTypes)(ref __result)).Modify(num);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Attack), "ModifyDamage")]
	internal static class KickConfiguredImpact
	{
		[HarmonyPriority(0)]
		private static void Postfix(Attack __instance, HitData __0)
		{
			if (__0 == null || !KickBootVisuals.TryGetTier(__instance.GetWeapon(), out var _))
			{
				return;
			}
			bool num = __instance.m_attackAnimation == "unarmed_kick";
			if (num)
			{
				float num2 = BalanceConfig.Value(BalanceConfig.HeavyDamageMultiplier);
				if (num2 != 1f)
				{
					((DamageTypes)(ref __0.m_damage)).Modify(num2);
				}
			}
			float num3 = BalanceConfig.Value(num ? BalanceConfig.HeavyStaggerMultiplier : BalanceConfig.KickStaggerMultiplier);
			if (num3 != 1f)
			{
				__0.m_staggerMultiplier *= num3;
			}
		}
	}
	[HarmonyPatch(typeof(Attack), "GetAttackStamina")]
	internal static class KickConfiguredStamina
	{
		private static void Postfix(Attack __instance, ref float __result)
		{
			__result = BalanceConfig.ScaleStamina(__result, __instance.GetWeapon());
		}
	}
	[HarmonyPatch(typeof(Attack), "DoMeleeAttack")]
	internal static class KickConfiguredWear
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>();
			int num = 0;
			FieldInfo objB = AccessTools.Field(typeof(SharedData), "m_useDurabilityDrain");
			MethodInfo methodInfo = AccessTools.Method(typeof(BalanceConfig), "ScaleWear", (Type[])null, (Type[])null);
			foreach (CodeInstruction instruction in instructions)
			{
				list.Add(instruction);
				if (instruction.opcode == OpCodes.Ldfld && object.Equals(instruction.operand, objB))
				{
					list.Add(new CodeInstruction(OpCodes.Ldarg_0, (object)null));
					list.Add(new CodeInstruction(OpCodes.Call, (object)methodInfo));
					num++;
				}
			}
			if (num != 1)
			{
				throw new InvalidOperationException("Mix Kicking: expected one melee durability drain read, found " + num);
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[]
	{
		typeof(ItemData),
		typeof(int),
		typeof(bool),
		typeof(float),
		typeof(int),
		typeof(bool)
	})]
	internal static class KickConfiguredStaminaTooltip
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>();
			int num = 0;
			FieldInfo objB = AccessTools.Field(typeof(Attack), "m_attackStamina");
			MethodInfo methodInfo = AccessTools.Method(typeof(BalanceConfig), "ScaleStamina", (Type[])null, (Type[])null);
			foreach (CodeInstruction instruction in instructions)
			{
				list.Add(instruction);
				if (instruction.opcode == OpCodes.Ldfld && object.Equals(instruction.operand, objB))
				{
					list.Add(new CodeInstruction(OpCodes.Ldarg_0, (object)null));
					list.Add(new CodeInstruction(OpCodes.Call, (object)methodInfo));
					num++;
				}
			}
			if (num != 2)
			{
				throw new InvalidOperationException("Mix Kicking: expected two stamina tooltip reads, found " + num);
			}
			return list;
		}
	}
	public struct FootCalibration
	{
		public Vector3 LocalForward;

		public Vector3 LocalUp;

		public Vector3 Offset;

		public Vector3 Scale;

		public string Source;

		public float WrapWidth;

		public Vector3 LocalWrapForward;

		public Vector3 LocalWrapFootForward;

		public Vector3 LocalWrapFootUp;

		public bool WrapFollowsShin;

		public bool MirrorBoot;

		public bool ToeFollowsRig;

		public Vector3 LocalToeForward;

		public Vector3 LocalToeUp;

		public Vector3 LocalToeOffset;
	}
	public static class BootAttachment
	{
		private const float SoleDepth = 0.1565f;

		private const float ShaftTop = 0.26f;

		private const float ToeBallReference = 0.16f;

		public static bool IsNativeViking(Animator animator)
		{
			if (!Object.op_Implicit((Object)(object)animator) || !Object.op_Implicit((Object)(object)animator.avatar))
			{
				return false;
			}
			string name = ((Object)animator.avatar).name;
			if (!string.Equals(name, "player_maleAvatar", StringComparison.OrdinalIgnoreCase))
			{
				return string.Equals(name, "player_femAvatar", StringComparison.OrdinalIgnoreCase);
			}
			return true;
		}

		private static bool BindMatrix(SkinnedMeshRenderer[] skins, Transform bone, out Matrix4x4 result, out SkinnedMeshRenderer owner)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			foreach (SkinnedMeshRenderer val in skins)
			{
				if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.sharedMesh))
				{
					continue;
				}
				int num = Array.IndexOf(val.bones, bone);
				if (num >= 0)
				{
					Matrix4x4[] bindposes = val.sharedMesh.bindposes;
					if (num < bindposes.Length)
					{
						result = ((Component)val).transform.localToWorldMatrix * ((Matrix4x4)(ref bindposes[num])).inverse;
						owner = val;
						return true;
					}
				}
			}
			result = Matrix4x4.identity;
			owner = null;
			return false;
		}

		private static bool RestMatrix(Animator animator, Transform bone, Dictionary<string, SkeletonBone> skeleton, out Matrix4x4 result)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			List<Transform> list = new List<Transform>();
			Transform val = bone;
			while (Object.op_Implicit((Object)(object)val) && (Object)(object)val != (Object)(object)((Component)animator).transform)
			{
				list.Add(val);
				val = val.parent;
			}
			if ((Object)(object)val != (Object)(object)((Component)animator).transform)
			{
				result = Matrix4x4.identity;
				return false;
			}
			result = ((Component)animator).transform.localToWorldMatrix;
			for (int num = list.Count - 1; num >= 0; num--)
			{
				if (!skeleton.TryGetValue(((Object)list[num]).name, out var value))
				{
					return false;
				}
				result *= Matrix4x4.TRS(value.position, value.rotation, value.scale);
			}
			return true;
		}

		public static bool Calibrate(Animator animator, Transform reference, Transform foot, Transform knee, Transform toes, SkinnedMeshRenderer[] skins, out FootCalibration calibration)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: 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_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: 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_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: 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_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_03af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Unknown result type (might be due to invalid IL or missing references)
			//IL_042d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0431: Unknown result type (might be due to invalid IL or missing references)
			//IL_0433: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_043c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0441: 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_044f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0453: Unknown result type (might be due to invalid IL or missing references)
			//IL_0455: Unknown result type (might be due to invalid IL or missing references)
			//IL_045a: Unknown result type (might be due to invalid IL or missing references)
			//IL_045e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0463: Unknown result type (might be due to invalid IL or missing references)
			//IL_0470: Unknown result type (might be due to invalid IL or missing references)
			//IL_0475: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0404: Unknown result type (might be due to invalid IL or missing references)
			//IL_0409: Unknown result type (might be due to invalid IL or missing references)
			//IL_040e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0413: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_0495: Unknown result type (might be due to invalid IL or missing references)
			//IL_049a: Unknown result type (might be due to invalid IL or missing references)
			//IL_049e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04de: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0504: Unknown result type (might be due to invalid IL or missing references)
			//IL_0508: Unknown result type (might be due to invalid IL or missing references)
			//IL_050a: Unknown result type (might be due to invalid IL or missing references)
			//IL_050c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0511: Unknown result type (might be due to invalid IL or missing references)
			//IL_0515: Unknown result type (might be due to invalid IL or missing references)
			//IL_051a: Unknown result type (might be due to invalid IL or missing references)
			//IL_051f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0523: Unknown result type (might be due to invalid IL or missing references)
			//IL_0528: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0565: Unknown result type (might be due to invalid IL or missing references)
			//IL_056a: Unknown result type (might be due to invalid IL or missing references)
			//IL_056e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0570: Unknown result type (might be due to invalid IL or missing references)
			//IL_0575: Unknown result type (might be due to invalid IL or missing references)
			//IL_0579: Unknown result type (might be due to invalid IL or missing references)
			//IL_055c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_036d: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			//IL_0376: Unknown result type (might be due to invalid IL or missing references)
			//IL_037b: Unknown result type (might be due to invalid IL or missing references)
			//IL_057e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0592: Unknown result type (might be due to invalid IL or missing references)
			//IL_0597: Unknown result type (might be due to invalid IL or missing references)
			//IL_059b: Unknown result type (might be due to invalid IL or missing references)
			//IL_059d: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0589: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05de: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e3: Unknown result type (might be due to invalid IL or missing references)
			calibration = default(FootCalibration);
			if (!Object.op_Implicit((Object)(object)animator) || !Object.op_Implicit((Object)(object)reference) || !Object.op_Implicit((Object)(object)foot) || !Object.op_Implicit((Object)(object)knee))
			{
				return false;
			}
			Matrix4x4 result = Matrix4x4.identity;
			Matrix4x4 result2;
			SkinnedMeshRenderer owner;
			SkinnedMeshRenderer owner2;
			bool flag = BindMatrix(skins, foot, out result2, out owner) && BindMatrix(skins, knee, out result, out owner2);
			bool flag2 = false;
			Matrix4x4 result3 = Matrix4x4.identity;
			if (flag)
			{
				flag2 = Object.op_Implicit((Object)(object)toes) && BindMatrix(skins, toes, out result3, out owner2);
			}
			else
			{
				Dictionary<string, SkeletonBone> dictionary = new Dictionary<string, SkeletonBone>();
				SkeletonBone[] skeleton = animator.avatar.humanDescription.skeleton;
				foreach (SkeletonBone val in skeleton)
				{
					dictionary[val.name] = val;
				}
				if (!RestMatrix(animator, foot, dictionary, out result2) || !RestMatrix(animator, knee, dictionary, out result))
				{
					return false;
				}
				flag2 = Object.op_Implicit((Object)(object)toes) && RestMatrix(animator, toes, dictionary, out result3);
			}
			Vector3 val2 = Vector4.op_Implicit(((Matrix4x4)(ref result2)).GetColumn(3));
			Vector3 val3 = Vector4.op_Implicit(((Matrix4x4)(ref result)).GetColumn(3));
			Vector3 val4 = reference.up;
			Vector3 normalized = ((Vector3)(ref val4)).normalized;
			Vector3 val5 = (flag2 ? Vector3.ProjectOnPlane(Vector4.op_Implicit(((Matrix4x4)(ref result3)).GetColumn(3)) - val2, normalized) : Vector3.ProjectOnPlane(reference.forward, normalized));
			float magnitude = ((Vector3)(ref val5)).magnitude;
			bool flag3 = IsNativeViking(animator);
			if (flag3)
			{
				val5 = Vector3.ProjectOnPlane(((Component)animator).transform.forward, normalized);
			}
			else if (magnitude < 1E-05f)
			{
				val5 = reference.forward;
			}
			((Vector3)(ref val5)).Normalize();
			float num = Vector3.Distance(val2, val3);
			if (num < 0.03f || num > 2f)
			{
				return false;
			}
			float num2 = num / 0.42f;
			float num3 = ((flag2 && magnitude > 1E-05f) ? Mathf.Clamp(magnitude / 0.16f, 0.7f * num2, 1.3f * num2) : num2);
			float num4 = Vector3.Dot(val2 - reference.position, normalized);
			if (Object.op_Implicit((Object)(object)owner) && Object.op_Implicit((Object)(object)owner.sharedMesh))
			{
				Bounds bounds = owner.sharedMesh.bounds;
				float num5 = float.PositiveInfinity;
				for (int j = -1; j <= 1; j += 2)
				{
					for (int k = -1; k <= 1; k += 2)
					{
						for (int l = -1; l <= 1; l += 2)
						{
							Vector3 val6 = ((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)j, (float)k, (float)l));
							num5 = Mathf.Min(num5, Vector3.Dot(((Component)owner).transform.TransformPoint(val6), normalized));
						}
					}
				}
				float num6 = Vector3.Dot(val2, normalized) - num5;
				if (num6 >= 0.01f * num2 && num6 <= 0.25f * num2)
				{
					num4 = num6;
				}
			}
			if (num4 < 0.01f * num2 || num4 > 0.25f * num2)
			{
				num4 = 0.1f * num2;
			}
			float num7 = (num4 + num * 0.55f) / 0.41649997f;
			if (flag3)
			{
				num7 = num4 / 0.1565f;
			}
			float num8 = num3;
			if (flag3)
			{
				num8 = 0.69f * num2;
				Transform boneTransform = animator.GetBoneTransform((HumanBodyBones)(((Object)(object)foot == (Object)(object)animator.GetBoneTransform((HumanBodyBones)5)) ? 6 : 5));
				if (Object.op_Implicit((Object)(object)boneTransform) && BindMatrix(skins, boneTransform, out var result4, out owner2))
				{
					val4 = Vector3.ProjectOnPlane(Vector4.op_Implicit(((Matrix4x4)(ref result4)).GetColumn(3)) - val2, normalized);
					float magnitude2 = ((Vector3)(ref val4)).magnitude;
					num8 = Mathf.Min(num8, Mathf.Max(0.01f, (magnitude2 - 0.012f * num2) / 0.291f));
				}
			}
			Vector3 localToeOffset = Vector3.zero;
			if (flag3 && flag2)
			{
				Vector3 val7 = val2 + Quaternion.LookRotation(val5, normalized) * Vector3.Scale(new Vector3(num8, num7, num3), new Vector3(0f, -0.15f, 0.16f));
				localToeOffset = Quaternion.Inverse(((Matrix4x4)(ref result3)).rotation) * (val7 - Vector4.op_Implicit(((Matrix4x4)(ref result3)).GetColumn(3)));
			}
			FootCalibration footCalibration = default(FootCalibration);
			Matrix4x4 inverse = ((Matrix4x4)(ref result2)).inverse;
			val4 = ((Matrix4x4)(ref inverse)).MultiplyVector(val5);
			footCalibration.LocalForward = ((Vector3)(ref val4)).normalized;
			inverse = ((Matrix4x4)(ref result2)).inverse;
			val4 = ((Matrix4x4)(ref inverse)).MultiplyVector(normalized);
			footCalibration.LocalUp = ((Vector3)(ref val4)).normalized;
			footCalibration.Scale = new Vector3(num8, num7, num3);
			footCalibration.WrapWidth = (flag3 ? (num3 * 1.07f) : num3);
			inverse = ((Matrix4x4)(ref result)).inverse;
			val4 = ((Matrix4x4)(ref inverse)).MultiplyVector(val5);
			footCalibration.LocalWrapForward = ((Vector3)(ref val4)).normalized;
			inverse = ((Matrix4x4)(ref result2)).inverse;
			val4 = ((Matrix4x4)(ref inverse)).MultiplyVector(Quaternion.LookRotation(Vector3.ProjectOnPlane(val5, val3 - val2), val3 - val2) * Vector3.forward);
			footCalibration.LocalWrapFootForward = ((Vector3)(ref val4)).normalized;
			inverse = ((Matrix4x4)(ref result2)).inverse;
			val4 = val3 - val2;
			val4 = ((Matrix4x4)(ref inverse)).MultiplyVector(((Vector3)(ref val4)).normalized);
			footCalibration.LocalWrapFootUp = ((Vector3)(ref val4)).normalized;
			footCalibration.WrapFollowsShin = flag3;
			footCalibration.MirrorBoot = (Object)(object)foot == (Object)(object)animator.GetBoneTransform((HumanBodyBones)6);
			footCalibration.ToeFollowsRig = flag3 && flag2;
			Vector3 localToeForward;
			if (!flag2)
			{
				localToeForward = Vector3.forward;
			}
			else
			{
				inverse = ((Matrix4x4)(ref result3)).inverse;
				val4 = ((Matrix4x4)(ref inverse)).MultiplyVector(val5);
				localToeForward = ((Vector3)(ref val4)).normalized;
			}
			footCalibration.LocalToeForward = localToeForward;
			Vector3 localToeUp;
			if (!flag2)
			{
				localToeUp = Vector3.up;
			}
			else
			{
				inverse = ((Matrix4x4)(ref result3)).inverse;
				val4 = ((Matrix4x4)(ref inverse)).MultiplyVector(normalized);
				localToeUp = ((Vector3)(ref val4)).normalized;
			}
			footCalibration.LocalToeUp = localToeUp;
			footCalibration.LocalToeOffset = localToeOffset;
			footCalibration.Offset = (Vector3)(flag3 ? Vector3.zero : new Vector3(0f, 0.1565f * num7 - num4, 0.03f * num2));
			footCalibration.Source = (flag3 ? "Valheim native ankle bind pose" : (flag ? "mesh bind pose" : "avatar rest skeleton"));
			calibration = footCalibration;
			return true;
		}

		public static void Place(Transform visual, Transform foot, FootCalibration calibration)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_005c: 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)
			Vector3 val = foot.TransformDirection(calibration.LocalForward);
			Vector3 val2 = foot.TransformDirection(calibration.LocalUp);
			Quaternion val3 = Quaternion.LookRotation(val, val2);
			visual.SetPositionAndRotation(foot.position + val3 * calibration.Offset, val3);
			Vector3 scale = calibration.Scale;
			if (calibration.MirrorBoot)
			{
				scale.x = 0f - scale.x;
			}
			visual.localScale = scale;
		}

		public static void PlaceCalibratedWrap(Transform visual, Transform foot, Transform knee, FootCalibration calibration)
		{
			//IL_0018: 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_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			Vector3 forward = (calibration.WrapFollowsShin ? knee.TransformDirection(calibration.LocalWrapForward) : foot.TransformDirection(calibration.LocalForward));
			PlaceWrap(visual, foot, knee, forward, calibration.WrapWidth);
		}

		public static void PlaceWrap(Transform visual, Transform foot, Transform knee, Vector3 forward, float width = 1f)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = knee.position - foot.position;
			if (!(((Vector3)(ref val)).sqrMagnitude < 1E-06f))
			{
				Vector3 val2 = Vector3.ProjectOnPlane(forward, val);
				if (((Vector3)(ref val2)).sqrMagnitude < 1E-06f)
				{
					val2 = Vector3.ProjectOnPlane(Vector3.forward, val);
				}
				if (((Vector3)(ref val2)).sqrMagnitude < 1E-06f)
				{
					val2 = Vector3.ProjectOnPlane(Vector3.right, val);
				}
				visual.SetPositionAndRotation(foot.position, Quaternion.LookRotation(val2, val));
				visual.localScale = new Vector3(width, ((Vector3)(ref val)).magnitude * 0.85f / 0.42f, width);
			}
		}
	}
	internal static class BootLore
	{
		internal static string Get(string biome, bool thai)
		{
			switch (biome)
			{
			case "Meadows":
				if (!thai)
				{
					return "Dew-darkened hide binds cloth from a warrior's first shelter. The fallen leave their prints upon the meadow and follow the Allfather's ravens.";
				}
				return "หน\u0e31งท\u0e35\u0e48ผ\u0e48านน\u0e49ำค\u0e49างถ\u0e39กพ\u0e31นท\u0e31บด\u0e49วยผ\u0e49าจากเร\u0e37อนหล\u0e31งแรก ผ\u0e39\u0e49ตายผ\u0e39\u0e49หน\u0e36\u0e48งฝากรอยเท\u0e49าไว\u0e49บนท\u0e38\u0e48ง แล\u0e49วออกเด\u0e34นตามเส\u0e35ยงกาของบ\u0e34ดาแห\u0e48งสรรพส\u0e34\u0e48ง";
			case "BlackForest":
				if (!thai)
				{
					return "Dull bronze clasps troll hide that still smells of pine. Root and stone groan beneath these soles before the forest knows a stranger has come.";
				}
				return "ทองส\u0e31มฤทธ\u0e34\u0e4cหม\u0e48นโอบหน\u0e31งโทรลล\u0e4cท\u0e35\u0e48ย\u0e31งม\u0e35กล\u0e34\u0e48นสน ว\u0e48าก\u0e31นว\u0e48าผ\u0e39\u0e49สวมได\u0e49ย\u0e34นรากไม\u0e49คราง ก\u0e48อนเงาใต\u0e49พ\u0e38\u0e48มจะร\u0e39\u0e49ต\u0e31วว\u0e48าม\u0e35แขก";
			case "Ocean":
				if (!thai)
				{
					return "Salt stiffens the hide beneath a serpent's scales. Each knot remembers a sailor who never returned, yet these soles still seek another shore.";
				}
				return "เกล\u0e47ดจากท\u0e49องทะเลถ\u0e39กเย\u0e47บต\u0e34ดหน\u0e31งช\u0e38\u0e48มเกล\u0e37อ เช\u0e37อกท\u0e38กปมผ\u0e39กไว\u0e49เพ\u0e37\u0e48อผ\u0e39\u0e49ท\u0e35\u0e48ไม\u0e48กล\u0e31บข\u0e36\u0e49นเร\u0e37อ แต\u0e48รองเท\u0e49าค\u0e39\u0e48น\u0e35\u0e49ย\u0e31งรอฝ\u0e31\u0e48งถ\u0e31ดไป";
			case "Swamp":
				if (!thai)
				{
					return "Ancient roots bind iron hauled from black mud. The swamp never leaves the leather. Its wearer counts no nights, only the steps that rise above the water.";
				}
				return "รากไม\u0e49เก\u0e48าร\u0e31ดเหล\u0e47กท\u0e35\u0e48ข\u0e38ดข\u0e36\u0e49นจากโคลนดำ กล\u0e34\u0e48นหนองไม\u0e48เคยจาง ผ\u0e39\u0e49สวมจ\u0e36งเล\u0e34กน\u0e31บค\u0e37น และน\u0e31บเพ\u0e35ยงรอยเท\u0e49าท\u0e35\u0e48พ\u0e49นน\u0e49ำ";
			case "Mountain":
				if (!thai)
				{
					return "Cold silver sleeps beneath wolf hide. The fangs at the ankle once belonged to the mountain's master. Where the wind devours all speech, only crushed snow answers.";
				}
				return "เง\u0e34นเย\u0e47นจ\u0e31ดซ\u0e48อนอย\u0e39\u0e48ใต\u0e49หน\u0e31งหมาป\u0e48า เข\u0e35\u0e49ยวท\u0e35\u0e48ข\u0e49อเท\u0e49าเคยเป\u0e47นของเจ\u0e49าถ\u0e34\u0e48น บนส\u0e31นเขาท\u0e35\u0e48ลมกล\u0e37นท\u0e38กคำ ม\u0e35เพ\u0e35ยงเส\u0e35ยงห\u0e34มะแตกใต\u0e49ฝ\u0e48าเท\u0e49า";
			case "Plains":
				if (!thai)
				{
					return "Black metal pins thick lox hide. Needles taken from the golden grass line its seams. No warrior crosses these plains unseen.";
				}
				return "หน\u0e31งล\u0e47อกซ\u0e4cหนาหน\u0e31กถ\u0e39กตร\u0e36งด\u0e49วยโลหะดำ เข\u0e47มแหลมเป\u0e47นของฝากจากท\u0e38\u0e48งส\u0e35ทอง ท\u0e35\u0e48น\u0e35\u0e48ไม\u0e48ม\u0e35ผ\u0e39\u0e49ใดเหย\u0e35ยบหญ\u0e49าส\u0e39งโดยไร\u0e49ผ\u0e39\u0e49เฝ\u0e49ามอง";
			case "Mistlands":
				if (!thai)
				{
					return "Broken carapace and seeker silk cover older seams. Beneath Yggdrasil's roots, a smith shaped them for those who must keep walking when the path disappears.";
				}
				return "กระดองแตกร\u0e49าวก\u0e31บไหมซ\u0e35คเกอร\u0e4cป\u0e34ดท\u0e31บรอยเย\u0e47บเก\u0e48า ช\u0e48างต\u0e35เหล\u0e47กใต\u0e49รากอ\u0e34กดราซ\u0e34ลสร\u0e49างม\u0e31นให\u0e49ผ\u0e39\u0e49ท\u0e35\u0e48ต\u0e49องเด\u0e34นต\u0e48อ แม\u0e49มองไม\u0e48เห\u0e47นพ\u0e37\u0e49นตรงหน\u0e49า";
			case "Ashlands":
				if (!thai)
				{
					return "Flametal rivets hold charred ask hide. A morgen heart fed the smith's rite. The smith never spoke of what looked back from the fire, and no one asked twice.";
				}
				return "หน\u0e31งอ\u0e31สก\u0e4cไหม\u0e49เกร\u0e35ยมถ\u0e39กหม\u0e38ดเฟลมเมท\u0e31ลตร\u0e36งไว\u0e49 ห\u0e31วใจมอร\u0e4cเกนถ\u0e39กใช\u0e49ในพ\u0e34ธ\u0e35ต\u0e35เหล\u0e47ก ช\u0e48างไม\u0e48กล\u0e48าวถ\u0e36งส\u0e34\u0e48งท\u0e35\u0e48เห\u0e47นในไฟ และไม\u0e48ม\u0e35ผ\u0e39\u0e49ใดถามซ\u0e49ำ";
			case "DeepNorth":
				if (!thai)
				{
					return "Dull gold rests in wood split by bitter cold. A frozen core lies sealed beneath the hide. Beyond the last light, an exile's oath weighs more than snow.";
				}
				return "ทองหม\u0e48นฝ\u0e31งในไม\u0e49ท\u0e35\u0e48หนาวจนแตกร\u0e49าว แกนเย\u0e47นถ\u0e39กป\u0e34ดผน\u0e36กไว\u0e49ใต\u0e49หน\u0e31ง สำหร\u0e31บผ\u0e39\u0e49ถ\u0e39กเนรเทศท\u0e35\u0e48เด\u0e34นเลยแสงส\u0e38ดท\u0e49าย คำสาบานย\u0e31งหน\u0e31กกว\u0e48าห\u0e34มะ";
			default:
				if (!thai)
				{
					return "The footsteps of the fallen in the tenth world.";
				}
				return "รอยเท\u0e49าของผ\u0e39\u0e49ตายในด\u0e34นแดนท\u0e35\u0e48ส\u0e34บ";
			}
		}
	}
	internal static class CartPullPassive
	{
		private sealed class PullState
		{
			internal Vagon Cart;

			internal ItemData Item;

			internal GameObject Prefab;

			internal bool Checked;

			internal bool Eligible;
		}

		internal sealed class CartSpeedRange : AcceptableValueBase
		{
			internal CartSpeedRange()
				: base(typeof(float))
			{
			}

			internal static float Normalize(float value)
			{
				if (!float.IsNaN(value) && !float.IsInfinity(value))
				{
					return Math.Max(0.1f, Math.Min(3f, value));
				}
				return 1.25f;
			}

			public override object Clamp(object value)
			{
				return Normalize((float)value);
			}

			public override bool IsValid(object value)
			{
				if (value is float num && !float.IsNaN(num) && !float.IsInfinity(num) && num >= 0.1f)
				{
					return num <= 3f;
				}
				return false;
			}

			public override string ToDescriptionString()
			{
				return "# Acceptable value range: From 0.1 to 3; non-finite values reset to 1.25";
			}
		}

		internal static ConfigEntry<float> Speed;

		private static readonly Dictionary<Player, PullState> Players = new Dictionary<Player, PullState>();

		private static readonly Dictionary<Vagon, Player> Carts = new Dictionary<Vagon, Player>();

		private static readonly FieldInfo Attached = typeof(Vagon).GetField("m_attachedObject", BindingFlags.Instance | BindingFlags.NonPublic);

		internal static void Initialize(ConfigFile config)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			Speed = config.Bind<float>("Utility", "CartPullSpeedMultiplier", 1.25f, new ConfigDescription("Movement speed while actively pulling a cart with a MixKicking weapon equipped. Default 1.25 grants +25%; 1 disables the bonus. Range 0.1-3. Cart mass, cargo, slope, stamina and joint physics are unchanged. Server-synced; admins only. In-game changes apply immediately; restart after editing the file externally.", (AcceptableValueBase)(object)new CartSpeedRange(), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			} }));
		}

		internal static void Record(Vagon cart)
		{
			ForgetCart(cart);
			if (Object.op_Implicit((Object)(object)cart))
			{
				object? value = Attached.GetValue(cart);
				GameObject val = (GameObject)((value is GameObject) ? value : null);
				Player val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<Player>() : null);
				if (Object.op_Implicit((Object)(object)val2) && cart.IsAttached((Character)(object)val2))
				{
					ForgetPlayer(val2);
					Players.Add(val2, new PullState
					{
						Cart = cart
					});
					Carts.Add(cart, val2);
				}
			}
		}

		internal static void ForgetCart(Vagon cart)
		{
			if (cart != null && Carts.TryGetValue(cart, out var value))
			{
				Carts.Remove(cart);
				if (Players.TryGetValue(value, out var value2) && value2.Cart == cart)
				{
					Players.Remove(value);
				}
			}
		}

		internal static void ForgetPlayer(Player player)
		{
			if (player != null && Players.TryGetValue(player, out var value))
			{
				Players.Remove(player);
				Carts.Remove(value.Cart);
			}
		}

		internal static float Multiplier(Character character)
		{
			Player val = (Player)(object)((character is Player) ? character : null);
			if (!Object.op_Implicit((Object)(object)val) || !Players.TryGetValue(val, out var value))
			{
				return 1f;
			}
			if (!Object.op_Implicit((Object)(object)value.Cart) || !value.Cart.IsAttached((Character)(object)val))
			{
				ForgetPlayer(val);
				return 1f;
			}
			ItemData rightItem = KickBootVisuals.GetRightItem((Humanoid)(object)val);
			GameObject val2 = rightItem?.m_dropPrefab;
			if (!value.Checked || rightItem != value.Item || (Object)(object)val2 != (Object)(object)value.Prefab)
			{
				value.Checked = true;
				value.Item = rightItem;
				value.Prefab = val2;
				value.Eligible = KickBootVisuals.TryGetTier(rightItem, out var _);
			}
			if (!value.Eligible)
			{
				return 1f;
			}
			if (Speed != null)
			{
				return CartSpeedRange.Normalize(Speed.Value);
			}
			return 1.25f;
		}

		internal static float ScaleSpeed(float speed, Character character)
		{
			return speed * Multiplier(character);
		}

		internal static string Tooltip()
		{
			float num = ((Speed == null) ? 1.25f : CartSpeedRange.Normalize(Speed.Value));
			if (num == 1f)
			{
				return string.Empty;
			}
			return "\n\n<color=orange>Hauler's Stride</color>\n" + ((num - 1f) * 100f).ToString("+0.##;-0.##;0", CultureInfo.InvariantCulture) + "% movement speed while pulling a cart.";
		}

		internal static void Shutdown()
		{
			Players.Clear();
			Carts.Clear();
		}
	}
	[HarmonyPatch(typeof(Vagon), "AttachTo")]
	internal static class KickCartAttached
	{
		private static void Postfix(Vagon __instance)
		{
			CartPullPassive.Record(__instance);
		}
	}
	[HarmonyPatch(typeof(Vagon), "Detach")]
	internal static class KickCartDetached
	{
		private static void Prefix(Vagon __instance)
		{
			CartPullPassive.ForgetCart(__instance);
		}
	}
	[HarmonyPatch(typeof(Vagon), "OnDestroy")]
	internal static class KickCartDestroyed
	{
		private static void Prefix(Vagon __instance)
		{
			CartPullPassive.ForgetCart(__instance);
		}
	}
	[HarmonyPatch(typeof(Player), "OnDestroy")]
	internal static class KickCartPlayerDestroyed
	{
		private static void Prefix(Player __instance)
		{
			CartPullPassive.ForgetPlayer(__instance);
		}
	}
	[HarmonyPatch(typeof(Character), "UpdateWalking")]
	internal static class KickCartMovement
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Expected O, but got Unknown
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Expected O, but got Unknown
			FieldInfo[] array = new FieldInfo[4]
			{
				AccessTools.Field(typeof(Character), "m_speed"),
				AccessTools.Field(typeof(Character), "m_walkSpeed"),
				AccessTools.Field(typeof(Character), "m_runSpeed"),
				AccessTools.Field(typeof(Character), "m_crouchSpeed")
			};
			int[] array2 = new int[array.Length];
			List<CodeInstruction> list = new List<CodeInstruction>();
			MethodInfo methodInfo = AccessTools.Method(typeof(CartPullPassive), "ScaleSpeed", (Type[])null, (Type[])null);
			foreach (CodeInstruction instruction in instructions)
			{
				list.Add(instruction);
				if (instruction.opcode != OpCodes.Ldfld)
				{
					continue;
				}
				for (int i = 0; i < array.Length; i++)
				{
					if (object.Equals(instruction.operand, array[i]))
					{
						list.Add(new CodeInstruction(OpCodes.Ldarg_0, (object)null));
						list.Add(new CodeInstruction(OpCodes.Call, (object)methodInfo));
						array2[i]++;
					}
				}
			}
			for (int j = 0; j < array2.Length; j++)
			{
				if (array2[j] != 1)
				{
					throw new InvalidOperationException("Mix Kicking: expected one cart speed branch for " + array[j].Name + ", found " + array2[j]);
				}
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "SetupCharacterPreview")]
	internal static class KickingCharacterPreview
	{
		private static void Postfix(GameObject ___m_playerInstance, GameObject ___m_characterSelectScreen)
		{
			KickAssetLifetime.CharacterChanged(___m_playerInstance);
			VisualLoadPolicy.CharacterScreen = ___m_characterSelectScreen;
			if (Object.op_Implicit((Object)(object)___m_playerInstance))
			{
				(___m_playerInstance.GetComponent<FightingArmorVisuals>() ?? ___m_playerInstance.AddComponent<FightingArmorVisuals>()).CharacterPreview = true;
				(___m_playerInstance.GetComponent<KickBootVisualDriver>() ?? ___m_playerInstance.AddComponent<KickBootVisualDriver>()).CharacterPreview = true;
			}
		}
	}
	internal sealed class CounterAnimationClock
	{
		private int marker;

		private float sampled;

		internal float Sample(float wallElapsed, float duration)
		{
			if (float.IsNaN(wallElapsed) || float.IsInfinity(wallElapsed))
			{
				return sampled;
			}
			float num = Math.Max(sampled, Math.Min(duration, Math.Max(0f, wallElapsed)));
			if (marker < CounterHeavyTimeline.Hits.Length && CounterHeavyTimeline.Hits[marker] <= duration && num >= CounterHeavyTimeline.Hits[marker])
			{
				num = CounterHeavyTimeline.Hits[marker++];
			}
			return sampled = num;
		}
	}
	internal sealed class CounterChargeState
	{
		private bool charged;

		private bool infinite;

		private bool reserved;

		private double granted;

		private double expires;

		internal const double RequestTransitLimit = 0.75;

		internal int Generation { get; private set; }

		internal double RecoveryUntil { get; private set; }

		internal bool Ready(double now)
		{
			if (charged && !reserved)
			{
				if (!infinite)
				{
					return now <= expires;
				}
				return true;
			}
			return false;
		}

		internal bool Retain(double now)
		{
			if (!charged || (!infinite && !(now <= expires + 0.75 + 0.02)))
			{
				return Recovering(now);
			}
			return true;
		}

		internal double Remaining(double now)
		{
			if (!Ready(now))
			{
				return 0.0;
			}
			if (!infinite)
			{
				return Math.Max(0.0, expires - now);
			}
			return double.PositiveInfinity;
		}

		internal void Grant(double now, float seconds, bool forever, int generation = 0)
		{
			charged = true;
			reserved = false;
			infinite = forever;
			granted = now;
			expires = now + (double)seconds;
			Generation = ((generation > 0) ? generation : (Generation + 1));
			RecoveryUntil = 0.0;
		}

		internal bool Reserve(double now)
		{
			if (!Ready(now))
			{
				return false;
			}
			reserved = true;
			return true;
		}

		internal void CancelReservation(int generation)
		{
			if (Generation == generation)
			{
				reserved = false;
			}
		}

		internal void Confirm(int generation)
		{
			if (Generation == generation)
			{
				charged = false;
				reserved = false;
			}
		}

		internal bool ConsumeAt(double pressedAt, double receivedAt, int generation)
		{
			if (!charged || generation != Generation || double.IsNaN(pressedAt) || double.IsInfinity(pressedAt) || receivedAt - pressedAt > 0.75 || pressedAt - receivedAt > 0.02 || pressedAt < granted - 0.02 || (!infinite && pressedAt > expires + 0.02))
			{
				return false;
			}
			charged = false;
			reserved = false;
			return true;
		}

		internal void Miss(double now)
		{
			RecoveryUntil = Math.Max(RecoveryUntil, now + 0.7);
		}

		internal bool Recovering(double now)
		{
			return now < RecoveryUntil;
		}

		internal void Clear()
		{
			charged = false;
			reserved = false;
			RecoveryUntil = 0.0;
		}
	}
	internal static class CounterDummyIdentity
	{
		internal static bool Matches(string prefab, string componentType = "")
		{
			string text = (prefab ?? "").Replace("_", "").Replace("-", "").Replace(" ", "")
				.ToLowerInvariant();
			if (!text.Contains("dummy") && !text.Contains("archerytarget") && !text.Contains("trainingtarget") && !text.Contains("practicetarget"))
			{
				if (!string.IsNullOrEmpty(componentType))
				{
					return componentType.IndexOf("dummy", StringComparison.OrdinalIgnoreCase) >= 0;
				}
				return false;
			}
			return true;
		}
	}
	internal static class CounterHeavyAssets
	{
		internal static AnimationClip Clip;

		private static MonoBehaviour host;

		private static string path;

		private static AssetBundle bundle;

		private static AssetBundleCreateRequest opening;

		private static Coroutine worker;

		private static bool loading;

		private static bool failed;

		internal static bool Ready
		{
			get
			{
				if (Object.op_Implicit((Object)(object)Clip))
				{
					return ((Motion)Clip).isHumanMotion;
				}
				return false;
			}
		}

		internal static void Initialize(MonoBehaviour owner, string directory)
		{
			host = owner;
			path = Path.Combine(directory, "mkscounterheavy");
		}

		internal static void Request()
		{
			if (!Ready && !loading && !failed && Object.op_Implicit((Object)(object)host))
			{
				loading = true;
				worker = host.StartCoroutine(Load());
			}
		}

		private static IEnumerator Load()
		{
			if (!File.Exists(path))
			{
				failed = true;
				loading = false;
				yield break;
			}
			opening = AssetBundle.LoadFromFileAsync(path);
			yield return opening;
			bundle = opening.assetBundle;
			opening = null;
			if (Object.op_Implicit((Object)(object)bundle))
			{
				AssetBundleRequest req = bundle.LoadAssetAsync<AnimationClip>("MKS_CounterHeavy");
				yield return req;
				Object asset = req.asset;
				Clip = (AnimationClip)(object)((asset is AnimationClip) ? asset : null);
			}
			failed = !Ready;
			loading = false;
			worker = null;
		}

		internal static void Shutdown()
		{
			if (Object.op_Implicit((Object)(object)host) && worker != null)
			{
				host.StopCoroutine(worker);
			}
			worker = null;
			if (opening != null)
			{
				AssetBundleCreateRequest req = opening;
				opening = null;
				if (((AsyncOperation)req).isDone)
				{
					if (Object.op_Implicit((Object)(object)req.assetBundle))
					{
						req.assetBundle.Unload(false);
					}
				}
				else
				{
					((AsyncOperation)req).completed += delegate
					{
						if (Object.op_Implicit((Object)(object)req.assetBundle))
						{
							req.assetBundle.Unload(false);
						}
					};
				}
			}
			if (Object.op_Implicit((Object)(object)bundle))
			{
				bundle.Unload(false);
			}
			bundle = null;
			Clip = null;
			loading = (failed = false);
			host = null;
		}
	}
	internal static class CounterHeavyBuff
	{
		private const string EffectName = "MKS_CounterHeavyReady108";

		private static StatusEffect prototype;

		private static Sprite icon;

		private static Texture2D texture;

		private static int hash;

		internal static void Initialize(string folder)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_006e: 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)
			hash = StringExtensionMethods.GetStableHashCode("MKS_CounterHeavyReady108");
			string path = Path.Combine(folder, "Icons", "CounterHeavy.png");
			if (File.Exists(path))
			{
				texture = new Texture2D(2, 2, (TextureFormat)4, false);
				if (ImageConversion.LoadImage(texture, File.ReadAllBytes(path), true))
				{
					icon = Sprite.Create(texture, new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), new Vector2(0.5f, 0.5f));
				}
			}
			prototype = (StatusEffect)(object)ScriptableObject.CreateInstance<CounterReadyEffect>();
			((Object)prototype).name = "MKS_CounterHeavyReady108";
			prototype.m_name = "Counter Heavy";
			prototype.m_tooltip = "Parry counter ready. Use Secondary to spend one charge.";
			prototype.m_icon = icon;
		}

		internal static void Sync(Player player, CounterChargeState state)
		{
			if (!Object.op_Implicit((Object)(object)player) || !Object.op_Implicit((Object)(object)prototype))
			{
				return;
			}
			SEMan sEMan = ((Character)player).GetSEMan();
			bool num = CounterHeavyConfig.Enabled.Value && CounterHeavyAssets.Ready && state.Ready(Time.time);
			StatusEffect val = sEMan.GetStatusEffect(hash);
			if (!num)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					sEMan.RemoveStatusEffect(hash, true);
				}
				return;
			}
			float num2 = (float)state.Remaining(Time.time);
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = sEMan.AddStatusEffect(prototype, false, 0, 0f, (short)(-1));
			}
			if (Object.op_Implicit((Object)(object)val))
			{
				val.m_ttl = (float.IsInfinity(num2) ? 0f : (val.GetDuration() + num2));
			}
		}

		internal static void Remove(Player player)
		{
			if (Object.op_Implicit((Object)(object)player))
			{
				((Character)player).GetSEMan().RemoveStatusEffect(hash, true);
			}
		}

		internal static void Shutdown()
		{
			Remove(Player.m_localPlayer);
			if (Object.op_Implicit((Object)(object)prototype))
			{
				Object.Destroy((Object)(object)prototype);
			}
			if (Object.op_Implicit((Object)(object)icon))
			{
				Object.Destroy((Object)(object)icon);
			}
			if (Object.op_Implicit((Object)(object)texture))
			{
				Object.Destroy((Object)(object)texture);
			}
			prototype = null;
			icon = null;
			texture = null;
		}
	}
	internal sealed class CounterReadyEffect : StatusEffect
	{
		public override string GetIconText()
		{
			if (!(base.m_ttl <= 0f))
			{
				return ((StatusEffect)this).GetIconText();
			}
			return "∞";
		}
	}
	internal static class CounterHeavyConfig
	{
		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<bool> Infinite;

		internal static ConfigEntry<float> Damage;

		internal static ConfigEntry<float> Duration;

		internal static void Initialize(ConfigFile config)
		{
			//IL_001a: 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_0027: Expected O, but got Unknown
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_0067: 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_0074: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Expected O, but got Unknown
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Expected O, but got Unknown
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Expected O, but got Unknown
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Expected O, but got Unknown
			Enabled = config.Bind<bool>("CounterHeavy", "Enabled", true, new ConfigDescription("Enable Parry-earned Counter Heavy charges. Server-synced; admins only.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			} }));
			Damage = config.Bind<float>("CounterHeavy", "DamageMultiplier", 2f, new ConfigDescription("Total Counter Heavy damage relative to the existing Heavy. One means one Heavy across the complete sequence.", (AcceptableValueBase)(object)new TakedownConfig.FiniteRange(0.1f, 20f, 2f), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			} }));
			Duration = config.Bind<float>("CounterHeavy", "DurationSeconds", 3f, new ConfigDescription("Global charge lifetime in seconds. Another successful Parry refreshes it; cap is one charge.", (AcceptableValueBase)(object)new TakedownConfig.FiniteRange(1f, 60f, 3f), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			} }));
			Infinite = config.Bind<bool>("CounterHeavy", "InfiniteDuration", false, new ConfigDescription("Keep the single charge until spent. Overrides DurationSeconds; it does not make the attack or enemy lock infinite.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			} }));
		}
	}
	internal sealed class CounterHeavySession
	{
		internal Player Player;

		internal Character Victim;

		internal CounterTarget Target;

		internal bool Practice;

		internal ZDOID AttackerId;

		internal ZDOID VictimId;

		internal long Peer;

		internal int Token;

		internal int ServerHit;

		internal int ChargeGeneration;

		internal int Contacts;

		internal readonly CounterImpactCursor Impacts = new CounterImpactCursor();

		internal bool OwnerStarted;

		internal bool StartAcknowledged;

		internal bool RecoveryApplied;

		internal float ServerExpires;

		internal float Began;

		internal float Lease;

		internal float Heartbeat;

		internal float DamageScale;

		internal bool Broken;

		internal bool RemoteServerSession;

		internal float StaminaCost;

		internal ItemData Weapon;

		internal CounterHeavyPresentation Presentation;

		internal Vector3 Anchor;

		internal Vector3 Forward;

		internal bool HasTarget => VictimId != ZDOID.None;

		internal float Duration
		{
			get
			{
				if (!HasTarget)
				{
					return 0.75f;
				}
				return 2.3f;
			}
		}
	}
	internal sealed class CounterParryClaim
	{
		internal Player Player;

		internal Character Victim;

		internal long Peer;

		internal float Expires;
	}
	internal static class CounterHeavyNetwork
	{
		private const string RequestRpc = "MKS_CounterCharge_Request_108f";

		private const string StateRpc = "MKS_CounterCharge_State_108f";

		internal static readonly Dictionary<ZDOID, CounterHeavySession> Sessions = new Dictionary<ZDOID, CounterHeavySession>();

		private static readonly Dictionary<ZDOID, CounterChargeState> Charges = new Dictionary<ZDOID, CounterChargeState>();

		private static readonly Dictionary<ZDOID, CounterParryClaim> Claims = new Dictionary<ZDOID, CounterParryClaim>();

		private static readonly Dictionary<ZDOID, int> AcceptedParries = new Dictionary<ZDOID, int>();

		private static readonly List<CounterHeavySession> Scratch = new List<CounterHeavySession>();

		private static readonly List<ZDOID> OldKeys = new List<ZDOID>();

		private static readonly Func<ZRoutedRpc, long> ServerPeer = AccessTools.MethodDelegate<Func<ZRoutedRpc, long>>(AccessTools.Method(typeof(ZRoutedRpc), "GetServerPeerID", (Type[])null, (Type[])null), (object)null, true);

		private static readonly FieldRef<Attack, Humanoid> AttackCharacter = AccessTools.FieldRefAccess<Attack, Humanoid>("m_character");

		private static readonly FieldRef<Attack, ItemData> AttackWeapon = AccessTools.FieldRefAccess<Attack, ItemData>("m_weapon");

		private static readonly Action<Attack, HitData, float> ModifyDamage = AccessTools.MethodDelegate<Action<Attack, HitData, float>>(AccessTools.Method(typeof(Attack), "ModifyDamage", (Type[])null, (Type[])null), (object)null, true);

		private static readonly Func<Attack, float> AttackStamina = AccessTools.MethodDelegate<Func<Attack, float>>(AccessTools.Method(typeof(Attack), "GetAttackStamina", (Type[])null, (Type[])null), (object)null, true);

		private static ZRoutedRpc routed;

		private static float nextScan;

		private static float pendingUntil;

		private static float parryUntil;

		private static Player pendingPlayer;

		private static Player parryPlayer;

		private static Character parryVictim;

		private static int nextToken;

		private static int pendingGeneration;

		private static int nextChargeGeneration;

		private static int nextParrySequence;

		private static bool pendingCancel;

		internal static bool Running;

		private static bool Server
		{
			get
			{
				if (Object.op_Implicit((Object)(object)ZNet.instance))
				{
					return ZNet.instance.IsServer();
				}
				return false;
			}
		}

		internal static bool Owns(Character c)
		{
			ZNetView val = (Object.op_Implicit((Object)(object)c) ? ((Component)c).GetComponent<ZNetView>() : null);
			if (Object.op_Implicit((Object)(object)val) && val.IsValid())
			{
				return val.IsOwner();
			}
			return false;
		}

		private static Character Find(ZDOID id)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (id == ZDOID.None)
			{
				return null;
			}
			GameObject val = (Object.op_Implicit((Object)(object)ZNetScene.instance) ? ZNetScene.instance.FindInstance(id) : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return null;
			}
			return val.GetComponent<Character>();
		}

		private static CounterTarget FindTarget(ZDOID id)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			return CounterTarget.Resolve((id != ZDOID.None && Object.op_Implicit((Object)(object)ZNetScene.instance)) ? ZNetScene.instance.FindInstance(id) : null);
		}

		private static CounterChargeState Charge(ZDOID id)
		{
			//IL_0005: 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)
			if (!Charges.TryGetValue(id, out var value))
			{
				value = new CounterChargeState();
				Charges[id] = value;
			}
			return value;
		}

		internal static bool LocalReady(Player p)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (CounterHeavyConfig.Enabled.Value && CounterHeavyAssets.Ready && Object.op_Implicit((Object)(object)p) && Charges.TryGetValue(((Character)p).GetZDOID(), out var value))
			{
				return value.Ready(Time.time);
			}
			return false;
		}

		internal static bool Recovering(Player p)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)p) && Charges.TryGetValue(((Character)p).GetZDOID(), out var value))
			{
				return value.Recovering(Time.time);
			}
			return false;
		}

		internal static CounterHeavySession For(Character c)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)c))
			{
				return null;
			}
			ZDOID zDOID = c.GetZDOID();
			if (Sessions.TryGetValue(zDOID, out var value) && !value.Broken)
			{
				return value;
			}
			foreach (KeyValuePair<ZDOID, CounterHeavySession> session in Sessions)
			{
				if (!session.Value.Broken && session.Value.HasTarget && session.Value.VictimId == zDOID)
				{
					return session.Value;
				}
			}
			return null;
		}

		internal static bool Valid(CounterHeavySession s)
		{
			if (Running && s != null && !s.Broken && Time.time - s.Lease <= 2f)
			{
				if (!Server)
				{
					return Time.time - s.Began <= s.Duration + 1f;
				}
				return Time.time <= s.ServerExpires;
			}
			return false;
		}

		internal static bool Pinned(Character c)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			CounterHeavySession counterHeavySession = For(c);
			if (Valid(counterHeavySession) && counterHeavySession.HasTarget)
			{
				return counterHeavySession.VictimId == c.GetZDOID();
			}
			return false;
		}

		internal static bool Protected(Character c)
		{
			CounterHeavySession counterHeavySession = For(c);
			if (Valid(counterHeavySession) && counterHeavySession.HasTarget && !counterHeavySession.Practice)
			{
				return (Object)(object)counterHeavySession.Player == (Object)(object)c;
			}
			return false;
		}

		internal static bool SuppressAttack(Attack a)
		{
			return Pinned((Character)(object)AttackCharacter.Invoke(a));
		}

		internal static void CancelPending(Player p)
		{
			if (Pending(p))
			{
				pendingCancel = true;
			}
		}

		internal static bool Pending(Player p)
		{
			if ((Object)(object)pendingPlayer == (Object)(object)p)
			{
				return Time.time < pendingUntil;
			}
			return false;
		}

		private static Attack Context(Player p, ItemData w)
		{
			Attack val = w.m_shared.m_secondaryAttack.Clone();
			AttackCharacter.Invoke(val) = (Humanoid)(object)p;
			AttackWeapon.Invoke(val) = w;
			return val;
		}

		private static float Cost(Player p)
		{
			ItemData rightItem = KickBootVisuals.GetRightItem((Humanoid)(object)p);
			if (rightItem == null)
			{
				return float.PositiveInfinity;
			}
			Character attackOwner = FeetSkill.AttackOwner;
			try
			{
				FeetSkill.AttackOwner = (Character)(object)p;
				return AttackStamina(Context(p, rightItem));
			}
			finally
			{
				FeetSkill.AttackOwner = attackOwner;
			}
		}

		internal static void Parried(Player p, Character v)
		{
			if (Running && CounterHeavyConfig.Enabled.Value && Object.op_Implicit((Object)(object)p) && Object.op_Implicit((Object)(object)v) && !v.IsBoss() && !v.IsPlayer() && KickBootVisuals.TryGetEquippedTier((Humanoid)(object)p, out var _))
			{
				parryPlayer = p;
				parryVictim = v;
				parryUntil = Time.time + 2f;
				Trace("Parry detected; waiting for local stagger confirmation.");
			}
		}

		internal static void Update()
		{
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0516: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_0549: Unknown result type (might be due to invalid IL or missing references)
			//IL_054e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0555: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0403: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_046d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0473: Unknown result type (might be due to invalid IL or missing references)
			if (ZRoutedRpc.instance != routed)
			{
				Clear();
				routed = ZRoutedRpc.instance;
				if (routed != null)
				{
					routed.Register<ZPackage>("MKS_CounterCharge_Request_108f", (Action<long, ZPackage>)ReceiveRequest);
					routed.Register<ZPackage>("MKS_CounterCharge_State_108f", (Action<long, ZPackage>)ReceiveState);
				}
			}
			if (routed == null || !Object.op_Implicit((Object)(object)ZNet.instance))
			{
				return;
			}
			float time = Time.time;
			Player localPlayer = Player.m_localPlayer;
			if (Object.op_Implicit((Object)(object)pendingPlayer) && pendingUntil > 0f && time > pendingUntil && For((Character)(object)pendingPlayer) == null)
			{
				Charge(((Character)pendingPlayer).GetZDOID()).CancelReservation(pendingGeneration);
				pendingUntil = 0f;
				pendingCancel = false;
			}
			if (Object.op_Implicit((Object)(object)parryPlayer) && Object.op_Implicit((Object)(object)parryVictim) && time <= parryUntil && parryVictim.IsStaggering() && !Pinned(parryVictim))
			{
				Send(4, parryPlayer, parryVictim, ++nextParrySequence, 0f);
				Trace("Local stagger confirmed; charge request sent.");
				parryPlayer = null;
				parryVictim = null;
			}
			if (time > parryUntil)
			{
				if (Object.op_Implicit((Object)(object)parryPlayer))
				{
					Trace("Parry expired without local stagger confirmation.");
				}
				parryPlayer = null;
				parryVictim = null;
			}
			if (Object.op_Implicit((Object)(object)localPlayer))
			{
				CounterChargeState counterChargeState = Charge(((Character)localPlayer).GetZDOID());
				if (((Character)localPlayer).IsDead() || !CounterHeavyConfig.Enabled.Value || !KickBootVisuals.TryGetEquippedTier((Humanoid)(object)localPlayer, out var biome))
				{
					counterChargeState.Clear();
				}
				CounterHeavyBuff.Sync(localPlayer, counterChargeState);
				if (CounterHeavyConfig.Enabled.Value && KickBootVisuals.TryGetEquippedTier((Humanoid)(object)localPlayer, out biome))
				{
					CounterHeavyAssets.Request();
				}
			}
			if (time >= nextScan)
			{
				nextScan = time + 0.05f;
				if (Server)
				{
					ValidateClaims(time);
					ServerTick(time);
				}
				PruneCharges(time);
			}
			Scratch.Clear();
			foreach (KeyValuePair<ZDOID, CounterHeavySession> session in Sessions)
			{
				Scratch.Add(session.Value);
			}
			foreach (CounterHeavySession item in Scratch)
			{
				if (item.RemoteServerSession)
				{
					continue;
				}
				if (!Valid(item) || !Object.op_Implicit((Object)(object)item.Player) || ((Character)item.Player).IsDead() || (item.HasTarget && (item.Target == null || !item.Target.Alive || item.Target.IsBoss)) || !CounterHeavyConfig.Enabled.Value)
				{
					if (Server)
					{
						EndServer(item);
					}
					else
					{
						EndLocal(item);
					}
					continue;
				}
				if ((Object)(object)item.Player == (Object)(object)localPlayer)
				{
					if (KickBootVisuals.GetRightItem((Humanoid)(object)item.Player) == item.Weapon)
					{
						Vector3 val = ((Component)item.Player).transform.position - item.Anchor;
						if (!(((Vector3)(ref val)).sqrMagnitude > 25f))
						{
							if (time >= item.Heartbeat)
							{
								item.Heartbeat = time + 0.4f;
								Send(3, item.Player, item.Victim, item.Token, 0f);
							}
							goto IL_03ac;
						}
					}
					Release(item.Player);
					continue;
				}
				goto IL_03ac;
				IL_03ac:
				if (item.Presentation != null)
				{
					continue;
				}
				CounterHeavyAssets.Request();
				if (!CounterHeavyAssets.Ready)
				{
					continue;
				}
				try
				{
					if ((Object)(object)item.Player == (Object)(object)localPlayer)
					{
						item.Began = Time.time;
						item.OwnerStarted = true;
					}
					item.Presentation = new CounterHeavyPresentation(item.Player, item.Victim, item.Anchor, item.Forward, item.Began, item.Duration, (Object)(object)item.Player == (Object)(object)localPlayer, item.Target?.Root);
					if ((Object)(object)item.Player == (Object)(object)localPlayer)
					{
						Send(5, item.Player, item.Victim, item.Token, 0f);
					}
				}
				catch (Exception ex)
				{
					ManualLogSource log = KickAnimations.Log;
					if (log != null)
					{
						log.LogWarning((object)("Counter Heavy restored after visual failure: " + ex.Message));
					}
					if ((Object)(object)item.Player == (Object)(object)localPlayer)
					{
						Release(item.Player);
					}
					else
					{
						EndLocal(item);
					}
				}
			}
			OldKeys.Clear();
			foreach (KeyValuePair<ZDOID, CounterHeavySession> session2 in Sessions)
			{
				if (session2.Value.Broken)
				{
					OldKeys.Add(session2.Key);
				}
			}
			foreach (ZDOID oldKey in OldKeys)
			{
				Sessions.Remove(oldKey);
			}
		}

		private static void PruneCharges(float now)
		{
			//IL_0021: 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_0066: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: 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_0128: Unknown result type (might be due to invalid IL or missing references)
			OldKeys.Clear();
			foreach (KeyValuePair<ZDOID, int> acceptedParry in AcceptedParries)
			{
				if (!Exists(acceptedParry.Key))
				{
					OldKeys.Add(acceptedParry.Key);
				}
			}
			foreach (ZDOID oldKey in OldKeys)
			{
				AcceptedParries.Remove(oldKey);
			}
			OldKeys.Clear();
			foreach (KeyValuePair<ZDOID, CounterChargeState> charge in Charges)
			{
				if (!Exists(charge.Key) || (!charge.Value.Retain(now) && !Sessions.ContainsKey(charge.Key)))
				{
					OldKeys.Add(charge.Key);
				}
			}
			foreach (ZDOID oldKey2 in OldKeys)
			{
				Charges.Remove(oldKey2);
			}
		}

		private static void Trace(string message)
		{
			ManualLogSource log = KickAnimations.Log;
			if (log != null)
			{
				log.LogInfo((object)("[CounterNet] " + message));
			}
		}

		private static void ValidateClaims(float now)
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			OldKeys.Clear();
			foreach (KeyValuePair<ZDOID, CounterParryClaim> claim in Claims)
			{
				CounterParryClaim value = claim.Value;
				if (now > value.Expires || !Object.op_Implicit((Object)(object)value.Player) || !Object.op_Implicit((Object)(object)value.Victim) || ((Character)value.Player).IsDead() || value.Victim.IsDead() || value.Victim.IsBoss() || !CounterHeavyConfig.Enabled.Value || !KickBootVisuals.TryGetEquippedTier((Humanoid)(object)value.Player, out var _))
				{
					OldKeys.Add(claim.Key);
					continue;
				}
				if (Pinned(value.Victim))
				{
					OldKeys.Add(claim.Key);
					continue;
				}
				Charge(claim.Key).Grant(now, CounterHeavyConfig.Duration.Value, CounterHeavyConfig.Infinite.Value, ++nextChargeGeneration);
				SendCharge(value.Peer, value.Player);
				Trace("Charge granted; generation=" + Charge(claim.Key).Generation);
				OldKeys.Add(claim.Key);
			}
			foreach (ZDOID oldKey in OldKeys)
			{
				Claims.Remove(oldKey);
			}
		}

		internal static void LateUpdate()
		{
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			Scratch.Clear();
			foreach (KeyValuePair<ZDOID, CounterHeavySession> session in Sessions)
			{
				Scratch.Add(session.Value);
			}
			foreach (CounterHeavySession item in Scratch)
			{
				try
				{
					if (item.Broken || item.Presentation == null)
					{
						continue;
					}
					item.Presentation.UpdatePose();
					if ((Object)(object)item.Player != (Object)(object)Player.m_localPlayer)
					{
						continue;
					}
					if (item.HasTarget)
					{
						int index;
						while (item.Impacts.Take(item.Presentation.SampledTime, out index))
						{
							if (Damage(item, index))
							{
								item.Contacts++;
								Send(1, item.Player, item.Victim, item.Token, item.Presentation.SampledTime, index);
							}
						}
					}
					if (item.Presentation.SampledTime >= item.Duration)
					{
						Release(item.Player);
					}
				}
				catch (Exception ex)
				{
					ManualLogSource log = KickAnimations.Log;
					if (log != null)
					{
						log.LogWarning((object)("Counter Heavy pose stopped: " + ex.Message));
					}
					if ((Object)(object)item.Player == (Object)(object)Player.m_localPlayer)
					{
						Release(item.Player);
					}
					else
					{
						EndLocal(item);
					}
				}
			}
		}

		private static bool InReach(Player p, CounterTarget target)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)p) || target == null || !target.Alive || ((Character)p).IsDead())
			{
				return false;
			}
			Character character = target.Character;
			if (Object.op_Implicit((Object)(object)character) && For(character) != null)
			{
				return false;
			}
			if (!target.IsDummy && (!Object.op_Implicit((Object)(object)character) || character.IsTamed() || !BaseAI.IsEnemy((Character)(object)p, character)))
			{
				return false;
			}
			Vector3 val = (Object.op_Implicit((Object)(object)character) ? target.Position : target.Center) - (Object.op_Implicit((Object)(object)character) ? ((Component)p).transform.position : ((Character)p).GetCenterPoint());
			if (((Vector3)(ref val)).sqrMagnitude > 6.25f || (Object.op_Implicit((Object)(object)character) && Mathf.Abs(val.y) > 1f) || Vector3.Dot(((Component)p).transform.forward, ((Vector3)(ref val)).normalized) < 0.4f)
			{
				return false;
			}
			Vector3 centerPoint = ((Character)p).GetCenterPoint();
			Vector3 center = target.Center;
			RaycastHit val2 = default(RaycastHit);
			if (Physics.Linecast(centerPoint, center, ref val2, LayerMask.GetMask(new string[4] { "Default", "static_solid", "piece", "terrain" }), (QueryTriggerInteraction)1) && !((Component)((RaycastHit)(ref val2)).collider).transform.IsChildOf(target.Root.transform) && (Object)(object)((Component)((RaycastHit)(ref val2)).collider).gameObject != (Object)(object)target.Root)
			{
				return false;
			}
			return true;
		}

		internal static bool TryStart(Player p)
		{
			//IL_00a1: 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_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			if (!CounterHeavyConfig.Enabled.Value || !Object.op_Implicit((Object)(object)p) || (Object)(object)p != (Object)(object)Player.m_localPlayer || Recovering(p) || !KickBootVisuals.TryGetEquippedTier((Humanoid)(object)p, out var _) || ((Character)p).InAttack() || ((Character)p).IsStaggering() || p.GetStamina() < Cost(p))
			{
				return false;
			}
			KickCombatDriver kickCombatDriver = KickCombatDriver.Local((Humanoid)(object)p);
			if ((Object)(object)kickCombatDriver != (Object)null && (kickCombatDriver.Committed || kickCombatDriver.Recovery || kickCombatDriver.WindupLocked))
			{
				return false;
			}
			CounterHeavyAssets.Request();
			if (!CounterHeavyAssets.Ready || routed == null)
			{
				return false;
			}
			CounterTarget counterTarget = null;
			float num = float.MaxValue;
			HashSet<ZDOID> hashSet = new HashSet<ZDOID>();
			Collider[] array = Physics.OverlapSphere(((Character)p).GetCenterPoint(), 3.5f, -1, (QueryTriggerInteraction)1);
			for (int i = 0; i < array.Length; i++)
			{
				CounterTarget counterTarget2 = CounterTarget.Resolve(((Component)array[i]).gameObject);
				if (counterTarget2 != null && hashSet.Add(counterTarget2.Id) && InReach(p, counterTarget2))
				{
					Vector3 val = counterTarget2.Position - ((Component)p).transform.position;
					float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
					if (sqrMagnitude < num)
					{
						num = sqrMagnitude;
						counterTarget = counterTarget2;
					}
				}
			}
			if (counterTarget != null && counterTarget.IsBoss)
			{
				return false;
			}
			bool flag = counterTarget?.IsDummy ?? false;
			if (!flag && !LocalReady(p))
			{
				return false;
			}
			CounterChargeState counterChargeState = Charge(((Character)p).GetZDOID());
			if (!flag && !counterChargeState.Reserve(Time.time))
			{
				return false;
			}
			pendingGeneration = counterChargeState.Generation;
			CounterHeavyBuff.Sync(p, counterChargeState);
			pendingPlayer = p;
			pendingCancel = false;
			pendingUntil = Time.time + 2f;
			Send(flag ? 7 : 0, p, counterTarget?.Character, 0, p.GetStamina(), -1, counterTarget?.Id ?? ZDOID.None);
			return true;
		}

		internal static void Release(Player p)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			CounterHeavySession counterHeavySession = For((Character)(object)p);
			if (counterHeavySession != null)
			{
				if (counterHeavySession.Contacts == 0 && !counterHeavySession.RecoveryApplied)
				{
					Charge(counterHeavySession.AttackerId).Miss(Time.time);
					counterHeavySession.RecoveryApplied = true;
				}
				Send(2, p, counterHeavySession.Victim, counterHeavySession.Token, 0f);
				EndLocal(counterHeavySession);
			}
		}

		private static void Send(int kind, Player p, Character v, int token, float stamina, int impact = -1, ZDOID targetId = default(ZDOID))
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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)
			if (routed != null && Object.op_Implicit((Object)(object)p))
			{
				ZPackage val = new ZPackage();
				val.Write(kind);
				val.Write(((Character)p).GetZDOID());
				val.Write((targetId != ZDOID.None) ? targetId : (Object.op_Implicit((Object)(object)v) ? v.GetZDOID() : ((token != 0 && Sessions.TryGetValue(((Character)p).GetZDOID(), out var value)) ? value.VictimId : ZDOID.None)));
				val.Write(token);
				val.Write(stamina);
				val.Write((kind == 0 || kind == 7) ? Cost(p) : 0f);
				val.Write((kind == 0 || kind == 7 || kind == 4) ? ZNet.instance.GetTime().Ticks : 0);
				val.Write((kind == 0 || kind == 7) ? pendingGeneration : 0);
				val.Write(impact);
				routed.InvokeRoutedRPC(ServerPeer(routed), "MKS_CounterCharge_Request_108f", new object[1] { val });
			}
		}

		private static bool SenderOwns(long sender, ZDOID id)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			if (id == ZDOID.None)
			{
				return false;
			}
			if (sender == ZNet.GetUID() && Object.op_Implicit((Object)(object)Player.m_localPlayer) && id == ((Character)Player.m_localPlayer).GetZDOID())
			{
				return true;
			}
			ZNetPeer peer = ZNet.instance.GetPeer(sender);
			if (peer != null)
			{
				return peer.m_characterID == id;
			}
			return false;
		}

		private unsafe static void ReceiveRequest(long sender, ZPackage pkg)
		{
			//IL_0018: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_0348: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_0359: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0406: Unknown result type (might be due to invalid IL or missing references)
			//IL_0407: Unknown result type (might be due to invalid IL or missing references)
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_040e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0458: Unknown result type (might be due to invalid IL or missing references)
			//IL_044f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_045d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0463: Unknown result type (might be due to invalid IL or missing references)
			//IL_0465: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a9: Unknown result type (might be due to invalid IL or missing references)
			if (!Server || !Running)
			{
				return;
			}
			try
			{
				int num = pkg.ReadInt();
				ZDOID val = pkg.ReadZDOID();
				ZDOID val2 = pkg.ReadZDOID();
				int num2 = pkg.ReadInt();
				float num3 = pkg.ReadSingle();
				float num4 = pkg.ReadSingle();
				long num5 = pkg.ReadLong();
				int num6 = pkg.ReadInt();
				int num7 = pkg.ReadInt();
				Character obj = Find(val);
				Player val3 = (Player)(object)((obj is Player) ? obj : null);
				if (!SenderOwns(sender, val))
				{
					string text = sender.ToString();
					ZDOID val4 = val;
					Trace("Request rejected: peer character ID mismatch; sender=" + text + ", requested=" + ((object)(*(ZDOID*)(&val4))/*cast due to .constrained prefix*/).ToString());
					return;
				}
				if (sender != ZNet.GetUID() && (num == 4 || num == 0 || num == 7))
				{
					ReceiveRemote(sender, num,