Decompiled source of ODINFLIGHT v2.1.0

Odinflight.dll

Decompiled a month ago
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Resources;
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 UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Odinflight")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Odinflight")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("fc736e31-12ed-4975-8014-7612f09091a2")]
[assembly: AssemblyFileVersion("2.1")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.1.0.0")]
[module: UnverifiableCode]
namespace Odinflight
{
	public class AnimationClipOverrides : List<KeyValuePair<AnimationClip, AnimationClip>>
	{
		public AnimationClip this[string name]
		{
			get
			{
				return Find((KeyValuePair<AnimationClip, AnimationClip> x) => ((Object)x.Key).name == name).Value;
			}
			set
			{
				int num = FindIndex((KeyValuePair<AnimationClip, AnimationClip> x) => ((Object)x.Key).name == name);
				if (num != -1)
				{
					base[num] = new KeyValuePair<AnimationClip, AnimationClip>(base[num].Key, value);
				}
			}
		}

		public AnimationClipOverrides(int capacity)
			: base(capacity)
		{
		}
	}
	public class RecipeStub
	{
		public class RequirementStub
		{
			public string Component;

			public int Amount;

			public int AmountPerLevel;

			public bool Recoverable = true;

			private RequirementStub()
			{
			}

			public static RequirementStub Parse(string def)
			{
				string[] array = def.Split(new char[1] { ':' });
				if (array.Length < 2)
				{
					return null;
				}
				RequirementStub requirementStub = new RequirementStub();
				requirementStub.Component = array[0];
				int.TryParse(array[1], out requirementStub.Amount);
				if (array.Length > 2)
				{
					int.TryParse(array[2], out requirementStub.AmountPerLevel);
				}
				return requirementStub;
			}
		}

		public ItemDrop Item;

		public string CraftingStation;

		public string RepairStation;

		public int MinStationLevel = 1;

		public List<RequirementStub> Requirements = new List<RequirementStub>();

		public string Name => "Recipe" + ((Object)Item).name;
	}
	[HarmonyPatch]
	public static class AssetHelper
	{
		public delegate void CustomPrefabsDelegate();

		public static readonly List<GameObject> Prefabs = new List<GameObject>();

		private static readonly List<RecipeStub> RecipeStubs = new List<RecipeStub>();

		private static readonly List<KeyValuePair<string, StatusEffect>> StatusEffects = new List<KeyValuePair<string, StatusEffect>>();

		public static event CustomPrefabsDelegate PreCustomPrefabRegistration;

		public static event CustomPrefabsDelegate PostCustomPrefabRegistration;

		public static AssetBundle LoadAssetBundle(string name)
		{
			Assembly callingAssembly = Assembly.GetCallingAssembly();
			return AssetBundle.LoadFromStream(callingAssembly.GetManifestResourceStream(callingAssembly.GetName().Name + "." + name));
		}

		public static void RegisterPrefab(GameObject prefab)
		{
			if (!Object.op_Implicit((Object)(object)ZNetScene.instance) || !Object.op_Implicit((Object)(object)ZNetScene.instance.GetPrefab(((Object)prefab).name)))
			{
				Prefabs.Add(prefab);
				if (Object.op_Implicit((Object)(object)ZNetScene.instance))
				{
					ZNetScene.instance.m_namedPrefabs[StringExtensionMethods.GetStableHashCode(((Object)prefab).name)] = prefab;
					ObjectDB.m_instance.m_itemByHash[StringExtensionMethods.GetStableHashCode(((Object)prefab).name)] = prefab;
				}
			}
		}

		public static GameObject CreateNewPrefab(string name, string originalPrefab)
		{
			GameObject obj = Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab(originalPrefab), Plugin.PrefabOwner.transform);
			((Object)obj).name = name;
			RegisterPrefab(obj);
			return obj;
		}

		public static void RegisterRecipe(RecipeStub rs)
		{
			RecipeStubs.Add(rs);
		}

		public static void RegisterStatusEffect<T>(string name) where T : StatusEffect
		{
			StatusEffects.Add(new KeyValuePair<string, StatusEffect>(name, (StatusEffect)(object)ScriptableObject.CreateInstance<T>()));
		}

		public static RecipeStub GetRecipeStub(string itemName)
		{
			return RecipeStubs.Find((RecipeStub r) => ((Object)r.Item).name == itemName);
		}

		public static Recipe BuildRecipe(RecipeStub rs, ObjectDB odb)
		{
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)ZNetScene.instance))
			{
				return null;
			}
			Recipe val = ScriptableObject.CreateInstance<Recipe>();
			val.m_item = rs.Item;
			GameObject itemPrefab = odb.GetItemPrefab(rs.CraftingStation);
			val.m_craftingStation = ((itemPrefab != null) ? itemPrefab.GetComponentInChildren<CraftingStation>(true) : null);
			if ((Object)(object)val.m_craftingStation == (Object)null)
			{
				ZNetScene instance = ZNetScene.instance;
				object craftingStation;
				if (instance == null)
				{
					craftingStation = null;
				}
				else
				{
					GameObject prefab = instance.GetPrefab(rs.CraftingStation);
					craftingStation = ((prefab != null) ? prefab.GetComponentInChildren<CraftingStation>(true) : null);
				}
				val.m_craftingStation = (CraftingStation)craftingStation;
				if ((Object)(object)val.m_craftingStation == (Object)null)
				{
					Plugin.Log.LogInfo((object)("BuildRecipe couldn't find crafting station " + rs.CraftingStation + " for " + rs.Name));
					return null;
				}
			}
			if (!string.IsNullOrWhiteSpace(rs.RepairStation))
			{
				GameObject itemPrefab2 = odb.GetItemPrefab(rs.RepairStation);
				val.m_repairStation = ((itemPrefab2 != null) ? itemPrefab2.GetComponentInChildren<CraftingStation>(true) : null);
				if ((Object)(object)val.m_repairStation == (Object)null)
				{
					ZNetScene instance2 = ZNetScene.instance;
					object repairStation;
					if (instance2 == null)
					{
						repairStation = null;
					}
					else
					{
						GameObject prefab2 = instance2.GetPrefab(rs.RepairStation);
						repairStation = ((prefab2 != null) ? prefab2.GetComponentInChildren<CraftingStation>(true) : null);
					}
					val.m_repairStation = (CraftingStation)repairStation;
					if ((Object)(object)val.m_repairStation == (Object)null)
					{
						Plugin.Log.LogInfo((object)("BuildRecipe couldn't find declared repair station " + rs.RepairStation + " for " + rs.Name));
						return null;
					}
				}
				if ((Object)(object)val.m_repairStation == (Object)null)
				{
					return null;
				}
			}
			val.m_minStationLevel = Mathf.Max(1, rs.MinStationLevel);
			List<Requirement> list = new List<Requirement>();
			foreach (RecipeStub.RequirementStub requirement in rs.Requirements)
			{
				GameObject itemPrefab3 = odb.GetItemPrefab(requirement.Component);
				ItemDrop val2 = ((itemPrefab3 != null) ? itemPrefab3.GetComponentInChildren<ItemDrop>(true) : null);
				if (!Object.op_Implicit((Object)(object)val2))
				{
					Plugin.Log.LogInfo((object)("BuildRecipe couldn't get requirement component " + requirement.Component + " for " + rs.Name));
					return null;
				}
				Requirement val3 = new Requirement();
				val3.m_resItem = val2;
				val3.m_amount = requirement.Amount;
				val3.m_amountPerLevel = requirement.AmountPerLevel;
				val3.m_recover = requirement.Recoverable;
				list.Add(val3);
			}
			val.m_resources = list.ToArray();
			return val;
		}

		private static void PopulateObjectDB(ObjectDB odb)
		{
			if (Prefabs.Count > 0 && !Object.op_Implicit((Object)(object)odb.m_items.Find((GameObject p) => ((Object)p).name == ((Object)Prefabs[0]).name)))
			{
				foreach (GameObject prefab in Prefabs)
				{
					if (Object.op_Implicit((Object)(object)prefab.GetComponentInChildren<ItemDrop>(true)))
					{
						odb.m_items.Add(prefab);
					}
				}
				odb.UpdateRegisters();
			}
			if (RecipeStubs.Count > 0 && !Object.op_Implicit((Object)(object)odb.GetRecipe(RecipeStubs[0].Item.m_itemData)))
			{
				foreach (RecipeStub recipeStub in RecipeStubs)
				{
					Recipe val = BuildRecipe(recipeStub, odb);
					if (Object.op_Implicit((Object)(object)val))
					{
						odb.m_recipes.Add(val);
						Plugin.Log.LogInfo((object)("Added recipe " + ((Object)val).name));
					}
				}
			}
			if (StatusEffects.Count <= 0 || Object.op_Implicit((Object)(object)odb.GetStatusEffect(StringExtensionMethods.GetStableHashCode(StatusEffects[0].Key))))
			{
				return;
			}
			foreach (KeyValuePair<string, StatusEffect> statusEffect in StatusEffects)
			{
				odb.m_StatusEffects.Add(statusEffect.Value);
			}
		}

		public static void UpdateRecipes()
		{
			foreach (RecipeStub recipeStub in RecipeStubs)
			{
				Recipe r = BuildRecipe(recipeStub, ObjectDB.instance);
				if (Object.op_Implicit((Object)(object)r))
				{
					Recipe val = ObjectDB.instance.m_recipes.Find((Recipe rt) => ((Object)rt).name == ((Object)r).name);
					if (Object.op_Implicit((Object)(object)val))
					{
						ObjectDB.instance.m_recipes.Remove(val);
					}
					ObjectDB.instance.m_recipes.Add(r);
					Plugin.Log.LogInfo((object)("Updated recipe " + ((Object)r).name));
				}
			}
		}

		public static void AssetCleanup()
		{
			Prefabs.Clear();
			RecipeStubs.Clear();
			StatusEffects.Clear();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		public static void AwakePostfix(ObjectDB __instance)
		{
			PopulateObjectDB(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")]
		public static void CopyOtherDBPostfix(ObjectDB __instance, ObjectDB other)
		{
			PopulateObjectDB(__instance);
		}

		[HarmonyFinalizer]
		[HarmonyPatch(typeof(ZNetScene), "Awake")]
		[HarmonyPriority(0)]
		public static void AwakeFinalizer(ZNetScene __instance)
		{
			AssetHelper.PreCustomPrefabRegistration?.Invoke();
			foreach (GameObject prefab in Prefabs)
			{
				__instance.m_namedPrefabs[StringExtensionMethods.GetStableHashCode(((Object)prefab).name)] = prefab;
			}
			AssetHelper.PostCustomPrefabRegistration?.Invoke();
		}
	}
	public class SE_Odinflight : SE_Stats
	{
		public const string SEName = "ODINFLIGHT";

		public static readonly int SENameHash = StringExtensionMethods.GetStableHashCode("ODINFLIGHT");

		public SE_Odinflight()
		{
			((Object)this).name = "ODINFLIGHT";
			((StatusEffect)this).m_tooltip = "";
		}

		public override bool CanAdd(Character character)
		{
			return character.IsPlayer();
		}

		public override bool IsDone()
		{
			if (Object.op_Implicit((Object)(object)PlayerPatches.CurrentWings))
			{
				return !Object.op_Implicit((Object)(object)((StatusEffect)this).m_character);
			}
			return true;
		}
	}
	public class Wings : MonoBehaviour
	{
		private readonly int BeltStrengthHash = StringExtensionMethods.GetStableHashCode("BeltStrength");

		private float BasePlayerMass = 200f;

		public Rigidbody RB;

		public Rigidbody PilotRB;

		private CapsuleCollider Collider;

		public Player Pilot;

		public bool Flying;

		private Vector3 PilotLean;

		private float MaxPilotLean = 5f;

		private float MinLeanRecovery = 0.01f;

		private float FlapCooldownTimer;

		private bool PlayerFlapped;

		private bool CrouchPressed;

		public bool AirBraking;

		private bool RecoveringFromAirBraking;

		public void Start()
		{
			RB = ((Component)this).GetComponent<Rigidbody>();
			Collider = ((Component)this).GetComponent<CapsuleCollider>();
		}

		public void PilotEquipped(Player pilot)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			Pilot = pilot;
			PilotLean = Vector3.zero;
			PilotRB = ((Component)Pilot).GetComponent<Rigidbody>();
		}

		public void StartFlying()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			RB.position = ((Component)Pilot).transform.position + Vector3.up;
			RB.rotation = ((Component)Pilot).transform.rotation;
			RB.linearVelocity = PilotRB.linearVelocity;
			RB.useGravity = true;
			PilotLean = Vector3.zero;
			RB.mass = BasePlayerMass + 300f * ((Humanoid)Pilot).GetInventory().GetTotalWeight() / Pilot.GetMaxCarryWeight() * Plugin.PlayerInventoryMassMultiplier.Value;
			PilotLean = Vector3.zero;
			((Collider)Collider).enabled = true;
			FlapCooldownTimer = 0f;
			((Component)this).gameObject.layer = 28;
			Flying = true;
		}

		public void AlignToVelocity()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			Quaternion val = default(Quaternion);
			((Quaternion)(ref val)).SetLookRotation(RB.linearVelocity);
			RB.rotation = Quaternion.RotateTowards(RB.rotation, val, 360f);
		}

		public void SyncPilot()
		{
			//IL_0011: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			((Component)Pilot).transform.position = RB.position;
			((Component)Pilot).transform.rotation = RB.rotation;
			((Character)Pilot).m_maxAirAltitude = ((Component)Pilot).transform.position.y;
		}

		public void StopFlying()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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)
			Quaternion val = (AirBraking ? Quaternion.LookRotation(-((Component)RB).transform.up, Vector3.up) : Quaternion.LookRotation(((Component)RB).transform.forward, Vector3.up));
			((Component)Pilot).transform.rotation = val * Quaternion.FromToRotation(val * Vector3.up, Vector3.up);
			((Component)this).gameObject.layer = 2;
			AirBraking = false;
			RecoveringFromAirBraking = false;
			CrouchPressed = false;
			((Collider)Collider).enabled = false;
			PilotLean = Vector3.zero;
			RB.useGravity = false;
			Flying = false;
		}

		public void PilotUnequipped()
		{
			if (Flying)
			{
				StopFlying();
			}
			Pilot = null;
		}

		public void PilotControls(Vector3 movedir, bool jump)
		{
			//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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: 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_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			if ((ZInput.GetButtonDown("Crouch") || ZInput.GetButtonDown("JoyCrouch")) && !CrouchPressed)
			{
				CrouchPressed = true;
				AirBraking = true;
				PilotLean = Vector3.zero;
				RecoveringFromAirBraking = false;
			}
			else if (ZInput.GetButtonUp("Crouch") && ZInput.GetButtonUp("Crouch") && CrouchPressed)
			{
				CrouchPressed = false;
				AirBraking = false;
				RecoveringFromAirBraking = true;
			}
			else if (!AirBraking)
			{
				if (movedir != Vector3.zero)
				{
					RecoveringFromAirBraking = false;
					PilotLean += movedir * Plugin.LeanRate.Value * Time.deltaTime;
					if (((Vector3)(ref PilotLean)).sqrMagnitude > MaxPilotLean * MaxPilotLean)
					{
						PilotLean = ((Vector3)(ref PilotLean)).normalized * MaxPilotLean;
					}
				}
				else if (PilotLean != Vector3.zero)
				{
					if (((Vector3)(ref PilotLean)).magnitude < MinLeanRecovery)
					{
						PilotLean = Vector3.zero;
					}
					else
					{
						PilotLean = ((Vector3)(ref PilotLean)).normalized * (((Vector3)(ref PilotLean)).magnitude - Plugin.LeanRate.Value * Time.deltaTime);
					}
				}
			}
			if (!jump || !(FlapCooldownTimer <= 0f))
			{
				return;
			}
			if (((Character)Pilot).HaveStamina(Plugin.FlapStaminaCost.Value))
			{
				FlapCooldownTimer = Plugin.FlapSpeed.Value;
				PlayerFlapped = true;
				float num = Plugin.FlapStaminaCost.Value;
				if (((Character)Pilot).GetSEMan().HaveStatusEffect(SEMan.s_statusEffectWet))
				{
					num *= Plugin.WetWingFlapCostMod.Value;
				}
				((Character)Pilot).UseStamina(num);
				PlayerPatches.PlayerVisualsTable[Pilot.GetPlayerID()].FlapWings();
				((Character)Pilot).m_nview.InvokeRPC(ZNetView.Everybody, "WingsFlapped", new object[1] { Pilot.GetPlayerID() });
			}
			else
			{
				Hud.instance.StaminaBarEmptyFlash();
			}
		}

		public void OnCollisionEnter(Collision coll)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: 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_005c: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			if (!((Character)Pilot).m_nview.IsOwner() || (Object)(object)coll.gameObject.GetComponent<Player>() == (Object)(object)Pilot)
			{
				return;
			}
			ContactPoint[] contacts = coll.contacts;
			for (int i = 0; i < contacts.Length; i++)
			{
				ContactPoint val = contacts[i];
				float num = (AirBraking ? Vector3.Dot(((ContactPoint)(ref val)).normal, ((Component)RB).transform.forward) : Vector3.Dot(((ContactPoint)(ref val)).normal, ((Component)RB).transform.up));
				if (num < Plugin.MinSafeLandingDot.Value)
				{
					((Character)Pilot).m_hitEffects.Create(((Component)Pilot).transform.position, ((Component)Pilot).transform.rotation, (Transform)null, 1f, -1);
					ItemData currentWingsItem = PlayerPatches.CurrentWingsItem;
					float durability = currentWingsItem.m_durability;
					float num2 = 1f - num;
					Vector3 linearVelocity = RB.linearVelocity;
					currentWingsItem.m_durability = durability - num2 * ((Vector3)(ref linearVelocity)).magnitude * 10f;
				}
			}
			PlayerPatches.StopFlying();
		}

		public void DoGliderPhysics()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: 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_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: 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_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: 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_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: 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_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0340: Unknown result type (might be due to invalid IL or missing references)
			//IL_0345: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_034f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_0359: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_0389: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_0398: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_039c: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: 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_03aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0536: Unknown result type (might be due to invalid IL or missing references)
			//IL_053b: Unknown result type (might be due to invalid IL or missing references)
			//IL_056d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0572: Unknown result type (might be due to invalid IL or missing references)
			//IL_0576: Unknown result type (might be due to invalid IL or missing references)
			//IL_057b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0586: Unknown result type (might be due to invalid IL or missing references)
			//IL_058b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0594: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_048e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0493: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04de: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0503: Unknown result type (might be due to invalid IL or missing references)
			//IL_050d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0512: Unknown result type (might be due to invalid IL or missing references)
			//IL_0517: Unknown result type (might be due to invalid IL or missing references)
			//IL_051c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0529: Unknown result type (might be due to invalid IL or missing references)
			//IL_042a: Unknown result type (might be due to invalid IL or missing references)
			//IL_042f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0459: Unknown result type (might be due to invalid IL or missing references)
			//IL_045e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0465: Unknown result type (might be due to invalid IL or missing references)
			//IL_046f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0474: Unknown result type (might be due to invalid IL or missing references)
			//IL_0479: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0600: Unknown result type (might be due to invalid IL or missing references)
			//IL_0605: Unknown result type (might be due to invalid IL or missing references)
			//IL_060a: Unknown result type (might be due to invalid IL or missing references)
			//IL_060e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0613: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0649: Unknown result type (might be due to invalid IL or missing references)
			//IL_064d: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val4;
			if (AirBraking)
			{
				Quaternion val = Quaternion.LookRotation(((Character)Pilot).m_lookDir, Vector3.up);
				val *= Quaternion.FromToRotation(Vector3.up, Vector3.back);
				((Component)RB).transform.rotation = Quaternion.RotateTowards(((Component)RB).transform.rotation, val, Plugin.AirBrakeRotationRate.Value * Time.fixedDeltaTime);
			}
			else if (RecoveringFromAirBraking)
			{
				Quaternion val2 = Quaternion.LookRotation(RB.linearVelocity, Vector3.up);
				((Component)RB).transform.rotation = Quaternion.RotateTowards(((Component)RB).transform.rotation, val2, Plugin.AirBrakeRotationRate.Value * Time.fixedDeltaTime);
				Vector3 val3 = ((Component)RB).transform.rotation * Vector3.forward;
				val4 = RB.linearVelocity;
				if ((double)Vector3.Dot(val3, ((Vector3)(ref val4)).normalized) > 0.99)
				{
					RB.rotation = val2;
					RecoveringFromAirBraking = false;
				}
			}
			val4 = RB.linearVelocity;
			Vector3 normalized = ((Vector3)(ref val4)).normalized;
			float num = 0f;
			float num2 = Vector3.Dot(normalized, ((Component)RB).transform.forward);
			float num3 = Vector3.Dot(normalized, ((Component)RB).transform.up);
			Vector3 val5 = EnvMan.instance.GetWindForce() * Plugin.WindScalar.Value;
			float num4 = Vector3.Dot(normalized, val5);
			val4 = RB.linearVelocity;
			float num5 = ((Vector3)(ref val4)).magnitude + num4;
			if (num2 > 0f)
			{
				float num6 = 0f - num3;
				if (num6 <= Plugin.HardStallAngleDot.Value && num6 > Plugin.MinLiftAngleDot.Value)
				{
					num = num5 * (0.2f + num6 + (float)(PlayerPatches.CurrentWingsItem.m_quality - 1) * 0.033f);
					if (num6 >= Plugin.StallAngleDot.Value)
					{
						num *= (Plugin.HardStallAngleDot.Value - num6) / (Plugin.HardStallAngleDot.Value - Plugin.StallAngleDot.Value);
					}
					if (RB.position.y > 500f)
					{
						num *= Mathf.Clamp01(1f - (RB.position.y - 500f) / (Plugin.MaximumAltitudeForLift.Value - 500f));
					}
				}
			}
			Vector3 val6 = ((Component)RB).transform.up * num * Plugin.LiftForceScalar.Value;
			if (num > 0f)
			{
				val6 *= Plugin.BiomeLiftModifiers[EnvMan.instance.GetBiome()];
			}
			val6 -= Vector3.Dot(RB.linearVelocity, ((Component)RB).transform.forward) * Plugin.ForwardDragCoefficient.Value * ((Component)RB).transform.forward;
			val6 -= Vector3.Dot(RB.linearVelocity, ((Component)RB).transform.right) * Plugin.RightDragCoefficient.Value * ((Component)RB).transform.right;
			val6 -= Vector3.Dot(RB.linearVelocity, ((Component)RB).transform.up) * Plugin.UpDragCoefficient.Value * ((Component)RB).transform.up;
			val6 += val5;
			RB.AddForce(val6, (ForceMode)0);
			Quaternion rotation = ((Component)RB).transform.rotation;
			Vector3 eulerAngles = ((Quaternion)(ref rotation)).eulerAngles;
			eulerAngles.x = (eulerAngles.z = 0f);
			((Quaternion)(ref rotation)).eulerAngles = eulerAngles;
			float num7 = Vector3.Dot(((Component)RB).transform.right, Vector3.up);
			if (!AirBraking)
			{
				if (num5 > 0f)
				{
					float num8 = Mathf.Clamp01(num2);
					val4 = RB.linearVelocity;
					float num9 = num8 * ((Vector3)(ref val4)).magnitude * (0f - num7) * Plugin.TurnScalar.Value * num5;
					Transform transform = ((Component)RB).transform;
					transform.rotation *= Quaternion.Euler(Vector3.up * num9 * Time.fixedDeltaTime);
				}
				Quaternion rotation2 = ((Component)RB).transform.rotation;
				float num10 = Plugin.LeanRate.Value + (float)(PlayerPatches.CurrentWingsItem.m_quality - 1) * 2f;
				rotation2 *= Quaternion.Euler(Vector3.forward * (0f - PilotLean.x) * num10 * Time.fixedDeltaTime);
				rotation2 *= Quaternion.Euler(Vector3.right * PilotLean.z * num10 * Time.fixedDeltaTime);
				((Component)RB).transform.rotation = rotation2;
			}
			val4 = RB.linearVelocity;
			if (((Vector3)(ref val4)).sqrMagnitude > (Plugin.MaxSpeed.Value + num4) * (Plugin.MaxSpeed.Value + num4))
			{
				Rigidbody rB = RB;
				val4 = RB.linearVelocity;
				Vector3 val7 = -((Vector3)(ref val4)).normalized;
				val4 = RB.linearVelocity;
				rB.AddForce(val7 * ((Vector3)(ref val4)).sqrMagnitude * Plugin.MaxSpeedEnforceRate.Value, (ForceMode)0);
			}
			if (PlayerFlapped && FlapCooldownTimer > 0f)
			{
				Vector3 val8;
				if (AirBraking)
				{
					val8 = -((Character)Pilot).m_lookDir;
				}
				else
				{
					val4 = ((Component)RB).transform.forward + ((Component)RB).transform.up;
					val8 = ((Vector3)(ref val4)).normalized;
				}
				float num11 = Plugin.FlapForce.Value;
				if (((Character)Pilot).GetSEMan().HaveStatusEffect(BeltStrengthHash))
				{
					num11 *= 1.25f;
				}
				RB.AddForce(val8 * num11, (ForceMode)0);
			}
			SyncPilot();
		}

		public void FixedUpdate()
		{
			if (Object.op_Implicit((Object)(object)Pilot))
			{
				if (Flying)
				{
					DoGliderPhysics();
				}
				else
				{
					SyncToPlayer();
				}
			}
		}

		private void SyncToPlayer()
		{
			//IL_0011: 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_0047: 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_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)
			((Component)this).transform.position = ((Component)Pilot).transform.position;
			((Component)this).transform.rotation = ((Component)Pilot).transform.rotation;
			RB.position = ((Component)Pilot).transform.position;
			RB.rotation = ((Component)Pilot).transform.rotation;
			RB.linearVelocity = Vector3.zero;
			RB.angularVelocity = Vector3.zero;
		}

		public void LateUpdate()
		{
			if (!Object.op_Implicit((Object)(object)Pilot))
			{
				return;
			}
			if (FlapCooldownTimer > 0f)
			{
				FlapCooldownTimer -= Time.deltaTime;
				if (FlapCooldownTimer <= 0f)
				{
					PlayerFlapped = false;
					((Character)Pilot).m_zanim.SetBool("onGround", true);
				}
			}
			if (Flying)
			{
				SyncPilot();
			}
			else
			{
				SyncToPlayer();
			}
		}
	}
	[HarmonyPatch(typeof(Hud))]
	public class HudPatches
	{
		public static WingsWindIndicator WWI;

		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		public static void AwakePostfix(Hud __instance)
		{
			GameObject obj = Object.Instantiate<GameObject>(Plugin.WingsHudPrefab, __instance.m_shipHudRoot.transform.parent);
			WWI = obj.AddComponent<WingsWindIndicator>();
			obj.SetActive(false);
		}
	}
	[HarmonyPatch(typeof(Player))]
	public class PlayerPatches
	{
		public class PlayerVisuals
		{
			private const float MaxFeatherWindSpeed = 6.12f;

			private const float MinFeatherWindSpeed = 1f;

			private const float MaxFeatherWindIntensity = 0.06f;

			private const float MinFeatherWindIntensity = 0.01f;

			private const float DryFeatherSmoothness = 0.05f;

			private const float WetFeatherSmoothness = 0.9f;

			public Player Player;

			public Animator PlayerAnim;

			public CharacterAnimEvent PlayerCAE;

			public RuntimeAnimatorController PlayerRAC;

			public AnimatorOverrideController PlayerNormalAOC;

			public AnimatorOverrideController PlayerFlyingAOC;

			public SkinnedMeshRenderer CurrentWingsSMR;

			public VisEquipment PlayerVE;

			public Color NormalTintColor;

			public EffectList WingFlapSFX;

			public bool IsWet;

			public bool HasWings;

			public bool IsFlying;

			public float FlapCooldownTimer;

			public void SetupPlayerVisuals(Player p)
			{
				//IL_0085: Unknown result type (might be due to invalid IL or missing references)
				//IL_008f: Expected O, but got Unknown
				//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b0: Expected O, but got Unknown
				//IL_0141: Unknown result type (might be due to invalid IL or missing references)
				//IL_014b: Expected O, but got Unknown
				//IL_0159: Unknown result type (might be due to invalid IL or missing references)
				//IL_015f: Expected O, but got Unknown
				if (!Object.op_Implicit((Object)(object)((Character)p).m_nview) || !((Character)p).m_nview.IsValid())
				{
					return;
				}
				CurrentWingsSMR = null;
				PlayerAnim = ((Component)p).gameObject.GetComponentInChildren<Animator>();
				PlayerCAE = ((Component)p).gameObject.GetComponentInChildren<CharacterAnimEvent>();
				if (!Object.op_Implicit((Object)(object)PlayerAnim) || !Object.op_Implicit((Object)(object)PlayerCAE))
				{
					return;
				}
				PlayerRAC = PlayerAnim.runtimeAnimatorController;
				if (!Object.op_Implicit((Object)(object)PlayerRAC))
				{
					return;
				}
				PlayerNormalAOC = new AnimatorOverrideController(PlayerRAC);
				((Object)PlayerNormalAOC).name = "Player Normal Anims";
				PlayerFlyingAOC = new AnimatorOverrideController(PlayerRAC);
				((Object)PlayerFlyingAOC).name = "Player Flying Anims";
				AnimationClipOverrides animationClipOverrides = new AnimationClipOverrides(PlayerRAC.animationClips.Length);
				PlayerFlyingAOC.GetOverrides((List<KeyValuePair<AnimationClip, AnimationClip>>)animationClipOverrides);
				AnimationClip[] animationClips = PlayerRAC.animationClips;
				foreach (AnimationClip val in animationClips)
				{
					if (string.Compare(((Object)val).name, "JumpTweaked", ignoreCase: true) == 0)
					{
						animationClipOverrides[((Object)val).name] = Plugin.PlayerFlap;
					}
					else
					{
						animationClipOverrides[((Object)val).name] = Plugin.PlayerGlide;
					}
				}
				PlayerFlyingAOC.ApplyOverrides((IList<KeyValuePair<AnimationClip, AnimationClip>>)animationClipOverrides);
				WingFlapSFX = new EffectList();
				WingFlapSFX.m_effectPrefabs = (EffectData[])(object)new EffectData[1]
				{
					new EffectData()
				};
				WingFlapSFX.m_effectPrefabs[0].m_enabled = true;
				WingFlapSFX.m_effectPrefabs[0].m_prefab = Plugin.WingFlapSFXPrefab;
				IsFlying = false;
				FlapCooldownTimer = 0f;
				PlayerVE = ((Component)p).gameObject.GetComponentInChildren<VisEquipment>();
				Player = p;
				UpdatePlayerSMR();
			}

			private void UpdatePlayerSMR()
			{
				//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
				if (!Object.op_Implicit((Object)(object)PlayerVE))
				{
					CurrentWingsSMR = null;
					HasWings = false;
					return;
				}
				if (!string.IsNullOrWhiteSpace(PlayerVE.m_shoulderItem) && PlayerVE.m_shoulderItem.EndsWith("Wings"))
				{
					List<GameObject> shoulderItemInstances = PlayerVE.m_shoulderItemInstances;
					if (shoulderItemInstances != null && shoulderItemInstances.Count > 0)
					{
						HasWings = true;
						CurrentWingsSMR = PlayerVE.m_shoulderItemInstances[0].GetComponentInChildren<SkinnedMeshRenderer>();
						if (Object.op_Implicit((Object)(object)CurrentWingsSMR))
						{
							NormalTintColor = ((Renderer)CurrentWingsSMR).material.GetColor("_ColorTint");
						}
						return;
					}
				}
				HasWings = false;
				CurrentWingsSMR = null;
			}

			public void SetFlying(bool flying, bool jumpstart)
			{
				IsFlying = flying;
				if (Object.op_Implicit((Object)(object)PlayerAnim))
				{
					PlayerAnim.runtimeAnimatorController = (RuntimeAnimatorController)(object)(flying ? PlayerFlyingAOC : PlayerNormalAOC);
				}
				if (Object.op_Implicit((Object)(object)PlayerCAE))
				{
					PlayerCAE.m_footIK = !flying;
				}
				if (flying)
				{
					if (jumpstart)
					{
						((Character)Player).m_zanim.SetTrigger("jump");
					}
					((Character)Player).m_zanim.SetBool("onGround", !jumpstart);
					((Character)Player).m_zanim.SetFloat("forward_speed", 1f);
				}
			}

			public void UpdateVisuals()
			{
				//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_0173: Unknown result type (might be due to invalid IL or missing references)
				if (!Object.op_Implicit((Object)(object)PlayerVE))
				{
					return;
				}
				if (HasWings)
				{
					if (string.IsNullOrWhiteSpace(PlayerVE.m_shoulderItem) || !PlayerVE.m_shoulderItem.EndsWith("Wings"))
					{
						CurrentWingsSMR = null;
						HasWings = false;
					}
					else if (!Object.op_Implicit((Object)(object)CurrentWingsSMR))
					{
						UpdatePlayerSMR();
					}
				}
				else if (string.IsNullOrWhiteSpace(PlayerVE.m_shoulderItem) || !PlayerVE.m_shoulderItem.EndsWith("Wings"))
				{
					if (Object.op_Implicit((Object)(object)CurrentWingsSMR))
					{
						CurrentWingsSMR = null;
					}
				}
				else if (Object.op_Implicit((Object)(object)CurrentWingsSMR))
				{
					HasWings = true;
				}
				else
				{
					UpdatePlayerSMR();
				}
				if (HasWings)
				{
					if (IsFlying)
					{
						((Renderer)CurrentWingsSMR).material.SetFloat("_WindSpeed", 6.12f);
						((Renderer)CurrentWingsSMR).material.SetFloat("_WindIntensity", 0.06f);
					}
					else
					{
						((Renderer)CurrentWingsSMR).material.SetFloat("_WindSpeed", 1f);
						((Renderer)CurrentWingsSMR).material.SetFloat("_WindIntensity", 0.01f);
					}
					if (IsWet)
					{
						((Renderer)CurrentWingsSMR).material.SetFloat("_Smoothness", 0.9f);
						((Renderer)CurrentWingsSMR).material.SetColor("_ColorTint", Color.white);
					}
					else
					{
						((Renderer)CurrentWingsSMR).material.SetFloat("_Smoothness", 0.05f);
						((Renderer)CurrentWingsSMR).material.SetColor("_ColorTint", NormalTintColor);
					}
					if (FlapCooldownTimer > 0f)
					{
						FlapCooldownTimer -= Time.deltaTime;
						if (FlapCooldownTimer <= 0f)
						{
							((Character)Player).m_zanim.SetBool("onGround", true);
						}
					}
				}
				else
				{
					CurrentWingsSMR = null;
				}
			}

			public void FlapWings()
			{
				//IL_006d: 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)
				FlapCooldownTimer = Plugin.FlapSpeed.Value / 2f;
				((Character)Player).ResetGroundContact();
				((Character)Player).m_lastGroundTouch = 1f;
				((Character)Player).m_zanim.SetBool("onGround", false);
				((Character)Player).m_zanim.SetTrigger("jump");
				WingFlapSFX.Create(((Component)Player).transform.position, ((Component)Player).transform.rotation, (Transform)null, 1f, -1);
			}
		}

		public const string START_FLYING = "StartFlying";

		public const string STOP_FLYING = "StopFlying";

		public const string WINGS_FLAPPED = "WingsFlapped";

		public const string WET_STATUS = "WetStatus";

		private static bool PgDownPressed;

		public static Wings CurrentWings;

		public static ItemData CurrentWingsItem;

		public static float UseTimer;

		private static float MaxViewDistance;

		public static readonly Dictionary<long, PlayerVisuals> PlayerVisualsTable = new Dictionary<long, PlayerVisuals>();

		private static bool F12Pressed;

		private static int WetNameHash;

		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		public static void AwakePostfix(Player __instance)
		{
			if (((Character)__instance).IsOwner())
			{
				PgDownPressed = false;
				CurrentWings = null;
				UseTimer = 0f;
			}
			((Character)__instance).m_nview.Register<long, bool>("StartFlying", (Action<long, long, bool>)RPC_StartFlying);
			((Character)__instance).m_nview.Register<long>("StopFlying", (Action<long, long>)RPC_StopFlying);
			((Character)__instance).m_nview.Register<long>("WingsFlapped", (Action<long, long>)RPC_WingsFlapped);
			((Character)__instance).m_nview.Register<long, bool>("WetStatus", (Action<long, long, bool>)RPC_WetStatus);
		}

		public static void EquipWings(ItemData item)
		{
			//IL_0039: 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)Player.m_localPlayer == (Object)null))
			{
				if (Object.op_Implicit((Object)(object)HudPatches.WWI))
				{
					((Component)HudPatches.WWI).gameObject.SetActive(true);
				}
				GameObject obj = Object.Instantiate<GameObject>(Plugin.WingsActorPrefab, ((Component)Player.m_localPlayer).transform.position, ((Component)Player.m_localPlayer).transform.rotation);
				CurrentWingsItem = item;
				CurrentWings = obj.AddComponent<Wings>();
				CurrentWings.PilotEquipped(Player.m_localPlayer);
				((Character)Player.m_localPlayer).GetSEMan().AddStatusEffect(SE_Odinflight.SENameHash, false, 0, 0f);
			}
		}

		public static void RPC_StartFlying(long zdoID, long senderID, bool jumpstart)
		{
			if (senderID != Player.m_localPlayer.GetPlayerID())
			{
				if (PlayerVisualsTable.TryGetValue(senderID, out var value))
				{
					value.SetFlying(flying: true, jumpstart);
					return;
				}
				ManualLogSource log = Plugin.Log;
				string text = senderID.ToString();
				Player player = Player.GetPlayer(senderID);
				log.LogInfo((object)("RPC_StartFlying couldn't find PlayerVisuals for " + text + "," + ((player != null) ? player.GetPlayerName() : null)));
			}
		}

		public static void StartFlying(bool jumpstart)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			Debug.Log((object)"StartFlying");
			if (!((Character)Player.m_localPlayer).HaveStamina(0f))
			{
				Hud.instance.StaminaBarEmptyFlash();
				return;
			}
			CurrentWings.StartFlying();
			((Character)Player.m_localPlayer).m_run = (((Character)Player.m_localPlayer).m_running = false);
			((Character)Player.m_localPlayer).AttachStart(((Component)CurrentWings).transform, (GameObject)null, true, false, false, "", Vector3.zero, (Transform)null);
			PlayerVisualsTable[Player.m_localPlayer.GetPlayerID()].SetFlying(flying: true, jumpstart);
			((Character)Player.m_localPlayer).m_nview.InvokeRPC(ZNetView.Everybody, "StartFlying", new object[2]
			{
				Player.m_localPlayer.GetPlayerID(),
				jumpstart
			});
			UseTimer = 0f;
			MaxViewDistance = GameCamera.instance.m_maxDistance;
			GameCamera.instance.m_maxDistance = GameCamera.instance.m_maxDistanceBoat;
		}

		public static void RPC_StopFlying(long zdoID, long senderID)
		{
			if (senderID != Player.m_localPlayer.GetPlayerID() && PlayerVisualsTable.TryGetValue(senderID, out var value))
			{
				value.SetFlying(flying: false, jumpstart: false);
			}
		}

		public static void StopFlying()
		{
			CurrentWings.StopFlying();
			((Character)Player.m_localPlayer).AttachStop();
			GameCamera.instance.m_maxDistance = MaxViewDistance;
			PlayerVisualsTable[Player.m_localPlayer.GetPlayerID()].SetFlying(flying: false, jumpstart: false);
			((Character)Player.m_localPlayer).m_nview.InvokeRPC(ZNetView.Everybody, "StopFlying", new object[1] { Player.m_localPlayer.GetPlayerID() });
		}

		public static void UnequipWings()
		{
			if (Object.op_Implicit((Object)(object)CurrentWings))
			{
				if (CurrentWings.Flying)
				{
					StopFlying();
				}
				CurrentWings.PilotUnequipped();
			}
			UseTimer = 0f;
			CurrentWings = null;
			CurrentWingsItem = null;
			((Character)Player.m_localPlayer).GetSEMan().RemoveStatusEffect(SE_Odinflight.SENameHash, false);
		}

		public static void RPC_WingsFlapped(long zdoID, long senderID)
		{
			if (senderID != Player.m_localPlayer.GetPlayerID() && PlayerVisualsTable.TryGetValue(senderID, out var value))
			{
				value.FlapWings();
			}
		}

		public static void RPC_WetStatus(long zdoID, long senderID, bool wet)
		{
			if (senderID != Player.m_localPlayer.GetPlayerID() && PlayerVisualsTable.TryGetValue(senderID, out var value))
			{
				value.IsWet = wet;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("Update")]
		public static void UpdatePostfix(Player __instance)
		{
			long playerID = __instance.GetPlayerID();
			if (playerID == 0L)
			{
				return;
			}
			if (!PlayerVisualsTable.TryGetValue(playerID, out var value))
			{
				Plugin.Log.LogInfo((object)("Creating PlayerVisuals for id = " + playerID + "," + __instance.GetPlayerName()));
				value = new PlayerVisuals();
				PlayerVisualsTable[__instance.GetPlayerID()] = value;
			}
			if ((Object)(object)value.Player != (Object)(object)__instance)
			{
				Plugin.Log.LogInfo((object)("SetupPlayerVisuals for id = " + playerID + "," + __instance.GetPlayerName()));
				value.SetupPlayerVisuals(__instance);
			}
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				if (WetNameHash == 0)
				{
					WetNameHash = StringExtensionMethods.GetStableHashCode(Localization.instance.Localize("$se_wet_name"));
				}
				bool flag = ((Character)__instance).GetSEMan().HaveStatusEffect(WetNameHash);
				if (value.IsWet != flag)
				{
					if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
					{
						value.IsWet = flag;
					}
					((Character)__instance).m_nview.InvokeRPC(ZNetView.Everybody, "WetStatus", new object[2] { playerID, flag });
				}
			}
			value.UpdateVisuals();
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			if ((((Character)__instance).IsSwimming() || (!((Character)__instance).IsOnGround() && ((Character)__instance).InLiquid()) || ((Character)__instance).GetSEMan().HaveStatusEffect(SEMan.s_statusEffectTared)) && Object.op_Implicit((Object)(object)CurrentWings) && CurrentWings.Flying)
			{
				StopFlying();
			}
			UseTimer += Time.deltaTime;
			if (((Character)__instance).TakeInput())
			{
				if ((ZInput.GetButtonDown("Use") || ZInput.GetButtonDown("JoyUse")) && Object.op_Implicit((Object)(object)CurrentWings) && CurrentWings.Flying && UseTimer >= 0.5f)
				{
					StopFlying();
				}
				if (Object.op_Implicit((Object)(object)CurrentWings))
				{
					_ = CurrentWings.Flying;
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("SetControls")]
		public static bool SetControlsPrefix(Player __instance, Vector3 movedir, bool attack, bool attackHold, bool secondaryAttack, bool block, bool blockHold, bool jump, bool crouch, bool run, bool autoRun)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)CurrentWings) && CurrentWings.Flying)
			{
				CurrentWings.PilotControls(movedir, jump);
				return false;
			}
			if (jump && Object.op_Implicit((Object)(object)CurrentWings) && !CurrentWings.Flying && !((Character)__instance).IsOnGround() && !((Character)__instance).IsSwimming() && !((Character)__instance).IsFlying() && !((Character)__instance).IsDebugFlying())
			{
				StartFlying(jumpstart: false);
				CurrentWings.AlignToVelocity();
				return false;
			}
			return true;
		}

		[HarmonyPostfix]
		[HarmonyPatch("OnDeath")]
		public static void OnDeathPostfix(Player __instance)
		{
			if (Object.op_Implicit((Object)(object)CurrentWings))
			{
				if (CurrentWings.Flying)
				{
					CurrentWings.StopFlying();
				}
				CurrentWings.PilotUnequipped();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("OnSwimming")]
		public static void OnSwimmingPostfix(Player __instance)
		{
			if (Object.op_Implicit((Object)(object)CurrentWings) && CurrentWings.Flying)
			{
				StopFlying();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("ResetCharacter")]
		public static void ResetCharacterPostfix(Player __instance)
		{
			((Humanoid)__instance).m_inventory.m_inventory.Clear();
		}
	}
	[HarmonyPatch(typeof(Humanoid))]
	public class HumanoidPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch("EquipItem")]
		public static bool EquipItemPrefix(Humanoid __instance, ItemData item)
		{
			//IL_0024: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected I4, but got Unknown
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || !Object.op_Implicit((Object)(object)PlayerPatches.CurrentWings) || item == null)
			{
				return true;
			}
			ItemType itemType = item.m_shared.m_itemType;
			switch (itemType - 2)
			{
			case 0:
			case 1:
			case 2:
			case 3:
			case 7:
			case 10:
			case 11:
			case 12:
			case 13:
			case 17:
			case 20:
				return false;
			default:
				return true;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("EquipItem")]
		public static void EquipItemPostfix(Humanoid __instance, ItemData item, bool __result)
		{
			if (((Character)__instance).IsPlayer() && (item?.m_shared.m_name.EndsWith(" Wings") ?? false) && __result)
			{
				Player val = (Player)(object)((__instance is Player) ? __instance : null);
				if (((Humanoid)val).m_rightItem != null)
				{
					((Humanoid)val).UnequipItem(((Humanoid)val).m_rightItem, true);
				}
				if (((Humanoid)val).m_leftItem != null)
				{
					((Humanoid)val).UnequipItem(((Humanoid)val).m_leftItem, true);
				}
				PlayerPatches.EquipWings(item);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("UnequipItem")]
		public static void UnequipItemPostfix(Humanoid __instance, ItemData item)
		{
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && item != null && item.m_shared.m_name.EndsWith(" Wings"))
			{
				PlayerPatches.UnequipWings();
			}
		}
	}
	[HarmonyPatch(typeof(Character))]
	public class CharacterPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch("UpdateWalking")]
		public static bool UpdateWalkingPrefix(Character __instance)
		{
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			if (Object.op_Implicit((Object)(object)PlayerPatches.CurrentWings) && PlayerPatches.CurrentWings.Flying)
			{
				return false;
			}
			return true;
		}

		[HarmonyPrefix]
		[HarmonyPatch("Damage")]
		public static void DamagePrefix(Character __instance, HitData hit)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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)
			if (Object.op_Implicit((Object)(object)PlayerPatches.CurrentWings) && hit.m_point == __instance.m_lastGroundPoint && hit.m_dir == __instance.m_lastGroundNormal)
			{
				hit.m_damage.m_damage /= 5f;
			}
		}
	}
	[HarmonyPatch(typeof(VisEquipment))]
	public class VisEquipmentPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch("AttachArmor")]
		public static bool AttachArmorPrefix(VisEquipment __instance, int itemHash, int variant, ref List<GameObject> __result)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Invalid comparison between Unknown and I4
			//IL_0135: 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_03d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(itemHash);
			if ((Object)(object)itemPrefab != (Object)(object)Plugin.OdinWingsPrefab)
			{
				ItemDrop componentInChildren = itemPrefab.GetComponentInChildren<ItemDrop>();
				if (Object.op_Implicit((Object)(object)componentInChildren) && (int)componentInChildren.m_itemData.m_shared.m_itemType == 17 && Object.op_Implicit((Object)(object)__instance.m_nview) && __instance.m_nview.IsValid() && PlayerPatches.PlayerVisualsTable.TryGetValue(__instance.m_nview.m_zdo.GetOwner(), out var value))
				{
					value.HasWings = false;
					value.CurrentWingsSMR = null;
				}
				return true;
			}
			if ((Object)(object)itemPrefab == (Object)null)
			{
				ZLog.Log((object)("Missing attach item: " + itemHash + "  ob:" + ((Object)((Component)__instance).gameObject).name));
				__result = null;
				return false;
			}
			List<GameObject> list = new List<GameObject>();
			int childCount = itemPrefab.transform.childCount;
			for (int i = 0; i < childCount; i++)
			{
				Transform child = itemPrefab.transform.GetChild(i);
				if (!((Object)((Component)child).gameObject).name.StartsWith("attach_"))
				{
					continue;
				}
				string text = ((Object)((Component)child).gameObject).name.Substring(7);
				GameObject val;
				if (text == "skin")
				{
					val = Object.Instantiate<GameObject>(((Component)child).gameObject, ((Component)__instance.m_bodyModel).transform.position, ((Component)__instance.m_bodyModel).transform.parent.rotation, ((Component)__instance.m_bodyModel).transform.parent);
					val.SetActive(true);
					SkinnedMeshRenderer[] componentsInChildren = val.GetComponentsInChildren<SkinnedMeshRenderer>();
					foreach (SkinnedMeshRenderer val2 in componentsInChildren)
					{
						if (Object.op_Implicit((Object)(object)__instance.m_nview) && __instance.m_nview.IsValid() && PlayerPatches.PlayerVisualsTable.TryGetValue(__instance.m_nview.m_zdo.GetOwner(), out var value2))
						{
							value2.HasWings = true;
							value2.CurrentWingsSMR = val2;
							value2.NormalTintColor = ((Renderer)val2).material.GetColor("_ColorTint");
						}
						val2.rootBone = __instance.m_bodyModel.rootBone;
						Transform[] origBones = val2.bones;
						Transform[] array = (Transform[])(object)new Transform[__instance.m_bodyModel.bones.Length];
						int b;
						for (b = 0; b < array.Length; b++)
						{
							if (b >= origBones.Length)
							{
								array[b] = __instance.m_bodyModel.bones[b];
								continue;
							}
							Transform val3 = Array.Find(__instance.m_bodyModel.bones, (Transform c) => ((Object)c).name == ((Object)origBones[b]).name);
							array[b] = (Object.op_Implicit((Object)(object)val3) ? val3 : origBones[b]);
						}
						val2.bones = array;
					}
					Cloth[] componentsInChildren2 = val.GetComponentsInChildren<Cloth>();
					foreach (Cloth val4 in componentsInChildren2)
					{
						if (__instance.m_clothColliders.Length != 0)
						{
							if (val4.capsuleColliders.Length != 0)
							{
								List<CapsuleCollider> list2 = new List<CapsuleCollider>(__instance.m_clothColliders);
								list2.AddRange(val4.capsuleColliders);
								val4.capsuleColliders = list2.ToArray();
							}
							else
							{
								val4.capsuleColliders = __instance.m_clothColliders;
							}
						}
					}
				}
				else
				{
					Transform val5 = Utils.FindChild(__instance.m_visual.transform, text, (IterativeSearchType)0);
					if ((Object)(object)val5 == (Object)null)
					{
						ZLog.LogWarning((object)("Missing joint " + text + " in item " + ((Object)itemPrefab).name));
						continue;
					}
					val = Object.Instantiate<GameObject>(((Component)child).gameObject);
					val.SetActive(true);
					val.transform.SetParent(val5);
					val.transform.localPosition = Vector3.zero;
					val.transform.localRotation = Quaternion.identity;
				}
				if (variant >= 0)
				{
					IEquipmentVisual componentInChildren2 = val.GetComponentInChildren<IEquipmentVisual>();
					if (componentInChildren2 != null)
					{
						componentInChildren2.Setup(variant);
					}
				}
				VisEquipment.CleanupInstance(val);
				VisEquipment.EnableEquippedEffects(val);
				list.Add(val);
			}
			__result = list;
			return false;
		}
	}
	[HarmonyPatch(typeof(AnimationEffect))]
	public class AnimationEffectPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch("Effect")]
		public static bool EffectPrefix(AnimationEffect __instance, AnimationEvent e)
		{
			return e.objectReferenceParameter is GameObject;
		}
	}
	[HarmonyPatch(typeof(GameCamera))]
	public class GameCameraPatches
	{
		private static Vector3 NormalCameraUp;

		[HarmonyPrefix]
		[HarmonyPatch("GetCameraPosition")]
		public static bool GetCameraPositionPrefix(GameCamera __instance, float dt, ref Vector3 pos, ref Quaternion rot)
		{
			//IL_0025: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: 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_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: 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_0115: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)PlayerPatches.CurrentWings) && PlayerPatches.CurrentWings.Flying)
			{
				Player localPlayer = Player.m_localPlayer;
				Vector3 offsetedEyePos = __instance.GetOffsetedEyePos();
				Vector3 val = offsetedEyePos + -((Character)localPlayer).m_lookDir * __instance.m_distance;
				__instance.CollideRay2(((Character)localPlayer).m_eye.position, offsetedEyePos, ref val);
				__instance.UpdateNearClipping(offsetedEyePos, val, dt);
				float liquidLevel = ((Character)localPlayer).GetLiquidLevel();
				if (val.y < liquidLevel + __instance.m_minWaterDistance)
				{
					val.y = liquidLevel + __instance.m_minWaterDistance;
					__instance.m_waterClipping = true;
				}
				else
				{
					__instance.m_waterClipping = false;
				}
				pos = val;
				if (!Plugin.ImmersiveFlyingCameraMode.Value)
				{
					rot = Quaternion.LookRotation(((Character)localPlayer).m_lookDir, Vector3.up);
				}
				else if (PlayerPatches.CurrentWings.AirBraking)
				{
					rot = Quaternion.LookRotation(((Character)localPlayer).m_lookDir, Vector3.up);
				}
				else if (NormalCameraUp == Vector3.zero)
				{
					rot = Quaternion.LookRotation(((Character)localPlayer).m_lookDir, ((Component)localPlayer).transform.up);
				}
				else
				{
					rot = Quaternion.RotateTowards(Quaternion.LookRotation(((Character)localPlayer).m_lookDir, NormalCameraUp), Quaternion.LookRotation(((Character)localPlayer).m_lookDir, ((Component)localPlayer).transform.up), Plugin.AirBrakeRotationRate.Value * Time.deltaTime);
				}
				return false;
			}
			return true;
		}

		[HarmonyPostfix]
		[HarmonyPatch("GetCameraPosition")]
		public static void GetCameraPositionPostfix(ref Vector3 pos, ref Quaternion rot)
		{
			//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_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			NormalCameraUp = rot * Vector3.up;
		}
	}
	[HarmonyPatch(typeof(ItemData))]
	public class ItemDataPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("GetTooltip", new Type[]
		{
			typeof(ItemData),
			typeof(int),
			typeof(bool),
			typeof(float),
			typeof(int)
		})]
		public static void GetTooltipPostfix(ItemData item, int qualityLevel, bool crafting, float worldLevel, int stackOverride, ref string __result)
		{
			if (item.m_shared.m_name.EndsWith("Wings"))
			{
				int num = 100 + (qualityLevel - 1) * 3;
				if (qualityLevel == 4)
				{
					num = 110;
				}
				__result = __result + "\nLift: <color=orange>" + num + "%</color>";
				__result = __result + "\nLean Speed: <color=orange>" + (100 + (qualityLevel - 1) * 25) + "%</color>";
			}
		}
	}
	[HarmonyPatch(typeof(Recipe))]
	public class RecipePatches
	{
		[HarmonyPrefix]
		[HarmonyPatch("GetRequiredStationLevel")]
		public static bool GetRequiredStationLevelPrefix(Recipe __instance, int quality, ref int __result)
		{
			if (__instance.m_item.m_itemData.m_shared.m_name.EndsWith("Wings"))
			{
				__result = __instance.m_minStationLevel;
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(EnvMan))]
	public class EnvManPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch("UpdateWind")]
		public static bool UpdateWindPrefix(EnvMan __instance, long timeSec, float dt)
		{
			//IL_002e: 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_017d: 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_00de: 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_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.m_debugWind)
			{
				float num = (float)Math.PI / 180f * __instance.m_debugWindAngle;
				Vector3 val = default(Vector3);
				((Vector3)(ref val))..ctor(Mathf.Sin(num), 0f, Mathf.Cos(num));
				__instance.SetTargetWind(val, __instance.m_debugWindIntensity);
			}
			else
			{
				EnvSetup currentEnvironment = __instance.GetCurrentEnvironment();
				if (currentEnvironment != null)
				{
					State state = Random.state;
					float num2 = 0f;
					float num3 = 0.5f;
					__instance.AddWindOctave(timeSec, 1, ref num2, ref num3);
					__instance.AddWindOctave(timeSec, 2, ref num2, ref num3);
					__instance.AddWindOctave(timeSec, 4, ref num2, ref num3);
					__instance.AddWindOctave(timeSec, 8, ref num2, ref num3);
					Random.state = state;
					Vector3 val2 = default(Vector3);
					((Vector3)(ref val2))..ctor(Mathf.Sin(num2), 0f, Mathf.Cos(num2));
					num3 = Mathf.Lerp(currentEnvironment.m_windMin, currentEnvironment.m_windMax, num3);
					if (Object.op_Implicit((Object)(object)Player.m_localPlayer))
					{
						Vector3 position = ((Component)Player.m_localPlayer).transform.position;
						float magnitude = ((Vector3)(ref position)).magnitude;
						if (magnitude > 10500f - __instance.m_edgeOfWorldWidth)
						{
							float num4 = Utils.LerpStep(10500f - __instance.m_edgeOfWorldWidth, 10500f, magnitude);
							num4 = 1f - Mathf.Pow(1f - num4, 2f);
							position = ((Component)Player.m_localPlayer).transform.position;
							val2 = ((Vector3)(ref position)).normalized;
							num3 = Mathf.Lerp(num3, 1f, num4);
						}
						else if (((Character)Player.m_localPlayer).GetSEMan().HaveStatusAttribute((StatusAttribute)4))
						{
							val2 = ((Component)Player.m_localPlayer).transform.forward;
						}
					}
					__instance.SetTargetWind(val2, num3);
				}
			}
			__instance.UpdateWindTransition(dt);
			return false;
		}
	}
	public class LocalConfigVar<T>
	{
		private readonly T _Var;

		public T Value => _Var;

		public LocalConfigVar(T v)
		{
			_Var = v;
		}
	}
	[BepInPlugin("pfhoenix.odinflight", "Odinflight", "2.1")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Version = "2.1";

		public const string ModName = "Odinflight";

		private Harmony _Harmony;

		public static ManualLogSource Log;

		public static GameObject PrefabOwner;

		private AssetBundle AB;

		public static AnimationClip PlayerGlide;

		public static AnimationClip PlayerFlap;

		public static GameObject OdinWingsPrefab;

		public static GameObject WingsActorPrefab;

		public static GameObject WingsHudPrefab;

		public static GameObject WingFlapSFXPrefab;

		public static Dictionary<Biome, float> BiomeLiftModifiers = new Dictionary<Biome, float>
		{
			{
				(Biome)0,
				0f
			},
			{
				(Biome)1,
				1.1f
			},
			{
				(Biome)2,
				0.9f
			},
			{
				(Biome)4,
				0.9f
			},
			{
				(Biome)8,
				1f
			},
			{
				(Biome)16,
				1.15f
			},
			{
				(Biome)32,
				1.2f
			},
			{
				(Biome)64,
				0.8f
			},
			{
				(Biome)256,
				0.85f
			},
			{
				(Biome)512,
				0.9f
			}
		};

		public static LocalConfigVar<float> PilotMassScalar;

		public static LocalConfigVar<float> LiftForceScalar;

		public static LocalConfigVar<float> ForwardDragCoefficient;

		public static LocalConfigVar<float> RightDragCoefficient;

		public static LocalConfigVar<float> UpDragCoefficient;

		public static LocalConfigVar<float> MinSafeLandingDot;

		public static LocalConfigVar<float> StallAngleDot;

		public static LocalConfigVar<float> HardStallAngleDot;

		public static LocalConfigVar<float> LeanRate;

		public static LocalConfigVar<float> TurnScalar;

		public static LocalConfigVar<float> MaxSpeed;

		public static LocalConfigVar<float> WindScalar;

		public static LocalConfigVar<float> FlapSpeed;

		public static LocalConfigVar<float> FlapForce;

		public static LocalConfigVar<float> AirBrakeRotationRate;

		public static LocalConfigVar<float> MaxSpeedEnforceRate;

		public static LocalConfigVar<float> MinLiftAngleDot;

		public object AutomatedConfigDiscovery;

		public static ConfigEntry<string> OdinWingsRecipeCraftingStation;

		public static ConfigEntry<string> OdinWingsComponent1;

		public static ConfigEntry<string> OdinWingsComponent2;

		public static ConfigEntry<string> OdinWingsComponent3;

		public static ConfigEntry<string> OdinWingsComponent4;

		[NonSerialized]
		public static ConfigEntry<bool> ImmersiveFlyingCameraMode;

		public static ConfigEntry<float> FlapStaminaCost;

		public static ConfigEntry<float> PlayerInventoryMassMultiplier;

		public static ConfigEntry<float> MaximumAltitudeForLift;

		public static ConfigEntry<float> WetWingFlapCostMod;

		private void UpdateRecipeStubs()
		{
			Log.LogInfo((object)"UpdateRecipeStubs called");
			RecipeStub recipeStub = AssetHelper.GetRecipeStub("OdinWings");
			if (recipeStub == null)
			{
				recipeStub = new RecipeStub();
				recipeStub.Item = OdinWingsPrefab.GetComponentInChildren<ItemDrop>(true);
				AssetHelper.RegisterRecipe(recipeStub);
			}
			recipeStub.CraftingStation = OdinWingsRecipeCraftingStation.Value;
			recipeStub.Requirements.Clear();
			RecipeStub.RequirementStub requirementStub = RecipeStub.RequirementStub.Parse(OdinWingsComponent1.Value);
			if (requirementStub != null)
			{
				recipeStub.Requirements.Add(requirementStub);
			}
			requirementStub = RecipeStub.RequirementStub.Parse(OdinWingsComponent2.Value);
			if (requirementStub != null)
			{
				recipeStub.Requirements.Add(requirementStub);
			}
			requirementStub = RecipeStub.RequirementStub.Parse(OdinWingsComponent3.Value);
			if (requirementStub != null)
			{
				recipeStub.Requirements.Add(requirementStub);
			}
			requirementStub = RecipeStub.RequirementStub.Parse(OdinWingsComponent4.Value);
			if (requirementStub != null)
			{
				recipeStub.Requirements.Add(requirementStub);
			}
		}

		private void ServerConfigReceived()
		{
			UpdateRecipeStubs();
			AssetHelper.UpdateRecipes();
		}

		private void ConfigReloaded()
		{
			UpdateRecipeStubs();
			AssetHelper.UpdateRecipes();
		}

		private void Awake()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			Log = new ManualLogSource((string)null);
			if (!Object.op_Implicit((Object)(object)PrefabOwner))
			{
				PrefabOwner = new GameObject("OdinflightPrefabOwner");
				PrefabOwner.SetActive(false);
				Object.DontDestroyOnLoad((Object)(object)PrefabOwner);
			}
			AB = AssetHelper.LoadAssetBundle("odinflightbundle");
			PlayerFlap = AB.LoadAsset<AnimationClip>("assets/AnimationClip/FlyForward_0.anim");
			PlayerGlide = AB.LoadAsset<AnimationClip>("assets/AnimationClip/Glide_NoFlap.anim");
			OdinWingsPrefab = AB.LoadAsset<GameObject>("assets/PrefabInstance/OdinWings.prefab");
			AssetHelper.RegisterPrefab(OdinWingsPrefab);
			WingsActorPrefab = AB.LoadAsset<GameObject>("assets/PrefabInstance/WingActor.prefab");
			AssetHelper.RegisterPrefab(WingsActorPrefab);
			WingsHudPrefab = AB.LoadAsset<GameObject>("assets/PrefabInstance/WingsHud.prefab");
			Object.DontDestroyOnLoad((Object)(object)WingsHudPrefab);
			WingsHudPrefab.AddComponent<WingsWindIndicator>();
			WingFlapSFXPrefab = AB.LoadAsset<GameObject>("assets/PrefabInstance/SFX_WingFlap.prefab");
			Object.DontDestroyOnLoad((Object)(object)WingFlapSFXPrefab);
			AutomatedConfigDiscovery = this;
			OdinWingsRecipeCraftingStation = ((BaseUnityPlugin)this).Config.Bind<string>("Odin Wings", "Odin Wings Crafting Station", "piece_artisanstation", "Crafting station required to craft Odin Wings");
			OdinWingsComponent1 = ((BaseUnityPlugin)this).Config.Bind<string>("Odin Wings", "Odin Wings Component 1", "Feathers:100:10", "Format is Item:Amount:AmountIncreasePerLevel");
			OdinWingsComponent2 = ((BaseUnityPlugin)this).Config.Bind<string>("Odin Wings", "Odin Wings Component 2", "Resin:20:2", "Format is Item:Amount:AmountIncreasePerLevel");
			OdinWingsComponent3 = ((BaseUnityPlugin)this).Config.Bind<string>("Odin Wings", "Odin Wings Component 3", "LoxPelt:2", "Format is Item:Amount:AmountIncreasePerLevel");
			OdinWingsComponent4 = ((BaseUnityPlugin)this).Config.Bind<string>("Odin Wings", "Odin Wings Component 4", "LinenThread:20:2", "Format is Item:Amount:AmountIncreasePerLevel");
			ImmersiveFlyingCameraMode = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Immersive Camera Mode", true, "Camera mode while flying tilts with the player.");
			FlapStaminaCost = ((BaseUnityPlugin)this).Config.Bind<float>("Odin Wings", "Flap Stamina Cost", 5f, "Stamina required to flap wings");
			PlayerInventoryMassMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Odin Wings", "Player Inventory Mass Multiplier", 1f, "Multiplier for the mass of the player's inventory (modify with extreme care!)");
			MaximumAltitudeForLift = ((BaseUnityPlugin)this).Config.Bind<float>("Odin Wings", "Maximum altitude for lift", 550f, "The altitude at which wings will no longer generate lift");
			WetWingFlapCostMod = ((BaseUnityPlugin)this).Config.Bind<float>("Odin Wings", "Wet Wing Flap Cost Multiplier", 1.25f, "Stamina cost multiplier to flap wet wings");
			UpdateRecipeStubs();
			AssetHelper.RegisterStatusEffect<SE_Odinflight>("ODINFLIGHT");
			PilotMassScalar = new LocalConfigVar<float>(0.5f);
			LiftForceScalar = new LocalConfigVar<float>(550f);
			ForwardDragCoefficient = new LocalConfigVar<float>(0.5f);
			RightDragCoefficient = new LocalConfigVar<float>(0.85f);
			UpDragCoefficient = new LocalConfigVar<float>(0.99f);
			MinSafeLandingDot = new LocalConfigVar<float>(0.7071f);
			StallAngleDot = new LocalConfigVar<float>(0.342f);
			HardStallAngleDot = new LocalConfigVar<float>(0.5f);
			LeanRate = new LocalConfigVar<float>(8f);
			TurnScalar = new LocalConfigVar<float>(0.02f);
			MaxSpeed = new LocalConfigVar<float>(40f);
			WindScalar = new LocalConfigVar<float>(10f);
			FlapSpeed = new LocalConfigVar<float>(0.25f);
			FlapForce = new LocalConfigVar<float>(12500f);
			AirBrakeRotationRate = new LocalConfigVar<float>(180f);
			MaxSpeedEnforceRate = new LocalConfigVar<float>(3f);
			MinLiftAngleDot = new LocalConfigVar<float>(-0.1f);
			_Harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
		}

		private void OnDestroy()
		{
			if (_Harmony != null)
			{
				_Harmony.UnpatchSelf();
			}
			AssetHelper.AssetCleanup();
		}
	}
	public class WingsWindEffect : MonoBehaviour
	{
		public Wings CurrentWings;

		public float m_multiplier = 20f;

		public int m_particleEmissionMin = 1;

		public int m_particleEmissionMax = 5;

		private ParticleSystem m_ps;

		private void Start()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			m_ps = ((Component)this).GetComponent<ParticleSystem>();
			VelocityOverLifetimeModule velocityOverLifetime = m_ps.velocityOverLifetime;
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).space = (ParticleSystemSimulationSpace)0;
		}

		private void Update()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: 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_008b: 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_009a: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			Vector3 windForce = EnvMan.instance.GetWindForce();
			windForce *= m_multiplier;
			VelocityOverLifetimeModule velocityOverLifetime = m_ps.velocityOverLifetime;
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).x = MinMaxCurve.op_Implicit(windForce.x + CurrentWings.RB.linearVelocity.x);
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).z = MinMaxCurve.op_Implicit(windForce.z + CurrentWings.RB.linearVelocity.z);
			ShapeModule shape = m_ps.shape;
			Vector3 position = CurrentWings.RB.linearVelocity * Time.deltaTime;
			((ShapeModule)(ref shape)).position = position;
			EmissionModule emission = m_ps.emission;
			((EmissionModule)(ref emission)).rateOverTimeMultiplier = Mathf.Lerp((float)m_particleEmissionMin, (float)m_particleEmissionMax, EnvMan.instance.GetWindIntensity());
		}
	}
	public class WingsWindIndicator : MonoBehaviour
	{
		public Image[] WindIcons;

		public void Start()
		{
			WindIcons = ((Component)this).GetComponentsInChildren<Image>();
		}

		public void Update()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: 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_012e: 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_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && Object.op_Implicit((Object)(object)PlayerPatches.CurrentWings))
			{
				Vector3 windForce = EnvMan.instance.GetWindForce();
				float magnitude = ((Vector3)(ref windForce)).magnitude;
				if (magnitude >= 0.4f)
				{
					((Graphic)WindIcons[0]).color = Color.white;
					if (magnitude >= 0.7f)
					{
						((Graphic)WindIcons[1]).color = Color.white;
						((Graphic)WindIcons[2]).color = new Color(1f, 1f, 1f, (magnitude - 0.7f) / 0.3f);
					}
					else
					{
						((Graphic)WindIcons[1]).color = new Color(1f, 1f, 1f, (magnitude - 0.4f) / 0.3f);
						((Graphic)WindIcons[2]).color = Color.clear;
					}
				}
				else
				{
					((Graphic)WindIcons[0]).color = new Color(1f, 1f, 1f, magnitude / 0.4f);
					((Graphic)WindIcons[1]).color = Color.clear;
					((Graphic)WindIcons[2]).color = Color.clear;
				}
				Vector3 windDir = EnvMan.instance.GetWindDir();
				float num = 0f - Utils.YawFromDirection(((Component)Player.m_localPlayer).transform.InverseTransformDirection(windDir));
				((Component)this).transform.localRotation = Quaternion.Euler(0f, 0f, num);
			}
			else
			{
				((Component)this).gameObject.SetActive(false);
			}
		}
	}
}
namespace Odinflight.Properties
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class Resources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					resourceMan = new ResourceManager("Odinflight.Properties.Resources", typeof(Resources).Assembly);
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal Resources()
		{
		}
	}
}