Decompiled source of ComboAxe v1.0.0

BepInEx/plugins/ComboAxe.dll

Decompiled 20 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using UnityEngine;

[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("ComboAxe")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+d85e09a9fa6f2977c1991ff84e6c844fa86504d8")]
[assembly: AssemblyProduct("ComboAxe")]
[assembly: AssemblyTitle("ComboAxe")]
[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 ComboAxe
{
	[Serializable]
	public sealed class AxeMotionDocument
	{
		public int schema;

		public float sampleRate;

		public AxeMotionClip[] clips;
	}
	[Serializable]
	public sealed class AxeMotionClip
	{
		public string name;

		public float length;

		public float sampleRate;

		public AxeMotionFrame[] frames;
	}
	[Serializable]
	public sealed class AxeMotionFrame
	{
		public int anchor;

		public Vector3 position;

		public Quaternion rotation;

		public bool releaseRight;

		public bool releaseLeft;
	}
	public static class AxePoseSampling
	{
		public static bool TrySample(AxeMotionClip clip, float seconds, Transform right, Transform left, out Vector3 position, out Quaternion rotation, out AxeMotionFrame state)
		{
			//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_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_00c2: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			position = Vector3.zero;
			rotation = Quaternion.identity;
			state = null;
			if (clip == null || clip.frames == null || clip.frames.Length == 0 || (Object)(object)right == (Object)null || (Object)(object)left == (Object)null)
			{
				return false;
			}
			float num = Mathf.Clamp(seconds * clip.sampleRate, 0f, (float)(clip.frames.Length - 1));
			int num2 = Mathf.FloorToInt(num);
			int num3 = Mathf.Min(num2 + 1, clip.frames.Length - 1);
			float num4 = num - (float)num2;
			AxeMotionFrame axeMotionFrame = clip.frames[num2];
			AxeMotionFrame axeMotionFrame2 = clip.frames[num3];
			Transform val = ((axeMotionFrame.anchor == 0) ? right : left);
			Transform val2 = ((axeMotionFrame2.anchor == 0) ? right : left);
			position = Vector3.Lerp(val.TransformPoint(axeMotionFrame.position), val2.TransformPoint(axeMotionFrame2.position), num4);
			rotation = Quaternion.Slerp(val.rotation * axeMotionFrame.rotation, val2.rotation * axeMotionFrame2.rotation, num4);
			state = ((num4 < 0.5f) ? axeMotionFrame : axeMotionFrame2);
			return true;
		}
	}
	internal static class ClipSets
	{
		private class Own
		{
			public AnimatorOverrideController Controller;

			public RuntimeAnimatorController Base;
		}

		internal const string BundleFile = "comboaxe.bundle";

		private static AssetBundle bundle;

		private static bool bundleTried;

		private static Stream embeddedBundleStream;

		private static readonly Dictionary<string, AnimationClip> clips = new Dictionary<string, AnimationClip>();

		private static readonly ConditionalWeakTable<Animator, Own> own = new ConditionalWeakTable<Animator, Own>();

		private static readonly Move[] Moves = new Move[9]
		{
			Move.L1,
			Move.L2,
			Move.L3,
			Move.S1,
			Move.S2,
			Move.S3,
			Move.H1,
			Move.H2,
			Move.H3
		};

		internal static string ResolveName(SetKey key, Move m)
		{
			string text = Families.ClipName(key.Family, m, key.Variant);
			if (key.Variant != Variant.Shield && (Object)(object)Clip(text) == (Object)null)
			{
				text = Families.ClipName(key.Family, m);
			}
			return text;
		}

		private static AnimationClip Resolve(SetKey key, Move m)
		{
			return Clip(ResolveName(key, m));
		}

		internal static TextAsset ReadTextAsset(string path)
		{
			if (!Object.op_Implicit((Object)(object)bundle))
			{
				return null;
			}
			return bundle.LoadAsset<TextAsset>(path);
		}

		internal static bool AllBaseClipsPresent(out string missing)
		{
			List<string> list = new List<string>();
			Family[] array = new Family[2]
			{
				Family.Raider,
				Family.Exec
			};
			foreach (Family f in array)
			{
				Move[] moves = Moves;
				foreach (Move m in moves)
				{
					string text = Families.ClipName(f, m);
					if ((Object)(object)Clip(text) == (Object)null)
					{
						list.Add(text);
					}
				}
			}
			missing = string.Join(", ", list.ToArray());
			return list.Count == 0;
		}

		internal static AnimationClip Clip(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return null;
			}
			if (clips.TryGetValue(name, out var value))
			{
				return value;
			}
			if (!bundleTried)
			{
				bundleTried = true;
				string text = Path.Combine(Plugin.PluginFolder ?? "", "comboaxe.bundle");
				if (File.Exists(text))
				{
					bundle = AssetBundle.LoadFromFile(text);
					Plugin.Log.Log((LogLevel)(Object.op_Implicit((Object)(object)bundle) ? 16 : 4), (object)(Object.op_Implicit((Object)(object)bundle) ? ("Loaded bundle " + text) : ("Bundle found but could not be read: " + text)));
				}
				else
				{
					bundle = LoadEmbeddedBundle();
					Plugin.Log.Log((LogLevel)(Object.op_Implicit((Object)(object)bundle) ? 16 : 4), (object)(Object.op_Implicit((Object)(object)bundle) ? "No bundle file next to the DLL - loaded the embedded copy from this assembly." : ("Bundle not found: " + text + ", and this build has no embedded bundle.")));
				}
			}
			value = (Object.op_Implicit((Object)(object)bundle) ? bundle.LoadAsset<AnimationClip>(name) : null);
			if ((Object)(object)value == (Object)null)
			{
				bool flag = name.EndsWith("_Free", StringComparison.Ordinal) || name.EndsWith("_Torch", StringComparison.Ordinal);
				Plugin.Log.Log((LogLevel)(flag ? 32 : 4), (object)("Custom clip '" + name + "' not found in the bundle."));
			}
			else if (!Array.Exists(value.events, (AnimationEvent e) => e.functionName == "OnAttackTrigger"))
			{
				Plugin.Log.LogWarning((object)("Custom clip '" + name + "' has no OnAttackTrigger event - it would never hit. Ignoring it."));
				value = null;
			}
			else
			{
				Plugin.Log.LogDebug((object)$"Custom clip '{name}' loaded ({value.length:0.00}s).");
			}
			clips[name] = value;
			return value;
		}

		private static AssetBundle LoadEmbeddedBundle()
		{
			try
			{
				Assembly executingAssembly = Assembly.GetExecutingAssembly();
				string text = null;
				string[] manifestResourceNames = executingAssembly.GetManifestResourceNames();
				foreach (string text2 in manifestResourceNames)
				{
					if (text2.EndsWith("comboaxe.bundle", StringComparison.OrdinalIgnoreCase))
					{
						text = text2;
						break;
					}
				}
				if (text == null)
				{
					return null;
				}
				using Stream stream = executingAssembly.GetManifestResourceStream(text);
				if (stream == null)
				{
					return null;
				}
				MemoryStream memoryStream = new MemoryStream();
				stream.CopyTo(memoryStream);
				memoryStream.Position = 0L;
				embeddedBundleStream = memoryStream;
				return AssetBundle.LoadFromStream((Stream)memoryStream);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Could not load the embedded bundle (" + ex.GetType().Name + ": " + ex.Message + ")."));
				return null;
			}
		}

		private static Dictionary<string, AnimationClip> Pairs(SetKey? key)
		{
			Dictionary<string, AnimationClip> dictionary = new Dictionary<string, AnimationClip>();
			if (!key.HasValue)
			{
				return dictionary;
			}
			Move[] moves = Moves;
			foreach (Move m in moves)
			{
				AnimationClip val = Resolve(key.Value, m);
				if ((Object)(object)val != (Object)null)
				{
					dictionary[Families.HostClip(m)] = val;
				}
			}
			return dictionary;
		}

		internal static void Apply(Animator animator, SetKey? key)
		{
			if ((Object)(object)animator == (Object)null)
			{
				return;
			}
			Dictionary<string, AnimationClip> want = Pairs(key);
			AnimatorOverrideController aoc = default(AnimatorOverrideController);
			ref AnimatorOverrideController reference = ref aoc;
			RuntimeAnimatorController runtimeAnimatorController = animator.runtimeAnimatorController;
			reference = (AnimatorOverrideController)(object)((runtimeAnimatorController is AnimatorOverrideController) ? runtimeAnimatorController : null);
			if ((Object)(object)aoc == (Object)null)
			{
				if (want.Count == 0)
				{
					return;
				}
				aoc = Wrap(animator);
				if ((Object)(object)aoc == (Object)null)
				{
					return;
				}
			}
			if (!Matches(aoc, want))
			{
				Preserving(animator, delegate
				{
					Write(aoc, want);
				});
			}
			if (want.Count == 0)
			{
				Unwrap(animator);
			}
		}

		internal static bool OursPresent(Animator animator, SetKey key)
		{
			AnimatorOverrideController val = (AnimatorOverrideController)(((Object)(object)animator != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null);
			Dictionary<string, AnimationClip> dictionary = Pairs(key);
			if ((Object)(object)val != (Object)null && dictionary.Count > 0)
			{
				return Matches(val, dictionary);
			}
			return false;
		}

		private static bool IsHost(string clipName)
		{
			Move[] moves = Moves;
			for (int i = 0; i < moves.Length; i++)
			{
				if (Families.HostClip(moves[i]) == clipName)
				{
					return true;
				}
			}
			return false;
		}

		private static bool Matches(AnimatorOverrideController aoc, Dictionary<string, AnimationClip> want)
		{
			List<KeyValuePair<AnimationClip, AnimationClip>> list = new List<KeyValuePair<AnimationClip, AnimationClip>>();
			aoc.GetOverrides(list);
			foreach (KeyValuePair<AnimationClip, AnimationClip> item in list)
			{
				if (!((Object)(object)item.Key == (Object)null) && IsHost(((Object)item.Key).name))
				{
					want.TryGetValue(((Object)item.Key).name, out var value);
					if ((Object)(object)item.Value != (Object)(object)value)
					{
						return false;
					}
				}
			}
			return true;
		}

		private static void Write(AnimatorOverrideController aoc, Dictionary<string, AnimationClip> want)
		{
			List<KeyValuePair<AnimationClip, AnimationClip>> list = new List<KeyValuePair<AnimationClip, AnimationClip>>();
			aoc.GetOverrides(list);
			for (int i = 0; i < list.Count; i++)
			{
				AnimationClip key = list[i].Key;
				if (!((Object)(object)key == (Object)null) && IsHost(((Object)key).name))
				{
					want.TryGetValue(((Object)key).name, out var value);
					list[i] = new KeyValuePair<AnimationClip, AnimationClip>(key, value);
				}
			}
			aoc.ApplyOverrides((IList<KeyValuePair<AnimationClip, AnimationClip>>)list);
		}

		private static AnimatorOverrideController Wrap(Animator animator)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			RuntimeAnimatorController runtimeAnimatorController = animator.runtimeAnimatorController;
			if ((Object)(object)runtimeAnimatorController == (Object)null)
			{
				return null;
			}
			AnimatorOverrideController controller = new AnimatorOverrideController(runtimeAnimatorController)
			{
				name = ((Object)runtimeAnimatorController).name + " (ComboAxe)"
			};
			Preserving(animator, delegate
			{
				animator.runtimeAnimatorController = (RuntimeAnimatorController)(object)controller;
			});
			own.Remove(animator);
			own.Add(animator, new Own
			{
				Controller = controller,
				Base = runtimeAnimatorController
			});
			return controller;
		}

		private static void Unwrap(Animator animator)
		{
			if (!own.TryGetValue(animator, out var o))
			{
				return;
			}
			if ((Object)(object)animator.runtimeAnimatorController != (Object)(object)o.Controller)
			{
				own.Remove(animator);
				return;
			}
			List<KeyValuePair<AnimationClip, AnimationClip>> list = new List<KeyValuePair<AnimationClip, AnimationClip>>();
			o.Controller.GetOverrides(list);
			foreach (KeyValuePair<AnimationClip, AnimationClip> item in list)
			{
				if ((Object)(object)item.Value != (Object)null)
				{
					return;
				}
			}
			Preserving(animator, delegate
			{
				animator.runtimeAnimatorController = o.Base;
			});
			own.Remove(animator);
		}

		private static void Preserving(Animator animator, Action change)
		{
			//IL_0034: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected I4, but got Unknown
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: 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_0132: Expected I4, but got Unknown
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			int layerCount = animator.layerCount;
			AnimatorStateInfo[] array = (AnimatorStateInfo[])(object)new AnimatorStateInfo[layerCount];
			float[] array2 = new float[layerCount];
			for (int i = 0; i < layerCount; i++)
			{
				array[i] = (animator.IsInTransition(i) ? animator.GetNextAnimatorStateInfo(i) : animator.GetCurrentAnimatorStateInfo(i));
				array2[i] = animator.GetLayerWeight(i);
			}
			AnimatorControllerParameter[] parameters = animator.parameters;
			float[] array3 = new float[parameters.Length];
			for (int j = 0; j < parameters.Length; j++)
			{
				AnimatorControllerParameterType type = parameters[j].type;
				switch (type - 1)
				{
				case 0:
					array3[j] = animator.GetFloat(parameters[j].nameHash);
					break;
				case 2:
					array3[j] = animator.GetInteger(parameters[j].nameHash);
					break;
				case 3:
					array3[j] = (animator.GetBool(parameters[j].nameHash) ? 1f : 0f);
					break;
				}
			}
			float speed = animator.speed;
			change();
			animator.Update(0f);
			for (int k = 0; k < parameters.Length; k++)
			{
				AnimatorControllerParameterType type = parameters[k].type;
				switch (type - 1)
				{
				case 0:
					animator.SetFloat(parameters[k].nameHash, array3[k]);
					break;
				case 2:
					animator.SetInteger(parameters[k].nameHash, (int)array3[k]);
					break;
				case 3:
					animator.SetBool(parameters[k].nameHash, array3[k] != 0f);
					break;
				}
			}
			for (int l = 0; l < layerCount && l < animator.layerCount; l++)
			{
				animator.SetLayerWeight(l, array2[l]);
				AnimatorStateInfo currentAnimatorStateInfo = animator.GetCurrentAnimatorStateInfo(l);
				if (((AnimatorStateInfo)(ref currentAnimatorStateInfo)).fullPathHash != ((AnimatorStateInfo)(ref array[l])).fullPathHash)
				{
					animator.Play(((AnimatorStateInfo)(ref array[l])).fullPathHash, l, ((AnimatorStateInfo)(ref array[l])).normalizedTime);
				}
			}
			animator.speed = speed;
		}
	}
	public enum Move
	{
		None,
		L1,
		L2,
		L3,
		S1,
		S2,
		S3,
		H1,
		H2,
		H3
	}
	public enum Press
	{
		Primary,
		Special
	}
	public static class ComboGraph
	{
		public static Move Next(Move current, Press press, bool inWindow)
		{
			if (press == Press.Primary)
			{
				if (!inWindow)
				{
					return Move.L1;
				}
				return current switch
				{
					Move.L1 => Move.L2, 
					Move.L2 => Move.L3, 
					_ => Move.L1, 
				};
			}
			if (!inWindow)
			{
				return Move.H1;
			}
			return current switch
			{
				Move.L1 => Move.S1, 
				Move.L2 => Move.S2, 
				Move.L3 => Move.S3, 
				Move.H1 => Move.H2, 
				Move.H2 => Move.H3, 
				_ => Move.H1, 
			};
		}

		public static bool ChainsAtChainPoint(Move current, Press press)
		{
			if (press == Press.Primary)
			{
				if (current != Move.L1)
				{
					return current == Move.L2;
				}
				return true;
			}
			if (current != Move.L1 && current != Move.L2 && current != Move.L3 && current != Move.H1)
			{
				return current == Move.H2;
			}
			return true;
		}

		public static bool IsFinisher(Move m)
		{
			if (m != Move.S1 && m != Move.S2)
			{
				return m == Move.S3;
			}
			return true;
		}
	}
	internal class ComboState : MonoBehaviour
	{
		internal SetKey Key;

		internal Move Current;

		internal bool Running;

		internal string Clip;

		internal bool Exiting;

		internal float StartedAt = -10f;

		internal float CaptureAt;

		internal float LastActive = -10f;

		internal float EndedAt = -10f;

		internal float AbsentSince = -1f;

		internal string LastTrigger;

		internal float LastTriggerAt = -10f;

		internal SetKey? Preloaded;

		internal SetKey? RemoteApplied;

		internal float NextPreload;

		internal static ComboState Of(Component c)
		{
			ComboState component = c.GetComponent<ComboState>();
			if ((Object)(object)component != (Object)null)
			{
				return component;
			}
			if ((Object)(object)c.GetComponent<GripSlide>() == (Object)null)
			{
				c.gameObject.AddComponent<GripSlide>();
			}
			return c.gameObject.AddComponent<ComboState>();
		}

		internal void Begin(SetKey key, Move move)
		{
			Key = key;
			Current = move;
			Running = true;
			Clip = null;
			Exiting = false;
			StartedAt = (LastActive = Time.time);
			CaptureAt = Time.time + 0.05f;
			AbsentSince = -1f;
		}
	}
	public enum Family
	{
		Raider,
		Exec
	}
	public enum Variant
	{
		Shield,
		Free,
		Torch
	}
	public static class Families
	{
		public const string Prefix = "comboaxe_";

		public const string RaiderAttack = "swing_axe";

		public const string ExecAttack = "battleaxe_attack";

		internal static readonly string[,] Hosts = new string[9, 3]
		{
			{ "swing_longsword0", "Attack1", "chain MEASURED; speed, root TO-PROBE" },
			{ "swing_longsword1", "Attack2", "chain MEASURED; speed, root TO-PROBE" },
			{ "swing_longsword2", "Attack3", "chain MEASURED; speed, root TO-PROBE" },
			{ "battleaxe_secondary", "BattleAxeAltAttack", "speed, root, start from L1 TO-PROBE" },
			{ "sword_secondary", "Sword-Attack-R4", "speed, root, start from L2 TO-PROBE" },
			{ "greatsword_secondary", "Greatsword Secondary Attack", "speed, root, start from L3 TO-PROBE (never measured)" },
			{ "atgeir_attack0", "2Hand-Spear-Attack1", "chain MEASURED; speed, root TO-PROBE" },
			{ "atgeir_attack1", "2Hand-Spear-Attack9", "chain MEASURED; speed, root TO-PROBE" },
			{ "atgeir_attack2", "2Hand-Spear-Attack3", "chain MEASURED; speed, root TO-PROBE" }
		};

		public static readonly Move[] Moves = new Move[9]
		{
			Move.L1,
			Move.L2,
			Move.L3,
			Move.S1,
			Move.S2,
			Move.S3,
			Move.H1,
			Move.H2,
			Move.H3
		};

		public const float LastChainBonus = 1f;

		public static Family? Detect(bool axesSkill, bool oneHanded, bool twoHanded, string attack)
		{
			if (!axesSkill)
			{
				return null;
			}
			if (oneHanded && attack == "swing_axe")
			{
				return Family.Raider;
			}
			if (twoHanded && attack == "battleaxe_attack")
			{
				return Family.Exec;
			}
			return null;
		}

		public static string AttackName(Family f)
		{
			if (f != Family.Raider)
			{
				return "comboaxe_exec";
			}
			return "comboaxe_raider";
		}

		public static string SpecialTrigger(Family f, Move m)
		{
			switch (m)
			{
			case Move.S1:
			case Move.S2:
			case Move.S3:
				return AttackName(f) + "_s" + (int)(m - 4 + 1);
			case Move.H1:
			case Move.H2:
			case Move.H3:
				return AttackName(f) + "_h" + (int)(m - 7 + 1);
			default:
				return null;
			}
		}

		public static bool ParseTrigger(string trigger, out Family family, out Move move)
		{
			family = Family.Raider;
			move = Move.None;
			if (trigger == null || !trigger.StartsWith("comboaxe_", StringComparison.Ordinal))
			{
				return false;
			}
			Family[] array = new Family[2]
			{
				Family.Raider,
				Family.Exec
			};
			int num = 0;
			while (num < array.Length)
			{
				Family family2 = array[num];
				string text = AttackName(family2);
				string text2;
				if (trigger.StartsWith(text, StringComparison.Ordinal))
				{
					text2 = trigger.Substring(text.Length);
					if (text2 == null)
					{
						goto IL_0142;
					}
					int length = text2.Length;
					if (length != 1)
					{
						if (length != 3)
						{
							goto IL_0142;
						}
						switch (text2[2])
						{
						case '1':
							break;
						case '2':
							goto IL_00d8;
						case '3':
							goto IL_00f6;
						default:
							goto IL_0142;
						}
						if (!(text2 == "_s1"))
						{
							if (!(text2 == "_h1"))
							{
								goto IL_0142;
							}
							move = Move.H1;
						}
						else
						{
							move = Move.S1;
						}
					}
					else
					{
						switch (text2[0])
						{
						case '0':
							break;
						case '1':
							goto IL_0119;
						case '2':
							goto IL_011e;
						default:
							goto IL_0142;
						}
						move = Move.L1;
					}
					goto IL_0144;
				}
				num++;
				continue;
				IL_0142:
				return false;
				IL_0119:
				move = Move.L2;
				goto IL_0144;
				IL_00d8:
				if (!(text2 == "_s2"))
				{
					if (!(text2 == "_h2"))
					{
						goto IL_0142;
					}
					move = Move.H2;
				}
				else
				{
					move = Move.S2;
				}
				goto IL_0144;
				IL_011e:
				move = Move.L3;
				goto IL_0144;
				IL_0144:
				family = family2;
				return true;
				IL_00f6:
				if (!(text2 == "_s3"))
				{
					if (!(text2 == "_h3"))
					{
						goto IL_0142;
					}
					move = Move.H3;
				}
				else
				{
					move = Move.S3;
				}
				goto IL_0144;
			}
			return false;
		}

		public static string Suffix(Variant v)
		{
			return v switch
			{
				Variant.Torch => "_Torch", 
				Variant.Free => "_Free", 
				_ => "", 
			};
		}

		public static string ClipName(Family f, Move m, Variant v = Variant.Shield)
		{
			return f.ToString() + m.ToString() + ((f == Family.Raider) ? Suffix(v) : "");
		}

		public static string HostTrigger(Move m)
		{
			if (m != Move.None)
			{
				return Hosts[(int)(m - 1), 0];
			}
			return null;
		}

		public static string HostClip(Move m)
		{
			if (m != Move.None)
			{
				return Hosts[(int)(m - 1), 1];
			}
			return null;
		}

		public static string HostStatus(Move m)
		{
			if (m != Move.None)
			{
				return Hosts[(int)(m - 1), 2];
			}
			return null;
		}

		public static bool IsHostClip(string clip)
		{
			Move[] moves = Moves;
			for (int i = 0; i < moves.Length; i++)
			{
				if (HostClip(moves[i]) == clip)
				{
					return true;
				}
			}
			return false;
		}

		public static bool IsHostTrigger(string trigger)
		{
			Move[] moves = Moves;
			for (int i = 0; i < moves.Length; i++)
			{
				if (HostTrigger(moves[i]) == trigger)
				{
					return true;
				}
			}
			return false;
		}

		public static float Damage(Family f, Move m)
		{
			bool flag = m >= Move.L1 && m <= Move.L3;
			bool flag2 = m >= Move.H1;
			if (f == Family.Raider)
			{
				if (!flag)
				{
					if (!flag2)
					{
						return 1.7f;
					}
					return 2.2f;
				}
				return 1f;
			}
			if (!flag)
			{
				if (!flag2)
				{
					return 2f;
				}
				return 2.7f;
			}
			return 1.25f;
		}
	}
	internal static class FamilyItems
	{
		private static readonly Dictionary<SharedData, Family> families = new Dictionary<SharedData, Family>();

		internal static void ObjectDBPostfix(ObjectDB __instance)
		{
			Register(__instance);
		}

		internal static void Register(ObjectDB db)
		{
			if ((Object)(object)db == (Object)null || db.m_items == null)
			{
				return;
			}
			int num = 0;
			int num2 = 0;
			foreach (GameObject item in db.m_items)
			{
				if (!((Object)(object)item == (Object)null))
				{
					Family? family = Apply(item.GetComponent<ItemDrop>()?.m_itemData?.m_shared);
					if (family == Family.Raider)
					{
						num++;
					}
					else if (family == Family.Exec)
					{
						num2++;
					}
				}
			}
			Plugin.Log.LogInfo((object)$"Raider family on {num} one-handed axes, Executioner family on {num2} battleaxes (dual axes stay vanilla).");
		}

		internal static Family? FamilyOf(ItemData item)
		{
			return Apply(item?.m_shared);
		}

		private static Family? Apply(SharedData s)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Invalid comparison between Unknown and I4
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Invalid comparison between Unknown and I4
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Invalid comparison between Unknown and I4
			if (s == null || s.m_attack == null)
			{
				return null;
			}
			if (families.TryGetValue(s, out var value))
			{
				return value;
			}
			bool flag = (int)s.m_skillType == 7;
			bool flag2 = (int)s.m_itemType == 3;
			bool flag3 = (int)s.m_itemType == 14;
			string attackAnimation = s.m_attack.m_attackAnimation;
			Family? result = Families.Detect(flag, flag2, flag3, attackAnimation);
			if (!result.HasValue && flag)
			{
				if (flag2 && attackAnimation == Families.AttackName(Family.Raider))
				{
					result = Family.Raider;
				}
				else if (flag3 && attackAnimation == Families.AttackName(Family.Exec))
				{
					result = Family.Exec;
				}
			}
			if (!result.HasValue)
			{
				return null;
			}
			families[s] = result.Value;
			s.m_attack.m_attackAnimation = Families.AttackName(result.Value);
			if (s.m_attack.m_attackChainLevels != 3)
			{
				Plugin.Log.LogWarning((object)$"{s.m_name}: vanilla m_attackChainLevels is {s.m_attack.m_attackChainLevels}, not 3 - L3 may be unreachable (left as is).");
			}
			return result;
		}
	}
	internal static class GripCurves
	{
		internal static readonly Dictionary<string, float[]> Slide = new Dictionary<string, float[]>
		{
			{
				"ExecL1",
				new float[27]
				{
					0f, 0f, 0f, 0f, 0f, 0.07f, 0.14f, 0.2333f, 0.4067f, 0.5f,
					0.4758f, 0.4194f, 0.3558f, 0.3093f, 0.2762f, 0.18f, 0.18f, 0.18f, 0.1675f, 0.14f,
					0.1125f, 0.1f, 0.0948f, 0.0824f, 0.0676f, 0.0552f, 0.05f
				}
			},
			{
				"ExecL2",
				new float[29]
				{
					0.05f, 0.0411f, 0.0189f, -0.01f, -0.0389f, -0.0611f, -0.07f, -0.057f, -0.033f, -0.02f,
					-0.0148f, -0.0052f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, -0.035f,
					-0.07f, -0.07f, -0.07f, -0.07f, -0.07f, -0.07f, -0.0519f, -0.0181f, 0f
				}
			},
			{
				"ExecL3",
				new float[32]
				{
					0f, 0f, 0f, 0f, 0f, 0.07f, 0.14f, 0.2333f, 0.4067f, 0.5f,
					0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.434f, 0.327f, 0.2762f, 0.18f, 0.18f,
					0.18f, 0.1717f, 0.1518f, 0.1282f, 0.1083f, 0.1f, 0.0963f, 0.087f, 0.075f, 0.063f,
					0.0537f, 0.05f
				}
			},
			{
				"ExecS1",
				new float[41]
				{
					0.05f, 0.05f, 0.05f, 0.05f, 0.05f, 0.05f, 0.1281f, 0.3f, 0.4719f, 0.55f,
					0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f,
					0.55f, 0.55f, 0.4675f, 0.3338f, 0.2504f, 0.05f, 0.05f, 0.05f, 0.05f, 0.05f,
					0.05f, 0.05f, 0.05f, 0.05f, 0.05f, 0.05f, 0.05f, 0.05f, 0.05f, 0.05f,
					0.05f
				}
			},
			{
				"ExecS2",
				new float[45]
				{
					0f, 0f, 0f, 0f, 0f, 0f, 0.0023f, 0.0538f, 0.1209f, 0.1459f,
					0.221f, 0.3405f, 0.4513f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
					0.5f, 0.4832f, 0.4278f, 0.3606f, 0.3102f, 0.2762f, 0.18f, 0.18f, 0.18f, 0.1797f,
					0.1733f, 0.1604f, 0.144f, 0.1269f, 0.112f, 0.1022f, 0.0998f, 0.0967f, 0.0906f, 0.0825f,
					0.0736f, 0.0648f, 0.0573f, 0.052f, 0.05f
				}
			},
			{
				"ExecS3",
				new float[50]
				{
					0.05f, 0.05f, 0.05f, 0.05f, 0.05f, 0.05f, 0.05f, 0.05f, 0.05f, 0.05f,
					0.1281f, 0.3f, 0.4719f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f,
					0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.4675f, 0.3338f,
					0.2504f, 0.05f, 0.05f, 0.05f, 0.05f, 0.05f, 0.05f, 0.05f, 0.05f, 0.0189f,
					-0.0389f, -0.07f, -0.067f, -0.0591f, -0.0478f, -0.035f, -0.0221f, -0.0109f, -0.003f, 0f
				}
			},
			{
				"ExecH1",
				new float[50]
				{
					0f, 0f, 0f, 0f, 0f, 0f, 0.0363f, 0.1037f, 0.14f, 0.1826f,
					0.2843f, 0.4057f, 0.5074f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f,
					0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.55f, 0.4813f, 0.3573f,
					0.2942f, 0.05f, 0.05f, 0.05f, 0.05f, 0.05f, 0.05f, 0.05f, 0.05f, 0.05f,
					0.05f, 0.05f, 0.05f, 0.05f, 0.05f, 0.05f, 0.05f, 0.05f, 0.05f, 0.05f
				}
			},
			{
				"ExecH2",
				new float[46]
				{
					0.05f, 0.0448f, 0.0312f, 0.012f, -0.01f, -0.032f, -0.0512f, -0.0648f, -0.07f, -0.0683f,
					-0.0637f, -0.057f, -0.0491f, -0.0408f, -0.033f, -0.0263f, -0.0217f, -0.02f, -0.02f, -0.02f,
					-0.02f, -0.02f, -0.02f, -0.02f, -0.02f, -0.013f, -0.0021f, 0f, 0f, 0f,
					0f, -0.0181f, -0.0519f, -0.07f, -0.07f, -0.07f, -0.07f, -0.07f, -0.07f, -0.07f,
					-0.0648f, -0.0519f, -0.035f, -0.0181f, -0.0052f, 0f
				}
			},
			{
				"ExecH3",
				new float[59]
				{
					0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f,
					0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f,
					0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f,
					0f, -0.0078f, -0.0222f, -0.03f, -0.043f, -0.0593f, -0.0642f, -0.07f, -0.07f, -0.07f,
					-0.07f, -0.07f, -0.07f, -0.07f, -0.07f, -0.07f, -0.07f, -0.07f, -0.0684f, -0.0639f,
					-0.0572f, -0.049f, -0.0398f, -0.0302f, -0.021f, -0.0128f, -0.0061f, -0.0016f, 0f
				}
			}
		};

		internal static readonly Dictionary<string, float[]> Roll = new Dictionary<string, float[]>
		{
			{
				"ExecL1",
				new float[27]
				{
					0f, 3.502f, 6.909f, 10.223f, 13.444f, 16.539f, 19.542f, 22.45f, 25.266f, 27.987f,
					30.616f, 33.151f, 35.591f, 37.933f, 40.177f, 42.322f, 44.37f, 46.353f, 48.241f, 50.035f,
					51.736f, 53.344f, 54.86f, 56.283f, 57.613f, 58.852f, 60f
				}
			},
			{
				"ExecL2",
				new float[29]
				{
					60f, 76.076f, 92.039f, 107.808f, 123.305f, 138.463f, 153.218f, 167.519f, 181.324f, 194.599f,
					207.322f, 219.482f, 231.075f, 242.108f, 252.594f, 262.553f, 272.013f, 281.004f, 289.562f, 297.723f,
					305.527f, 313.015f, 320.227f, 327.206f, 333.993f, 340.629f, 347.156f, 353.605f, 360f
				}
			},
			{
				"ExecL3",
				new float[32]
				{
					0f, 1.3f, 2.69f, 4.171f, 5.742f, 7.404f, 9.156f, 10.998f, 12.93f, 14.922f,
					17.006f, 19.182f, 21.45f, 23.811f, 26.266f, 28.812f, 31.423f, 33.946f, 36.378f, 38.749f,
					41.028f, 43.214f, 45.307f, 47.307f, 49.218f, 51.038f, 52.762f, 54.393f, 55.932f, 57.379f,
					58.735f, 60f
				}
			},
			{
				"ExecS1",
				new float[41]
				{
					60f, 56.86f, 53.812f, 50.858f, 48.011f, 45.292f, 42.726f, 40.335f, 38.139f, 36.156f,
					34.399f, 32.879f, 31.603f, 30.575f, 29.796f, 29.264f, 28.974f, 28.917f, 29.084f, 29.464f,
					30.043f, 30.807f, 31.739f, 32.824f, 34.045f, 35.387f, 36.828f, 38.35f, 39.964f, 41.669f,
					43.464f, 45.351f, 47.299f, 49.216f, 51.038f, 52.762f, 54.393f, 55.932f, 57.379f, 58.735f,
					60f
				}
			},
			{
				"ExecS2",
				new float[45]
				{
					0f, -0.77f, -1.448f, -2.032f, -2.518f, -2.896f, -3.148f, -3.257f, -3.208f, -2.988f,
					-2.587f, -2f, -1.222f, -0.255f, 0.898f, 2.231f, 3.737f, 5.403f, 7.217f, 9.165f,
					11.232f, 13.397f, 15.652f, 17.997f, 20.433f, 22.931f, 25.521f, 28.203f, 30.792f, 33.289f,
					35.693f, 38.005f, 40.227f, 42.358f, 44.4f, 46.351f, 48.213f, 49.983f, 51.692f, 53.31f,
					54.834f, 56.265f, 57.604f, 58.849f, 60f
				}
			},
			{
				"ExecS3",
				new float[50]
				{
					60f, 55.942f, 52.006f, 48.163f, 44.415f, 40.769f, 37.242f, 33.851f, 30.612f, 27.534f,
					24.628f, 21.897f, 19.343f, 16.967f, 14.763f, 12.726f, 10.847f, 9.117f, 7.522f, 6.05f,
					4.689f, 3.424f, 2.24f, 1.147f, 0.145f, -0.765f, -1.586f, -2.347f, -3.113f, -3.94f,
					-4.68f, -5.33f, -5.889f, -6.355f, -6.729f, -6.977f, -7.132f, -7.195f, -7.153f, -6.999f,
					-6.733f, -6.355f, -5.872f, -5.294f, -4.626f, -3.867f, -3.016f, -2.103f, -1.098f, 0f
				}
			},
			{
				"ExecH1",
				new float[50]
				{
					0f, 0f, 0f, 0f, 0f, 0.031f, 0.154f, 0.37f, 0.678f, 1.079f,
					1.573f, 2.16f, 2.839f, 3.612f, 4.477f, 5.404f, 6.423f, 7.534f, 8.738f, 10.034f,
					11.423f, 12.906f, 14.481f, 16.149f, 17.911f, 19.766f, 21.714f, 23.755f, 25.889f, 28.113f,
					30.427f, 32.708f, 34.981f, 37.194f, 39.315f, 41.344f, 43.282f, 45.127f, 46.879f, 48.534f,
					50.096f, 51.575f, 52.963f, 54.251f, 55.442f, 56.539f, 57.543f, 58.454f, 59.273f, 60f
				}
			},
			{
				"ExecH2",
				new float[46]
				{
					60f, 73.88f, 87.653f, 101.258f, 114.631f, 127.709f, 140.432f, 152.748f, 164.609f, 175.975f,
					186.815f, 197.103f, 206.825f, 215.972f, 224.546f, 232.555f, 240.015f, 246.95f, 253.387f, 259.362f,
					264.911f, 270.075f, 274.897f, 279.418f, 283.683f, 287.731f, 291.602f, 295.33f, 298.948f, 302.475f,
					305.942f, 309.319f, 312.667f, 316.102f, 319.627f, 323.242f, 326.947f, 330.742f, 334.627f, 338.512f,
					342.305f, 346.034f, 349.665f, 353.202f, 356.647f, 360f
				}
			},
			{
				"ExecH3",
				new float[59]
				{
					0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f,
					0f, 0f, 0f, 0f, 0f, 0f, -0.031f, -0.154f, -0.369f, -0.676f,
					-1.075f, -1.565f, -2.147f, -2.819f, -3.584f, -4.41f, -5.329f, -6.341f, -7.445f, -8.638f,
					-9.923f, -11.205f, -12.364f, -13.429f, -14.401f, -15.279f, -16.061f, -16.747f, -17.328f, -17.796f,
					-18.139f, -18.349f, -18.414f, -18.329f, -18.086f, -17.682f, -17.115f, -16.387f, -15.5f, -14.461f,
					-13.278f, -11.963f, -10.529f, -8.988f, -7.381f, -5.676f, -3.877f, -1.985f, 0f
				}
			}
		};
	}
	internal class GripSlide : MonoBehaviour
	{
		private struct Blend
		{
			public Vector3 Butt;

			public Quaternion Rotation;

			public float Weight;

			public float Dominant;

			public float Time;

			public string Name;

			public AxeMotionFrame State;
		}

		private static readonly Dictionary<string, AxeMotionClip> motion = new Dictionary<string, AxeMotionClip>();

		private static readonly Move[] moves = new Move[9]
		{
			Move.L1,
			Move.L2,
			Move.L3,
			Move.S1,
			Move.S2,
			Move.S3,
			Move.H1,
			Move.H2,
			Move.H3
		};

		private readonly List<AnimatorClipInfo> playing = new List<AnimatorClipInfo>(2);

		private Animator anim;

		private VisEquipment vis;

		private Transform right;

		private Transform left;

		private Transform item;

		private Transform parent;

		private Vector3 basePos;

		private Quaternion baseRot;

		private WeaponShaftFrame model;

		private bool applied;

		private bool measured;

		private bool usable;

		internal static bool LoadMotion(out string error)
		{
			//IL_002d: Expected O, but got Unknown
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			error = "Missing rigid axe motion in the animation bundle.";
			TextAsset val = ClipSets.ReadTextAsset("Assets/OutAxe/RigidAxeMotion.json");
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			AxeMotionDocument axeMotionDocument;
			try
			{
				axeMotionDocument = JsonConvert.DeserializeObject<AxeMotionDocument>(val.text);
			}
			catch (JsonException ex)
			{
				JsonException ex2 = ex;
				error = "Invalid rigid axe motion: " + ((Exception)(object)ex2).Message;
				return false;
			}
			if (axeMotionDocument == null || axeMotionDocument.schema != 1 || axeMotionDocument.clips == null || axeMotionDocument.clips.Length != moves.Length || !Finite(axeMotionDocument.sampleRate) || axeMotionDocument.sampleRate < 30f || axeMotionDocument.sampleRate > 240f)
			{
				error = $"Invalid rigid axe motion header (schema {axeMotionDocument?.schema}, sample rate {axeMotionDocument?.sampleRate}, clips {axeMotionDocument?.clips?.Length}).";
				return false;
			}
			Dictionary<string, AxeMotionClip> dictionary = new Dictionary<string, AxeMotionClip>();
			Move[] array = moves;
			foreach (Move m in array)
			{
				string name = Families.ClipName(Family.Exec, m);
				AxeMotionClip axeMotionClip = Array.Find(axeMotionDocument.clips, (AxeMotionClip value) => value != null && value.name == name);
				error = "Invalid rigid axe motion for " + name;
				if (axeMotionClip == null || axeMotionClip.sampleRate != axeMotionDocument.sampleRate || !Finite(axeMotionClip.length) || Mathf.Abs(axeMotionClip.length - ClipSets.Clip(name).length) > 0.001f || axeMotionClip.frames == null || axeMotionClip.frames.Length != Mathf.RoundToInt(axeMotionClip.length * axeMotionClip.sampleRate) + 1)
				{
					return false;
				}
				AxeMotionFrame[] frames = axeMotionClip.frames;
				foreach (AxeMotionFrame axeMotionFrame in frames)
				{
					if (axeMotionFrame == null || axeMotionFrame.anchor < 0 || axeMotionFrame.anchor > 1 || ((axeMotionFrame.anchor == 0) ? axeMotionFrame.releaseRight : axeMotionFrame.releaseLeft) || !Finite(axeMotionFrame.position.x) || !Finite(axeMotionFrame.position.y) || !Finite(axeMotionFrame.position.z) || !Finite(axeMotionFrame.rotation.x) || !Finite(axeMotionFrame.rotation.y) || !Finite(axeMotionFrame.rotation.z) || !Finite(axeMotionFrame.rotation.w) || Mathf.Abs(Quaternion.Dot(axeMotionFrame.rotation, axeMotionFrame.rotation) - 1f) > 0.01f)
					{
						return false;
					}
				}
				dictionary.Add(name, axeMotionClip);
			}
			motion.Clear();
			foreach (KeyValuePair<string, AxeMotionClip> item in dictionary)
			{
				motion.Add(item.Key, item.Value);
			}
			Plugin.Log.LogInfo((object)$"Loaded rigid axe motion for {motion.Count} clips at {axeMotionDocument.sampleRate:0} Hz.");
			error = null;
			return true;
		}

		private static bool Finite(float value)
		{
			if (!float.IsNaN(value))
			{
				return !float.IsInfinity(value);
			}
			return false;
		}

		private void LateUpdate()
		{
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: 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_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)anim == (Object)null)
			{
				ZSyncAnimation component = ((Component)this).GetComponent<ZSyncAnimation>();
				anim = (((Object)(object)component != (Object)null && Refs.AnimatorOf != null) ? Refs.AnimatorOf.Invoke(component) : null);
				if ((Object)(object)anim == (Object)null || !anim.isHuman)
				{
					Restore();
					return;
				}
				right = anim.GetBoneTransform((HumanBodyBones)18);
				left = anim.GetBoneTransform((HumanBodyBones)17);
			}
			if ((Object)(object)vis == (Object)null)
			{
				vis = ((Component)this).GetComponent<VisEquipment>();
			}
			if ((Object)(object)vis == (Object)null || Refs.RightItemInstance == null || anim.layerCount == 0)
			{
				Restore();
				return;
			}
			GameObject val = Refs.RightItemInstance.Invoke(vis);
			Transform val2 = (Object.op_Implicit((Object)(object)val) ? val.transform : null);
			Transform val3 = (Object.op_Implicit((Object)(object)val2) ? val2.parent : null);
			if ((Object)(object)val2 != (Object)(object)item || (Object)(object)val3 != (Object)(object)parent)
			{
				if ((Object)(object)val2 != (Object)(object)item)
				{
					Restore();
				}
				applied = false;
				item = val2;
				parent = val3;
				measured = false;
			}
			if (!Object.op_Implicit((Object)(object)item) || !Object.op_Implicit((Object)(object)parent))
			{
				return;
			}
			Blend blend = default(Blend);
			anim.GetCurrentAnimatorClipInfo(0, playing);
			Sample(anim.GetCurrentAnimatorStateInfo(0), ref blend);
			if (anim.IsInTransition(0))
			{
				anim.GetNextAnimatorClipInfo(0, playing);
				Sample(anim.GetNextAnimatorStateInfo(0), ref blend);
			}
			if (blend.Weight <= 0f)
			{
				Restore();
				return;
			}
			if (!applied)
			{
				basePos = item.localPosition;
				baseRot = item.localRotation;
			}
			if (!measured)
			{
				measured = true;
				usable = WeaponShaftGeometry.TryMeasure(item, out model);
			}
			if (!usable)
			{
				Restore();
				return;
			}
			Quaternion val4 = blend.Rotation * Quaternion.Inverse(model.rotation);
			Vector3 val5 = blend.Butt - val4 * Vector3.Scale(item.lossyScale, model.butt);
			float num = Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(0.02f, 0.4f, blend.Weight));
			item.SetPositionAndRotation(Vector3.Lerp(parent.TransformPoint(basePos), val5, num), Quaternion.Slerp(parent.rotation * baseRot, val4, num));
			applied = true;
		}

		private void Sample(AnimatorStateInfo state, ref Blend blend)
		{
			//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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			foreach (AnimatorClipInfo item in playing)
			{
				AnimatorClipInfo current = item;
				if ((Object)(object)((AnimatorClipInfo)(ref current)).clip == (Object)null || ((AnimatorClipInfo)(ref current)).weight <= 0f || !motion.TryGetValue(((Object)((AnimatorClipInfo)(ref current)).clip).name, out var value))
				{
					continue;
				}
				float num = Mathf.Clamp01(((AnimatorStateInfo)(ref state)).normalizedTime) * value.length;
				if (AxePoseSampling.TrySample(value, num, right, left, out var position, out var rotation, out var state2))
				{
					float num2 = ((AnimatorClipInfo)(ref current)).weight / (blend.Weight + ((AnimatorClipInfo)(ref current)).weight);
					blend.Butt = Vector3.Lerp(blend.Butt, position, num2);
					blend.Rotation = ((blend.Weight == 0f) ? rotation : Quaternion.Slerp(blend.Rotation, rotation, num2));
					blend.Weight += ((AnimatorClipInfo)(ref current)).weight;
					if (!(((AnimatorClipInfo)(ref current)).weight < blend.Dominant))
					{
						blend.Dominant = ((AnimatorClipInfo)(ref current)).weight;
						blend.Name = value.name;
						blend.Time = num;
						blend.State = state2;
					}
				}
			}
		}

		private void Restore()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if (applied && Object.op_Implicit((Object)(object)item) && (Object)(object)item.parent == (Object)(object)parent)
			{
				item.localPosition = basePos;
				item.localRotation = baseRot;
			}
			applied = false;
		}

		private void OnDisable()
		{
			Restore();
		}
	}
	internal static class HitTracking
	{
		internal static string LastOwnClip = "";

		private const float NeverShowedUp = 1.5f;

		private const float PreloadAfter = 0.3f;

		private const float PreloadEvery = 0.25f;

		private const float EndGrace = 0.15f;

		internal static void SyncPostfix(ZSyncAnimation __instance)
		{
			ComboState component = ((Component)__instance).GetComponent<ComboState>();
			if ((Object)(object)component != (Object)null && component.Running)
			{
				Track(__instance, component);
			}
			Preload(__instance, component);
		}

		private static void Track(ZSyncAnimation z, ComboState st)
		{
			if (st.Clip == null && Time.time > st.StartedAt + 1.5f)
			{
				End(st);
			}
			else
			{
				if (Time.time < st.CaptureAt || Refs.AnimatorOf == null)
				{
					return;
				}
				Animator val = Refs.AnimatorOf.Invoke(z);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				string text = TopClip(val.GetCurrentAnimatorClipInfo(0));
				string text2 = (val.IsInTransition(0) ? TopClip(val.GetNextAnimatorClipInfo(0)) : null);
				if (st.Clip == null)
				{
					string text3 = ClipSets.ResolveName(st.Key, st.Current);
					if (text != text3 && text2 != text3)
					{
						return;
					}
					st.Clip = text3;
					if ((Object)(object)((Component)z).GetComponent<Player>() == (Object)(object)Player.m_localPlayer)
					{
						LastOwnClip = text3;
					}
				}
				if (text == st.Clip || text2 == st.Clip)
				{
					st.AbsentSince = -1f;
					st.LastActive = Time.time;
					st.Exiting = text == st.Clip && text2 != null && text2 != st.Clip;
					return;
				}
				if (st.AbsentSince < 0f)
				{
					st.AbsentSince = Time.time;
				}
				if (Time.time - st.AbsentSince >= 0.15f)
				{
					End(st);
				}
			}
		}

		private static void End(ComboState st)
		{
			st.Running = false;
			st.Exiting = false;
			st.EndedAt = Time.time;
		}

		private static void Preload(ZSyncAnimation z, ComboState st)
		{
			Humanoid component = ((Component)z).GetComponent<Humanoid>();
			if ((Object)(object)component == (Object)null || (Object)(object)component != (Object)(object)Player.m_localPlayer || Refs.AnimatorOf == null || ((Object)(object)st != (Object)null && (st.Running || Time.time < st.LastActive + 0.3f || Time.time < st.NextPreload)))
			{
				return;
			}
			if ((Object)(object)st == (Object)null)
			{
				st = ComboState.Of((Component)(object)z);
			}
			st.NextPreload = Time.time + 0.25f;
			Animator val = Refs.AnimatorOf.Invoke(z);
			if (!((Object)(object)val == (Object)null))
			{
				SetKey? setKey = OffHand.KeyOf(component);
				if (!Nullable.Equals(setKey, st.Preloaded) || (setKey.HasValue && !ClipSets.OursPresent(val, setKey.Value)))
				{
					ClipSets.Apply(val, setKey);
					st.Preloaded = setKey;
				}
			}
		}

		internal static void EquipPrefix(Humanoid __instance, ItemData item)
		{
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || item == null || !item.IsWeapon() || FamilyItems.FamilyOf(item).HasValue)
			{
				return;
			}
			ZSyncAnimation component = ((Component)__instance).GetComponent<ZSyncAnimation>();
			Animator val = (((Object)(object)component != (Object)null && Refs.AnimatorOf != null) ? Refs.AnimatorOf.Invoke(component) : null);
			if (!((Object)(object)val == (Object)null))
			{
				ClipSets.Apply(val, null);
				ComboState component2 = ((Component)component).GetComponent<ComboState>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.Preloaded = null;
				}
			}
		}

		private static string TopClip(AnimatorClipInfo[] infos)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			AnimationClip val = null;
			float num = -1f;
			for (int i = 0; i < infos.Length; i++)
			{
				AnimatorClipInfo val2 = infos[i];
				if ((Object)(object)((AnimatorClipInfo)(ref val2)).clip != (Object)null && ((AnimatorClipInfo)(ref val2)).weight > num)
				{
					val = ((AnimatorClipInfo)(ref val2)).clip;
					num = ((AnimatorClipInfo)(ref val2)).weight;
				}
			}
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return ((Object)val).name;
		}
	}
	internal static class OffHand
	{
		internal static Variant Of(Component c)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Invalid comparison between Unknown and I4
			Humanoid val = (((Object)(object)c != (Object)null) ? c.GetComponent<Humanoid>() : null);
			VisEquipment val2 = (((Object)(object)val != (Object)null) ? val.GetVisEquipment() : null);
			if ((Object)(object)val2 == (Object)null || Refs.LeftItemHash == null)
			{
				return Variant.Shield;
			}
			int num = Refs.LeftItemHash.Invoke(val2);
			if (num == 0)
			{
				return Variant.Free;
			}
			SharedData val3 = SharedFromHash(num);
			if (val3 == null || (int)val3.m_itemType != 15)
			{
				return Variant.Shield;
			}
			return Variant.Torch;
		}

		internal static SetKey? KeyOf(Humanoid h)
		{
			Family? family = FamilyItems.FamilyOf(((Object)(object)h != (Object)null) ? h.GetCurrentWeapon() : null);
			if (family.HasValue)
			{
				return new SetKey(family.Value, Of((Component)(object)h));
			}
			return null;
		}

		private static SharedData SharedFromHash(int hash)
		{
			if (hash == 0 || (Object)(object)ObjectDB.instance == (Object)null)
			{
				return null;
			}
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(hash);
			if (!((Object)(object)itemPrefab != (Object)null))
			{
				return null;
			}
			return itemPrefab.GetComponent<ItemDrop>()?.m_itemData?.m_shared;
		}
	}
	[BepInPlugin("andythedemon.comboaxe", "Combo Axe", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "andythedemon.comboaxe";

		public const string PluginName = "Combo Axe";

		public const string Version = "1.0.0";

		internal const string ComboSpearGuid = "andythedemon.combospear";

		internal const string ComboBrawlerGuid = "andythedemon.combobrawler";

		internal static ConfigEntry<bool> Enabled;

		internal static ManualLogSource Log;

		internal static string PluginFolder;

		private static Harmony harmony;

		private void Awake()
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Turns Combo Axe on or off. Off: axes and battleaxes attack exactly as in vanilla. Takes effect the next time the game starts.");
			if (!Enabled.Value)
			{
				Log.LogInfo((object)"Combo Axe 1.0.0 is turned off in its config (General / Enabled) - nothing is changed.");
				return;
			}
			PluginFolder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			if (!ClipSets.AllBaseClipsPresent(out var missing))
			{
				Log.LogError((object)("Combo Axe 1.0.0: the bundle is missing or incomplete (" + missing + ") - nothing is patched, axes stay vanilla."));
				return;
			}
			if (!GripSlide.LoadMotion(out var error))
			{
				Log.LogError((object)("Combo Axe 1.0.0: " + error));
				return;
			}
			harmony = new Harmony("andythedemon.comboaxe");
			Refs.Init();
			Log.LogInfo((object)HostTableLine());
			Patch("the axe families", delegate
			{
				harmony.Patch((MethodBase)AccessTools.Method(typeof(ObjectDB), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, HM(typeof(FamilyItems), "ObjectDBPostfix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				harmony.Patch((MethodBase)AccessTools.Method(typeof(ObjectDB), "CopyOtherDB", (Type[])null, (Type[])null), (HarmonyMethod)null, HM(typeof(FamilyItems), "ObjectDBPostfix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			});
			Patch("the combo triggers", delegate
			{
				harmony.Patch((MethodBase)AccessTools.Method(typeof(ZSyncAnimation), "RPC_SetTrigger", (Type[])null, (Type[])null), HM(typeof(Triggers), "Prefix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			});
			Patch("the move tracking", delegate
			{
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_006f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0083: Expected O, but got Unknown
				harmony.Patch((MethodBase)AccessTools.Method(typeof(ZSyncAnimation), "SyncParameters", (Type[])null, (Type[])null), (HarmonyMethod)null, HM(typeof(HitTracking), "SyncPostfix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				harmony.Patch((MethodBase)AccessTools.Method(typeof(Humanoid), "EquipItem", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.Method(typeof(HitTracking), "EquipPrefix", (Type[])null, (Type[])null))
				{
					priority = 800
				}, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			});
			Patch("the specials", delegate
			{
				harmony.Patch((MethodBase)AccessTools.Method(typeof(Player), "HaveQueuedChain", (Type[])null, (Type[])null), (HarmonyMethod)null, HM(typeof(Specials), "HaveQueuedChainPostfix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				harmony.Patch((MethodBase)AccessTools.Method(typeof(Humanoid), "StartAttack", new Type[2]
				{
					typeof(Character),
					typeof(bool)
				}, (Type[])null), HM(typeof(Specials), "StartAttackPrefix"), HM(typeof(Specials), "StartAttackPostfix"), (HarmonyMethod)null, HM(typeof(Specials), "StartAttackFinalizer"), (HarmonyMethod)null);
			});
			bool flag = Chainloader.PluginInfos.ContainsKey("andythedemon.combospear");
			bool flag2 = Chainloader.PluginInfos.ContainsKey("andythedemon.combobrawler");
			if (flag || flag2)
			{
				Log.LogInfo((object)("True damage numbers: left to " + (flag ? "Combo Spear" : "Combo Brawler") + "."));
			}
			else
			{
				Patch("the true damage numbers", delegate
				{
					TrueDamage.Register(harmony);
				});
			}
			Log.LogInfo((object)"Combo Axe 1.0.0 loaded.");
		}

		internal static string HostTableLine()
		{
			StringBuilder stringBuilder = new StringBuilder("Host states (change in Families.Hosts after the host probe):");
			Move[] moves = Families.Moves;
			foreach (Move move in moves)
			{
				stringBuilder.Append($" {move}={Families.HostTrigger(move)}/'{Families.HostClip(move)}' [{Families.HostStatus(move)}];");
			}
			return stringBuilder.ToString();
		}

		internal static void Patch(string feature, Action register)
		{
			try
			{
				register();
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Could not patch " + feature + " (" + ex.GetType().Name + ": " + ex.Message + "); it is off."));
			}
		}

		internal static HarmonyMethod HM(Type type, string method)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			return new HarmonyMethod(AccessTools.Method(type, method, (Type[])null, (Type[])null));
		}
	}
	internal static class Refs
	{
		internal static FieldRef<Humanoid, Attack> CurrentAttack;

		internal static FieldRef<ZSyncAnimation, Animator> AnimatorOf;

		internal static FieldRef<Player, float> QueuedAttack;

		internal static FieldRef<Player, float> QueuedSecond;

		internal static FieldRef<Player, bool> SecondaryHold;

		internal static FieldRef<Attack, int> ChainLevel;

		internal static FieldRef<Character, CharacterAnimEvent> AnimEvent;

		internal static FieldRef<VisEquipment, int> LeftItemHash;

		internal static FieldRef<VisEquipment, GameObject> RightItemInstance;

		internal static void Init()
		{
			CurrentAttack = Get<Humanoid, Attack>("m_currentAttack");
			AnimatorOf = Get<ZSyncAnimation, Animator>("m_animator");
			QueuedAttack = Get<Player, float>("m_queuedAttackTimer");
			QueuedSecond = Get<Player, float>("m_queuedSecondAttackTimer");
			SecondaryHold = Get<Player, bool>("m_secondaryAttackHold");
			ChainLevel = Get<Attack, int>("m_currentAttackCainLevel");
			AnimEvent = Get<Character, CharacterAnimEvent>("m_animEvent");
			LeftItemHash = Get<VisEquipment, int>("m_currentLeftItemHash");
			RightItemInstance = Get<VisEquipment, GameObject>("m_rightItemInstance");
		}

		internal static bool ChainPointReached(Character c)
		{
			CharacterAnimEvent val = ((AnimEvent != null) ? AnimEvent.Invoke(c) : null);
			if ((Object)(object)val != (Object)null)
			{
				return val.CanChain();
			}
			return false;
		}

		private static FieldRef<T, F> Get<T, F>(string field) where T : class
		{
			try
			{
				return AccessTools.FieldRefAccess<T, F>(field);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Field " + typeof(T).Name + "." + field + " not found (" + ex.GetType().Name + "); the feature that needs it is off."));
				return null;
			}
		}
	}
	public readonly struct SetKey : IEquatable<SetKey>
	{
		public readonly Family Family;

		public readonly Variant Variant;

		public SetKey(Family family, Variant variant)
		{
			Family = family;
			Variant = ((family == Family.Raider) ? variant : Variant.Shield);
		}

		public bool Equals(SetKey o)
		{
			if (Family == o.Family)
			{
				return Variant == o.Variant;
			}
			return false;
		}

		public override bool Equals(object obj)
		{
			if (obj is SetKey o)
			{
				return Equals(o);
			}
			return false;
		}

		public override int GetHashCode()
		{
			return (int)((int)Family * 8 + Variant);
		}

		public override string ToString()
		{
			return Family.ToString() + ((Family == Family.Raider) ? ("/" + Variant) : "");
		}
	}
	internal static class Specials
	{
		internal sealed class SpecialState
		{
			public string Animation;

			public HitData Saved;
		}

		internal sealed class HitData
		{
			private AttackType type;

			private bool hitTerrain;

			private bool lowerDamagePerHit;

			private bool hitThroughWalls;

			private bool multiHit;

			private bool pickaxeSpecial;

			private bool harvest;

			private float range;

			private float height;

			private float heightChar1;

			private float heightChar2;

			private float offset;

			private float angle;

			private float rayWidth;

			private float rayWidthCharExtra;

			private float maxYAngle;

			private float spawnOnHitChance;

			private string originJoint;

			private HitPointType hitPointType;

			private DestructibleType resetChainIfHit;

			private GameObject spawnOnTrigger;

			private GameObject spawnOnHit;

			private GameObject projectile;

			internal static HitData Of(Attack a)
			{
				//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_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_00eb: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
				return new HitData
				{
					type = a.m_attackType,
					hitTerrain = a.m_hitTerrain,
					lowerDamagePerHit = a.m_lowerDamagePerHit,
					hitThroughWalls = a.m_hitThroughWalls,
					multiHit = a.m_multiHit,
					pickaxeSpecial = a.m_pickaxeSpecial,
					harvest = a.m_harvest,
					range = a.m_attackRange,
					height = a.m_attackHeight,
					heightChar1 = a.m_attackHeightChar1,
					heightChar2 = a.m_attackHeightChar2,
					offset = a.m_attackOffset,
					angle = a.m_attackAngle,
					rayWidth = a.m_attackRayWidth,
					rayWidthCharExtra = a.m_attackRayWidthCharExtra,
					maxYAngle = a.m_maxYAngle,
					spawnOnHitChance = a.m_spawnOnHitChance,
					originJoint = a.m_attackOriginJoint,
					hitPointType = a.m_hitPointtype,
					resetChainIfHit = a.m_resetChainIfHit,
					spawnOnTrigger = a.m_spawnOnTrigger,
					spawnOnHit = a.m_spawnOnHit,
					projectile = a.m_attackProjectile
				};
			}

			internal void ApplyTo(Attack a)
			{
				//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_00da: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
				a.m_attackType = type;
				a.m_hitTerrain = hitTerrain;
				a.m_lowerDamagePerHit = lowerDamagePerHit;
				a.m_hitThroughWalls = hitThroughWalls;
				a.m_multiHit = multiHit;
				a.m_pickaxeSpecial = pickaxeSpecial;
				a.m_harvest = harvest;
				a.m_attackRange = range;
				a.m_attackHeight = height;
				a.m_attackHeightChar1 = heightChar1;
				a.m_attackHeightChar2 = heightChar2;
				a.m_attackOffset = offset;
				a.m_attackAngle = angle;
				a.m_attackRayWidth = rayWidth;
				a.m_attackRayWidthCharExtra = rayWidthCharExtra;
				a.m_maxYAngle = maxYAngle;
				a.m_spawnOnHitChance = spawnOnHitChance;
				a.m_attackOriginJoint = originJoint;
				a.m_hitPointtype = hitPointType;
				a.m_resetChainIfHit = resetChainIfHit;
				a.m_spawnOnTrigger = spawnOnTrigger;
				a.m_spawnOnHit = spawnOnHit;
				a.m_attackProjectile = projectile;
			}
		}

		internal const float ChainWindow = 0.25f;

		internal static void HaveQueuedChainPostfix(Player __instance, ref bool __result)
		{
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && Refs.CurrentAttack != null)
			{
				ComboState component = ((Component)__instance).GetComponent<ComboState>();
				if (!((Object)(object)component == (Object)null) && component.Running && FamilyItems.FamilyOf(((Humanoid)__instance).GetCurrentWeapon()).HasValue && Refs.CurrentAttack.Invoke((Humanoid)(object)__instance) != null && Refs.QueuedSecond != null && Refs.QueuedSecond.Invoke(__instance) > 0f)
				{
					__result = Refs.ChainPointReached((Character)(object)__instance) && ComboGraph.ChainsAtChainPoint(component.Current, Press.Special);
				}
			}
		}

		internal static bool StartAttackPrefix(Humanoid __instance, bool secondaryAttack, out SpecialState __state)
		{
			__state = null;
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			ItemData currentWeapon = __instance.GetCurrentWeapon();
			Family? family = FamilyItems.FamilyOf(currentWeapon);
			if (!family.HasValue)
			{
				return true;
			}
			ComboState component = ((Component)__instance).GetComponent<ComboState>();
			if (!secondaryAttack)
			{
				Player val = (Player)(object)((__instance is Player) ? __instance : null);
				if (val != null)
				{
					return !SpecialPending(val);
				}
				return true;
			}
			if ((Object)(object)component != (Object)null && component.Running && component.StartedAt >= Time.time)
			{
				return false;
			}
			Attack val2 = currentWeapon.m_shared?.m_secondaryAttack;
			if (val2 == null)
			{
				return true;
			}
			Move current = (((Object)(object)component != (Object)null) ? component.Current : Move.None);
			bool inWindow = (Object)(object)component != (Object)null && (component.Running || Time.time - component.EndedAt <= 0.25f);
			Move m = ComboGraph.Next(current, Press.Special, inWindow);
			__state = new SpecialState
			{
				Animation = val2.m_attackAnimation
			};
			Attack attack = currentWeapon.m_shared.m_attack;
			if (family.Value == Family.Raider && attack != null)
			{
				__state.Saved = HitData.Of(val2);
				HitData.Of(attack).ApplyTo(val2);
			}
			val2.m_attackAnimation = Families.SpecialTrigger(family.Value, m);
			return true;
		}

		private static bool SpecialPending(Player p)
		{
			if (Refs.QueuedSecond == null || !(Refs.QueuedSecond.Invoke(p) > 0f))
			{
				if (Refs.SecondaryHold != null)
				{
					return Refs.SecondaryHold.Invoke(p);
				}
				return false;
			}
			return true;
		}

		internal static void StartAttackFinalizer(Humanoid __instance, SpecialState __state)
		{
			if (__state != null)
			{
				Attack val = __instance.GetCurrentWeapon()?.m_shared?.m_secondaryAttack;
				if (val != null)
				{
					val.m_attackAnimation = __state.Animation;
					__state.Saved?.ApplyTo(val);
				}
			}
		}

		internal static void StartAttackPostfix(Humanoid __instance, bool secondaryAttack, bool __result)
		{
			if (!__result || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || Refs.CurrentAttack == null)
			{
				return;
			}
			Attack val = Refs.CurrentAttack.Invoke(__instance);
			Family? family = FamilyItems.FamilyOf(__instance.GetCurrentWeapon());
			if (val != null && family.HasValue)
			{
				Move move = MoveOf(val, family.Value, secondaryAttack);
				if (move != Move.None)
				{
					val.m_damageMultiplier = Families.Damage(family.Value, move);
					val.m_lastChainDamageMultiplier = 1f;
				}
			}
		}

		private static Move MoveOf(Attack a, Family family, bool secondary)
		{
			if (secondary)
			{
				if (!Families.ParseTrigger(a.m_attackAnimation, out var family2, out var move) || family2 != family)
				{
					return Move.None;
				}
				return move;
			}
			if (a.m_attackAnimation != Families.AttackName(family))
			{
				return Move.None;
			}
			int num = ((Refs.ChainLevel != null) ? Refs.ChainLevel.Invoke(a) : 0);
			return (Move)(1 + Mathf.Clamp(num, 0, 2));
		}
	}
	internal static class Triggers
	{
		internal const string Ignored = "comboaxe_dup_ignored";

		internal static void Prefix(ZSyncAnimation __instance, ref string name)
		{
			if (name == null || name.StartsWith("comboaxe_dup_ignored", StringComparison.Ordinal))
			{
				return;
			}
			if (!Families.ParseTrigger(name, out var family, out var move))
			{
				ClearRemoteOnVanillaHost(__instance, name);
				return;
			}
			ComboState comboState = ComboState.Of((Component)(object)__instance);
			bool flag = comboState.Running && comboState.Current == move && Time.time < comboState.LastActive + 0.05f;
			if (name == comboState.LastTrigger && (flag || Time.time - comboState.LastTriggerAt < 0.12f))
			{
				Plugin.Log.LogDebug((object)("Duplicate trigger '" + name + "' swallowed (would have restarted the move)."));
				name = "comboaxe_dup_ignored";
				return;
			}
			comboState.LastTrigger = name;
			comboState.LastTriggerAt = Time.time;
			SetKey setKey = new SetKey(family, OffHand.Of((Component)(object)__instance));
			comboState.Begin(setKey, move);
			Animator val = ((Refs.AnimatorOf != null) ? Refs.AnimatorOf.Invoke(__instance) : null);
			if ((Object)(object)val != (Object)null)
			{
				ClipSets.Apply(val, setKey);
				if (!IsLocal((Component)(object)__instance))
				{
					comboState.RemoteApplied = setKey;
				}
			}
			name = Families.HostTrigger(move);
		}

		private static void ClearRemoteOnVanillaHost(ZSyncAnimation z, string name)
		{
			if (!Families.IsHostTrigger(name) || IsLocal((Component)(object)z))
			{
				return;
			}
			ComboState component = ((Component)z).GetComponent<ComboState>();
			if (!((Object)(object)component == (Object)null) && component.RemoteApplied.HasValue)
			{
				Animator val = ((Refs.AnimatorOf != null) ? Refs.AnimatorOf.Invoke(z) : null);
				if (!((Object)(object)val == (Object)null))
				{
					ClipSets.Apply(val, null);
					component.RemoteApplied = null;
					component.Running = false;
				}
			}
		}

		private static bool IsLocal(Component c)
		{
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				return (Object)(object)c.GetComponent<Player>() == (Object)(object)Player.m_localPlayer;
			}
			return false;
		}
	}
	internal static class TrueDamage
	{
		[ThreadStatic]
		private static HitData current;

		internal static void Register(Harmony harmony)
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(Character), "ApplyDamage", new Type[4]
			{
				typeof(HitData),
				typeof(bool),
				typeof(bool),
				typeof(DamageModifier)
			}, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(DamageText), "ShowText", new Type[4]
			{
				typeof(DamageModifier),
				typeof(Vector3),
				typeof(float),
				typeof(bool)
			}, (Type[])null);
			if (methodInfo == null || methodInfo2 == null)
			{
				Plugin.Log.LogError((object)"Character.ApplyDamage / DamageText.ShowText not found; damage numbers are left as they are.");
				return;
			}
			harmony.Patch((MethodBase)methodInfo, Plugin.HM(typeof(TrueDamage), "ApplyPrefix"), (HarmonyMethod)null, (HarmonyMethod)null, Plugin.HM(typeof(TrueDamage), "ApplyFinalizer"), (HarmonyMethod)null);
			harmony.Patch((MethodBase)methodInfo2, Plugin.HM(typeof(TrueDamage), "ShowTextPrefix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Plugin.Log.LogInfo((object)"True damage numbers: on (shows the damage a hit really deals).");
		}

		internal static void ApplyPrefix(HitData hit, out HitData __state)
		{
			__state = current;
			current = hit;
		}

		internal static void ApplyFinalizer(HitData __state)
		{
			current = __state;
		}

		internal static void ShowTextPrefix(ref float dmg)
		{
			if (current != null)
			{
				dmg = current.GetTotalDamage();
			}
		}
	}
	public struct WeaponShaftFrame
	{
		public Vector3 butt;

		public Vector3 axis;

		public Vector3 edge;

		public Quaternion rotation;

		public float length;

		public string method;
	}
	public static class WeaponShaftGeometry
	{
		private struct Edge
		{
			public Vector3 a;

			public Vector3 b;
		}

		public static bool TryMeasure(Transform item, out WeaponShaftFrame frame)
		{
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: 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_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: 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_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_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03de: 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_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_040c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0440: Unknown result type (might be due to invalid IL or missing references)
			//IL_0445: Unknown result type (might be due to invalid IL or missing references)
			//IL_0447: 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_0454: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_0464: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Unknown result type (might be due to invalid IL or missing references)
			//IL_046f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0474: Unknown result type (might be due to invalid IL or missing references)
			//IL_0478: Unknown result type (might be due to invalid IL or missing references)
			//IL_047d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: 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_0378: 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_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Unknown result type (might be due to invalid IL or missing references)
			//IL_039e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b2: 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_048d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0493: Unknown result type (might be due to invalid IL or missing references)
			//IL_0498: Unknown result type (might be due to invalid IL or missing references)
			//IL_049d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0501: 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_0516: Unknown result type (might be due to invalid IL or missing references)
			//IL_051e: 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_052a: Unknown result type (might be due to invalid IL or missing references)
			//IL_052c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0534: Unknown result type (might be due to invalid IL or missing references)
			//IL_0539: Unknown result type (might be due to invalid IL or missing references)
			//IL_053b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0540: Unknown result type (might be due to invalid IL or missing references)
			//IL_0544: 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_054b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0550: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_04dc: 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)
			frame = default(WeaponShaftFrame);
			List<Vector3> list = new List<Vector3>();
			List<Edge> list2 = new List<Edge>();
			bool flag = false;
			MeshFilter[] componentsInChildren = ((Component)item).GetComponentsInChildren<MeshFilter>(true);
			foreach (MeshFilter val in componentsInChildren)
			{
				Mesh sharedMesh = val.sharedMesh;
				if ((Object)(object)sharedMesh == (Object)null || !((Component)val).gameObject.activeInHierarchy)
				{
					continue;
				}
				Matrix4x4 val2 = item.worldToLocalMatrix * ((Component)val).transform.localToWorldMatrix;
				if (sharedMesh.isReadable)
				{
					Vector3[] vertices = sharedMesh.vertices;
					for (int j = 0; j < vertices.Length; j++)
					{
						vertices[j] = ((Matrix4x4)(ref val2)).MultiplyPoint3x4(vertices[j]);
					}
					list.AddRange(vertices);
					int[] triangles = sharedMesh.triangles;
					for (int k = 0; k + 2 < triangles.Length; k += 3)
					{
						for (int l = 0; l < 3; l++)
						{
							list2.Add(new Edge
							{
								a = vertices[triangles[k + l]],
								b = vertices[triangles[k + (l + 1) % 3]]
							});
						}
					}
					flag = true;
					continue;
				}
				Bounds bounds = sharedMesh.bounds;
				for (int m = -1; m <= 1; m += 2)
				{
					for (int n = -1; n <= 1; n += 2)
					{
						for (int num = -1; num <= 1; num += 2)
						{
							list.Add(((Matrix4x4)(ref val2)).MultiplyPoint3x4(((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)m, (float)n, (float)num))));
						}
					}
				}
			}
			if (list.Count < 4)
			{
				return false;
			}
			Vector3 center = Mean(list);
			Vector3 axis = Principal(list, center, Vector3.zero);
			if (((Vector3)(ref axis)).sqrMagnitude < 0.9f)
			{
				return false;
			}
			Range(list, axis, out var lo, out var hi);
			float span = hi - lo;
			if (span < 0.3f)
			{
				return false;
			}
			if (Spread(list, center, axis, lo, lo + span * 0.2f) > Spread(list, center, axis, hi - span * 0.2f, hi))
			{
				axis = -axis;
			}
			Range(list, axis, out lo, out hi);
			span = hi - lo;
			Vector3 val3 = Vector3.zero;
			Vector3 val4 = Vector3.zero;
			float num2 = 0f;
			foreach (Edge item2 in list2)
			{
				Vector3 val5 = item2.b - item2.a;
				float magnitude = ((Vector3)(ref val5)).magnitude;
				if (!(magnitude < span * 0.3f) && !(Mathf.Abs(Vector3.Dot(val5 / magnitude, axis)) < 0.92f) && !(Mathf.Min(Vector3.Dot(item2.a, axis), Vector3.Dot(item2.b, axis)) > lo + span * 0.35f))
				{
					val3 += ((Vector3.Dot(val5, axis) < 0f) ? (-val5) : val5);
					val4 += (item2.a + item2.b) * 0.5f * magnitude;
					num2 += magnitude;
				}
			}
			Vector3 val6;
			string method;
			if (num2 > 0.01f)
			{
				axis = ((Vector3)(ref val3)).normalized;
				val6 = val4 / num2;
				method = "mesh shaft edges";
			}
			else
			{
				val6 = Vector3.zero;
				method = (flag ? "mesh axis / attach origin" : "bounds axis / attach origin");
			}
			Range(list, axis, out lo, out hi);
			span = hi - lo;
			List<Vector3> points = list.FindAll((Vector3 point) => Vector3.Dot(point, axis) > lo + span * 0.7f);
			Vector3 val7 = Mean(points);
			Vector3 val8 = Principal(points, val7, axis);
			Vector3 val9;
			if (((Vector3)(ref val8)).sqrMagnitude < 0.5f)
			{
				val9 = Vector3.ProjectOnPlane(Vector3.right, axis);
				val8 = ((Vector3)(ref val9)).normalized;
			}
			if (((Vector3)(ref val8)).sqrMagnitude < 0.5f)
			{
				val9 = Vector3.ProjectOnPlane(Vector3.up, axis);
				val8 = ((Vector3)(ref val9)).normalized;
			}
			Vector3 val10 = Vector3.ProjectOnPlane(val7 - val6, axis);
			if (((Vector3)(ref val10)).sqrMagnitude > 0.0001f && Vector3.Dot(val8, val10) < 0f)
			{
				val8 = -val8;
			}
			WeaponShaftFrame weaponShaftFrame = new WeaponShaftFrame
			{
				butt = val6 + axis * (lo - Vector3.Dot(val6, axis)),
				axis = axis,
				edge = val8
			};
			val9 = Vector3.Cross(axis, val8);
			weaponShaftFrame.rotation = Quaternion.LookRotation(((Vector3)(ref val9)).normalized, val8);
			weaponShaftFrame.length = span;
			weaponShaftFrame.method = method;
			frame = weaponShaftFrame;
			return true;
		}

		private static Vector3 Mean(List<Vector3> points)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.zero;
			foreach (Vector3 point in points)
			{
				val += point;
			}
			if (points.Count != 0)
			{
				return val / (float)points.Count;
			}
			return val;
		}

		private static void Range(List<Vector3> points, Vector3 axis, out float lo, out float hi)
		{
			//IL_0019: 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)
			lo = float.PositiveInfinity;
			hi = float.NegativeInfinity;
			foreach (Vector3 point in points)
			{
				float num = Vector3.Dot(point, axis);
				lo = Mathf.Min(lo, num);
				hi = Mathf.Max(hi, num);
			}
		}

		private static float Spread(List<Vector3> points, Vector3 center, Vector3 axis, float lo, float hi)
		{
			//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_002e: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			int num2 = 0;
			foreach (Vector3 point in points)
			{
				float num3 = Vector3.Dot(point, axis);
				if (!(num3 < lo) && !(num3 > hi))
				{
					float num4 = num;
					Vector3 val = Vector3.ProjectOnPlane(point - center, axis);
					num = num4 + ((Vector3)(ref val)).sqrMagnitude;
					num2++;
				}
			}
			if (num2 != 0)
			{
				return num / (float)num2;
			}
			return 0f;
		}

		private static Vector3 Principal(List<Vector3> points, Vector3 center, Vector3 exclude)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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_0086: 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_0098: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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_0053: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: 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_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: 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_0144: 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_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: 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_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: 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)
			float num = 0f;
			float num2 = 0f;
			float num3 = 0f;
			float num4 = 0f;
			float num5 = 0f;
			float num6 = 0f;
			foreach (Vector3 point in points)
			{
				Vector3 val = point - center;
				if (((Vector3)(ref exclude)).sqrMagnitude > 0.5f)
				{
					val = Vector3.ProjectOnPlane(val, exclude);
				}
				num += val.x * val.x;
				num2 += val.x * val.y;
				num3 += val.x * val.z;
				num4 += val.y * val.y;
				num5 += val.y * val.z;
				num6 += val.z * val.z;
			}
			Vector3 val2 = Vector3.zero;
			float num7 = -1f;
			Vector3[] array = (Vector3[])(object)new Vector3[3]
			{
				Vector3.right,
				Vector3.up,
				Vector3.forward
			};
			Vector3 val5 = default(Vector3);
			for (int i = 0; i < array.Length; i++)
			{
				Vector3 val3 = array[i];
				Vector3 val4;
				if (((Vector3)(ref exclude)).sqrMagnitude > 0.5f)
				{
					val4 = Vector3.ProjectOnPlane(val3, exclude);
					val3 = ((Vector3)(ref val4)).normalized;
				}
				for (int j = 0; j < 24; j++)
				{
					val4 = new Vector3(num * val3.x + num2 * val3.y + num3 * val3.z, num2 * val3.x + num4 * val3.y + num5 * val3.z, num3 * val3.x + num5 * val3.y + num6 * val3.z);
					val3 = ((Vector3)(ref val4)).normalized;
				}
				((Vector3)(ref val5))..ctor(num * val3.x + num2 * val3.y + num3 * val3.z, num2 * val3.x + num4 * val3.y + num5 * val3.z, num3 * val3.x + num5 * val3.y + num6 * val3.z);
				float num8 = Vector3.Dot(val3, val5);
				if (num8 > num7)
				{
					num7 = num8;
					val2 = val3;
				}
			}
			return ((Vector3)(ref val2)).normalized;
		}
	}
}