Decompiled source of ShieldBash v1.0.1

ShieldBash.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Utils;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.Playables;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace ShieldBash;

internal static class Bash
{
	private static bool _broken;

	private static bool _active;

	private static bool _hitDone;

	private static float _t;

	private static float _duration;

	private static float _lastStart = -999f;

	private const float SuppressTime = 0.5f;

	private static float RangeNow => Plugin.Range.Value;

	private static float AngleNow => Plugin.HalfAngle.Value;

	public static bool Active => _active;

	public static float Elapsed => _t;

	public static float Duration => _duration;

	public static void Tick(Player p)
	{
		if (_broken || !Plugin.Enabled.Value)
		{
			return;
		}
		try
		{
			float deltaTime = Time.deltaTime;
			if (!_active)
			{
				TryStart(p);
			}
			if (_active)
			{
				_t += deltaTime;
				if (!_hitDone && _t >= Plugin.HitTime.Value)
				{
					_hitDone = true;
					DoHit(p);
				}
				if (_t >= _duration)
				{
					_active = false;
				}
			}
		}
		catch (Exception ex)
		{
			_broken = true;
			Logger.LogError((object)("[ShieldBash] Error, shield bash disabled for this session: " + ex));
			Shutdown();
		}
	}

	private static void TryStart(Player p)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		if (Input.GetKeyDown(Plugin.BashKey.Value) && CanStart(p))
		{
			Begin(p);
		}
	}

	private static bool CanStart(Player p)
	{
		if (Time.time - _lastStart < Plugin.Cooldown.Value)
		{
			return false;
		}
		if (((Character)p).IsDead() || !Safe.Bool(p, "TakeInput", fallback: true) || !Safe.Bool(p, "IsBlocking", fallback: false))
		{
			return false;
		}
		if (Safe.Bool(p, "InAttack", fallback: false) || Safe.Bool(p, "InDodge", fallback: false) || Safe.Bool(p, "IsStaggering", fallback: false) || Safe.Bool(p, "IsKnockedBack", fallback: false))
		{
			return false;
		}
		if (Shield(p) == null)
		{
			return false;
		}
		return Safe.Get(p, "HaveStamina", true, Plugin.StaminaCost.Value);
	}

	public static bool BlockVanillaAttack(Humanoid h, bool secondary)
	{
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Invalid comparison between Unknown and I4
		if (_broken || !Plugin.Enabled.Value)
		{
			return false;
		}
		Player val = (Player)(object)((h is Player) ? h : null);
		if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer || secondary)
		{
			return false;
		}
		if ((int)Plugin.BashKey.Value != 323)
		{
			return false;
		}
		try
		{
			if (Time.time - _lastStart < 0.5f)
			{
				return true;
			}
			if (CanStart(val))
			{
				Begin(val);
				return true;
			}
		}
		catch (Exception ex)
		{
			_broken = true;
			Logger.LogError((object)("[ShieldBash] Error, shield bash disabled for this session: " + ex));
			Shutdown();
		}
		return false;
	}

	private static void Begin(Player p)
	{
		Safe.Call(p, "UseStamina", Plugin.StaminaCost.Value);
		_active = true;
		_hitDone = false;
		_t = 0f;
		_lastStart = Time.time;
		_duration = Mathf.Max(Plugin.HitTime.Value + 0.2f, Plugin.CodeDuration.Value);
	}

	private static ItemData Shield(Player p)
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Invalid comparison between Unknown and I4
		ItemData val = Safe.Field<ItemData>(p, "m_leftItem", null);
		if (val == null || val.m_shared == null || (int)val.m_shared.m_itemType != 5)
		{
			return null;
		}
		return val;
	}

	private static bool IsEnemy(Player p, Character c)
	{
		bool fallback = !c.IsPlayer() && !c.IsTamed();
		return Safe.Static(typeof(BaseAI), "IsEnemy", fallback, p, c);
	}

	private static void DoHit(Player p)
	{
		//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_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: 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_0194: 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_01e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f3: 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_0202: Unknown result type (might be due to invalid IL or missing references)
		//IL_0207: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		Vector3 forward = ((Component)p).transform.forward;
		forward.y = 0f;
		if (((Vector3)(ref forward)).sqrMagnitude < 0.0001f)
		{
			forward = Vector3.forward;
		}
		((Vector3)(ref forward)).Normalize();
		Vector3 position = ((Component)p).transform.position;
		List<KeyValuePair<float, Character>> list = new List<KeyValuePair<float, Character>>();
		foreach (Character allCharacter in Character.GetAllCharacters())
		{
			if (!((Object)(object)allCharacter == (Object)null) && !((Object)(object)allCharacter == (Object)(object)p) && !allCharacter.IsDead() && IsEnemy(p, allCharacter))
			{
				Vector3 val = ((Component)allCharacter).transform.position - position;
				val.y = 0f;
				float magnitude = ((Vector3)(ref val)).magnitude;
				if (!(magnitude > RangeNow + Safe.Get(allCharacter, "GetRadius", 0.5f)) && (!(magnitude > 0.05f) || !(Vector3.Angle(forward, val) > AngleNow)) && !(Mathf.Abs(((Component)allCharacter).transform.position.y - position.y) > 2.5f))
				{
					list.Add(new KeyValuePair<float, Character>(magnitude, allCharacter));
				}
			}
		}
		list.Sort((KeyValuePair<float, Character> a, KeyValuePair<float, Character> b) => a.Key.CompareTo(b.Key));
		int num = Mathf.Min(list.Count, Plugin.MaxTargets.Value);
		for (int num2 = 0; num2 < num; num2++)
		{
			Push(p, list[num2].Value, forward);
		}
		if (num > 0 && Plugin.SkillGain.Value > 0f)
		{
			Safe.Call(p, "RaiseSkill", (object)(SkillType)6, Plugin.SkillGain.Value);
		}
		PlayEffect(p, position + forward * 1f + Vector3.up * 1.2f);
		if (Plugin.DebugLog.Value)
		{
			Logger.LogInfo((object)("[ShieldBash] Bash: blunt " + BluntDamage(p).ToString("0.#") + ", knockback x" + PushMultiplier(p).ToString("0.00") + " (Blocking skill " + (BlockSkill(p) * 100f).ToString("0") + "), " + num + " targets" + ((num > 0) ? (" (" + string.Join(", ", NamesOf(list, num)) + ")") : "")));
		}
	}

	private static IEnumerable<string> NamesOf(List<KeyValuePair<float, Character>> l, int n)
	{
		for (int i = 0; i < n; i++)
		{
			yield return l[i].Value.m_name + " " + l[i].Key.ToString("0.0") + "m";
		}
	}

	private static void Push(Player p, Character c, Vector3 fwd)
	{
		//IL_0006: 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_001b: 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_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Expected O, but got Unknown
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: 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_00af: 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_00ee: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = ((Component)c).transform.position - ((Component)p).transform.position;
		val.y = 0f;
		val = ((((Vector3)(ref val)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref val)).normalized : fwd);
		bool flag = Safe.Bool(c, "IsBoss", fallback: false);
		HitData val2 = new HitData();
		val2.m_dir = val;
		val2.m_point = Safe.Get<Vector3>(c, "GetCenterPoint", ((Component)c).transform.position + Vector3.up, Array.Empty<object>());
		val2.m_pushForce = Plugin.PushForce.Value * PushMultiplier(p) * (flag ? 0.3f : 1f);
		val2.m_attacker = ((Character)p).GetZDOID();
		val2.m_damage.m_blunt = BluntDamage(p);
		c.Damage(val2);
		if (Plugin.Stagger.Value && !flag)
		{
			Safe.Call(c, "Stagger", val);
			StaggerShortener.Attach(c, Plugin.StaggerRatio.Value);
		}
	}

	public static float BluntDamage(Player p)
	{
		float num = Shield(p)?.m_shared.m_blockPower ?? 0f;
		return Mathf.Max(Plugin.BluntMin.Value, num * Plugin.BluntRatio.Value) * (1f + BlockSkill(p) * Plugin.SkillDamage.Value);
	}

	public static float BlockSkill(Player p)
	{
		return Mathf.Clamp01(Safe.Get(p, "GetSkillFactor", 0f, (object)(SkillType)6));
	}

	public static float PushMultiplier(Player p)
	{
		return 1f + BlockSkill(p) * Plugin.SkillPush.Value;
	}

	private static void PlayEffect(Player p, Vector3 pos)
	{
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: 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)
		try
		{
			ItemData val = Shield(p);
			if (val != null)
			{
				FieldInfo fieldInfo = AccessTools.Field(typeof(SharedData), "m_blockEffect");
				EffectList val2 = (EffectList)((fieldInfo != null) ? /*isinst with value type is only supported in some contexts*/: null);
				if (val2 != null)
				{
					val2.Create(pos, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
				}
			}
		}
		catch
		{
		}
	}

	public static void Shutdown()
	{
		_active = false;
	}
}
[HarmonyPatch(typeof(Humanoid), "StartAttack")]
internal static class StartAttackPatch
{
	private static bool Prefix(Humanoid __instance, bool secondaryAttack, ref bool __result)
	{
		if (!Bash.BlockVanillaAttack(__instance, secondaryAttack))
		{
			return true;
		}
		__result = false;
		return false;
	}
}
[HarmonyPatch(typeof(Player), "Update")]
internal static class PlayerUpdatePatch
{
	private static void Postfix(Player __instance)
	{
		if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
		{
			Bash.Tick(__instance);
		}
	}
}
internal sealed class ClipLibrary
{
	private readonly string _bundleName;

	private bool _tried;

	private AssetBundle _bundle;

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

	public ClipLibrary(string bundleName)
	{
		_bundleName = bundleName;
	}

	public AnimationClip Get(string name)
	{
		Load();
		if (string.IsNullOrEmpty(name))
		{
			return null;
		}
		if (!_clips.TryGetValue(name.Trim().ToLowerInvariant(), out var value))
		{
			return null;
		}
		return value;
	}

	private void Load()
	{
		if (_tried)
		{
			return;
		}
		_tried = true;
		try
		{
			_bundle = AssetUtils.LoadAssetBundleFromResources(_bundleName, typeof(ClipLibrary).Assembly);
			if ((Object)(object)_bundle == (Object)null)
			{
				Logger.LogInfo((object)("[ShieldBash] Animasyon paketi yok (" + _bundleName + "): animasyonsuz çalışır"));
				return;
			}
			List<string> list = new List<string>();
			AnimationClip[] array = _bundle.LoadAllAssets<AnimationClip>();
			foreach (AnimationClip val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					_clips[((Object)val).name.ToLowerInvariant()] = val;
					list.Add(((Object)val).name + " (" + val.length.ToString("0.00") + " sn" + (((Motion)val).isLooping ? ", döngü" : "") + (((Motion)val).isHumanMotion ? ", insansı" : ", İNSANSI DEĞİL") + ")");
				}
			}
			Logger.LogInfo((object)("[ShieldBash] Animasyon paketi açıldı: " + ((list.Count > 0) ? string.Join(", ", list) : "klip yok")));
		}
		catch (Exception ex)
		{
			Logger.LogWarning((object)("[ShieldBash] Animasyon paketi açılamadı: " + ex.Message));
		}
	}
}
internal enum ClipMask
{
	None,
	UpperBody,
	LowerBody
}
internal sealed class ClipPlayer
{
	private PlayableGraph _graph;

	private AnimationClipPlayable _clip;

	private AnimationPlayableOutput _output;

	private AvatarMask _mask;

	private float _weight;

	public float Weight => _weight;

	public bool Valid => ((PlayableGraph)(ref _graph)).IsValid();

	public float Length { get; private set; }

	public double Time
	{
		get
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (!((PlayableGraph)(ref _graph)).IsValid())
			{
				return 0.0;
			}
			return PlayableExtensions.GetTime<AnimationClipPlayable>(_clip);
		}
	}

	public static ClipPlayer Create(Animator animator, AnimationClip clip, string name, ClipMask mask = ClipMask.None)
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_009f: 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_00b2: 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_00c0: 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_00e0: 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_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)animator == (Object)null || (Object)(object)clip == (Object)null)
		{
			return null;
		}
		ClipPlayer clipPlayer = new ClipPlayer
		{
			Length = clip.length
		};
		clipPlayer._graph = PlayableGraph.Create("ShieldBash_" + name);
		((PlayableGraph)(ref clipPlayer._graph)).SetTimeUpdateMode((DirectorUpdateMode)1);
		clipPlayer._clip = AnimationClipPlayable.Create(clipPlayer._graph, clip);
		((AnimationClipPlayable)(ref clipPlayer._clip)).SetApplyFootIK(true);
		clipPlayer._output = AnimationPlayableOutput.Create(clipPlayer._graph, name, animator);
		if (mask == ClipMask.None)
		{
			PlayableOutputExtensions.SetSourcePlayable<AnimationPlayableOutput, AnimationClipPlayable>(clipPlayer._output, clipPlayer._clip);
		}
		else
		{
			clipPlayer._mask = MakeMask(mask == ClipMask.UpperBody);
			AnimationLayerMixerPlayable val = AnimationLayerMixerPlayable.Create(clipPlayer._graph, 1);
			((PlayableGraph)(ref clipPlayer._graph)).Connect<AnimationClipPlayable, AnimationLayerMixerPlayable>(clipPlayer._clip, 0, val, 0);
			PlayableExtensions.SetInputWeight<AnimationLayerMixerPlayable>(val, 0, 1f);
			((AnimationLayerMixerPlayable)(ref val)).SetLayerMaskFromAvatarMask(0u, clipPlayer._mask);
			PlayableOutputExtensions.SetSourcePlayable<AnimationPlayableOutput, AnimationLayerMixerPlayable>(clipPlayer._output, val);
		}
		PlayableOutputExtensions.SetWeight<AnimationPlayableOutput>(clipPlayer._output, 0f);
		((PlayableGraph)(ref clipPlayer._graph)).Play();
		return clipPlayer;
	}

	private static AvatarMask MakeMask(bool upper)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Expected O, but got Unknown
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Invalid comparison between Unknown and I4
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Invalid comparison between Unknown and I4
		//IL_0037: 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_0019: Invalid comparison between Unknown and I4
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Invalid comparison between Unknown and I4
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Invalid comparison between Unknown and I4
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Invalid comparison between Unknown and I4
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Invalid comparison between Unknown and I4
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Invalid comparison between Unknown and I4
		AvatarMask val = new AvatarMask();
		int num = 13;
		for (int i = 0; i < num; i++)
		{
			AvatarMaskBodyPart val2 = (AvatarMaskBodyPart)i;
			bool flag = (int)val2 == 1 || (int)val2 == 2 || (int)val2 == 5 || (int)val2 == 6 || (int)val2 == 7 || (int)val2 == 8 || (int)val2 == 11 || (int)val2 == 12;
			val.SetHumanoidBodyPartActive(val2, upper ? flag : (!flag));
		}
		return val;
	}

	public void Restart()
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		if (((PlayableGraph)(ref _graph)).IsValid())
		{
			PlayableExtensions.SetTime<AnimationClipPlayable>(_clip, 0.0);
			PlayableExtensions.SetDone<AnimationClipPlayable>(_clip, false);
			PlayableExtensions.Play<AnimationClipPlayable>(_clip);
		}
	}

	public void Tick(float target, float fade, float speed, float dt)
	{
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		if (((PlayableGraph)(ref _graph)).IsValid())
		{
			_weight = Mathf.MoveTowards(_weight, Mathf.Clamp01(target), (fade > 0.001f) ? (dt / fade) : 1f);
			PlayableOutputExtensions.SetWeight<AnimationPlayableOutput>(_output, _weight);
			PlayableExtensions.SetSpeed<AnimationClipPlayable>(_clip, (double)speed);
		}
	}

	public void Destroy()
	{
		if (((PlayableGraph)(ref _graph)).IsValid())
		{
			((PlayableGraph)(ref _graph)).Destroy();
		}
		if ((Object)(object)_mask != (Object)null)
		{
			Object.Destroy((Object)(object)_mask);
		}
		_weight = 0f;
	}
}
[BepInPlugin("crecodev.ShieldBash", "ShieldBash", "1.0.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
	public const string PluginGUID = "crecodev.ShieldBash";

	public const string PluginName = "ShieldBash";

	public const string PluginVersion = "1.0.1";

	public static ConfigEntry<bool> Enabled;

	public static ConfigEntry<KeyCode> BashKey;

	public static ConfigEntry<float> StaminaCost;

	public static ConfigEntry<float> Cooldown;

	public static ConfigEntry<float> Range;

	public static ConfigEntry<float> HalfAngle;

	public static ConfigEntry<float> PushForce;

	public static ConfigEntry<bool> Stagger;

	public static ConfigEntry<float> StaggerRatio;

	public static ConfigEntry<float> BluntRatio;

	public static ConfigEntry<float> BluntMin;

	public static ConfigEntry<float> SkillDamage;

	public static ConfigEntry<float> SkillPush;

	public static ConfigEntry<float> SkillGain;

	public static ConfigEntry<int> MaxTargets;

	public static ConfigEntry<float> HitTime;

	public static ConfigEntry<float> CodeDuration;

	public static ConfigEntry<float> ThrustDist;

	public static ConfigEntry<float> BodyTwist;

	public static ConfigEntry<float> UpperHeight;

	public static ConfigEntry<float> UpperLow;

	public static ConfigEntry<float> UpperCross;

	public static ConfigEntry<float> SweepLeft;

	public static ConfigEntry<bool> DebugLog;

	private Harmony _harmony;

	private void Awake()
	{
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Expected O, but got Unknown
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Expected O, but got Unknown
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Expected O, but got Unknown
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Expected O, but got Unknown
		//IL_0166: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Expected O, but got Unknown
		//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cd: Expected O, but got Unknown
		//IL_0200: Unknown result type (might be due to invalid IL or missing references)
		//IL_020a: Expected O, but got Unknown
		//IL_023d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0247: Expected O, but got Unknown
		//IL_027a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0284: Expected O, but got Unknown
		//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c1: Expected O, but got Unknown
		//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fe: Expected O, but got Unknown
		//IL_0325: Unknown result type (might be due to invalid IL or missing references)
		//IL_032f: Expected O, but got Unknown
		//IL_0362: Unknown result type (might be due to invalid IL or missing references)
		//IL_036c: Expected O, but got Unknown
		//IL_039f: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a9: Expected O, but got Unknown
		//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e6: Expected O, but got Unknown
		//IL_0419: Unknown result type (might be due to invalid IL or missing references)
		//IL_0423: Expected O, but got Unknown
		//IL_0456: Unknown result type (might be due to invalid IL or missing references)
		//IL_0460: Expected O, but got Unknown
		//IL_0493: Unknown result type (might be due to invalid IL or missing references)
		//IL_049d: Expected O, but got Unknown
		//IL_04d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_04da: Expected O, but got Unknown
		//IL_050d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0517: Expected O, but got Unknown
		//IL_0554: Unknown result type (might be due to invalid IL or missing references)
		//IL_055e: Expected O, but got Unknown
		//IL_0573: Unknown result type (might be due to invalid IL or missing references)
		//IL_0578: Unknown result type (might be due to invalid IL or missing references)
		Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Turns the shield bash on or off.");
		BashKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "BashKey", (KeyCode)323, "While blocking with a shield, press this key to bash. Default: Left Click.");
		StaminaCost = ((BaseUnityPlugin)this).Config.Bind<float>("Bash", "Stamina", 15f, new ConfigDescription("Stamina cost of one bash. The bash is not performed if you don't have enough.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f), Array.Empty<object>()));
		Cooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Bash", "Cooldown", 1.5f, new ConfigDescription("Minimum time between two bashes (seconds).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 10f), Array.Empty<object>()));
		Range = ((BaseUnityPlugin)this).Config.Bind<float>("Bash", "Range", 2.2f, new ConfigDescription("Reach of the bash (meters). The enemy's own radius is added on top.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), Array.Empty<object>()));
		HalfAngle = ((BaseUnityPlugin)this).Config.Bind<float>("Bash", "Angle", 55f, new ConfigDescription("Half angle of the cone in front of you that the bash hits (degrees).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 120f), Array.Empty<object>()));
		PushForce = ((BaseUnityPlugin)this).Config.Bind<float>("Bash", "Knockback", 40f, new ConfigDescription("Knockback strength (goes through the game's own knockback calculation; big enemies move less).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f), Array.Empty<object>()));
		Stagger = ((BaseUnityPlugin)this).Config.Bind<bool>("Bash", "ForceStagger", false, "If on, every bash also forces a stagger on the enemy (length: StaggerRatio). Off = only blunt damage + knockback; the game decides if the enemy staggers.");
		BluntRatio = ((BaseUnityPlugin)this).Config.Bind<float>("Bash", "BluntDamageRatio", 0.25f, new ConfigDescription("Blunt damage = the shield's block power x this ratio (stronger shields hit harder).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
		SkillDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Skill", "DamageBonus", 1f, new ConfigDescription("At Blocking skill 100, blunt damage increases by this much (1 = double; scales linearly with skill).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>()));
		SkillPush = ((BaseUnityPlugin)this).Config.Bind<float>("Skill", "KnockbackBonus", 0.75f, new ConfigDescription("At Blocking skill 100, knockback increases by this much (0.75 = x1.75).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>()));
		SkillGain = ((BaseUnityPlugin)this).Config.Bind<float>("Skill", "SkillGain", 0.5f, new ConfigDescription("Blocking skill experience added for each bash that hits an enemy (the game's own skill gain; 0 = none).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>()));
		BluntMin = ((BaseUnityPlugin)this).Config.Bind<float>("Bash", "MinBluntDamage", 3f, new ConfigDescription("Minimum blunt damage, even with a weak shield.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f), Array.Empty<object>()));
		StaggerRatio = ((BaseUnityPlugin)this).Config.Bind<float>("Bash", "StaggerRatio", 0.5f, new ConfigDescription("Only used when ForceStagger is on. Stagger length as a fraction of a parry stagger (0.5 = half; the animation plays 2x faster). 1 = same as a parry.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 1f), Array.Empty<object>()));
		MaxTargets = ((BaseUnityPlugin)this).Config.Bind<int>("Bash", "MaxTargets", 3, new ConfigDescription("Maximum number of enemies one bash can hit.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 8), Array.Empty<object>()));
		HitTime = ((BaseUnityPlugin)this).Config.Bind<float>("Bash", "HitDelay", 0.3f, new ConfigDescription("Seconds after the key press when the bash connects (the moment the shield is highest/furthest forward).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 1.5f), Array.Empty<object>()));
		CodeDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Animation", "Duration", 0.75f, new ConfigDescription("Total length of the bash motion (seconds). The shield is at the top at HitDelay.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 2f), Array.Empty<object>()));
		ThrustDist = ((BaseUnityPlugin)this).Config.Bind<float>("Animation", "ThrustDistance", 0.35f, new ConfigDescription("How far the shield moves forward from the block position (meters).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
		BodyTwist = ((BaseUnityPlugin)this).Config.Bind<float>("Animation", "BodyTwist", 35f, new ConfigDescription("Body rotation during the bash (degrees; half as much in the opposite direction while winding up).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 90f), Array.Empty<object>()));
		UpperHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Animation", "StrikeHeight", 0.35f, new ConfigDescription("How far above the shoulder the shield is at the moment of impact (fraction of arm length; 0.35 = about head height).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-0.3f, 1f), Array.Empty<object>()));
		UpperLow = ((BaseUnityPlugin)this).Config.Bind<float>("Animation", "WindupLowness", 0.6f, new ConfigDescription("How far below the shoulder the shield drops while winding up (fraction of arm length; 0.6 = about hip height).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
		UpperCross = ((BaseUnityPlugin)this).Config.Bind<float>("Animation", "CrossAmount", 0.25f, new ConfigDescription("How far the shield crosses in front of the body to the right at impact (fraction of arm length; 0 = in front of the left shoulder).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-0.5f, 1f), Array.Empty<object>()));
		SweepLeft = ((BaseUnityPlugin)this).Config.Bind<float>("Animation", "SweepLeft", 0.7f, new ConfigDescription("How far the shield sweeps to the left after the impact, accelerating (fraction of arm length; 0 = no sweep).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1.5f), Array.Empty<object>()));
		DebugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "DetailedLog", false, "Write who each bash hit to the log.");
		ClearOldSettings();
		((Component)this).gameObject.AddComponent<PoseFix>();
		_harmony = new Harmony("crecodev.ShieldBash");
		_harmony.PatchAll();
		Logger.LogInfo((object)("[ShieldBash] 1.0.1 loaded. Key: " + ((object)BashKey.Value/*cast due to .constrained prefix*/).ToString()));
	}

	private void ClearOldSettings()
	{
		try
		{
			PropertyInfo propertyInfo = AccessTools.Property(typeof(ConfigFile), "OrphanedEntries");
			IDictionary dictionary = ((propertyInfo != null) ? (propertyInfo.GetValue(((BaseUnityPlugin)this).Config, null) as IDictionary) : null);
			if (dictionary != null && dictionary.Count != 0)
			{
				int count = dictionary.Count;
				dictionary.Clear();
				((BaseUnityPlugin)this).Config.Save();
				Logger.LogInfo((object)("[ShieldBash] removed " + count + " unused old settings from the config file"));
			}
		}
		catch (Exception ex)
		{
			Logger.LogWarning((object)("[ShieldBash] Could not remove old settings: " + ex.Message));
		}
	}

	private void OnDestroy()
	{
		Bash.Shutdown();
		Harmony harmony = _harmony;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
	}
}
[DefaultExecutionOrder(30000)]
internal class PoseFix : MonoBehaviour
{
	private Animator _anim;

	private Transform _hips;

	private Transform _spine;

	private Transform _chest;

	private ArmChain _arm;

	private readonly BoneLayer _layer = new BoneLayer();

	private bool _layered;

	private bool _disabled;

	private void Update()
	{
		if (InPhysics())
		{
			Apply();
		}
	}

	private void LateUpdate()
	{
		if (!InPhysics())
		{
			Apply();
		}
	}

	private bool InPhysics()
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Invalid comparison between Unknown and I4
		if ((Object)(object)_anim != (Object)null)
		{
			return (int)_anim.updateMode == 1;
		}
		return false;
	}

	private bool Bind(Player p)
	{
		Animator componentInChildren = ((Component)p).GetComponentInChildren<Animator>();
		if ((Object)(object)componentInChildren == (Object)(object)_anim && _arm != null)
		{
			return _arm.Valid;
		}
		if (_layered)
		{
			try
			{
				_layer.Restore();
			}
			catch
			{
			}
		}
		_anim = componentInChildren;
		GameObject gameObject = ((Component)p).gameObject;
		_hips = ProcAnim.FindBone(gameObject, (HumanBodyBones)0, "Hips");
		_spine = ProcAnim.FindBone(gameObject, (HumanBodyBones)7, "Spine");
		_chest = ProcAnim.FindBone(gameObject, (HumanBodyBones)8, "Spine1");
		_arm = ArmChain.Left(gameObject);
		_layer.Clear();
		_layer.Add(_hips);
		_layer.Add(_spine);
		_layer.Add(_chest);
		if (_arm.Valid)
		{
			_arm.AddTo(_layer);
		}
		_layered = false;
		return _arm.Valid;
	}

	private void Apply()
	{
		try
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || _disabled)
			{
				return;
			}
			if (!Bash.Active)
			{
				if (_layered)
				{
					_layer.Restore();
					_layered = false;
				}
			}
			else if (Bind(localPlayer))
			{
				_layer.Begin();
				_layered = true;
				CodeMotion(localPlayer);
				_layer.End();
			}
		}
		catch (Exception ex)
		{
			Logger.LogWarning((object)("[ShieldBash] Shield motion disabled: " + ex.Message));
			try
			{
				_layer.Restore();
			}
			catch
			{
			}
			_layered = false;
			_disabled = true;
		}
	}

	private static float S(float a, float b, float t)
	{
		return Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(a, b, t));
	}

	private void CodeMotion(Player p)
	{
		UppercutMotion(p);
	}

	private void UppercutMotion(Player p)
	{
		//IL_00a0: 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_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_015d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0161: Unknown result type (might be due to invalid IL or missing references)
		//IL_0166: Unknown result type (might be due to invalid IL or missing references)
		//IL_016b: 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_0177: Unknown result type (might be due to invalid IL or missing references)
		//IL_017c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0181: Unknown result type (might be due to invalid IL or missing references)
		//IL_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_0188: 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_0192: Unknown result type (might be due to invalid IL or missing references)
		//IL_0197: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: 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_01bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0201: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Unknown result type (might be due to invalid IL or missing references)
		//IL_0208: Unknown result type (might be due to invalid IL or missing references)
		//IL_020a: Unknown result type (might be due to invalid IL or missing references)
		//IL_020e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0213: 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_021c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0220: Unknown result type (might be due to invalid IL or missing references)
		//IL_0225: Unknown result type (might be due to invalid IL or missing references)
		//IL_0295: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0304: Unknown result type (might be due to invalid IL or missing references)
		//IL_0309: Unknown result type (might be due to invalid IL or missing references)
		//IL_030e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0315: 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_031f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0342: Unknown result type (might be due to invalid IL or missing references)
		//IL_0344: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
		float elapsed = Bash.Elapsed;
		float num = Mathf.Max(0.1f, Plugin.HitTime.Value);
		float num2 = Mathf.Max(num + 0.2f, Bash.Duration);
		float num3 = num * 0.45f;
		float num4 = num + (num2 - num) * 0.55f;
		float num5 = S(0f, num3 * 0.6f, elapsed) * (1f - S(num4, num2, elapsed));
		if (!(num5 <= 0.001f))
		{
			float num6 = S(0f, num3, elapsed);
			float num7 = S(num3, num, elapsed);
			float num8 = Mathf.Clamp01(Mathf.InverseLerp(num, num4, elapsed));
			float num9 = num8 * num8;
			Vector3 forward = ((Component)p).transform.forward;
			Vector3 right = ((Component)p).transform.right;
			Vector3 up = Vector3.up;
			Vector3 position = _arm.Upper.position;
			float num10 = Vector3.Distance(_arm.Upper.position, _arm.Lower.position) + Vector3.Distance(_arm.Lower.position, _arm.Hand.position);
			float value = Plugin.UpperHeight.Value;
			float value2 = Plugin.UpperLow.Value;
			float value3 = Plugin.UpperCross.Value;
			Vector3 position2 = _arm.Hand.position;
			Vector3 val = position + num10 * (forward * 0.25f - up * value2 - right * 0.25f);
			Vector3 val2 = position + num10 * (forward * 0.88f + up * value + right * value3);
			float value4 = Plugin.SweepLeft.Value;
			Vector3 val3 = position + num10 * (forward * 0.45f + up * (value + 0.05f) - right * value4);
			Vector3 target = Vector3.Lerp(Vector3.Lerp(Vector3.Lerp(position2, val, num6), val2, num7), val3, num9);
			float value5 = Plugin.BodyTwist.Value;
			float num11 = (0f - value5) * 0.5f * num6 * (1f - num7) + value5 * num7 * (1f - num9) - value5 * 0.8f * num9;
			float num12 = 6f * num6 * (1f - num7) - 8f * num7;
			if ((Object)(object)_spine != (Object)null)
			{
				ProcAnim.Rotate(_spine, up, num11 * 0.4f * num5);
				ProcAnim.Rotate(_spine, right, num12 * 0.5f * num5);
			}
			if ((Object)(object)_chest != (Object)null)
			{
				ProcAnim.Rotate(_chest, up, num11 * 0.6f * num5);
				ProcAnim.Rotate(_chest, right, num12 * 0.5f * num5);
			}
			Vector3 hint = position - right * 0.35f - up * 0.3f;
			TwoBoneIK.Solve(_arm.Upper, _arm.Lower, _arm.Hand, target, hint, num5);
		}
	}
}
public struct Spring
{
	public float Value;

	public float Velocity;

	public float Step(float target, float freq, float damping, float dt)
	{
		if (dt <= 0f)
		{
			return Value;
		}
		float num = (float)Math.PI * 2f * Mathf.Max(0.01f, freq);
		float num2 = num * num * (target - Value) - 2f * Mathf.Clamp01(damping) * num * Velocity;
		Velocity += num2 * dt;
		Value += Velocity * dt;
		return Value;
	}

	public void Reset(float value)
	{
		Value = value;
		Velocity = 0f;
	}
}
public struct SpringV3
{
	public Vector3 Value;

	public Vector3 Velocity;

	public Vector3 Step(Vector3 target, float freq, float damping, float dt)
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_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)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		if (dt <= 0f)
		{
			return Value;
		}
		float num = (float)Math.PI * 2f * Mathf.Max(0.01f, freq);
		Vector3 val = num * num * (target - Value) - 2f * Mathf.Clamp01(damping) * num * Velocity;
		Velocity += val * dt;
		Value += Velocity * dt;
		return Value;
	}

	public void Reset(Vector3 value)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		Value = value;
		Velocity = Vector3.zero;
	}
}
public static class ProcAnim
{
	public static bool UpdatesInPhysics(Animator a)
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Invalid comparison between Unknown and I4
		if ((Object)(object)a != (Object)null)
		{
			return (int)a.updateMode == 1;
		}
		return false;
	}

	public static bool UpdatesInPhysics(GameObject root)
	{
		if ((Object)(object)root != (Object)null)
		{
			return UpdatesInPhysics(root.GetComponentInChildren<Animator>());
		}
		return false;
	}

	public static float Wobble(float seed, float time, float freq)
	{
		return Mathf.PerlinNoise(seed * 13.37f, time * freq) * 2f - 1f;
	}

	public static void Rotate(Transform bone, Vector3 worldAxis, float degrees)
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)bone == (Object)null) && !(Mathf.Abs(degrees) < 0.0001f) && !(((Vector3)(ref worldAxis)).sqrMagnitude < 1E-08f))
		{
			bone.rotation = Quaternion.AngleAxis(degrees, ((Vector3)(ref worldAxis)).normalized) * bone.rotation;
		}
	}

	public static Transform FindBone(GameObject root, HumanBodyBones human, params string[] names)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)root == (Object)null)
		{
			return null;
		}
		Animator componentInChildren = root.GetComponentInChildren<Animator>();
		if ((Object)(object)componentInChildren != (Object)null && componentInChildren.isHuman)
		{
			Transform boneTransform = componentInChildren.GetBoneTransform(human);
			if ((Object)(object)boneTransform != (Object)null)
			{
				return boneTransform;
			}
		}
		return FindByName(root, names);
	}

	public static Transform FindByName(GameObject root, params string[] names)
	{
		if ((Object)(object)root == (Object)null || names == null)
		{
			return null;
		}
		Transform[] componentsInChildren = root.GetComponentsInChildren<Transform>(true);
		foreach (string b in names)
		{
			Transform[] array = componentsInChildren;
			foreach (Transform val in array)
			{
				if (string.Equals(((Object)val).name, b, StringComparison.OrdinalIgnoreCase))
				{
					return val;
				}
			}
		}
		return null;
	}

	public static Transform FindContaining(GameObject root, string part)
	{
		if ((Object)(object)root == (Object)null)
		{
			return null;
		}
		string value = part.ToLowerInvariant();
		Transform[] componentsInChildren = root.GetComponentsInChildren<Transform>(true);
		foreach (Transform val in componentsInChildren)
		{
			string text = ((Object)val).name.ToLowerInvariant();
			if (text.Contains(value) && !text.Contains("end") && !text.Contains("point"))
			{
				return val;
			}
		}
		return null;
	}

	public static Transform NearestBone(GameObject root, Vector3 point, params string[] prefer)
	{
		//IL_0027: 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)
		if ((Object)(object)root == (Object)null)
		{
			return null;
		}
		if (prefer != null && prefer.Length != 0)
		{
			Transform val = NearestBoneWhere(root, point, prefer);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
		}
		return NearestBoneWhere(root, point, null);
	}

	private static Transform NearestBoneWhere(GameObject root, Vector3 point, string[] prefer)
	{
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: 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)
		Transform result = null;
		float num = float.MaxValue;
		SkinnedMeshRenderer[] componentsInChildren = root.GetComponentsInChildren<SkinnedMeshRenderer>();
		foreach (SkinnedMeshRenderer val in componentsInChildren)
		{
			if ((Object)(object)val == (Object)null || val.bones == null)
			{
				continue;
			}
			Transform[] bones = val.bones;
			foreach (Transform val2 in bones)
			{
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				if (prefer != null)
				{
					string text = ((Object)val2).name.ToLowerInvariant();
					bool flag = false;
					foreach (string value in prefer)
					{
						if (text.Contains(value))
						{
							flag = true;
							break;
						}
					}
					if (!flag)
					{
						continue;
					}
				}
				Vector3 val3 = val2.position - point;
				float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
				if (sqrMagnitude < num)
				{
					num = sqrMagnitude;
					result = val2;
				}
			}
		}
		return result;
	}
}
public static class TwoBoneIK
{
	public static void Solve(Transform upper, Transform lower, Transform end, Vector3 target, Vector3 hint, float weight)
	{
		//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_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: 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_0081: 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_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_015b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01de: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f3: 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_0205: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Unknown result type (might be due to invalid IL or missing references)
		//IL_020b: Unknown result type (might be due to invalid IL or missing references)
		//IL_020c: 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_0212: 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_0242: Unknown result type (might be due to invalid IL or missing references)
		//IL_0244: 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_024a: 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_024c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0251: Unknown result type (might be due to invalid IL or missing references)
		//IL_0256: Unknown result type (might be due to invalid IL or missing references)
		//IL_0227: Unknown result type (might be due to invalid IL or missing references)
		//IL_0229: Unknown result type (might be due to invalid IL or missing references)
		//IL_022a: Unknown result type (might be due to invalid IL or missing references)
		//IL_022f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0234: Unknown result type (might be due to invalid IL or missing references)
		//IL_0239: Unknown result type (might be due to invalid IL or missing references)
		//IL_027c: Unknown result type (might be due to invalid IL or missing references)
		//IL_027e: 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_0289: Unknown result type (might be due to invalid IL or missing references)
		//IL_029e: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cb: 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_02e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0300: Unknown result type (might be due to invalid IL or missing references)
		//IL_0301: Unknown result type (might be due to invalid IL or missing references)
		//IL_0305: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)upper == (Object)null || (Object)(object)lower == (Object)null || (Object)(object)end == (Object)null || weight <= 0.0001f)
		{
			return;
		}
		Quaternion rotation = upper.rotation;
		Quaternion rotation2 = lower.rotation;
		Vector3 position = upper.position;
		Vector3 position2 = lower.position;
		Vector3 position3 = end.position;
		Vector3 val = position2 - position;
		float magnitude = ((Vector3)(ref val)).magnitude;
		val = position3 - position2;
		float magnitude2 = ((Vector3)(ref val)).magnitude;
		if (!(magnitude < 1E-05f) && !(magnitude2 < 1E-05f))
		{
			val = target - position;
			float num = Mathf.Clamp(((Vector3)(ref val)).magnitude, 0.001f, magnitude + magnitude2 - 0.001f);
			val = position3 - position;
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			val = position2 - position;
			Vector3 normalized2 = ((Vector3)(ref val)).normalized;
			val = position - position2;
			Vector3 normalized3 = ((Vector3)(ref val)).normalized;
			val = position3 - position2;
			Vector3 normalized4 = ((Vector3)(ref val)).normalized;
			val = target - position;
			Vector3 val2;
			if (!(((Vector3)(ref val)).sqrMagnitude > 1E-10f))
			{
				val2 = normalized;
			}
			else
			{
				val = target - position;
				val2 = ((Vector3)(ref val)).normalized;
			}
			Vector3 val3 = val2;
			float num2 = Mathf.Acos(Mathf.Clamp(Vector3.Dot(normalized, normalized2), -1f, 1f));
			float num3 = Mathf.Acos(Mathf.Clamp(Vector3.Dot(normalized3, normalized4), -1f, 1f));
			float num4 = Mathf.Acos(Mathf.Clamp(Vector3.Dot(normalized, val3), -1f, 1f));
			float num5 = Mathf.Acos(Mathf.Clamp((magnitude2 * magnitude2 - magnitude * magnitude - num * num) / (-2f * magnitude * num), -1f, 1f));
			float num6 = Mathf.Acos(Mathf.Clamp((num * num - magnitude * magnitude - magnitude2 * magnitude2) / (-2f * magnitude * magnitude2), -1f, 1f));
			Vector3 val4 = Vector3.Cross(position3 - position, hint - position);
			if (((Vector3)(ref val4)).sqrMagnitude < 1E-10f)
			{
				val4 = Vector3.Cross(position3 - position, position2 - position);
			}
			if (((Vector3)(ref val4)).sqrMagnitude < 1E-10f)
			{
				val4 = Vector3.Cross(position3 - position, Vector3.up);
			}
			((Vector3)(ref val4)).Normalize();
			Vector3 val5 = Vector3.Cross(position3 - position, target - position);
			bool num7 = ((Vector3)(ref val5)).sqrMagnitude > 1E-10f;
			if (num7)
			{
				((Vector3)(ref val5)).Normalize();
			}
			lower.rotation = Quaternion.AngleAxis((num6 - num3) * 57.29578f, val4) * lower.rotation;
			Quaternion val6 = Quaternion.AngleAxis((num5 - num2) * 57.29578f, val4);
			Quaternion val7 = (num7 ? Quaternion.AngleAxis(num4 * 57.29578f, val5) : Quaternion.identity);
			upper.rotation = val6 * val7 * rotation;
			if (weight < 0.9999f)
			{
				Quaternion rotation3 = upper.rotation;
				Quaternion rotation4 = lower.rotation;
				upper.rotation = Quaternion.Slerp(rotation, rotation3, weight);
				lower.rotation = Quaternion.Slerp(rotation2, rotation4, weight);
			}
		}
	}
}
public class BoneLayer
{
	private readonly List<Transform> _bones = new List<Transform>();

	private readonly List<Quaternion> _base = new List<Quaternion>();

	private readonly List<Quaternion> _written = new List<Quaternion>();

	private readonly List<Vector3> _basePos = new List<Vector3>();

	private readonly List<Vector3> _writtenPos = new List<Vector3>();

	private readonly List<bool> _has = new List<bool>();

	private readonly List<bool> _hold = new List<bool>();

	private readonly List<Vector3> _rest = new List<Vector3>();

	public int Count => _bones.Count;

	public void Add(Transform bone, bool holdLength = false)
	{
		//IL_002b: 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)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)bone == (Object)null) && !_bones.Contains(bone))
		{
			_hold.Add(holdLength);
			_rest.Add(bone.localPosition);
			_bones.Add(bone);
			_base.Add(bone.localRotation);
			_written.Add(bone.localRotation);
			_basePos.Add(bone.localPosition);
			_writtenPos.Add(bone.localPosition);
			_has.Add(item: false);
		}
	}

	public void Clear()
	{
		_bones.Clear();
		_base.Clear();
		_written.Clear();
		_basePos.Clear();
		_writtenPos.Clear();
		_has.Clear();
		_hold.Clear();
		_rest.Clear();
	}

	public void Begin()
	{
		//IL_002f: 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_00a7: 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_0068: 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)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: Unknown result type (might be due to invalid IL or missing references)
		for (int i = 0; i < _bones.Count; i++)
		{
			Transform val = _bones[i];
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			if (_has[i] && Same(val.localRotation, _written[i]))
			{
				val.localRotation = _base[i];
			}
			if (_has[i])
			{
				Vector3 val2 = val.localPosition - _writtenPos[i];
				if (((Vector3)(ref val2)).sqrMagnitude < 1E-12f)
				{
					val.localPosition = _basePos[i];
				}
			}
			_base[i] = val.localRotation;
			_basePos[i] = val.localPosition;
		}
		for (int j = 0; j < _bones.Count; j++)
		{
			if (_hold[j] && (Object)(object)_bones[j] != (Object)null)
			{
				_bones[j].localPosition = _rest[j];
			}
		}
	}

	public void End()
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		for (int i = 0; i < _bones.Count; i++)
		{
			Transform val = _bones[i];
			if (!((Object)(object)val == (Object)null))
			{
				_written[i] = val.localRotation;
				_writtenPos[i] = val.localPosition;
				_has[i] = true;
			}
		}
	}

	public void Restore()
	{
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: 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)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		for (int i = 0; i < _bones.Count; i++)
		{
			Transform val = _bones[i];
			if (!((Object)(object)val == (Object)null) && _has[i])
			{
				if (Same(val.localRotation, _written[i]))
				{
					val.localRotation = _base[i];
				}
				Vector3 val2 = val.localPosition - _writtenPos[i];
				if (((Vector3)(ref val2)).sqrMagnitude < 1E-12f)
				{
					val.localPosition = _basePos[i];
				}
				_has[i] = false;
			}
		}
	}

	private static bool Same(Quaternion a, Quaternion b)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		return Mathf.Abs(Quaternion.Dot(a, b)) > 0.999999f;
	}
}
public class ArmChain
{
	public Transform Upper;

	public Transform Lower;

	public Transform Hand;

	public bool Valid
	{
		get
		{
			if ((Object)(object)Upper != (Object)null && (Object)(object)Lower != (Object)null)
			{
				return (Object)(object)Hand != (Object)null;
			}
			return false;
		}
	}

	public static ArmChain Left(GameObject root)
	{
		ArmChain armChain = new ArmChain();
		armChain.Upper = ProcAnim.FindBone(root, (HumanBodyBones)13, "LeftArm");
		armChain.Lower = ProcAnim.FindBone(root, (HumanBodyBones)15, "LeftForeArm");
		armChain.Hand = ProcAnim.FindBone(root, (HumanBodyBones)17, "LeftHand");
		return armChain;
	}

	public static ArmChain Right(GameObject root)
	{
		ArmChain armChain = new ArmChain();
		armChain.Upper = ProcAnim.FindBone(root, (HumanBodyBones)14, "RightArm");
		armChain.Lower = ProcAnim.FindBone(root, (HumanBodyBones)16, "RightForeArm");
		armChain.Hand = ProcAnim.FindBone(root, (HumanBodyBones)18, "RightHand");
		return armChain;
	}

	public void AddTo(BoneLayer layer)
	{
		layer.Add(Upper, holdLength: true);
		layer.Add(Lower, holdLength: true);
		layer.Add(Hand, holdLength: true);
	}

	public static ArmChain LeftLeg(GameObject root)
	{
		ArmChain armChain = new ArmChain();
		armChain.Upper = ProcAnim.FindBone(root, (HumanBodyBones)1, "LeftUpLeg");
		armChain.Lower = ProcAnim.FindBone(root, (HumanBodyBones)3, "LeftLeg");
		armChain.Hand = ProcAnim.FindBone(root, (HumanBodyBones)5, "LeftFoot");
		return armChain;
	}

	public static ArmChain RightLeg(GameObject root)
	{
		ArmChain armChain = new ArmChain();
		armChain.Upper = ProcAnim.FindBone(root, (HumanBodyBones)2, "RightUpLeg");
		armChain.Lower = ProcAnim.FindBone(root, (HumanBodyBones)4, "RightLeg");
		armChain.Hand = ProcAnim.FindBone(root, (HumanBodyBones)6, "RightFoot");
		return armChain;
	}

	public void Pin(Vector3 target, Quaternion endRotation, Vector3 hint, float weight)
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//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_0038: Unknown result type (might be due to invalid IL or missing references)
		if (Valid)
		{
			TwoBoneIK.Solve(Upper, Lower, Hand, target, hint, weight);
			Hand.rotation = Quaternion.Slerp(Hand.rotation, endRotation, weight);
		}
	}
}
public class BoneAnchor
{
	public Transform Bone;

	public Vector3 Local;

	public Vector3 World
	{
		get
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Bone != (Object)null))
			{
				return Local;
			}
			return Bone.TransformPoint(Local);
		}
	}

	public static BoneAnchor At(GameObject root, Vector3 worldPoint, params string[] prefer)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		Transform val = ProcAnim.NearestBone(root, worldPoint, prefer);
		if ((Object)(object)val == (Object)null && (Object)(object)root != (Object)null)
		{
			val = root.transform;
		}
		return new BoneAnchor
		{
			Bone = val,
			Local = (((Object)(object)val != (Object)null) ? val.InverseTransformPoint(worldPoint) : worldPoint)
		};
	}
}
public class SurfaceSampler
{
	private Vector3[] _points;

	private Vector3[] _normals;

	public int Count
	{
		get
		{
			if (_points == null)
			{
				return 0;
			}
			return _points.Length;
		}
	}

	public string Source { get; private set; }

	public static SurfaceSampler Bake(GameObject root)
	{
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Expected O, 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_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0140: Unknown result type (might be due to invalid IL or missing references)
		//IL_0145: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)root == (Object)null)
		{
			return null;
		}
		SkinnedMeshRenderer val = null;
		int num = 0;
		SkinnedMeshRenderer[] componentsInChildren = root.GetComponentsInChildren<SkinnedMeshRenderer>();
		foreach (SkinnedMeshRenderer val2 in componentsInChildren)
		{
			if (!((Object)(object)val2 == (Object)null) && ((Renderer)val2).enabled && ((Component)val2).gameObject.activeInHierarchy && !((Object)(object)val2.sharedMesh == (Object)null))
			{
				int vertexCount = val2.sharedMesh.vertexCount;
				if (vertexCount > num)
				{
					val = val2;
					num = vertexCount;
				}
			}
		}
		if ((Object)(object)val == (Object)null)
		{
			return null;
		}
		Mesh val3 = new Mesh();
		try
		{
			val.BakeMesh(val3);
			Vector3[] vertices = val3.vertices;
			Vector3[] normals = val3.normals;
			if (vertices == null || vertices.Length == 0)
			{
				return null;
			}
			SurfaceSampler surfaceSampler = new SurfaceSampler
			{
				Source = ((Object)val).name
			};
			surfaceSampler._points = (Vector3[])(object)new Vector3[vertices.Length];
			surfaceSampler._normals = (Vector3[])(object)new Vector3[vertices.Length];
			Transform transform = ((Component)val).transform;
			bool flag = normals != null && normals.Length == vertices.Length;
			for (int j = 0; j < vertices.Length; j++)
			{
				surfaceSampler._points[j] = transform.TransformPoint(vertices[j]);
				Vector3[] normals2 = surfaceSampler._normals;
				int num2 = j;
				Vector3 val4;
				if (!flag)
				{
					val4 = Vector3.up;
				}
				else
				{
					Vector3 val5 = transform.TransformDirection(normals[j]);
					val4 = ((Vector3)(ref val5)).normalized;
				}
				normals2[num2] = val4;
			}
			return surfaceSampler;
		}
		catch (Exception)
		{
			return null;
		}
		finally
		{
			Object.Destroy((Object)(object)val3);
		}
	}

	public bool Closest(Vector3 p, out Vector3 point, out Vector3 normal)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_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)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		point = p;
		normal = Vector3.up;
		if (Count == 0)
		{
			return false;
		}
		int num = 0;
		float num2 = float.MaxValue;
		for (int i = 0; i < _points.Length; i++)
		{
			Vector3 val = _points[i] - p;
			float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
			if (sqrMagnitude < num2)
			{
				num2 = sqrMagnitude;
				num = i;
			}
		}
		point = _points[num];
		normal = _normals[num];
		return true;
	}

	public bool Farthest(Vector3 origin, Vector3 dir, float lateralTol, out Vector3 point, out Vector3 normal)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: 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_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_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)
		point = origin;
		normal = dir;
		if (Count == 0 || ((Vector3)(ref dir)).sqrMagnitude < 1E-08f)
		{
			return false;
		}
		((Vector3)(ref dir)).Normalize();
		float num = 0f;
		float num2 = lateralTol * lateralTol;
		bool result = false;
		for (int i = 0; i < _points.Length; i++)
		{
			Vector3 val = _points[i] - origin;
			float num3 = Vector3.Dot(val, dir);
			if (!(num3 <= num))
			{
				Vector3 val2 = val - dir * num3;
				if (!(((Vector3)(ref val2)).sqrMagnitude > num2))
				{
					num = num3;
					point = _points[i];
					normal = _normals[i];
					result = true;
				}
			}
		}
		return result;
	}

	public bool FirstAlong(Vector3 origin, Vector3 dir, float lateralTol, float minAlong, out Vector3 point, out Vector3 normal)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: 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_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		point = origin;
		normal = dir;
		if (Count == 0 || ((Vector3)(ref dir)).sqrMagnitude < 1E-08f)
		{
			return false;
		}
		((Vector3)(ref dir)).Normalize();
		float num = float.MaxValue;
		float num2 = lateralTol * lateralTol;
		bool result = false;
		for (int i = 0; i < _points.Length; i++)
		{
			Vector3 val = _points[i] - origin;
			float num3 = Vector3.Dot(val, dir);
			if (!(num3 < minAlong) && !(num3 >= num))
			{
				Vector3 val2 = val - dir * num3;
				if (!(((Vector3)(ref val2)).sqrMagnitude > num2))
				{
					num = num3;
					point = _points[i];
					normal = _normals[i];
					result = true;
				}
			}
		}
		return result;
	}

	public bool Outermost(Vector3 center, Vector3 dir, float heightTol, out Vector3 point)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: 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_003f: 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_0045: 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_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		point = center;
		if (Count == 0 || ((Vector3)(ref dir)).sqrMagnitude < 1E-08f)
		{
			return false;
		}
		((Vector3)(ref dir)).Normalize();
		float num = float.MinValue;
		bool result = false;
		for (int i = 0; i < _points.Length; i++)
		{
			Vector3 val = _points[i] - center;
			if (!(Mathf.Abs(val.y) > heightTol))
			{
				float num2 = Vector3.Dot(val, dir);
				Vector3 val2 = val - dir * num2;
				val2.y = 0f;
				if (!(((Vector3)(ref val2)).magnitude > heightTol * 1.5f) && num2 > num)
				{
					num = num2;
					point = _points[i];
					result = true;
				}
			}
		}
		return result;
	}
}
internal static class Safe
{
	private static readonly Dictionary<string, MethodInfo> _cache = new Dictionary<string, MethodInfo>();

	private static MethodInfo Find(Type t, string name, int argc, bool isStatic)
	{
		string text = t.FullName + "." + name + "/" + argc + (isStatic ? "s" : "");
		if (_cache.TryGetValue(text, out var value))
		{
			return value;
		}
		Type type = t;
		while (type != null && value == null)
		{
			MethodInfo methodInfo = null;
			MethodInfo[] methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo2 in methods)
			{
				if (methodInfo2.Name != name || methodInfo2.IsStatic != isStatic || methodInfo2.IsGenericMethodDefinition)
				{
					continue;
				}
				ParameterInfo[] parameters = methodInfo2.GetParameters();
				if (parameters.Length < argc)
				{
					continue;
				}
				bool flag = true;
				for (int j = argc; j < parameters.Length; j++)
				{
					if (!parameters[j].HasDefaultValue)
					{
						flag = false;
						break;
					}
				}
				if (flag && (methodInfo == null || parameters.Length < methodInfo.GetParameters().Length))
				{
					methodInfo = methodInfo2;
				}
			}
			value = methodInfo;
			type = type.BaseType;
		}
		_cache[text] = value;
		if (value == null)
		{
			Logger.LogWarning((object)("[ShieldBash] Not found in game: " + text + " (using fallback value)"));
		}
		return value;
	}

	public static bool Bool(object target, string name, bool fallback)
	{
		if (target == null)
		{
			return fallback;
		}
		try
		{
			MethodInfo methodInfo = Find(target.GetType(), name, 0, isStatic: false);
			if (methodInfo == null)
			{
				return fallback;
			}
			return (methodInfo.Invoke(target, Defaults(methodInfo, new object[0])) is bool flag) ? flag : fallback;
		}
		catch
		{
			return fallback;
		}
	}

	public static void Call(object target, string name, params object[] firstArgs)
	{
		if (target != null)
		{
			Invoke(target.GetType(), target, name, firstArgs, out var _);
		}
	}

	public static T Get<T>(object target, string name, T fallback, params object[] firstArgs)
	{
		if (target == null)
		{
			return fallback;
		}
		if (Invoke(target.GetType(), target, name, firstArgs, out var result) && result is T)
		{
			return (T)result;
		}
		return fallback;
	}

	public static T Static<T>(Type type, string name, T fallback, params object[] firstArgs)
	{
		if (Invoke(type, null, name, firstArgs, out var result) && result is T)
		{
			return (T)result;
		}
		return fallback;
	}

	private static bool Invoke(Type type, object target, string name, object[] firstArgs, out object result)
	{
		result = null;
		try
		{
			MethodInfo methodInfo = Find(type, name, firstArgs.Length, target == null);
			if (methodInfo == null)
			{
				return false;
			}
			result = methodInfo.Invoke(target, Defaults(methodInfo, firstArgs));
			return true;
		}
		catch (Exception ex)
		{
			Logger.LogWarning((object)("[ShieldBash] " + name + " call failed: " + ex.Message));
			return false;
		}
	}

	private static object[] Defaults(MethodInfo m, object[] firstArgs)
	{
		ParameterInfo[] parameters = m.GetParameters();
		object[] array = new object[parameters.Length];
		for (int i = 0; i < parameters.Length; i++)
		{
			if (i < firstArgs.Length)
			{
				array[i] = firstArgs[i];
			}
			else if (parameters[i].HasDefaultValue)
			{
				array[i] = parameters[i].DefaultValue;
			}
			else
			{
				array[i] = (parameters[i].ParameterType.IsValueType ? Activator.CreateInstance(parameters[i].ParameterType) : null);
			}
		}
		return array;
	}

	public static T Field<T>(object target, string name, T fallback) where T : class
	{
		if (target == null)
		{
			return fallback;
		}
		try
		{
			Traverse val = Traverse.Create(target).Field(name);
			return val.FieldExists() ? ((val.GetValue() as T) ?? fallback) : fallback;
		}
		catch
		{
			return fallback;
		}
	}
}
internal class StaggerShortener : MonoBehaviour
{
	private const float StartGrace = 0.25f;

	private const float MaxTime = 3f;

	private Character _c;

	private float _speed;

	private float _t;

	private bool _seen;

	private readonly List<Animator> _anims = new List<Animator>();

	private readonly List<float> _orig = new List<float>();

	public static void Attach(Character c, float ratio)
	{
		if (!((Object)(object)c == (Object)null) && !(ratio >= 0.999f))
		{
			StaggerShortener staggerShortener = ((Component)c).GetComponent<StaggerShortener>();
			if ((Object)(object)staggerShortener == (Object)null)
			{
				staggerShortener = ((Component)c).gameObject.AddComponent<StaggerShortener>();
			}
			staggerShortener.Begin(c, 1f / Mathf.Clamp(ratio, 0.2f, 1f));
		}
	}

	private void Begin(Character c, float speed)
	{
		Restore();
		_c = c;
		_speed = speed;
		_t = 0f;
		_seen = false;
		_anims.Clear();
		_orig.Clear();
		Animator[] componentsInChildren = ((Component)c).GetComponentsInChildren<Animator>();
		foreach (Animator val in componentsInChildren)
		{
			_anims.Add(val);
			_orig.Add(val.speed);
		}
	}

	private void LateUpdate()
	{
		_t += Time.deltaTime;
		bool flag = (Object)(object)_c != (Object)null && !_c.IsDead() && _c.IsStaggering();
		if (flag)
		{
			_seen = true;
		}
		if (!((Object)(object)_c != (Object)null) || !(_t < 3f) || (!flag && (_seen || !(_t < 0.25f))))
		{
			Restore();
			Object.Destroy((Object)(object)this);
		}
		else
		{
			if (!flag)
			{
				return;
			}
			for (int i = 0; i < _anims.Count; i++)
			{
				if ((Object)(object)_anims[i] != (Object)null)
				{
					_anims[i].speed = _orig[i] * _speed;
				}
			}
		}
	}

	private void Restore()
	{
		for (int i = 0; i < _anims.Count; i++)
		{
			if ((Object)(object)_anims[i] != (Object)null)
			{
				_anims[i].speed = _orig[i];
			}
		}
	}

	private void OnDestroy()
	{
		Restore();
	}
}