Decompiled source of ComboBrawler v1.0.2

BepInEx/plugins/ComboBrawler.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Rendering;

[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("ComboBrawler")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+2fc8d9ff94cefe0b70d4c23259b771fda99a9708")]
[assembly: AssemblyProduct("ComboBrawler")]
[assembly: AssemblyTitle("ComboBrawler")]
[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 ComboBrawler
{
	internal static class ClawGlow
	{
		private const float Peak = 0.35f;

		private const float Inflate = 0.01f;

		private static readonly Color Tint = new Color(0.45f, 0.7f, 1f);

		private static bool logged;

		private static readonly Dictionary<Mesh, Mesh> Shells = new Dictionary<Mesh, Mesh>();

		private static Shader shader;

		internal static IEnumerator Run(Character c, float seconds)
		{
			yield return null;
			List<GameObject> made = new List<GameObject>();
			List<Material> mats = new List<Material>();
			foreach (Renderer item in Sources(c))
			{
				GameObject val = Copy(item, mats);
				if ((Object)(object)val != (Object)null)
				{
					made.Add(val);
				}
			}
			if (made.Count == 0)
			{
				yield break;
			}
			for (float el = 0f; el < seconds; el += Time.deltaTime)
			{
				if (!((Object)(object)c != (Object)null))
				{
					break;
				}
				if (c.IsDead())
				{
					break;
				}
				float a = WolfMath.GlowAlpha(el, seconds, 0.35f);
				foreach (Material item2 in mats)
				{
					SetTint(item2, a);
				}
				yield return null;
			}
			foreach (GameObject item3 in made)
			{
				if ((Object)(object)item3 != (Object)null)
				{
					Object.Destroy((Object)(object)item3);
				}
			}
			foreach (Material item4 in mats)
			{
				Object.Destroy((Object)(object)item4);
			}
		}

		private static IEnumerable<Renderer> Sources(Character c)
		{
			VisEquipment ve = (((Object)(object)c != (Object)null) ? ((Component)c).GetComponent<VisEquipment>() : null);
			if ((Object)(object)ve == (Object)null)
			{
				yield break;
			}
			FieldRef<VisEquipment, GameObject>[] array = new FieldRef<VisEquipment, GameObject>[2]
			{
				Refs.RightItemInstance,
				Refs.LeftItemInstance
			};
			foreach (FieldRef<VisEquipment, GameObject> val in array)
			{
				GameObject val2 = ((val != null) ? val.Invoke(ve) : null);
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				Renderer[] componentsInChildren = val2.GetComponentsInChildren<Renderer>();
				foreach (Renderer val3 in componentsInChildren)
				{
					if (val3 is SkinnedMeshRenderer || val3 is MeshRenderer)
					{
						yield return val3;
					}
				}
			}
		}

		private static GameObject Copy(Renderer src, List<Material> mats)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Expected O, but got Unknown
			if ((Object)(object)shader == (Object)null)
			{
				shader = Shader.Find("Legacy Shaders/Particles/Additive") ?? Shader.Find("Particles/Additive") ?? Shader.Find("Sprites/Default") ?? Shader.Find("UI/Default");
			}
			if ((Object)(object)shader == (Object)null)
			{
				return null;
			}
			GameObject val = new GameObject("BrawlClawGlow");
			val.transform.SetParent(((Component)src).transform.parent, false);
			val.transform.localPosition = ((Component)src).transform.localPosition;
			val.transform.localRotation = ((Component)src).transform.localRotation;
			val.transform.localScale = ((Component)src).transform.localScale;
			val.layer = ((Component)src).gameObject.layer;
			SkinnedMeshRenderer val2 = (SkinnedMeshRenderer)(object)((src is SkinnedMeshRenderer) ? src : null);
			Renderer val3;
			if (val2 != null)
			{
				SkinnedMeshRenderer obj = val.AddComponent<SkinnedMeshRenderer>();
				obj.sharedMesh = Shell(val2.sharedMesh, Scale(src, val2.sharedMesh));
				obj.bones = val2.bones;
				obj.rootBone = val2.rootBone;
				obj.updateWhenOffscreen = true;
				val3 = (Renderer)(object)obj;
			}
			else
			{
				MeshFilter component = ((Component)src).GetComponent<MeshFilter>();
				if ((Object)(object)component == (Object)null || (Object)(object)component.sharedMesh == (Object)null)
				{
					Object.Destroy((Object)(object)val);
					return null;
				}
				val.AddComponent<MeshFilter>().sharedMesh = Shell(component.sharedMesh, Scale(src, component.sharedMesh));
				val3 = (Renderer)(object)val.AddComponent<MeshRenderer>();
			}
			Material val4 = new Material(shader);
			SetTint(val4, 0f);
			mats.Add(val4);
			Material[] array = (Material[])(object)new Material[Mathf.Max(1, src.sharedMaterials.Length)];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = val4;
			}
			val3.sharedMaterials = array;
			val3.shadowCastingMode = (ShadowCastingMode)0;
			val3.receiveShadows = false;
			return val;
		}

		private static void SetTint(Material m, float a)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if (m.HasProperty("_TintColor"))
			{
				m.SetColor("_TintColor", new Color(Tint.r * 0.5f, Tint.g * 0.5f, Tint.b * 0.5f, a));
			}
			else
			{
				m.color = new Color(Tint.r, Tint.g, Tint.b, a);
			}
		}

		private static float Scale(Renderer r, Mesh mesh)
		{
			//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)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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)
			if ((Object)(object)mesh == (Object)null)
			{
				return 1f;
			}
			Bounds bounds = mesh.bounds;
			Vector3 size = ((Bounds)(ref bounds)).size;
			float magnitude = ((Vector3)(ref size)).magnitude;
			bounds = r.bounds;
			size = ((Bounds)(ref bounds)).size;
			float magnitude2 = ((Vector3)(ref size)).magnitude;
			float num = ((magnitude > 1E-06f && magnitude2 > 1E-06f) ? (magnitude2 / magnitude) : 1f);
			if (!logged)
			{
				logged = true;
				Plugin.Log.LogInfo((object)$"Claw outline: shader {((Object)shader).name}, mesh {((Object)mesh).name} readable {mesh.isReadable}, world/mesh scale {num:0.###}");
			}
			return num;
		}

		private static Mesh Shell(Mesh src, float scale)
		{
			//IL_006e: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)src == (Object)null || !src.isReadable)
			{
				return src;
			}
			if (Shells.TryGetValue(src, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			Mesh val = Object.Instantiate<Mesh>(src);
			Vector3[] vertices = val.vertices;
			Vector3[] normals = val.normals;
			float num = 0.01f / Mathf.Max(1E-06f, scale);
			if (normals != null && normals.Length == vertices.Length)
			{
				for (int i = 0; i < vertices.Length; i++)
				{
					ref Vector3 reference = ref vertices[i];
					reference += normals[i] * num;
				}
				val.vertices = vertices;
				val.RecalculateBounds();
			}
			Shells[src] = val;
			return val;
		}
	}
	internal static class ClipSets
	{
		private class Own
		{
			public AnimatorOverrideController Controller;

			public RuntimeAnimatorController Base;
		}

		internal const string BundleFile = "combobrawler.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 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 ?? "", "combobrawler.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)
			{
				Plugin.Log.LogWarning((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("combobrawler.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(Style? style)
		{
			Dictionary<string, AnimationClip> dictionary = new Dictionary<string, AnimationClip>();
			if (!style.HasValue)
			{
				return dictionary;
			}
			Move[] moves = Moves;
			foreach (Move m in moves)
			{
				AnimationClip val = Clip(Styles.ClipName(style.Value, m));
				if ((Object)(object)val != (Object)null)
				{
					dictionary[Styles.HostClip(m)] = val;
				}
			}
			return dictionary;
		}

		internal static void Apply(Animator animator, Style? style)
		{
			if ((Object)(object)animator == (Object)null)
			{
				return;
			}
			Dictionary<string, AnimationClip> want = Pairs(style);
			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, Style style)
		{
			AnimatorOverrideController val = (AnimatorOverrideController)(((Object)(object)animator != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null);
			Dictionary<string, AnimationClip> dictionary = Pairs(style);
			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 (Styles.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 + " (ComboBrawler)"
			};
			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;
		}
	}
	[DefaultExecutionOrder(10000)]
	internal class FistHold : MonoBehaviour
	{
		private static readonly Dictionary<string, Quaternion> Fist = new Dictionary<string, Quaternion>
		{
			["LeftHandThumb1"] = new Quaternion(0.5547f, -0.2076f, -0.3706f, 0.7155f),
			["LeftHandThumb2"] = new Quaternion(-0.2336f, 0.1314f, 0.5942f, 0.7583f),
			["LeftHandThumb3"] = new Quaternion(-0.1547f, -0.2399f, 0.3091f, 0.9072f),
			["LeftHandIndex1"] = new Quaternion(0.7056f, -0.0774f, -0.0665f, 0.7013f),
			["LeftHandIndex2"] = new Quaternion(0.8006f, 0.0915f, 0.0522f, 0.5899f),
			["LeftHandIndex3"] = new Quaternion(0.5161f, 0.0075f, 0.0447f, 0.8554f),
			["LeftHandMiddle1"] = new Quaternion(0.6958f, -0.0408f, -0.0192f, 0.7168f),
			["LeftHandMiddle2"] = new Quaternion(0.8675f, 0.0252f, 0.0296f, 0.4958f),
			["LeftHandMiddle3"] = new Quaternion(0.5554f, 0.0339f, 0.0325f, 0.8303f),
			["LeftHandRing1"] = new Quaternion(0.6529f, 0.0145f, 0.0278f, 0.7568f),
			["LeftHandRing2"] = new Quaternion(0.8177f, -0.0011f, 0.0446f, 0.5739f),
			["LeftHandRing3"] = new Quaternion(0.5278f, 0.0084f, 0.0224f, 0.849f),
			["LeftHandPinky1"] = new Quaternion(0.6403f, 0.0448f, 0.0765f, 0.763f),
			["LeftHandPinky2"] = new Quaternion(0.7099f, -0.0146f, 0.0442f, 0.7028f),
			["LeftHandPinky3"] = new Quaternion(0.4321f, -0.0171f, 0.077f, 0.8984f),
			["RightHandThumb1"] = new Quaternion(0.6179f, 0.2628f, 0.3265f, 0.6652f),
			["RightHandThumb2"] = new Quaternion(-0.4899f, -0.0768f, -0.5109f, 0.7022f),
			["RightHandThumb3"] = new Quaternion(0.1296f, 0.2428f, -0.2951f, 0.915f),
			["RightHandIndex1"] = new Quaternion(0.7045f, 0.0771f, 0.0665f, 0.7023f),
			["RightHandIndex2"] = new Quaternion(0.7994f, -0.0917f, -0.0522f, 0.5915f),
			["RightHandIndex3"] = new Quaternion(0.5148f, -0.0075f, -0.0447f, 0.8561f),
			["RightHandMiddle1"] = new Quaternion(0.6946f, 0.0407f, 0.0193f, 0.718f),
			["RightHandMiddle2"] = new Quaternion(0.8665f, -0.0252f, -0.0296f, 0.4977f),
			["RightHandMiddle3"] = new Quaternion(0.5541f, -0.0339f, -0.0324f, 0.8312f),
			["RightHandRing1"] = new Quaternion(0.6517f, -0.0145f, -0.0277f, 0.7578f),
			["RightHandRing2"] = new Quaternion(0.8166f, 0.0011f, -0.0445f, 0.5755f),
			["RightHandRing3"] = new Quaternion(0.5266f, -0.0084f, -0.0224f, 0.8498f),
			["RightHandPinky1"] = new Quaternion(0.6393f, -0.0446f, -0.0764f, 0.7639f),
			["RightHandPinky2"] = new Quaternion(0.7087f, 0.0146f, -0.0441f, 0.704f),
			["RightHandPinky3"] = new Quaternion(0.431f, 0.017f, -0.0769f, 0.8989f)
		};

		private readonly List<KeyValuePair<Transform, Quaternion>> bones = new List<KeyValuePair<Transform, Quaternion>>();

		private VisEquipment vis;

		private int lastHash = int.MinValue;

		private bool closes;

		private bool collected;

		private float recollectAt;

		internal static void PlayerAwakePostfix(Player __instance)
		{
			Animator val = (((Object)(object)__instance != (Object)null) ? ((Component)__instance).GetComponentInChildren<Animator>() : null);
			if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).GetComponent<FistHold>() == (Object)null)
			{
				((Component)val).gameObject.AddComponent<FistHold>();
			}
		}

		private void Start()
		{
			vis = ((Component)this).GetComponentInParent<VisEquipment>();
		}

		private void OnEnable()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			Application.onBeforeRender += new UnityAction(Hold);
		}

		private void OnDisable()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			Application.onBeforeRender -= new UnityAction(Hold);
		}

		private void Collect()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			bones.Clear();
			Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if (Fist.TryGetValue(((Object)val).name, out var value))
				{
					bones.Add(new KeyValuePair<Transform, Quaternion>(val, value));
				}
			}
		}

		private void Hold()
		{
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)vis == (Object)null || Refs.RightItemHash == null)
			{
				return;
			}
			int num = Refs.RightItemHash.Invoke(vis);
			if (num != lastHash)
			{
				lastHash = num;
				GameObject val = ((num != 0 && (Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(num) : null);
				Style? s = (((Object)(object)val != (Object)null) ? Styles.OfPrefab(((Object)val).name) : ((Style?)null));
				closes = s.HasValue && StyleItems.Active.Contains(s.Value) && Styles.ClosesFists(s);
				collected = false;
				recollectAt = Time.time + 0.5f;
			}
			if (!closes)
			{
				return;
			}
			if (!collected || (recollectAt > 0f && Time.time >= recollectAt))
			{
				Collect();
				collected = true;
				if (Time.time >= recollectAt)
				{
					recollectAt = 0f;
				}
			}
			foreach (KeyValuePair<Transform, Quaternion> bone in bones)
			{
				if ((Object)(object)bone.Key != (Object)null)
				{
					bone.Key.localRotation = bone.Value;
				}
			}
		}
	}
	internal class ComboState : MonoBehaviour
	{
		internal Style Style;

		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 Style? Preloaded;

		internal float NextPreload;

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

		internal void Begin(Style style, Move move)
		{
			Style = style;
			Current = move;
			Running = true;
			Clip = null;
			Exiting = false;
			StartedAt = (LastActive = Time.time);
			CaptureAt = Time.time + 0.05f;
			AbsentSince = -1f;
		}
	}
	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 = Styles.ClipName(st.Style, 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))
			{
				Style? style = StyleItems.StyleOf(component.GetCurrentWeapon());
				if (style != st.Preloaded || (style.HasValue && !ClipSets.OursPresent(val, style.Value)))
				{
					ClipSets.Apply(val, style);
					st.Preloaded = style;
				}
			}
		}

		internal static void EquipPrefix(Humanoid __instance, ItemData item)
		{
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || item == null || !item.IsWeapon() || StyleItems.StyleOf(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 MultiHit
	{
		private sealed class Hits
		{
			public Style Style;

			public Move Move;

			public int Next;
		}

		private static readonly ConditionalWeakTable<Attack, Hits> running = new ConditionalWeakTable<Attack, Hits>();

		internal static void Start(Attack started, Style style, Move move)
		{
			running.Remove(started);
			running.Add(started, new Hits
			{
				Style = style,
				Move = move
			});
		}

		internal static void OnAttackTriggerPrefix(Attack __instance)
		{
			if (__instance != null && running.TryGetValue(__instance, out var value))
			{
				__instance.m_damageMultiplier = Styles.HitDamage(value.Style, value.Move, value.Next++);
			}
		}
	}
	[BepInPlugin("andythedemon.combobrawler", "Combo Brawler", "1.0.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "andythedemon.combobrawler";

		public const string PluginName = "Combo Brawler";

		public const string Version = "1.0.2";

		internal const string ComboSpearGuid = "andythedemon.combospear";

		internal static ConfigEntry<bool> Enabled;

		internal static ManualLogSource Log;

		internal static bool ComboSpearLoaded;

		internal static string PluginFolder;

		private static Harmony harmony;

		private void Awake()
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Turns Combo Brawler on or off. Off: fist weapons attack, block and parry exactly as in vanilla. Takes effect the next time the game starts.");
			if (!Enabled.Value)
			{
				Log.LogInfo((object)"Combo Brawler 1.0.2 is turned off in its config (General / Enabled) - nothing is changed.");
				return;
			}
			ComboSpearLoaded = Chainloader.PluginInfos.ContainsKey("andythedemon.combospear");
			PluginFolder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			harmony = new Harmony("andythedemon.combobrawler");
			Refs.Init();
			Patch("the fist weapon styles", delegate
			{
				harmony.Patch((MethodBase)AccessTools.Method(typeof(ObjectDB), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, HM(typeof(StyleItems), "ObjectDBPostfix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				harmony.Patch((MethodBase)AccessTools.Method(typeof(ObjectDB), "CopyOtherDB", (Type[])null, (Type[])null), (HarmonyMethod)null, HM(typeof(StyleItems), "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);
				harmony.Patch((MethodBase)AccessTools.Method(typeof(Attack), "OnAttackTrigger", (Type[])null, (Type[])null), HM(typeof(MultiHit), "OnAttackTriggerPrefix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			});
			Patch("the wolf's movement", delegate
			{
				harmony.Patch((MethodBase)AccessTools.Method(typeof(Player), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, HM(typeof(WolfMotion), "PlayerAwakePostfix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			});
			Patch("closed fists in the gloves", delegate
			{
				harmony.Patch((MethodBase)AccessTools.Method(typeof(Player), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, HM(typeof(FistHold), "PlayerAwakePostfix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			});
			if (ComboSpearLoaded)
			{
				Log.LogInfo((object)"True damage numbers: left to Combo Spear.");
			}
			else
			{
				Patch("the true damage numbers", delegate
				{
					TrueDamage.Register(harmony);
				});
			}
			Log.LogInfo((object)"Combo Brawler 1.0.2 loaded.");
		}

		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> AttackHold;

		internal static FieldRef<Player, bool> SecondaryHold;

		internal static FieldRef<Attack, int> ChainLevel;

		internal static FieldRef<Character, CharacterAnimEvent> AnimEvent;

		internal static FieldRef<Player, Quaternion> LookYaw;

		internal static FieldRef<VisEquipment, int> RightItemHash;

		internal static FieldRef<VisEquipment, GameObject> RightItemInstance;

		internal static FieldRef<VisEquipment, GameObject> LeftItemInstance;

		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");
			AttackHold = Get<Player, bool>("m_attackHold");
			SecondaryHold = Get<Player, bool>("m_secondaryAttackHold");
			ChainLevel = Get<Attack, int>("m_currentAttackCainLevel");
			AnimEvent = Get<Character, CharacterAnimEvent>("m_animEvent");
			LookYaw = Get<Player, Quaternion>("m_lookYaw");
			RightItemHash = Get<VisEquipment, int>("m_currentRightItemHash");
			RightItemInstance = Get<VisEquipment, GameObject>("m_rightItemInstance");
			LeftItemInstance = Get<VisEquipment, GameObject>("m_leftItemInstance");
		}

		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;
			}
		}
	}
	internal static class Specials
	{
		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 && StyleItems.StyleOf(((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 string __state)
		{
			__state = null;
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			ItemData currentWeapon = __instance.GetCurrentWeapon();
			Style? style = StyleItems.StyleOf(currentWeapon);
			if (!style.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 = val2.m_attackAnimation;
			val2.m_attackAnimation = Styles.SpecialTrigger(style.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, bool secondaryAttack, string __state)
		{
			if (__state != null)
			{
				Attack val = __instance.GetCurrentWeapon()?.m_shared?.m_secondaryAttack;
				if (val != null)
				{
					val.m_attackAnimation = __state;
				}
			}
		}

		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);
			Style? style = StyleItems.StyleOf(__instance.GetCurrentWeapon());
			if (val == null || !style.HasValue)
			{
				return;
			}
			Move move = MoveOf(val, style.Value, secondaryAttack);
			if (move != Move.None)
			{
				val.m_damageMultiplier = Styles.HitDamage(style.Value, move, 0);
				val.m_staggerMultiplier = Styles.Stagger(style.Value, move);
				val.m_lastChainDamageMultiplier = 1f;
				MultiHit.Start(val, style.Value, move);
				float num = Styles.Stamina(style.Value, move);
				if (num > 0f)
				{
					val.m_attackStamina = num;
				}
			}
		}

		private static Move MoveOf(Attack a, Style style, bool secondary)
		{
			if (secondary)
			{
				if (!Styles.ParseTrigger(a.m_attackAnimation, out var style2, out var move) || style2 != style)
				{
					return Move.None;
				}
				return move;
			}
			if (a.m_attackAnimation != Styles.AttackName(style))
			{
				return Move.None;
			}
			int num = ((Refs.ChainLevel != null) ? Refs.ChainLevel.Invoke(a) : 0);
			return (Move)(1 + Mathf.Clamp(num, 0, 2));
		}
	}
	internal static class StyleItems
	{
		internal static readonly HashSet<Style> Active = new HashSet<Style>
		{
			Style.Bear,
			Style.Wolf,
			Style.Brawler
		};

		private static readonly Dictionary<SharedData, Style> styled = new Dictionary<SharedData, Style>();

		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;
			}
			Dictionary<Style, int> dictionary = new Dictionary<Style, int>();
			foreach (GameObject item in db.m_items)
			{
				if (!((Object)(object)item == (Object)null))
				{
					SharedData val = item.GetComponent<ItemDrop>()?.m_itemData?.m_shared;
					if (Apply(((Object)item).name, val))
					{
						dictionary.TryGetValue(styled[val], out var value);
						dictionary[styled[val]] = value + 1;
					}
				}
			}
			foreach (KeyValuePair<Style, int> item2 in dictionary)
			{
				Plugin.Log.LogInfo((object)$"{item2.Key} style on {item2.Value} items.");
			}
		}

		internal static Style? StyleOf(ItemData item)
		{
			SharedData val = item?.m_shared;
			if (val == null)
			{
				return null;
			}
			if (styled.TryGetValue(val, out var value))
			{
				return value;
			}
			if (!((Object)(object)item.m_dropPrefab != (Object)null) || !Apply(((Object)item.m_dropPrefab).name, val))
			{
				return null;
			}
			return styled[val];
		}

		private static bool Apply(string prefab, SharedData s)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			if (s == null || s.m_attack == null)
			{
				return false;
			}
			Style? style = Styles.OfPrefab(prefab);
			if (!style.HasValue || !Active.Contains(style.Value))
			{
				return false;
			}
			if (styled.ContainsKey(s))
			{
				return true;
			}
			Attack attack = s.m_attack;
			attack.m_attackAnimation = Styles.AttackName(style.Value);
			attack.m_attackChainLevels = 3;
			attack.m_resetChainIfHit = (DestructibleType)0;
			styled[s] = style.Value;
			return true;
		}
	}
	public enum Style
	{
		Bear,
		Brawler,
		Wolf
	}
	public static class Styles
	{
		public static readonly string[] Prefabs = new string[6] { "FistBjornClaw", "FistBjornUndeadClaw", "FistFenrirClaw", "FistGold", "FistGold_BloodLightning", "FistGold_FrostFire" };

		private static readonly string[,] Hosts = new string[9, 2]
		{
			{ "greatsword0", "Greatsword BaseAttack (1)" },
			{ "greatsword1", "Greatsword BaseAttack (2)" },
			{ "greatsword2", "Greatsword BaseAttack (3)" },
			{ "axe_secondary", "Axe Secondary Attack" },
			{ "mace_secondary", "MaceAltAttack" },
			{ "dualaxes_secondary", "DualAxes Attack Cleave" },
			{ "battleaxe_attack0", "BattleAxe1" },
			{ "battleaxe_attack1", "BattleAxe2" },
			{ "battleaxe_attack2", "BattleAxe_Combo3" }
		};

		private static readonly float[] BrawlerDamage = new float[9] { 0.675f, 0.7f, 0.75f, 0.75f, 0.75f, 0.775f, 0.75f, 0.75f, 0.8f };

		public const float LastChainBonus = 1f;

		public static Style? OfPrefab(string prefabName)
		{
			switch (prefabName)
			{
			case "FistBjornClaw":
			case "FistBjornUndeadClaw":
				return Style.Bear;
			case "FistFenrirClaw":
				return Style.Wolf;
			case "FistGold":
			case "FistGold_BloodLightning":
			case "FistGold_FrostFire":
				return Style.Brawler;
			default:
				return null;
			}
		}

		public static string AttackName(Style s)
		{
			return "brawl_" + s.ToString().ToLowerInvariant();
		}

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

		public static bool ParseTrigger(string trigger, out Style style, out Move move)
		{
			style = Style.Bear;
			move = Move.None;
			if (trigger == null || !trigger.StartsWith("brawl_", StringComparison.Ordinal))
			{
				return false;
			}
			Style[] array = (Style[])Enum.GetValues(typeof(Style));
			int num = 0;
			while (num < array.Length)
			{
				Style style2 = array[num];
				string text = AttackName(style2);
				string text2;
				if (trigger.StartsWith(text, StringComparison.Ordinal))
				{
					text2 = trigger.Substring(text.Length);
					if (text2 == null)
					{
						goto IL_014c;
					}
					int length = text2.Length;
					if (length != 1)
					{
						if (length != 3)
						{
							goto IL_014c;
						}
						switch (text2[2])
						{
						case '1':
							break;
						case '2':
							goto IL_00e2;
						case '3':
							goto IL_0100;
						default:
							goto IL_014c;
						}
						if (!(text2 == "_s1"))
						{
							if (!(text2 == "_h1"))
							{
								goto IL_014c;
							}
							move = Move.H1;
						}
						else
						{
							move = Move.S1;
						}
					}
					else
					{
						switch (text2[0])
						{
						case '0':
							break;
						case '1':
							goto IL_0123;
						case '2':
							goto IL_0128;
						default:
							goto IL_014c;
						}
						move = Move.L1;
					}
					goto IL_014e;
				}
				num++;
				continue;
				IL_014c:
				return false;
				IL_0123:
				move = Move.L2;
				goto IL_014e;
				IL_00e2:
				if (!(text2 == "_s2"))
				{
					if (!(text2 == "_h2"))
					{
						goto IL_014c;
					}
					move = Move.H2;
				}
				else
				{
					move = Move.S2;
				}
				goto IL_014e;
				IL_0128:
				move = Move.L3;
				goto IL_014e;
				IL_014e:
				style = style2;
				return true;
				IL_0100:
				if (!(text2 == "_s3"))
				{
					if (!(text2 == "_h3"))
					{
						goto IL_014c;
					}
					move = Move.H3;
				}
				else
				{
					move = Move.S3;
				}
				goto IL_014e;
			}
			return false;
		}

		public static string ClipName(Style s, Move m)
		{
			return ClipStyle(s, m).ToString() + m;
		}

		public static Style ClipStyle(Style s, Move m)
		{
			return s;
		}

		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 float Damage(Style s, Move m)
		{
			switch (s)
			{
			case Style.Brawler:
				return BrawlerDamage[(int)(m - 1)];
			case Style.Wolf:
				if (m > Move.L3)
				{
					if (m < Move.H1)
					{
						return 1.8f;
					}
					return 1.5f;
				}
				return 1.2f;
			default:
				if (m >= Move.L1 && m <= Move.L3)
				{
					return 2f;
				}
				if (m >= Move.H1)
				{
					return 2.5f;
				}
				return 3f;
			}
		}

		public static bool ClosesFists(Style? s)
		{
			return s.HasValue;
		}

		public static float Stagger(Style s, Move m)
		{
			if (ClipStyle(s, m) != Style.Bear || m != Move.H3)
			{
				return 1f;
			}
			return 3f;
		}

		public static float[] HitShares(Style s, Move m)
		{
			if (s == Style.Wolf && (m == Move.S1 || m == Move.H2 || m == Move.S2))
			{
				return new float[2] { 0.5f, 0.5f };
			}
			return new float[1] { 1f };
		}

		public static float HitDamage(Style s, Move m, int hit)
		{
			float[] array = HitShares(s, m);
			if (array.Length == 0)
			{
				return 0f;
			}
			return Damage(s, m) * array[Math.Min(Math.Max(hit, 0), array.Length - 1)];
		}

		public static float Stamina(Style s, Move m)
		{
			if (s == Style.Wolf)
			{
				switch (m)
				{
				case Move.S1:
				case Move.S2:
				case Move.S3:
					return 18f;
				case Move.H1:
				case Move.H2:
				case Move.H3:
					return 22f;
				default:
					return 0f;
				}
			}
			switch (m)
			{
			case Move.S1:
			case Move.S2:
			case Move.S3:
				return 20f;
			case Move.H1:
			case Move.H2:
			case Move.H3:
				return 25f;
			default:
				return 0f;
			}
		}
	}
	internal static class Triggers
	{
		internal const string Ignored = "brawl_dup_ignored";

		internal static void Prefix(ZSyncAnimation __instance, ref string name)
		{
			if (name == null || name.StartsWith("brawl_dup_ignored", StringComparison.Ordinal) || !Styles.ParseTrigger(name, out var style, out var move))
			{
				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 = "brawl_dup_ignored";
				return;
			}
			comboState.LastTrigger = name;
			comboState.LastTriggerAt = Time.time;
			comboState.Begin(style, move);
			Animator val = ((Refs.AnimatorOf != null) ? Refs.AnimatorOf.Invoke(__instance) : null);
			if ((Object)(object)val != (Object)null)
			{
				ClipSets.Apply(val, style);
			}
			name = Styles.HostTrigger(move);
		}
	}
	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 static class WolfMath
	{
		public const float PassableRadius = 1.2f;

		public static float AirTime(float height, float gravity)
		{
			if (height <= 0f || gravity <= 0f)
			{
				return 0f;
			}
			return 2f * (float)Math.Sqrt(2f * height / gravity);
		}

		public static (float vForward, float vSide, float vUp) Launch(float forward, float side, float height, float gravity)
		{
			float num = Math.Max(0.1f, gravity);
			float item = ((height > 0f) ? ((float)Math.Sqrt(2f * num * height)) : 0f);
			float num2 = AirTime(height, num);
			if (!(num2 > 0.01f))
			{
				return (vForward: 0f, vSide: 0f, vUp: item);
			}
			return (vForward: forward / num2, vSide: side / num2, vUp: item);
		}

		public static float DashDistance(float targetDistance, float targetRadius, bool hasTarget)
		{
			if (!hasTarget)
			{
				return 2.8f;
			}
			if (targetRadius > 1.2f)
			{
				return Math.Max(0f, targetDistance - targetRadius - 0.8f);
			}
			return Math.Min(4.5f, targetDistance + targetRadius + 1f);
		}

		public static bool ShouldLaunch(bool isOwner, bool onGround)
		{
			return isOwner && onGround;
		}

		public static bool TurnsAfterDash(bool hasTarget, float targetRadius)
		{
			if (hasTarget)
			{
				return targetRadius <= 1.2f;
			}
			return false;
		}

		public static float ReturnDistance(float targetDistance, float targetRadius, float max)
		{
			return Math.Max(0f, Math.Min(max, targetDistance - targetRadius - 0.5f));
		}

		public static float GlowAlpha(float elapsed, float duration, float peak)
		{
			if (duration <= 0f || elapsed <= 0f || elapsed >= duration)
			{
				return 0f;
			}
			float num = elapsed / duration;
			float num2 = Math.Min(1f, num / 0.15f);
			float num3 = Math.Max(0f, (num - 0.6f) / 0.4f);
			return peak * num2 * num2 * (3f - 2f * num2) * (1f - num3 * num3 * (3f - 2f * num3));
		}

		public static float PivotFraction(float elapsed, float duration)
		{
			if (duration <= 0f)
			{
				return 1f;
			}
			float num = Math.Max(0f, Math.Min(1f, elapsed / duration));
			return num * num * (3f - 2f * num);
		}
	}
	internal class WolfMotion : MonoBehaviour
	{
		private Character owner;

		private Character dashTarget;

		private Character turnTarget;

		private Character Owner
		{
			get
			{
				if (!((Object)(object)owner != (Object)null))
				{
					return owner = ((Component)this).GetComponentInParent<Character>();
				}
				return owner;
			}
		}

		private static float Gravity => Mathf.Max(0.1f, 0f - Physics.gravity.y);

		internal static void PlayerAwakePostfix(Player __instance)
		{
			Animator val = (((Object)(object)__instance != (Object)null) ? ((Component)__instance).GetComponentInChildren<Animator>() : null);
			if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).GetComponent<WolfMotion>() == (Object)null)
			{
				((Component)val).gameObject.AddComponent<WolfMotion>();
			}
		}

		public void BrawlLeap(string args)
		{
			if (CanLaunch(out var c) && Parse(args, 3, out var a))
			{
				Launch(c, a[0], a[1], a[2]);
			}
		}

		public void BrawlDash(string args)
		{
			//IL_0064: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			if (CanLaunch(out var c) && Parse(args, 2, out var a))
			{
				dashTarget = FindTarget(c, 3.5f, 50f);
				bool flag = (Object)(object)dashTarget != (Object)null;
				float targetRadius = (flag ? dashTarget.GetRadius() : 0f);
				float targetDistance;
				if (!flag)
				{
					targetDistance = 0f;
				}
				else
				{
					Vector3 val = Flat(((Component)dashTarget).transform.position - ((Component)c).transform.position);
					targetDistance = ((Vector3)(ref val)).magnitude;
				}
				float num = WolfMath.DashDistance(targetDistance, targetRadius, flag);
				if (flag && WolfMath.TurnsAfterDash(hasTarget: true, targetRadius))
				{
					((MonoBehaviour)this).StartCoroutine(IgnoreCollisions(c, dashTarget, WolfMath.AirTime(a[1], Gravity) + 0.3f));
				}
				float result = 0f;
				string[] array = args.Split(',');
				if (array.Length > 2)
				{
					float.TryParse(array[2], NumberStyles.Float, CultureInfo.InvariantCulture, out result);
				}
				Launch(c, Mathf.Min(num, a[0]), result, a[1]);
			}
		}

		public void BrawlTurn(string args)
		{
			Character val = Owner;
			Character val2 = dashTarget;
			dashTarget = null;
			turnTarget = null;
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || val2.IsDead() || !WolfMath.TurnsAfterDash(hasTarget: true, val2.GetRadius()))
			{
				return;
			}
			ZNetView component = ((Component)val).GetComponent<ZNetView>();
			if (!((Object)(object)component == (Object)null) && component.IsValid() && component.IsOwner())
			{
				turnTarget = val2;
				float result = 0f;
				if (!string.IsNullOrEmpty(args))
				{
					float.TryParse(args, NumberStyles.Float, CultureInfo.InvariantCulture, out result);
				}
				((MonoBehaviour)this).StartCoroutine(Pivot(val, val2, result));
			}
		}

		public void BrawlReturn(string args)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			Character val = turnTarget;
			turnTarget = null;
			if (!((Object)(object)val == (Object)null) && !val.IsDead() && CanLaunch(out var c) && Parse(args, 2, out var a))
			{
				Vector3 val2 = Flat(((Component)val).transform.position - ((Component)c).transform.position);
				float num = WolfMath.ReturnDistance(((Vector3)(ref val2)).magnitude, val.GetRadius(), a[0]);
				if (num > 0.05f)
				{
					Launch(c, num, 0f, a[1]);
				}
			}
		}

		public void BrawlClawGlow(string args)
		{
			Character val = Owner;
			if (!((Object)(object)val == (Object)null) && !val.IsDead())
			{
				float result = 1f;
				if (!string.IsNullOrEmpty(args))
				{
					float.TryParse(args, NumberStyles.Float, CultureInfo.InvariantCulture, out result);
				}
				((MonoBehaviour)this).StartCoroutine(ClawGlow.Run(val, result));
			}
		}

		private static IEnumerator Pivot(Character c, Character t, float seconds)
		{
			Quaternion from = ((Component)c).transform.rotation;
			float el = 0f;
			while (!((Object)(object)c == (Object)null) && !((Object)(object)t == (Object)null) && !c.IsDead() && !t.IsDead())
			{
				Vector3 val = Flat(((Component)t).transform.position - ((Component)c).transform.position);
				if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
				{
					break;
				}
				Quaternion val2 = Quaternion.Slerp(from, Quaternion.LookRotation(((Vector3)(ref val)).normalized), WolfMath.PivotFraction(el, seconds));
				((Component)c).transform.rotation = val2;
				c.SetLookDir(val2 * Vector3.forward, 0f);
				Player val3 = (Player)(object)((c is Player) ? c : null);
				if (val3 != null && Refs.LookYaw != null)
				{
					Refs.LookYaw.Invoke(val3) = val2;
				}
				if (el >= seconds)
				{
					break;
				}
				yield return null;
				el += Time.deltaTime;
			}
		}

		private bool CanLaunch(out Character c)
		{
			c = Owner;
			if ((Object)(object)c == (Object)null || c.IsDead())
			{
				return false;
			}
			ZNetView component = ((Component)c).GetComponent<ZNetView>();
			return WolfMath.ShouldLaunch((Object)(object)component != (Object)null && component.IsValid() && component.IsOwner(), c.IsOnGround());
		}

		private static void Launch(Character c, float forward, float side, float height)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Flat(((Component)c).transform.forward);
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			Vector3 val2 = Vector3.Cross(Vector3.up, normalized);
			var (num, num2, num3) = WolfMath.Launch(forward, side, height, Gravity);
			c.ForceJump(normalized * num + val2 * num2 + Vector3.up * num3, false);
		}

		private static Character FindTarget(Character c, float range, float halfAngle)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			Character result = null;
			float num = float.MaxValue;
			Vector3 val = Flat(((Component)c).transform.forward);
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				if (!((Object)(object)allCharacter == (Object)null) && !((Object)(object)allCharacter == (Object)(object)c) && !allCharacter.IsDead() && !allCharacter.IsPlayer() && !allCharacter.IsTamed())
				{
					Vector3 val2 = Flat(((Component)allCharacter).transform.position - ((Component)c).transform.position);
					float magnitude = ((Vector3)(ref val2)).magnitude;
					if (!(magnitude > range + allCharacter.GetRadius()) && !(magnitude < 0.01f) && !(Vector3.Angle(normalized, val2) > halfAngle) && magnitude < num)
					{
						num = magnitude;
						result = allCharacter;
					}
				}
			}
			return result;
		}

		private static IEnumerator IgnoreCollisions(Character c, Character t, float seconds)
		{
			Collider[] mine = ((Component)c).GetComponentsInChildren<Collider>();
			Collider[] theirs = ((Component)t).GetComponentsInChildren<Collider>();
			SetIgnore(mine, theirs, ignore: true);
			yield return (object)new WaitForSeconds(seconds);
			SetIgnore(mine, theirs, ignore: false);
		}

		private static void SetIgnore(Collider[] a, Collider[] b, bool ignore)
		{
			foreach (Collider val in a)
			{
				foreach (Collider val2 in b)
				{
					if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null)
					{
						Physics.IgnoreCollision(val, val2, ignore);
					}
				}
			}
		}

		private static Vector3 Flat(Vector3 v)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			v.y = 0f;
			return v;
		}

		private static bool Parse(string args, int n, out float[] a)
		{
			a = new float[n];
			string[] array = (args ?? "").Split(',');
			if (array.Length < n)
			{
				return false;
			}
			for (int i = 0; i < n; i++)
			{
				if (!float.TryParse(array[i], NumberStyles.Float, CultureInfo.InvariantCulture, out a[i]))
				{
					return false;
				}
			}
			return true;
		}
	}
}