Decompiled source of WingsOfTheForgottenGods v1.0.2

WingsOfTheForgottenGods.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using WingsOfTheForgottenGods.Abilities;
using WingsOfTheForgottenGods.Abilities.CrimsonTar;
using WingsOfTheForgottenGods.Abilities.Hraesvelgr;
using WingsOfTheForgottenGods.Assets;
using WingsOfTheForgottenGods.Commands;
using WingsOfTheForgottenGods.Config;
using WingsOfTheForgottenGods.Core;
using WingsOfTheForgottenGods.Flight;
using WingsOfTheForgottenGods.Items;
using WingsOfTheForgottenGods.Localization;
using WingsOfTheForgottenGods.Network;
using WingsOfTheForgottenGods.Visuals;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Wings Of The Forgotten Gods")]
[assembly: AssemblyDescription("Craftable animated wings and controlled flight for Valheim")]
[assembly: AssemblyCompany("DarkSpider")]
[assembly: AssemblyProduct("Wings Of The Forgotten Gods")]
[assembly: InternalsVisibleTo("WingsOfTheForgottenGods.LogicTests")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: ComVisible(false)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.0")]
[module: UnverifiableCode]
[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 WingsOfTheForgottenGods
{
	[BepInPlugin("darkspider.wingsoftheforgottengods", "Wings Of The Forgotten Gods", "1.0.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[SynchronizationMode(/*Could not decode attribute arguments.*/)]
	internal sealed class WingsOfTheForgottenGodsPlugin : BaseUnityPlugin
	{
		internal const string PluginGuid = "darkspider.wingsoftheforgottengods";

		internal const string PluginName = "Wings Of The Forgotten Gods";

		internal const string PluginVersion = "1.0.2";

		private Harmony _harmony;

		private void Awake()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			ModLog.Init(((BaseUnityPlugin)this).Logger);
			WingConfig.Bind(((BaseUnityPlugin)this).Config);
			WingLocalization.Register();
			PrefabManager.OnVanillaPrefabsAvailable += WingItemRegistry.Register;
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new WingsCommand());
			_harmony = new Harmony("darkspider.wingsoftheforgottengods");
			_harmony.PatchAll(typeof(WingsOfTheForgottenGodsPlugin).Assembly);
			ModLog.Info("Wings Of The Forgotten Gods 1.0.2 loaded. Test command: wfg.wings spawn");
		}

		private void Update()
		{
			Player localPlayer = Player.m_localPlayer;
			WingFlightRuntime.Sync(localPlayer);
			WingFlightRuntime.FrameTick(localPlayer, Time.deltaTime);
		}

		private void OnDestroy()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= WingItemRegistry.Register;
			WingFlightRuntime.Clear();
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
}
namespace WingsOfTheForgottenGods.Visuals
{
	internal sealed class WingEquipmentDisplay : MonoBehaviour
	{
		private VisEquipment _equipment;

		private Player _owner;

		private WingVisualController _visual;

		private WingFlightState _state;

		private bool _powered;

		private int _lastCommand;

		private int _lastAnimation;

		private WingDefinition _definition;

		internal static void Sync(VisEquipment equipment, int shoulderHash)
		{
			if ((Object)(object)equipment == (Object)null)
			{
				return;
			}
			WingDefinition wingDefinition = WingCatalog.FindByItemHash(shoulderHash);
			WingEquipmentDisplay wingEquipmentDisplay = ((Component)equipment).GetComponent<WingEquipmentDisplay>();
			if (wingDefinition == null)
			{
				if ((Object)(object)wingEquipmentDisplay != (Object)null)
				{
					wingEquipmentDisplay.SetEquipped(equipped: false);
				}
				return;
			}
			if ((Object)(object)wingEquipmentDisplay == (Object)null)
			{
				wingEquipmentDisplay = ((Component)equipment).gameObject.AddComponent<WingEquipmentDisplay>();
			}
			wingEquipmentDisplay._equipment = equipment;
			if (wingEquipmentDisplay._definition != wingDefinition)
			{
				wingEquipmentDisplay.DestroyVisual();
				wingEquipmentDisplay._definition = wingDefinition;
			}
			wingEquipmentDisplay.SetEquipped(equipped: true);
		}

		private void SetEquipped(bool equipped)
		{
			if (!equipped)
			{
				DestroyVisual();
				Object.Destroy((Object)(object)this);
			}
			else
			{
				EnsureVisual();
			}
		}

		private void Update()
		{
			EnsureVisual();
			if (_visual == null)
			{
				return;
			}
			_visual.RefreshAnchor();
			if ((Object)(object)_owner == (Object)null || !WingNetworkState.TryRead(_owner, out var snapshot))
			{
				return;
			}
			if (snapshot.State != _state)
			{
				WingFlightState state = _state;
				_state = snapshot.State;
				_visual.SetState(state, _state, snapshot.WaterLaunch);
			}
			if (snapshot.Powered != _powered)
			{
				_powered = snapshot.Powered;
				_visual.SetPoweredTravel(_powered);
			}
			_visual.SetFlightAttitude(snapshot.Pitch, snapshot.Bank, _powered, Time.deltaTime);
			if (snapshot.AnimationValue != 0 && snapshot.AnimationValue != _lastAnimation)
			{
				_lastAnimation = snapshot.AnimationValue;
				_visual.ApplyNetworkAnimation(snapshot.Animation, WingNetworkState.AnimationElapsedSeconds(snapshot.AnimationStarted));
			}
			if (snapshot.AnimationValue == 0 && snapshot.CommandValue != 0 && snapshot.CommandValue != _lastCommand)
			{
				_lastCommand = snapshot.CommandValue;
				if (snapshot.Command == WingNetworkState.VisualCommand.FlightFlap)
				{
					_visual.RequestFlightFlap();
				}
				else if (snapshot.Command == WingNetworkState.VisualCommand.LightFlightFlap)
				{
					_visual.RequestLightFlightFlap();
				}
			}
		}

		private void EnsureVisual()
		{
			if (_visual != null)
			{
				return;
			}
			_owner = (((Object)(object)_equipment != (Object)null) ? (_equipment.m_playerComponent ?? ((Component)_equipment).GetComponentInParent<Player>()) : ((Component)this).GetComponentInParent<Player>());
			if ((Object)(object)_owner == (Object)null)
			{
				return;
			}
			ZNetView component = ((Component)_owner).GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && component.IsValid() && component.IsOwner())
			{
				((Behaviour)this).enabled = false;
				return;
			}
			_visual = new WingVisualController();
			if (_definition == null || !_visual.Create(_owner, _definition))
			{
				_visual = null;
				return;
			}
			_state = WingFlightState.Grounded;
			_powered = false;
			if (WingNetworkState.TryRead(_owner, out var snapshot))
			{
				_lastCommand = snapshot.CommandValue;
			}
		}

		private void DestroyVisual()
		{
			_visual?.Destroy();
			_visual = null;
			_owner = null;
			_state = WingFlightState.Grounded;
			_powered = false;
			_lastCommand = 0;
			_lastAnimation = 0;
		}

		private void OnDestroy()
		{
			DestroyVisual();
		}
	}
	internal static class WingRagdollVisual
	{
		internal static void EnsureNetworkDisplay(Ragdoll ragdoll)
		{
			if ((Object)(object)ragdoll != (Object)null && (Object)(object)((Component)ragdoll).GetComponent<RagdollWingNetworkDisplay>() == (Object)null)
			{
				((Component)ragdoll).gameObject.AddComponent<RagdollWingNetworkDisplay>().Initialize(ragdoll);
			}
		}

		internal static bool Attach(Ragdoll ragdoll, WingDefinition definition)
		{
			if ((Object)(object)ragdoll == (Object)null || definition == null)
			{
				return false;
			}
			GameObject val = WingAssetBundle.LoadPrefab(definition.VisualPrefab);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			GameObject val2 = Object.Instantiate<GameObject>(val, ((Component)ragdoll).transform);
			((Object)val2).name = definition.VisualPrefab + "_ragdoll";
			Collider[] componentsInChildren = val2.GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].enabled = false;
			}
			Animator componentInChildren = val2.GetComponentInChildren<Animator>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.Play("Wing_Folded_Idle", 0, 0f);
			}
			Transform val3 = ResolveChest(ragdoll);
			val2.AddComponent<RagdollWingFollower>().Initialize(((Component)ragdoll).transform, val3);
			Rigidbody body = (((Object)(object)val3 != (Object)null) ? ((Component)val3).GetComponentInParent<Rigidbody>() : null);
			val2.AddComponent<WingSecondaryMotion>().Initialize(((Component)ragdoll).transform, body, componentInChildren);
			return true;
		}

		private static Transform ResolveChest(Ragdoll ragdoll)
		{
			Animator[] componentsInChildren = ((Component)ragdoll).GetComponentsInChildren<Animator>(true);
			foreach (Animator val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && val.isHuman)
				{
					Transform val2 = val.GetBoneTransform((HumanBodyBones)54) ?? val.GetBoneTransform((HumanBodyBones)8) ?? val.GetBoneTransform((HumanBodyBones)7);
					if ((Object)(object)val2 != (Object)null)
					{
						return val2;
					}
				}
			}
			string[] obj = new string[5] { "UpperChest", "Chest", "Spine2", "Spine1", "Spine" };
			Transform[] componentsInChildren2 = ((Component)ragdoll).GetComponentsInChildren<Transform>(true);
			string[] array = obj;
			foreach (string b in array)
			{
				Transform[] array2 = componentsInChildren2;
				foreach (Transform val3 in array2)
				{
					string text = ((Object)val3).name;
					int num = text.LastIndexOf(':');
					if (num >= 0)
					{
						text = text.Substring(num + 1);
					}
					if (string.Equals(text, b, StringComparison.OrdinalIgnoreCase))
					{
						return val3;
					}
				}
			}
			return ((Component)ragdoll).transform;
		}
	}
	internal sealed class RagdollWingNetworkDisplay : MonoBehaviour
	{
		private Ragdoll _ragdoll;

		private bool _attached;

		private float _giveUpAt;

		internal void Initialize(Ragdoll ragdoll)
		{
			_ragdoll = ragdoll;
			_giveUpAt = Time.time + 3f;
		}

		private void Update()
		{
			if (!_attached && !((Object)(object)_ragdoll == (Object)null))
			{
				if (WingNetworkState.TryReadRagdollEquipment(_ragdoll, out var definition))
				{
					_attached = WingRagdollVisual.Attach(_ragdoll, definition);
				}
				else if (Time.time >= _giveUpAt)
				{
					Object.Destroy((Object)(object)this);
				}
			}
		}
	}
	internal sealed class RagdollWingFollower : MonoBehaviour
	{
		private Transform _root;

		private Transform _anchor;

		private Quaternion _rootFrameInAnchor;

		internal void Initialize(Transform root, Transform anchor)
		{
			//IL_0021: 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_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_0036: Unknown result type (might be due to invalid IL or missing references)
			_root = root;
			_anchor = (((Object)(object)anchor != (Object)null) ? anchor : root);
			_rootFrameInAnchor = Quaternion.Inverse(_anchor.rotation) * root.rotation;
		}

		private void LateUpdate()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_006c: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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)
			if (!((Object)(object)_root == (Object)null) && !((Object)(object)_anchor == (Object)null))
			{
				Quaternion val = _anchor.rotation * _rootFrameInAnchor;
				Vector3 val2 = default(Vector3);
				((Vector3)(ref val2))..ctor(WingConfig.AttachRight.Value, WingConfig.AttachUp.Value, 0f - WingConfig.AttachBack.Value);
				((Component)this).transform.position = _anchor.position + val * val2;
				((Component)this).transform.rotation = val * Quaternion.Euler(WingConfig.AttachPitch.Value, WingConfig.AttachYaw.Value, WingConfig.AttachRoll.Value);
				((Component)this).transform.localScale = Vector3.one * Mathf.Max(0.001f, WingConfig.WingScale.Value);
			}
		}
	}
	internal sealed class WingVisualController
	{
		private const string Folded = "Wing_Folded_Idle";

		private const string Unfold = "Wing_Unfold";

		private const string Fold = "Wing_Fold";

		private const string JumpFlap = "Wing_Jump_Flap";

		private const string Takeoff = "Wing_Takeoff";

		private const string ClimbLoop = "Wing_Climb_Loop";

		private const string ClimbExit = "Wing_Climb_Exit";

		private const string Glide = "Wing_Glide";

		private const string GlideToFlight = "Wing_Glide_To_Flight";

		private const string FlightToGlide = "Wing_Flight_To_Glide";

		private const string FlightLoop = "Wing_Flight_Loop";

		private const string FlightFlap = "Wing_Flight_Flap";

		private const string FlightLightFlap = "Wing_Flight_Light_Flap";

		private Player _owner;

		private GameObject _instance;

		private Animator _animator;

		private WingFollower _follower;

		private WingPlayerFlightPose _playerPose;

		private WingFlightState _state;

		private bool _poweredTravel;

		private bool _waterLaunch;

		private float _flightFlapStartedAt = -1f;

		private float _flightFlapDuration = 0.9f;

		internal bool Create(Player owner, WingDefinition definition)
		{
			Destroy();
			GameObject val = WingAssetBundle.LoadPrefab(definition.VisualPrefab);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			_owner = owner;
			_instance = Object.Instantiate<GameObject>(val, ((Component)owner).transform);
			((Object)_instance).name = definition.VisualPrefab + "_runtime";
			Collider[] componentsInChildren = _instance.GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].enabled = false;
			}
			_animator = _instance.GetComponentInChildren<Animator>(true);
			if ((Object)(object)_animator == (Object)null)
			{
				ModLog.Error("Wing prefab has no Animator: " + definition.VisualPrefab);
				Destroy();
				return false;
			}
			AnimationClip val2 = ((IEnumerable<AnimationClip>)_animator.runtimeAnimatorController.animationClips).FirstOrDefault((Func<AnimationClip, bool>)((AnimationClip clip) => ((Object)clip).name == "Wing_Flight_Flap"));
			_flightFlapDuration = (((Object)(object)val2 != (Object)null) ? Mathf.Max(0.1f, val2.length) : 0.9f);
			Animator val3 = ResolveBodyAnimator(owner);
			_playerPose = _instance.AddComponent<WingPlayerFlightPose>();
			_playerPose.Initialize(owner, val3);
			_follower = _instance.AddComponent<WingFollower>();
			_follower.SetAnchor(owner, ResolveChest(owner, val3), val3);
			_instance.AddComponent<WingSecondaryMotion>().Initialize(((Component)owner).transform, ((Component)owner).GetComponent<Rigidbody>(), _animator);
			WingAnimationEventReceiver wingAnimationEventReceiver = ((Component)_animator).gameObject.GetComponent<WingAnimationEventReceiver>();
			if ((Object)(object)wingAnimationEventReceiver == (Object)null)
			{
				wingAnimationEventReceiver = ((Component)_animator).gameObject.AddComponent<WingAnimationEventReceiver>();
			}
			wingAnimationEventReceiver.SetOwner(owner);
			_animator.Play("Wing_Folded_Idle", 0, 0f);
			return true;
		}

		internal void SetState(WingFlightState previous, WingFlightState next, bool waterLaunch)
		{
			_state = next;
			_waterLaunch = waterLaunch;
			_playerPose?.SetState(next);
			if (next == WingFlightState.Grounded || next == WingFlightState.Takeoff)
			{
				_poweredTravel = false;
				_playerPose?.SetFlying(flying: false);
			}
			WingNetworkState.PublishFlags(_owner, _state, _waterLaunch, _poweredTravel);
			if (next != WingFlightState.Flight)
			{
				_flightFlapStartedAt = -1f;
			}
			if ((Object)(object)_animator == (Object)null)
			{
				return;
			}
			switch (next)
			{
			case WingFlightState.Grounded:
				Play((previous == WingFlightState.Grounded) ? "Wing_Folded_Idle" : "Wing_Fold", 0.08f);
				break;
			case WingFlightState.Takeoff:
				Play(waterLaunch ? "Wing_Takeoff" : "Wing_Jump_Flap", 0.04f);
				break;
			case WingFlightState.Climb:
				if (_poweredTravel)
				{
					_flightFlapStartedAt = Time.time;
					Play("Wing_Flight_Flap", 0.08f);
				}
				else if (previous != WingFlightState.Takeoff)
				{
					Play("Wing_Climb_Loop", 0.1f);
				}
				break;
			case WingFlightState.Glide:
				switch (previous)
				{
				case WingFlightState.Grounded:
				case WingFlightState.Airborne:
					Play("Wing_Unfold", 0.22f);
					break;
				case WingFlightState.Takeoff:
				case WingFlightState.Climb:
					Play("Wing_Climb_Exit", 0.18f);
					break;
				case WingFlightState.Flight:
				case WingFlightState.Exhausted:
					Play("Wing_Flight_To_Glide", 0.1f);
					break;
				default:
					Play("Wing_Glide", 0.1f);
					break;
				}
				break;
			case WingFlightState.Flight:
				Play((previous == WingFlightState.Glide) ? "Wing_Glide_To_Flight" : "Wing_Flight_Loop", 0.1f);
				break;
			case WingFlightState.Exhausted:
				Play((previous == WingFlightState.Flight) ? "Wing_Flight_To_Glide" : "Wing_Glide", 0.1f);
				break;
			case WingFlightState.Airborne:
				break;
			}
		}

		internal void SetPoweredTravel(bool powered)
		{
			_playerPose?.SetFlying(powered);
			if (_poweredTravel == powered)
			{
				return;
			}
			_poweredTravel = powered;
			WingNetworkState.PublishFlags(_owner, _state, _waterLaunch, _poweredTravel);
			if (!((Object)(object)_animator == (Object)null) && _state != WingFlightState.Takeoff)
			{
				if (powered && _state == WingFlightState.Climb)
				{
					RequestFlightFlap();
				}
				else if (!powered && _state == WingFlightState.Climb)
				{
					Play("Wing_Climb_Loop", 0.12f);
				}
			}
		}

		internal void SetFlightAttitude(float pitch, float bank, bool powered, float dt)
		{
			float pitch2 = (powered ? pitch : 0f);
			float bank2 = (powered ? bank : 0f);
			_follower?.SetFlightAttitude(pitch2, bank2, powered);
			_playerPose?.SetFlightAttitude(pitch2, bank2);
			WingNetworkState.PublishAttitude(_owner, pitch2, bank2);
		}

		internal void RequestFlightFlap()
		{
			if ((Object)(object)_animator != (Object)null && (!(_flightFlapStartedAt >= 0f) || !(Time.time - _flightFlapStartedAt < _flightFlapDuration)))
			{
				WingNetworkState.PublishCommand(_owner, WingNetworkState.VisualCommand.FlightFlap);
				_flightFlapStartedAt = Time.time;
				Play("Wing_Flight_Flap", 0.08f);
			}
		}

		internal void RequestLightFlightFlap()
		{
			if ((Object)(object)_animator != (Object)null && _state == WingFlightState.Flight)
			{
				WingNetworkState.PublishCommand(_owner, WingNetworkState.VisualCommand.LightFlightFlap);
				Play("Wing_Flight_Light_Flap", 0.16f);
			}
		}

		internal float GetLiftFactor()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_animator == (Object)null)
			{
				return 0f;
			}
			AnimatorStateInfo val = (_animator.IsInTransition(0) ? _animator.GetNextAnimatorStateInfo(0) : _animator.GetCurrentAnimatorStateInfo(0));
			float time = ((AnimatorStateInfo)(ref val)).normalizedTime - Mathf.Floor(((AnimatorStateInfo)(ref val)).normalizedTime);
			if (((AnimatorStateInfo)(ref val)).IsName("Wing_Jump_Flap") || ((AnimatorStateInfo)(ref val)).IsName("Wing_Takeoff"))
			{
				return Stroke(time, 0.225f, 0.6f);
			}
			if (((AnimatorStateInfo)(ref val)).IsName("Wing_Flight_Flap"))
			{
				return Stroke(time, 23f / 90f, 34f / 45f);
			}
			if (((AnimatorStateInfo)(ref val)).IsName("Wing_Climb_Loop"))
			{
				return Stroke(time, 4f / 15f, 23f / 30f);
			}
			return 0f;
		}

		internal bool TryGetClimbPhase(out float phase)
		{
			//IL_001e: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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)
			phase = 0f;
			if ((Object)(object)_animator == (Object)null)
			{
				return false;
			}
			AnimatorStateInfo val = _animator.GetCurrentAnimatorStateInfo(0);
			if (!((AnimatorStateInfo)(ref val)).IsName("Wing_Climb_Loop") && _animator.IsInTransition(0))
			{
				AnimatorStateInfo nextAnimatorStateInfo = _animator.GetNextAnimatorStateInfo(0);
				if (((AnimatorStateInfo)(ref nextAnimatorStateInfo)).IsName("Wing_Climb_Loop"))
				{
					val = nextAnimatorStateInfo;
				}
			}
			if (!((AnimatorStateInfo)(ref val)).IsName("Wing_Climb_Loop"))
			{
				return false;
			}
			phase = Mathf.Repeat(((AnimatorStateInfo)(ref val)).normalizedTime, 1f);
			return true;
		}

		internal void RefreshAnchor()
		{
			if ((Object)(object)_follower != (Object)null && (Object)(object)_follower.Anchor == (Object)null)
			{
				Animator bodyAnimator = ResolveBodyAnimator(_owner);
				_follower.SetAnchor(_owner, ResolveChest(_owner, bodyAnimator), bodyAnimator);
			}
			if ((Object)(object)_animator != (Object)null && _poweredTravel && _flightFlapStartedAt >= 0f && Time.time - _flightFlapStartedAt >= _flightFlapDuration)
			{
				_flightFlapStartedAt = -1f;
				Play((_state == WingFlightState.Flight) ? "Wing_Flight_Loop" : "Wing_Climb_Loop", 0.1f);
			}
		}

		internal void Destroy()
		{
			if ((Object)(object)_instance != (Object)null)
			{
				Object.Destroy((Object)(object)_instance);
			}
			_owner = null;
			_instance = null;
			_animator = null;
			_follower = null;
			_playerPose = null;
			_state = WingFlightState.Grounded;
			_poweredTravel = false;
			_waterLaunch = false;
			_flightFlapStartedAt = -1f;
			_flightFlapDuration = 0.9f;
		}

		private void Play(string state, float blend)
		{
			WingNetworkState.PublishAnimation(_owner, NetworkAnimationForState(state));
			_animator.CrossFadeInFixedTime(state, blend, 0, 0f);
		}

		internal void ApplyNetworkAnimation(WingNetworkState.VisualAnimation animation, float elapsed)
		{
			if ((Object)(object)_animator == (Object)null)
			{
				return;
			}
			string text = StateForNetworkAnimation(animation);
			if (!string.IsNullOrEmpty(text))
			{
				float num = ClipLength(text);
				float num2 = ((!IsLoopingState(text)) ? Mathf.Clamp(elapsed, 0f, Mathf.Max(0f, num - 0.001f)) : ((num > 0.001f) ? Mathf.Repeat(elapsed, num) : 0f));
				_animator.CrossFadeInFixedTime(text, 0.05f, 0, num2);
				if (text == "Wing_Flight_Flap")
				{
					_flightFlapStartedAt = Time.time - Mathf.Min(elapsed, _flightFlapDuration);
				}
			}
		}

		private float ClipLength(string state)
		{
			Animator animator = _animator;
			if ((Object)(object)((animator != null) ? animator.runtimeAnimatorController : null) == (Object)null)
			{
				return 0f;
			}
			AnimationClip[] animationClips = _animator.runtimeAnimatorController.animationClips;
			foreach (AnimationClip val in animationClips)
			{
				if ((Object)(object)val != (Object)null && ((Object)val).name == state)
				{
					return val.length;
				}
			}
			return 0f;
		}

		private static bool IsLoopingState(string state)
		{
			switch (state)
			{
			default:
				return state == "Wing_Climb_Loop";
			case "Wing_Folded_Idle":
			case "Wing_Glide":
			case "Wing_Flight_Loop":
				return true;
			}
		}

		private static WingNetworkState.VisualAnimation NetworkAnimationForState(string state)
		{
			return state switch
			{
				"Wing_Folded_Idle" => WingNetworkState.VisualAnimation.Folded, 
				"Wing_Unfold" => WingNetworkState.VisualAnimation.Unfold, 
				"Wing_Fold" => WingNetworkState.VisualAnimation.Fold, 
				"Wing_Jump_Flap" => WingNetworkState.VisualAnimation.JumpFlap, 
				"Wing_Takeoff" => WingNetworkState.VisualAnimation.Takeoff, 
				"Wing_Climb_Loop" => WingNetworkState.VisualAnimation.ClimbLoop, 
				"Wing_Climb_Exit" => WingNetworkState.VisualAnimation.ClimbExit, 
				"Wing_Glide" => WingNetworkState.VisualAnimation.Glide, 
				"Wing_Glide_To_Flight" => WingNetworkState.VisualAnimation.GlideToFlight, 
				"Wing_Flight_To_Glide" => WingNetworkState.VisualAnimation.FlightToGlide, 
				"Wing_Flight_Loop" => WingNetworkState.VisualAnimation.FlightLoop, 
				"Wing_Flight_Flap" => WingNetworkState.VisualAnimation.FlightFlap, 
				"Wing_Flight_Light_Flap" => WingNetworkState.VisualAnimation.FlightLightFlap, 
				_ => WingNetworkState.VisualAnimation.None, 
			};
		}

		private static string StateForNetworkAnimation(WingNetworkState.VisualAnimation animation)
		{
			return animation switch
			{
				WingNetworkState.VisualAnimation.Folded => "Wing_Folded_Idle", 
				WingNetworkState.VisualAnimation.Unfold => "Wing_Unfold", 
				WingNetworkState.VisualAnimation.Fold => "Wing_Fold", 
				WingNetworkState.VisualAnimation.JumpFlap => "Wing_Jump_Flap", 
				WingNetworkState.VisualAnimation.Takeoff => "Wing_Takeoff", 
				WingNetworkState.VisualAnimation.ClimbLoop => "Wing_Climb_Loop", 
				WingNetworkState.VisualAnimation.ClimbExit => "Wing_Climb_Exit", 
				WingNetworkState.VisualAnimation.Glide => "Wing_Glide", 
				WingNetworkState.VisualAnimation.GlideToFlight => "Wing_Glide_To_Flight", 
				WingNetworkState.VisualAnimation.FlightToGlide => "Wing_Flight_To_Glide", 
				WingNetworkState.VisualAnimation.FlightLoop => "Wing_Flight_Loop", 
				WingNetworkState.VisualAnimation.FlightFlap => "Wing_Flight_Flap", 
				WingNetworkState.VisualAnimation.FlightLightFlap => "Wing_Flight_Light_Flap", 
				_ => null, 
			};
		}

		private static float Stroke(float time, float start, float end)
		{
			if (time <= start || time >= end)
			{
				return 0f;
			}
			return Mathf.Sin(Mathf.InverseLerp(start, end, time) * (float)Math.PI);
		}

		private static Animator ResolveBodyAnimator(Player player)
		{
			GameObject val = ((player != null) ? ((Character)player).GetVisual() : null);
			Animator[] array = (((Object)(object)val != (Object)null) ? val.GetComponentsInChildren<Animator>(true) : ((Component)player).GetComponentsInChildren<Animator>(true));
			foreach (Animator val2 in array)
			{
				if ((Object)(object)val2 != (Object)null && val2.isHuman)
				{
					return val2;
				}
			}
			return null;
		}

		private static Transform ResolveChest(Player player, Animator bodyAnimator = null)
		{
			bodyAnimator = bodyAnimator ?? ResolveBodyAnimator(player);
			if ((Object)(object)bodyAnimator != (Object)null)
			{
				Transform val = bodyAnimator.GetBoneTransform((HumanBodyBones)54) ?? bodyAnimator.GetBoneTransform((HumanBodyBones)8) ?? bodyAnimator.GetBoneTransform((HumanBodyBones)7);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			GameObject val2 = ((player != null) ? ((Character)player).GetVisual() : null);
			Transform[] array = (((Object)(object)val2 != (Object)null) ? val2.GetComponentsInChildren<Transform>(true) : ((Component)player).GetComponentsInChildren<Transform>(true));
			string[] array2 = new string[5] { "UpperChest", "Chest", "Spine2", "Spine1", "Spine" };
			foreach (string b in array2)
			{
				Transform[] array3 = array;
				foreach (Transform val3 in array3)
				{
					string text = ((Object)val3).name;
					int num = text.LastIndexOf(':');
					if (num >= 0)
					{
						text = text.Substring(num + 1);
					}
					if (string.Equals(text, b, StringComparison.OrdinalIgnoreCase))
					{
						return val3;
					}
				}
			}
			return ((Component)player).transform;
		}
	}
	internal sealed class WingAnimationEventReceiver : MonoBehaviour
	{
		private Player _owner;

		internal void SetOwner(Player owner)
		{
			_owner = owner;
		}

		public void HW_WingImpulse(AnimationEvent animationEvent)
		{
			if (animationEvent != null)
			{
				WingFlightRuntime.OnAnimationImpulse(_owner, animationEvent.stringParameter, animationEvent.intParameter);
			}
		}
	}
	[DefaultExecutionOrder(150)]
	internal sealed class WingPlayerFlightPose : MonoBehaviour
	{
		private sealed class BoneOffset
		{
			internal readonly Transform Bone;

			private Quaternion _beforeLocal;

			private Quaternion _appliedLocal;

			private bool _pending;

			internal BoneOffset(Transform bone)
			{
				Bone = bone;
			}

			internal void Apply(Quaternion worldOffset)
			{
				//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_0026: 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_0043: 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)
				if (!((Object)(object)Bone == (Object)null))
				{
					_beforeLocal = Bone.localRotation;
					Bone.rotation = worldOffset * Bone.rotation;
					_appliedLocal = Bone.localRotation;
					_pending = true;
				}
			}

			internal void SetWorldRotation(Quaternion worldRotation)
			{
				//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_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)Bone == (Object)null))
				{
					_beforeLocal = Bone.localRotation;
					Bone.rotation = worldRotation;
					_appliedLocal = Bone.localRotation;
					_pending = true;
				}
			}

			internal void SetLocalRotation(Quaternion localRotation)
			{
				//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_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)Bone == (Object)null))
				{
					_beforeLocal = Bone.localRotation;
					Bone.localRotation = localRotation;
					_appliedLocal = Bone.localRotation;
					_pending = true;
				}
			}

			internal void Restore()
			{
				//IL_001d: 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_003b: Unknown result type (might be due to invalid IL or missing references)
				if (_pending && !((Object)(object)Bone == (Object)null))
				{
					if (Quaternion.Angle(Bone.localRotation, _appliedLocal) < 0.05f)
					{
						Bone.localRotation = _beforeLocal;
					}
					_pending = false;
				}
			}
		}

		private Player _owner;

		private BoneOffset _hips;

		private BoneOffset _spine;

		private BoneOffset _chest;

		private BoneOffset _neck;

		private BoneOffset _leftUpper;

		private BoneOffset _leftLower;

		private BoneOffset _rightUpper;

		private BoneOffset _rightLower;

		private BoneOffset _leftUpperLeg;

		private BoneOffset _leftLowerLeg;

		private BoneOffset _rightUpperLeg;

		private BoneOffset _rightLowerLeg;

		private Transform _head;

		private Transform _leftHand;

		private Transform _rightHand;

		private Transform _leftFoot;

		private Transform _rightFoot;

		private bool _flying;

		private float _blend;

		private WingFlightState _state;

		private float _combatBlend;

		private float _flightPitch;

		private float _flightBank;

		private bool _airborneLowerBodyCached;

		private Quaternion _airborneHipsLocal;

		private Quaternion _airborneSpineLocal;

		private Quaternion _airborneChestLocal;

		private Quaternion _airborneLeftUpperLegLocal;

		private Quaternion _airborneLeftLowerLegLocal;

		private Quaternion _airborneRightUpperLegLocal;

		private Quaternion _airborneRightLowerLegLocal;

		internal void Initialize(Player owner, Animator animator)
		{
			_owner = owner;
			GameObject val = (((Object)(object)owner != (Object)null) ? ((Character)owner).GetVisual() : null);
			if (!((Object)(object)val == (Object)null))
			{
				Transform val2 = Human(animator, (HumanBodyBones)0) ?? FindBone(val, "hips", "pelvis");
				Transform val3 = Human(animator, (HumanBodyBones)7) ?? FindBone(val, "spine", "spine1");
				Transform val4 = Human(animator, (HumanBodyBones)54) ?? Human(animator, (HumanBodyBones)8) ?? FindBone(val, "upperchest", "chest", "spine2");
				Transform val5 = Human(animator, (HumanBodyBones)9) ?? FindBone(val, "neck");
				_head = Human(animator, (HumanBodyBones)10) ?? FindBone(val, "head");
				Transform val6 = Human(animator, (HumanBodyBones)13) ?? FindBone(val, "leftupperarm", "leftarm", "upperarm_l");
				Transform bone = Human(animator, (HumanBodyBones)15) ?? FindBone(val, "leftlowerarm", "leftforearm", "forearm_l");
				Transform val7 = Human(animator, (HumanBodyBones)14) ?? FindBone(val, "rightupperarm", "rightarm", "upperarm_r");
				Transform bone2 = Human(animator, (HumanBodyBones)16) ?? FindBone(val, "rightlowerarm", "rightforearm", "forearm_r");
				_leftHand = Human(animator, (HumanBodyBones)17) ?? FindBone(val, "lefthand", "hand_l");
				_rightHand = Human(animator, (HumanBodyBones)18) ?? FindBone(val, "righthand", "hand_r");
				Transform val8 = Human(animator, (HumanBodyBones)1) ?? FindBone(val, "leftupperleg", "leftthigh", "thigh_l");
				Transform bone3 = Human(animator, (HumanBodyBones)3) ?? FindBone(val, "leftlowerleg", "leftshin", "calf_l");
				Transform val9 = Human(animator, (HumanBodyBones)2) ?? FindBone(val, "rightupperleg", "rightthigh", "thigh_r");
				Transform bone4 = Human(animator, (HumanBodyBones)4) ?? FindBone(val, "rightlowerleg", "rightshin", "calf_r");
				_leftFoot = Human(animator, (HumanBodyBones)5) ?? FindBone(val, "leftfoot", "foot_l");
				_rightFoot = Human(animator, (HumanBodyBones)6) ?? FindBone(val, "rightfoot", "foot_r");
				_hips = new BoneOffset(val2);
				_spine = new BoneOffset(val3);
				_chest = new BoneOffset(val4);
				_neck = new BoneOffset(val5);
				_leftUpper = new BoneOffset(val6);
				_leftLower = new BoneOffset(bone);
				_rightUpper = new BoneOffset(val7);
				_rightLower = new BoneOffset(bone2);
				_leftUpperLeg = new BoneOffset(val8);
				_leftLowerLeg = new BoneOffset(bone3);
				_rightUpperLeg = new BoneOffset(val9);
				_rightLowerLeg = new BoneOffset(bone4);
				ModLog.Info("Player flight pose bones hips=" + ((Object)(object)val2 != (Object)null) + " spine=" + ((Object)(object)val3 != (Object)null && (Object)(object)val4 != (Object)null && (Object)(object)val5 != (Object)null) + " arms=" + ((Object)(object)val6 != (Object)null && (Object)(object)val7 != (Object)null) + " legs=" + ((Object)(object)val8 != (Object)null && (Object)(object)val9 != (Object)null));
			}
		}

		internal void SetFlying(bool flying)
		{
			_flying = flying;
		}

		internal void SetState(WingFlightState state)
		{
			_state = state;
			if (state != WingFlightState.Glide && state != WingFlightState.Climb)
			{
				_airborneLowerBodyCached = false;
			}
		}

		internal void SetFlightAttitude(float pitch, float bank)
		{
			_flightPitch = pitch;
			_flightBank = bank;
		}

		private void LateUpdate()
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_0092: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_052e: Unknown result type (might be due to invalid IL or missing references)
			//IL_052f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0531: Unknown result type (might be due to invalid IL or missing references)
			//IL_0533: Unknown result type (might be due to invalid IL or missing references)
			//IL_0535: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: 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_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: 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_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_0373: Unknown result type (might be due to invalid IL or missing references)
			//IL_0386: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_038d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Unknown result type (might be due to invalid IL or missing references)
			//IL_039e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0409: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_043b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0448: Unknown result type (might be due to invalid IL or missing references)
			//IL_044a: Unknown result type (might be due to invalid IL or missing references)
			//IL_044f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0456: Unknown result type (might be due to invalid IL or missing references)
			//IL_045b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0460: Unknown result type (might be due to invalid IL or missing references)
			//IL_0464: Unknown result type (might be due to invalid IL or missing references)
			//IL_0469: Unknown result type (might be due to invalid IL or missing references)
			//IL_046b: Unknown result type (might be due to invalid IL or missing references)
			//IL_046d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0472: Unknown result type (might be due to invalid IL or missing references)
			//IL_0479: Unknown result type (might be due to invalid IL or missing references)
			//IL_047e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0483: Unknown result type (might be due to invalid IL or missing references)
			//IL_0487: Unknown result type (might be due to invalid IL or missing references)
			//IL_048c: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_050f: Unknown result type (might be due to invalid IL or missing references)
			RestoreLastOffsets();
			float num = Mathf.Max(0.05f, WingConfig.FlightPoseBlendSeconds.Value);
			_blend = Mathf.MoveTowards(_blend, _flying ? 1f : 0f, Time.deltaTime / num);
			bool flag = (Object)(object)_owner != (Object)null && (_state == WingFlightState.Glide || _state == WingFlightState.Climb);
			bool flag2 = flag && IsBowCombat(_owner);
			Quaternion leftUpperWorld = Quaternion.identity;
			Quaternion leftLowerWorld = Quaternion.identity;
			Quaternion rightUpperWorld = Quaternion.identity;
			Quaternion rightLowerWorld = Quaternion.identity;
			Quaternion neckWorld = Quaternion.identity;
			if (flag2)
			{
				leftUpperWorld = (((Object)(object)_leftUpper?.Bone != (Object)null) ? _leftUpper.Bone.rotation : Quaternion.identity);
				leftLowerWorld = (((Object)(object)_leftLower?.Bone != (Object)null) ? _leftLower.Bone.rotation : Quaternion.identity);
				rightUpperWorld = (((Object)(object)_rightUpper?.Bone != (Object)null) ? _rightUpper.Bone.rotation : Quaternion.identity);
				rightLowerWorld = (((Object)(object)_rightLower?.Bone != (Object)null) ? _rightLower.Bone.rotation : Quaternion.identity);
				neckWorld = (((Object)(object)_neck?.Bone != (Object)null) ? _neck.Bone.rotation : Quaternion.identity);
			}
			bool flag3 = flag && (((Character)_owner).IsDrawingBow() || ((Character)_owner).InAttack());
			_combatBlend = Mathf.MoveTowards(_combatBlend, flag3 ? 1f : 0f, Time.deltaTime / num);
			if ((_blend <= 0.0001f && _combatBlend <= 0.0001f) || (Object)(object)_owner == (Object)null)
			{
				if (flag && !flag2)
				{
					CacheAirborneBodyFrame();
				}
				return;
			}
			if (_blend > 0.0001f)
			{
				Quaternion worldOffset = Quaternion.AngleAxis((WingConfig.FlightBodyPitchDegrees.Value - _flightPitch) * _blend, ((Component)_owner).transform.right) * Quaternion.AngleAxis(_flightBank * _blend, ((Component)_owner).transform.forward);
				_hips?.Apply(worldOffset);
				Vector3 right = ((Component)_owner).transform.right;
				Vector3 forward = ((Component)_owner).transform.forward;
				Vector3 val = Quaternion.AngleAxis(0f - _flightPitch, ((Component)_owner).transform.right) * Quaternion.AngleAxis(_flightBank, ((Component)_owner).transform.forward) * forward;
				Vector3 normalized = ((Vector3)(ref val)).normalized;
				PointBone(_spine, _chest?.Bone, normalized, _blend * 0.82f);
				PointBone(_chest, _neck?.Bone, normalized, _blend * 0.88f);
				PointBone(_neck, _head, normalized, _blend * 0.92f);
				val = -normalized - right * 0.14f;
				Vector3 normalized2 = ((Vector3)(ref val)).normalized;
				val = -normalized + right * 0.14f;
				Vector3 normalized3 = ((Vector3)(ref val)).normalized;
				PointBone(_leftUpper, _leftLower?.Bone, normalized2, _blend);
				PointBone(_rightUpper, _rightLower?.Bone, normalized3, _blend);
				PointBone(_leftLower, _leftHand, normalized2, _blend);
				PointBone(_rightLower, _rightHand, normalized3, _blend);
				val = -normalized - right * 0.055f;
				Vector3 normalized4 = ((Vector3)(ref val)).normalized;
				val = -normalized + right * 0.055f;
				Vector3 normalized5 = ((Vector3)(ref val)).normalized;
				PointBone(_leftUpperLeg, _leftLowerLeg?.Bone, normalized4, _blend * 0.92f);
				PointBone(_rightUpperLeg, _rightLowerLeg?.Bone, normalized5, _blend * 0.92f);
				PointBone(_leftLowerLeg, _leftFoot, normalized4, _blend * 0.96f);
				PointBone(_rightLowerLeg, _rightFoot, normalized5, _blend * 0.96f);
			}
			if (flag2 && _airborneLowerBodyCached)
			{
				PreserveAirborneBowFrame(leftUpperWorld, leftLowerWorld, rightUpperWorld, rightLowerWorld, neckWorld);
				return;
			}
			if (_combatBlend > 0.0001f)
			{
				StabilizeCombatTorso(_combatBlend);
			}
			if (flag)
			{
				CacheAirborneBodyFrame();
			}
		}

		private void StabilizeCombatTorso(float blend)
		{
			//IL_005a: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: 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_00f0: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: 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_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: 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_0198: 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_01cc: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_spine?.Bone == (Object)null || (Object)(object)_leftUpper?.Bone == (Object)null || (Object)(object)_rightUpper?.Bone == (Object)null)
			{
				return;
			}
			Vector3 up = ((Component)_owner).transform.up;
			Vector3 val = Vector3.ProjectOnPlane(_rightUpper.Bone.position - _leftUpper.Bone.position, up);
			Vector3 val2 = Vector3.ProjectOnPlane(((Character)_owner).GetVelocity(), up);
			if (((Vector3)(ref val2)).sqrMagnitude < 0.01f)
			{
				val2 = Vector3.ProjectOnPlane(((Component)_owner).transform.forward, up);
			}
			Vector3 val3 = Vector3.Cross(up, ((Vector3)(ref val2)).normalized);
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f || ((Vector3)(ref val3)).sqrMagnitude < 0.0001f)
			{
				return;
			}
			float num = Vector3.SignedAngle(((Vector3)(ref val)).normalized, ((Vector3)(ref val3)).normalized, up);
			num = Mathf.Clamp(num, -95f, 95f) * blend;
			if (!(Mathf.Abs(num) < 0.05f))
			{
				Quaternion rotation = _leftUpper.Bone.rotation;
				Quaternion rotation2 = _rightUpper.Bone.rotation;
				Quaternion worldRotation = (((Object)(object)_neck?.Bone != (Object)null) ? _neck.Bone.rotation : Quaternion.identity);
				_spine.Apply(Quaternion.AngleAxis(num, up));
				_leftUpper.SetWorldRotation(rotation);
				_rightUpper.SetWorldRotation(rotation2);
				if ((Object)(object)_neck?.Bone != (Object)null)
				{
					_neck.SetWorldRotation(worldRotation);
				}
			}
		}

		private static bool IsBowCombat(Player owner)
		{
			ItemData val = ((owner != null) ? ((Humanoid)owner).GetCurrentWeapon() : null);
			if (val != null && val.m_shared.m_attack.m_bowDraw)
			{
				if (!((Character)owner).IsDrawingBow())
				{
					return ((Character)owner).InAttack();
				}
				return true;
			}
			return false;
		}

		private void CacheAirborneBodyFrame()
		{
			//IL_00c9: 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_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: 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_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_hips?.Bone == (Object)null) && !((Object)(object)_spine?.Bone == (Object)null) && !((Object)(object)_chest?.Bone == (Object)null) && !((Object)(object)_leftUpperLeg?.Bone == (Object)null) && !((Object)(object)_leftLowerLeg?.Bone == (Object)null) && !((Object)(object)_rightUpperLeg?.Bone == (Object)null) && !((Object)(object)_rightLowerLeg?.Bone == (Object)null))
			{
				_airborneHipsLocal = _hips.Bone.localRotation;
				_airborneSpineLocal = _spine.Bone.localRotation;
				_airborneChestLocal = _chest.Bone.localRotation;
				_airborneLeftUpperLegLocal = _leftUpperLeg.Bone.localRotation;
				_airborneLeftLowerLegLocal = _leftLowerLeg.Bone.localRotation;
				_airborneRightUpperLegLocal = _rightUpperLeg.Bone.localRotation;
				_airborneRightLowerLegLocal = _rightLowerLeg.Bone.localRotation;
				_airborneLowerBodyCached = true;
			}
		}

		private void PreserveAirborneBowFrame(Quaternion leftUpperWorld, Quaternion leftLowerWorld, Quaternion rightUpperWorld, Quaternion rightLowerWorld, Quaternion neckWorld)
		{
			//IL_0007: 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_0029: 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_004b: 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_006d: 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_0095: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
			_hips.SetLocalRotation(_airborneHipsLocal);
			_spine.SetLocalRotation(_airborneSpineLocal);
			_chest.SetLocalRotation(_airborneChestLocal);
			_leftUpperLeg.SetLocalRotation(_airborneLeftUpperLegLocal);
			_leftLowerLeg.SetLocalRotation(_airborneLeftLowerLegLocal);
			_rightUpperLeg.SetLocalRotation(_airborneRightUpperLegLocal);
			_rightLowerLeg.SetLocalRotation(_airborneRightLowerLegLocal);
			_leftUpper?.SetWorldRotation(leftUpperWorld);
			_leftLower?.SetWorldRotation(leftLowerWorld);
			_rightUpper?.SetWorldRotation(rightUpperWorld);
			_rightLower?.SetWorldRotation(rightLowerWorld);
			_neck?.SetWorldRotation(neckWorld);
		}

		private static void PointBone(BoneOffset bone, Transform child, Vector3 desiredDirection, float blend)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0044: 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_0051: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)bone?.Bone == (Object)null) && !((Object)(object)child == (Object)null))
			{
				Vector3 val = child.position - bone.Bone.position;
				if (!(((Vector3)(ref val)).sqrMagnitude < 0.0001f))
				{
					Quaternion worldOffset = Quaternion.Slerp(Quaternion.identity, Quaternion.FromToRotation(((Vector3)(ref val)).normalized, desiredDirection), blend);
					bone.Apply(worldOffset);
				}
			}
		}

		private void RestoreLastOffsets()
		{
			_neck?.Restore();
			_chest?.Restore();
			_spine?.Restore();
			_leftLower?.Restore();
			_rightLower?.Restore();
			_leftUpper?.Restore();
			_rightUpper?.Restore();
			_leftLowerLeg?.Restore();
			_rightLowerLeg?.Restore();
			_leftUpperLeg?.Restore();
			_rightUpperLeg?.Restore();
			_hips?.Restore();
		}

		private static Transform Human(Animator animator, HumanBodyBones bone)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)animator != (Object)null) || !animator.isHuman)
			{
				return null;
			}
			return animator.GetBoneTransform(bone);
		}

		private static Transform FindBone(GameObject visual, params string[] candidates)
		{
			Transform[] componentsInChildren = visual.GetComponentsInChildren<Transform>(true);
			foreach (string value in candidates)
			{
				Transform[] array = componentsInChildren;
				foreach (Transform val in array)
				{
					string text = Normalize(((Object)val).name);
					if (text == Normalize(value) || text.EndsWith(Normalize(value)))
					{
						return val;
					}
				}
			}
			return null;
		}

		private static string Normalize(string value)
		{
			return new string(value.Where(char.IsLetterOrDigit).Select(char.ToLowerInvariant).ToArray());
		}

		private void OnDisable()
		{
			RestoreLastOffsets();
		}
	}
	[DefaultExecutionOrder(200)]
	internal sealed class WingFollower : MonoBehaviour
	{
		private Player _owner;

		private Quaternion _playerFrameInAnchor;

		internal Transform Anchor { get; private set; }

		internal void SetAnchor(Player owner, Transform anchor, Animator bodyAnimator)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: 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_00a3: 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_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_0076: 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_007c: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			_owner = owner;
			Anchor = (((Object)(object)anchor != (Object)null) ? anchor : ((owner != null) ? ((Component)owner).transform : null));
			if (!((Object)(object)Anchor == (Object)null))
			{
				Quaternion val = (((Object)(object)owner != (Object)null) ? ((Component)owner).transform.rotation : ((Component)this).transform.rotation);
				if (TryGetBindAnchorRotation(bodyAnimator, Anchor, out var rotation))
				{
					Quaternion val2 = Quaternion.Inverse(((Component)bodyAnimator).transform.rotation) * val;
					_playerFrameInAnchor = Quaternion.Inverse(rotation) * val2;
				}
				else
				{
					_playerFrameInAnchor = Quaternion.Inverse(Anchor.rotation) * val;
				}
				((Component)this).transform.SetParent(((Object)(object)owner != (Object)null) ? ((Component)owner).transform : null, true);
			}
		}

		private static bool TryGetBindAnchorRotation(Animator animator, Transform anchor, out Quaternion rotation)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			rotation = Quaternion.identity;
			if ((Object)(object)animator == (Object)null || (Object)(object)animator.avatar == (Object)null || !animator.avatar.isValid || (Object)(object)anchor == (Object)null)
			{
				return false;
			}
			SkeletonBone[] skeleton = animator.avatar.humanDescription.skeleton;
			Transform val = anchor;
			while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)((Component)animator).transform)
			{
				if (!TryFindBindRotation(skeleton, ((Object)val).name, out var rotation2))
				{
					return false;
				}
				rotation = rotation2 * rotation;
				val = val.parent;
			}
			return (Object)(object)val == (Object)(object)((Component)animator).transform;
		}

		private static bool TryFindBindRotation(SkeletonBone[] skeleton, string transformName, out Quaternion rotation)
		{
			//IL_0059: 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_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)
			string b = StripNamespace(transformName);
			for (int i = 0; i < skeleton.Length; i++)
			{
				if (string.Equals(skeleton[i].name, transformName, StringComparison.Ordinal) || string.Equals(StripNamespace(skeleton[i].name), b, StringComparison.OrdinalIgnoreCase))
				{
					rotation = skeleton[i].rotation;
					return true;
				}
			}
			rotation = Quaternion.identity;
			return false;
		}

		private static string StripNamespace(string name)
		{
			int num = name.LastIndexOf(':');
			if (num < 0)
			{
				return name;
			}
			return name.Substring(num + 1);
		}

		internal void SetFlightAttitude(float pitch, float bank, bool powered)
		{
		}

		private void LateUpdate()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_006c: 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_006e: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_owner == (Object)null) && !((Object)(object)Anchor == (Object)null))
			{
				Quaternion val = Anchor.rotation * _playerFrameInAnchor;
				Vector3 position = Anchor.position;
				Vector3 val2 = default(Vector3);
				((Vector3)(ref val2))..ctor(WingConfig.AttachRight.Value, WingConfig.AttachUp.Value, 0f - WingConfig.AttachBack.Value);
				((Component)this).transform.position = position + val * val2;
				((Component)this).transform.rotation = val * Quaternion.Euler(WingConfig.AttachPitch.Value, WingConfig.AttachYaw.Value, WingConfig.AttachRoll.Value);
				float num = Mathf.Max(0.001f, WingConfig.WingScale.Value);
				Vector3 lossyScale = ((Component)_owner).transform.lossyScale;
				((Component)this).transform.localScale = new Vector3(num / Mathf.Max(0.0001f, Mathf.Abs(lossyScale.x)), num / Mathf.Max(0.0001f, Mathf.Abs(lossyScale.y)), num / Mathf.Max(0.0001f, Mathf.Abs(lossyScale.z)));
			}
		}
	}
	[DefaultExecutionOrder(250)]
	internal sealed class WingSecondaryMotion : MonoBehaviour
	{
		private static readonly int FoldedHash = Animator.StringToHash("Wing_Folded_Idle");

		private static readonly int GlideHash = Animator.StringToHash("Wing_Glide");

		private static readonly int FlightLoopHash = Animator.StringToHash("Wing_Flight_Loop");

		private static readonly int FlightFlapHash = Animator.StringToHash("Wing_Flight_Flap");

		private static readonly int FlightLightFlapHash = Animator.StringToHash("Wing_Flight_Light_Flap");

		private static readonly int ClimbLoopHash = Animator.StringToHash("Wing_Climb_Loop");

		private static readonly int JumpFlapHash = Animator.StringToHash("Wing_Jump_Flap");

		private static readonly int TakeoffHash = Animator.StringToHash("Wing_Takeoff");

		private Transform _source;

		private Rigidbody _body;

		private Animator _animator;

		private Transform[] _tips;

		private Quaternion[] _lastOffsets;

		private Transform[] _spines;

		private Quaternion[] _spineBefore;

		private Quaternion[] _spineApplied;

		private bool[] _spinePending;

		private float[] _spineAlong;

		private float[] _spineSide;

		private float[] _contacts;

		private readonly RaycastHit[] _hits = (RaycastHit[])(object)new RaycastHit[6];

		private int _probeCursor;

		private Vector2 _smoothed;

		internal void Initialize(Transform source, Rigidbody body, Animator animator)
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			_source = source;
			_body = body;
			_animator = animator;
			Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true);
			_tips = (from value in ((Component)this).GetComponentsInChildren<Transform>(true)
				where value.childCount == 0 && (((Object)value).name.StartsWith("bone_right", StringComparison.OrdinalIgnoreCase) || ((Object)value).name.StartsWith("bone_left", StringComparison.OrdinalIgnoreCase))
				select value).ToArray();
			_lastOffsets = (Quaternion[])(object)new Quaternion[_tips.Length];
			_contacts = new float[_tips.Length];
			for (int num = 0; num < _lastOffsets.Length; num++)
			{
				_lastOffsets[num] = Quaternion.identity;
			}
			int[] flexIndices = new int[6] { 4, 8, 12, 16, 20, 24 };
			_spines = (from value in componentsInChildren
				where IsStructuralFlexBone(((Object)value).name, flexIndices)
				orderby ((Object)value).name
				select value).ToArray();
			_spineBefore = (Quaternion[])(object)new Quaternion[_spines.Length];
			_spineApplied = (Quaternion[])(object)new Quaternion[_spines.Length];
			_spinePending = new bool[_spines.Length];
			_spineAlong = new float[_spines.Length];
			_spineSide = new float[_spines.Length];
			for (int num2 = 0; num2 < _spines.Length; num2++)
			{
				int num3 = ParseStructuralIndex(((Object)_spines[num2]).name);
				_spineAlong[num2] = Mathf.Clamp01((float)num3 / 24f);
				_spineSide[num2] = (((Object)_spines[num2]).name.StartsWith("bone_left", StringComparison.OrdinalIgnoreCase) ? (-1f) : 1f);
			}
		}

		private void LateUpdate()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_00a5: 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_00b5: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: 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_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: 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_0210: 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_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			if (_tips != null && !((Object)(object)_source == (Object)null))
			{
				for (int i = 0; i < _tips.Length; i++)
				{
					Transform obj = _tips[i];
					obj.localRotation *= Quaternion.Inverse(_lastOffsets[i]);
				}
				RestoreStructuralFlex();
				Vector3 val = (((Object)(object)EnvMan.instance != (Object)null) ? EnvMan.instance.GetWindForce() : Vector3.zero);
				Vector3 val2 = (((Object)(object)_body != (Object)null) ? _body.linearVelocity : Vector3.zero);
				Vector3 val3 = _source.InverseTransformDirection(val * WingConfig.WindResponse.Value - val2 * WingConfig.AirflowResponse.Value);
				Vector2 val4 = default(Vector2);
				((Vector2)(ref val4))..ctor(val3.y, 0f - val3.x);
				_smoothed = Vector2.Lerp(_smoothed, Vector2.ClampMagnitude(val4, 1f), 1f - Mathf.Exp(-5f * Time.deltaTime));
				float num = Mathf.Max(0f, WingConfig.FeatherSoftnessDegrees.Value);
				ApplyStructuralFlex(num);
				ProbeEnvironment();
				float num2 = (float)WingNetworkState.NetworkTimeSeconds();
				for (int j = 0; j < _tips.Length; j++)
				{
					float num3 = Mathf.Sin(num2 * (1.7f + (float)(j % 7) * 0.07f) + (float)j * 1.618f) * 0.18f;
					float num4 = (((Object)_tips[j]).name.StartsWith("bone_left", StringComparison.OrdinalIgnoreCase) ? (-1f) : 1f);
					float num5 = _contacts[j] * Mathf.Max(0f, WingConfig.EnvironmentCollisionResponse.Value);
					Quaternion val5 = Quaternion.Euler((_smoothed.x + num3) * num, (_smoothed.y * 0.45f + num5 * num4) * num, (num3 + num5 * 0.5f) * num * num4);
					Transform obj2 = _tips[j];
					obj2.localRotation *= val5;
					_lastOffsets[j] = val5;
				}
			}
		}

		private void ApplyStructuralFlex(float featherDegrees)
		{
			//IL_0043: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: 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_01dc: 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_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			if (_spines == null || (Object)(object)_animator == (Object)null || _spines.Length == 0)
			{
				return;
			}
			AnimatorStateInfo val = (_animator.IsInTransition(0) ? _animator.GetNextAnimatorStateInfo(0) : _animator.GetCurrentAnimatorStateInfo(0));
			int shortNameHash = ((AnimatorStateInfo)(ref val)).shortNameHash;
			float num = ((shortNameHash == FoldedHash) ? 0.12f : ((shortNameHash == GlideHash) ? 0.32f : ((shortNameHash == FlightLoopHash) ? 0.48f : ((shortNameHash == FlightFlapHash || shortNameHash == FlightLightFlapHash || shortNameHash == ClimbLoopHash || shortNameHash == JumpFlapHash || shortNameHash == TakeoffHash) ? 1f : 0.68f))));
			if (shortNameHash == FlightLightFlapHash)
			{
				num = 0.58f;
			}
			bool flag = shortNameHash == FlightFlapHash || shortNameHash == FlightLightFlapHash || shortNameHash == ClimbLoopHash || shortNameHash == JumpFlapHash || shortNameHash == TakeoffHash;
			float num2 = (flag ? (Mathf.Repeat(((AnimatorStateInfo)(ref val)).normalizedTime, 1f) * (float)Math.PI * 2f) : ((float)WingNetworkState.NetworkTimeSeconds() * ((shortNameHash == FlightLoopHash) ? 2.4f : 1.65f)));
			float num3 = Mathf.Clamp(_smoothed.x, -1f, 1f);
			float num4 = featherDegrees * 0.34f * num;
			for (int i = 0; i < _spines.Length; i++)
			{
				Transform val2 = _spines[i];
				if (!((Object)(object)val2 == (Object)null))
				{
					float num5 = (Mathf.Sin(num2 - _spineAlong[i] * (flag ? 0.85f : 0.42f)) * 0.72f + num3 * 0.28f) * num4 * _spineSide[i];
					_spineBefore[i] = val2.localRotation;
					val2.rotation = Quaternion.AngleAxis(num5, ((Component)this).transform.forward) * val2.rotation;
					_spineApplied[i] = val2.localRotation;
					_spinePending[i] = true;
				}
			}
		}

		private void RestoreStructuralFlex()
		{
			//IL_0033: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			if (_spines == null)
			{
				return;
			}
			for (int num = _spines.Length - 1; num >= 0; num--)
			{
				Transform val = _spines[num];
				if (_spinePending[num] && !((Object)(object)val == (Object)null))
				{
					if (Quaternion.Angle(val.localRotation, _spineApplied[num]) < 0.05f)
					{
						val.localRotation = _spineBefore[num];
					}
					_spinePending[num] = false;
				}
			}
		}

		private static bool IsStructuralFlexBone(string name, int[] flexIndices)
		{
			int num = ParseStructuralIndex(name);
			if (num < 0)
			{
				return false;
			}
			for (int i = 0; i < flexIndices.Length; i++)
			{
				if (num == flexIndices[i])
				{
					return true;
				}
			}
			return false;
		}

		private static int ParseStructuralIndex(string name)
		{
			if (!name.StartsWith("bone_right.", StringComparison.OrdinalIgnoreCase) && !name.StartsWith("bone_left.", StringComparison.OrdinalIgnoreCase))
			{
				return -1;
			}
			int num = name.LastIndexOf('.');
			if (num < 0 || !int.TryParse(name.Substring(num + 1), out var result))
			{
				return -1;
			}
			return result;
		}

		private void ProbeEnvironment()
		{
			//IL_0094: 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)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			if (_tips.Length == 0)
			{
				return;
			}
			for (int i = 0; i < _contacts.Length; i++)
			{
				_contacts[i] = Mathf.MoveTowards(_contacts[i], 0f, Time.deltaTime * 4f);
			}
			int num = Mathf.Min(8, _tips.Length);
			for (int j = 0; j < num; j++)
			{
				int num2 = _probeCursor++ % _tips.Length;
				Transform val = _tips[num2];
				if ((Object)(object)val.parent == (Object)null)
				{
					continue;
				}
				Vector3 val2 = val.position - val.parent.position;
				float magnitude = ((Vector3)(ref val2)).magnitude;
				if (magnitude < 0.01f)
				{
					continue;
				}
				int num3 = Physics.RaycastNonAlloc(val.parent.position, val2 / magnitude, _hits, magnitude + 0.025f, -1, (QueryTriggerInteraction)1);
				for (int k = 0; k < num3; k++)
				{
					Collider collider = ((RaycastHit)(ref _hits[k])).collider;
					if (!((Object)(object)collider == (Object)null) && !((Component)collider).transform.IsChildOf(_source))
					{
						_contacts[num2] = 1f;
						break;
					}
				}
			}
		}

		private void OnDisable()
		{
			RestoreStructuralFlex();
		}
	}
}
namespace WingsOfTheForgottenGods.Patches
{
	[HarmonyPatch(typeof(VisEquipment), "SetShoulderEquipped", new Type[]
	{
		typeof(int),
		typeof(int),
		typeof(int)
	})]
	internal static class VisEquipmentSetShoulderEquippedPatch
	{
		private static void Postfix(VisEquipment __instance, int __0)
		{
			WingEquipmentDisplay.Sync(__instance, __0);
		}
	}
	[HarmonyPatch(typeof(Player), "SetControls", new Type[]
	{
		typeof(Vector3),
		typeof(bool),
		typeof(bool),
		typeof(bool),
		typeof(bool),
		typeof(bool),
		typeof(bool),
		typeof(bool),
		typeof(bool),
		typeof(bool),
		typeof(bool),
		typeof(bool)
	})]
	internal static class PlayerSetControlsPatch
	{
		private static void Prefix(Player __instance, ref Vector3 movedir, ref bool attack, ref bool attackHold, ref bool secondaryAttack, ref bool secondaryAttackHold, ref bool crouch, bool jump, bool run)
		{
			//IL_0017: 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)
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
			{
				if (WingFlightRuntime.UsesAircraftControls(__instance))
				{
					movedir = Vector3.zero;
				}
				if (WingFlightRuntime.BlocksAttacks(__instance))
				{
					attack = false;
					attackHold = false;
					secondaryAttack = false;
					secondaryAttackHold = false;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Character), "UpdateRotation", new Type[]
	{
		typeof(float),
		typeof(float),
		typeof(bool)
	})]
	internal static class CharacterUpdateRotationPatch
	{
		private static bool Prefix(Character __instance, ref float __result, bool ___m_attackHold)
		{
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (val == null || !WingFlightRuntime.LocksAirborneBowHeading(val, ___m_attackHold))
			{
				return true;
			}
			__result = 0f;
			return false;
		}
	}
	[HarmonyPatch(typeof(Player), "UpdateAttackBowDraw", new Type[]
	{
		typeof(ItemData),
		typeof(float)
	})]
	internal static class PlayerUpdateAttackBowDrawPatch
	{
		private static void Prefix(Player __instance, ref float ___m_attackDrawTime, bool ___m_attackHold, out bool __state)
		{
			__state = WingFlightRuntime.BeginAirborneBowUpdate(__instance, ___m_attackHold);
			if (__state && ___m_attackHold && !(___m_attackDrawTime >= 0f) && !((Character)__instance).IsBlocking() && !((Character)__instance).IsAttached())
			{
				___m_attackDrawTime = 0f;
			}
		}

		private static void Postfix(Player __instance, bool __state)
		{
			if (__state)
			{
				WingFlightRuntime.EndAirborneBowUpdate(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(Player), "InMinorAction")]
	internal static class PlayerInMinorActionPatch
	{
		private static void Postfix(Player __instance, ref bool __result)
		{
			if (WingFlightRuntime.BypassesMinorActionForBow(__instance))
			{
				__result = false;
			}
		}
	}
	[HarmonyPatch(typeof(GameCamera), "GetCameraPosition")]
	internal static class GameCameraGetPositionPatch
	{
		private static void Postfix(float dt, ref Vector3 pos, ref Quaternion rot)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			WingFlightRuntime.AdjustFlightCamera(Player.m_localPlayer, dt, pos, ref rot);
		}
	}
	[HarmonyPatch(typeof(Character), "OnRagdollCreated", new Type[] { typeof(Ragdoll) })]
	internal static class CharacterOnRagdollCreatedPatch
	{
		private static void Postfix(Character __instance, Ragdoll ragdoll)
		{
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (val != null && WingNetworkState.TryGetEquipped(val, out var definition))
			{
				WingRagdollVisual.EnsureNetworkDisplay(ragdoll);
				WingNetworkState.PublishRagdollEquipment(ragdoll, definition);
			}
		}
	}
	[HarmonyPatch(typeof(Ragdoll), "Awake")]
	internal static class RagdollAwakeWingPatch
	{
		private static void Postfix(Ragdoll __instance)
		{
			WingRagdollVisual.EnsureNetworkDisplay(__instance);
		}
	}
	[HarmonyPatch(typeof(Character), "UpdateSwimming", new Type[] { typeof(float) })]
	internal static class CharacterUpdateSwimmingPatch
	{
		private static void Postfix(Character __instance, float dt)
		{
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (val != null && (Object)(object)val == (Object)(object)Player.m_localPlayer)
			{
				WingFlightRuntime.ModifySwimmingVelocity(val, dt);
			}
		}
	}
}
namespace WingsOfTheForgottenGods.Network
{
	internal static class WingNetworkState
	{
		internal enum VisualCommand
		{
			None,
			FlightFlap,
			LightFlightFlap
		}

		internal enum VisualAnimation
		{
			None,
			Folded,
			Unfold,
			Fold,
			JumpFlap,
			Takeoff,
			ClimbLoop,
			ClimbExit,
			Glide,
			GlideToFlight,
			FlightToGlide,
			FlightLoop,
			FlightFlap,
			FlightLightFlap
		}

		internal readonly struct Snapshot
		{
			internal readonly WingFlightState State;

			internal readonly bool WaterLaunch;

			internal readonly bool Powered;

			internal readonly float Pitch;

			internal readonly float Bank;

			internal readonly int CommandValue;

			internal readonly int AnimationValue;

			internal readonly long AnimationStarted;

			internal VisualCommand Command => (VisualCommand)((CommandValue >> 24) & 0xFF);

			internal VisualAnimation Animation => (VisualAnimation)((AnimationValue >> 24) & 0xFF);

			internal Snapshot(WingFlightState state, bool waterLaunch, bool powered, float pitch, float bank, int commandValue, int animationValue, long animationStarted)
			{
				State = state;
				WaterLaunch = waterLaunch;
				Powered = powered;
				Pitch = pitch;
				Bank = bank;
				CommandValue = commandValue;
				AnimationValue = animationValue;
				AnimationStarted = animationStarted;
			}
		}

		private const int WaterLaunchBit = 256;

		private const int PoweredBit = 512;

		private const int CommandShift = 24;

		private const int SequenceMask = 16777215;

		private static readonly int FlagsKey = StringExtensionMethods.GetStableHashCode("darkspider.wingsoftheforgottengods.visual.flags");

		private static readonly int AttitudeKey = StringExtensionMethods.GetStableHashCode("darkspider.wingsoftheforgottengods.visual.attitude");

		private static readonly int CommandKey = StringExtensionMethods.GetStableHashCode("darkspider.wingsoftheforgottengods.visual.command");

		private static readonly int EquippedWingKey = StringExtensionMethods.GetStableHashCode("darkspider.wingsoftheforgottengods.equipment.wing");

		private static readonly int AnimationKey = StringExtensionMethods.GetStableHashCode("darkspider.wingsoftheforgottengods.visual.animation");

		private static readonly int AnimationStartedKey = StringExtensionMethods.GetStableHashCode("darkspider.wingsoftheforgottengods.visual.animation.started");

		private static Player _publishedOwner;

		private static int _publishedFlags = int.MinValue;

		private static int _publishedAttitude = int.MinValue;

		private static int _publishedEquipmentHash = int.MinValue;

		private static int _sequence;

		private static int _animationSequence;

		internal static void PublishFlags(Player player, WingFlightState state, bool waterLaunch, bool powered)
		{
			if (TryGetOwnedZdo(player, out var zdo))
			{
				PreparePublisher(player, zdo);
				int num = (int)((uint)(state & (WingFlightState)255) | (uint)(waterLaunch ? 256 : 0)) | (powered ? 512 : 0);
				if (num != _publishedFlags)
				{
					zdo.Set(FlagsKey, num, false);
					_publishedFlags = num;
				}
			}
		}

		internal static void PublishEquipment(Player player, WingDefinition definition)
		{
			if (TryGetOwnedZdo(player, out var zdo))
			{
				PreparePublisher(player, zdo);
				int num = ((definition != null) ? StringExtensionMethods.GetStableHashCode(definition.ItemPrefab) : 0);
				if (num != _publishedEquipmentHash)
				{
					zdo.Set(EquippedWingKey, num, false);
					_publishedEquipmentHash = num;
				}
			}
		}

		internal static bool HasEquipped(Player player, WingDefinition definition)
		{
			if ((Object)(object)player == (Object)null || definition == null)
			{
				return false;
			}
			if (WingItemRegistry.IsEquipped(player, out var definition2))
			{
				return definition2 == definition;
			}
			ZNetView component = ((Component)player).GetComponent<ZNetView>();
			ZDO val = (((Object)(object)component != (Object)null) ? component.GetZDO() : null);
			if (val != null)
			{
				return val.GetInt(EquippedWingKey, 0) == StringExtensionMethods.GetStableHashCode(definition.ItemPrefab);
			}
			return false;
		}

		internal static void PublishAttitude(Player player, float pitch, float bank)
		{
			if (TryGetOwnedZdo(player, out var zdo))
			{
				PreparePublisher(player, zdo);
				int num = PackAttitude(pitch, bank);
				if (num != _publishedAttitude)
				{
					zdo.Set(AttitudeKey, num, false);
					_publishedAttitude = num;
				}
			}
		}

		internal static void PublishCommand(Player player, VisualCommand command)
		{
			if (command != VisualCommand.None && TryGetOwnedZdo(player, out var zdo))
			{
				PreparePublisher(player, zdo);
				_sequence = (_sequence + 1) & 0xFFFFFF;
				if (_sequence == 0)
				{
					_sequence = 1;
				}
				zdo.Set(CommandKey, ((int)command << 24) | _sequence, false);
			}
		}

		internal static void PublishAnimation(Player player, VisualAnimation animation)
		{
			if (animation != VisualAnimation.None && TryGetOwnedZdo(player, out var zdo))
			{
				PreparePublisher(player, zdo);
				_animationSequence = (_animationSequence + 1) & 0xFFFFFF;
				if (_animationSequence == 0)
				{
					_animationSequence = 1;
				}
				zdo.Set(AnimationStartedKey, (long)(NetworkTimeSeconds() * 1000.0));
				zdo.Set(AnimationKey, ((int)animation << 24) | _animationSequence, false);
			}
		}

		internal static bool TryRead(Player player, out Snapshot snapshot)
		{
			snapshot = default(Snapshot);
			ZNetView val = (((Object)(object)player != (Object)null) ? ((Component)player).GetComponent<ZNetView>() : null);
			ZDO val2 = (((Object)(object)val != (Object)null) ? val.GetZDO() : null);
			if (val2 == null)
			{
				return false;
			}
			int num = val2.GetInt(FlagsKey, 0);
			int num2 = num & 0xFF;
			if (num2 < 0 || num2 > 6)
			{
				num2 = 0;
			}
			UnpackAttitude(val2.GetInt(AttitudeKey, 0), out var pitch, out var bank);
			snapshot = new Snapshot((WingFlightState)num2, (num & 0x100) != 0, (num & 0x200) != 0, pitch, bank, val2.GetInt(CommandKey, 0), val2.GetInt(AnimationKey, 0), val2.GetLong(AnimationStartedKey, 0L));
			return true;
		}

		internal static bool TryGetEquipped(Player player, out WingDefinition definition)
		{
			definition = null;
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			if (WingItemRegistry.IsEquipped(player, out definition))
			{
				return true;
			}
			ZNetView component = ((Component)player).GetComponent<ZNetView>();
			ZDO val = (((Object)(object)component != (Object)null) ? component.GetZDO() : null);
			if (val == null)
			{
				return false;
			}
			definition = WingCatalog.FindByItemHash(val.GetInt(EquippedWingKey, 0));
			return definition != null;
		}

		internal static void PublishRagdollEquipment(Ragdoll ragdoll, WingDefinition definition)
		{
			ZNetView val = (((Object)(object)ragdoll != (Object)null) ? ((Component)ragdoll).GetComponent<ZNetView>() : null);
			if (!((Object)(object)val == (Object)null) && val.IsValid() && val.IsOwner())
			{
				ZDO zDO = val.GetZDO();
				if (zDO != null)
				{
					zDO.Set(EquippedWingKey, (definition != null) ? StringExtensionMethods.GetStableHashCode(definition.ItemPrefab) : 0, false);
				}
			}
		}

		internal static bool TryReadRagdollEquipment(Ragdoll ragdoll, out WingDefinition definition)
		{
			definition = null;
			ZNetView val = (((Object)(object)ragdoll != (Object)null) ? ((Component)ragdoll).GetComponent<ZNetView>() : null);
			ZDO val2 = (((Object)(object)val != (Object)null) ? val.GetZDO() : null);
			if (val2 == null)
			{
				return false;
			}
			definition = WingCatalog.FindByItemHash(val2.GetInt(EquippedWingKey, 0));
			return definition != null;
		}

		internal static float AnimationElapsedSeconds(long startedMilliseconds)
		{
			if (startedMilliseconds <= 0)
			{
				return 0f;
			}
			return Mathf.Max(0f, (float)(NetworkTimeSeconds() - (double)startedMilliseconds / 1000.0));
		}

		private static bool TryGetOwnedZdo(Player player, out ZDO zdo)
		{
			zdo = null;
			ZNetView val = (((Object)(object)player != (Object)null) ? ((Component)player).GetComponent<ZNetView>() : null);
			if ((Object)(object)val == (Object)null || !val.IsValid() || !val.IsOwner())
			{
				return false;
			}
			zdo = val.GetZDO();
			return zdo != null;
		}

		private static void PreparePublisher(Player player, ZDO zdo)
		{
			if (!((Object)(object)_publishedOwner == (Object)(object)player))
			{
				_publishedOwner = player;
				_publishedFlags = int.MinValue;
				_publishedAttitude = int.MinValue;
				_publishedEquipmentHash = int.MinValue;
				_sequence = zdo.GetInt(CommandKey, 0) & 0xFFFFFF;
				_animationSequence = zdo.GetInt(AnimationKey, 0) & 0xFFFFFF;
			}
		}

		internal static double NetworkTimeSeconds()
		{
			if (!((Object)(object)ZNet.instance != (Object)null))
			{
				return Time.time;
			}
			return ZNet.instance.GetTimeSeconds();
		}

		private static int PackAttitude(float pitch, float bank)
		{
			short num = (short)Mathf.RoundToInt(Mathf.Clamp(pitch, -180f, 180f) * 10f);
			short num2 = (short)Mathf.RoundToInt(Mathf.Clamp(bank, -180f, 180f) * 10f);
			return (ushort)num | ((ushort)num2 << 16);
		}

		private static void UnpackAttitude(int packed, out float pitch, out float bank)
		{
			pitch = (float)(short)(packed & 0xFFFF) / 10f;
			bank = (float)(short)((packed >> 16) & 0xFFFF) / 10f;
		}
	}
}
namespace WingsOfTheForgottenGods.Localization
{
	internal static class WingLocalization
	{
		private static readonly Dictionary<string, string[]> Translations = new Dictionary<string, string[]>
		{
			["English"] = T("Wings of Hraesvelgr", "A gift from the great eagle who waits at the edge of heaven. Black, ivory and golden feathers remember the winds between worlds, lending their bearer speed and mastery of the open sky.", "Legacy of Hraesvelgr", "Grants flight.~Prevents all fall damage.~The aerial hunt preserves 80% of combat stamina.~A following wind carries you faster.~A mighty wingbeat casts lesser foes aside.", "Crimson Tar Wings", "Born from the blood of the fallen and the living tar of ancient beasts. Beneath their black skin something hungry still stirs, yearning for the open sky.", "Blood and Living Tar", "Grants flight.~Prevents all fall damage.~The tar-born recognize one of their own.~Living tar no longer binds your limbs.~Leech-blood restores life in close combat."),
			["Swedish"] = T("Hräsvelgs vingar", "En gåva från den väldiga örnen vid himlens rand. Svarta, elfenbensvita och gyllene fjädrar minns vindarna mellan världarna och skänker snabbhet och herravälde över den öppna skyn.", "Hräsvelgs arv", "Ger förmågan att flyga.~Förhindrar all fallskada.~Luftjakten sparar 80 % av stridsuthålligheten.~Medvind för dig snabbare fram.~Ett mäktigt vingslag slungar undan svagare fiender.", "Blodröda tjärvingar", "Födda ur de fallnas blod och uråldriga bestars levande tjära. Under den svarta huden rör sig ännu något hungrigt som längtar efter den öppna skyn.", "Blod och levande tjära", "Ger förmågan att flyga.~Förhindrar all fallskada.~De tjärfödda känner igen en av sina egna.~Levande tjära fjättrar dig inte längre.~Igelblod återger liv i närstrid."),
			["French"] = T("Ailes de Hræsvelgr", "Un don du grand aigle qui veille aux confins du ciel. Leurs plumes noires, ivoire et dorées se souviennent des vents entre les mondes et accordent vitesse et maîtrise des cieux.", "Héritage de Hræsvelgr", "Permet de voler.~Annule tous les dégâts de chute.~La chasse aérienne préserve 80 % de l'endurance de combat.~Le vent arrière vous porte plus vite.~Un puissant battement repousse les ennemis mineurs.", "Ailes de goudron cramoisi", "Nées du sang des défunts et du goudron vivant de bêtes antiques. Sous leur peau noire remue encore une faim avide de ciel ouvert.", "Sang et goudron vivant", "Permet de voler.~Annule tous les dégâts de chute.~Les créatures du goudron reconnaissent l'un des leurs.~Le goudron vivant ne vous entrave plus.~Le sang de sangsue rend de la vie au corps à corps."),
			["Italian"] = T("Ali di Hræsvelgr", "Un dono della grande aquila che attende ai confini del cielo. Le piume nere, avorio e dorate ricordano i venti tra i mondi e donano velocità e dominio dei cieli.", "Retaggio di Hræsvelgr", "Permette di volare.~Previene ogni danno da caduta.~La caccia aerea preserva l'80% della resistenza in combattimento.~Il vento in coda ti sospinge più veloce.~Un possente battito respinge i nemici minori.", "Ali di catrame cremisi", "Nate dal sangue dei caduti e dal catrame vivente di bestie antiche. Sotto la pelle nera si agita ancora qualcosa di affamato, bramoso del cielo aperto.", "Sangue e catrame vivente", "Permette di volare.~Previene ogni danno da caduta.~I nati dal catrame riconoscono uno dei loro.~Il catrame vivente non ti imprigiona più.~Il sangue di sanguisuga restituisce vita nel corpo a corpo."),
			["German"] = T("Flügel des Hræsvelgr", "Ein Geschenk des gewaltigen Adlers am Rand des Himmels. Schwarze, elfenbeinfarbene und goldene Federn bewahren die Winde zwischen den Welten und verleihen Schnelligkeit und Herrschaft über den freien Himmel.", "Hræsvelgrs Vermächtnis", "Ermöglicht das Fliegen.~Verhindert jeglichen Fallschaden.~Die Luftjagd spart 80 % der Kampfausdauer.~Rückenwind trägt dich schneller.~Ein mächtiger Flügelschlag schleudert schwächere Feinde fort.", "Karmesinrote Teerflügel", "Geboren aus dem Blut der Gefallenen und dem lebenden Teer uralter Bestien. Unter ihrer schwarzen Haut regt sich noch etwas Hungriges, das nach dem offenen Himmel verlangt.", "Blut und lebender Teer", "Ermöglicht das Fliegen.~Verhindert jeglichen Fallschaden.~Teerbrut erkennt dich als ihresgleichen.~Lebender Teer fesselt deine Glieder nicht mehr.~Egelblut schenkt im Nahkampf Leben zurück."),
			["Spanish"] = T("Alas de Hræsvelgr", "Un regalo de la gran águila que aguarda en el confín del cielo. Sus plumas negras, marfil y doradas recuerdan los vientos entre mundos y otorgan velocidad y dominio del firmamento.", "Legado de Hræsvelgr", "Permite volar.~Evita todo el daño por caída.~La caza aérea conserva un 80 % de la resistencia de combate.~El viento a favor te lleva más rápido.~Un poderoso aleteo aparta a los enemigos menores.", "Alas de brea carmesí", "Nacidas de la sangre de los caídos y la brea viviente de bestias antiguas. Bajo su piel negra aún se agita algo hambriento que ansía el cielo abierto.", "Sangre y brea viviente", "Permite volar.~Evita todo el daño por caída.~Los nacidos de la brea reconocen a uno de los suyos.~La brea viviente ya no inmoviliza tus miembros.~La sangre de sanguijuela restaura vida en combate cuerpo a cuerpo."),
			["Russian"] = T("Крылья Хресвельгра", "Дар великого орла, что ждёт у края небес. Чёрные, белые и золотые перья помнят ветры между мирами, даруя носителю стремительность и власть над открытым небом.", "Наследие Хресвельгра", "Позволяют летать.~Полностью защищают от урона при падении.~Воздушная охота бережёт 80% выносливости в бою.~Попутный ветер несёт вас быстрее.~Могучий взмах отбрасывает слабых врагов.", "Багровые дегтевые крылья", "Порождение крови павших и живого дёгтя древних чудовищ. Под чёрной кожей всё ещё шевелится нечто голодное, рвущееся в открытое небо.", "Кровь и живой дёготь", "Позволяют летать.~Полностью защищают от урона при падении.~Дегтевые твари признают в вас своего.~Живой дёготь больше не