Decompiled source of DragonBorn v1.0.2

plugins/DragonBorn.dll

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

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("NotTerra")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Valheim mod: dragon blood runs in your veins - become the Drake, Moder or Fader.")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2")]
[assembly: AssemblyProduct("DragonBorn")]
[assembly: AssemblyTitle("DragonBorn")]
[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 DragonBorn
{
	internal static class Combat
	{
		private static readonly Collider[] s_hits = (Collider[])(object)new Collider[256];

		private static readonly HashSet<GameObject> s_done = new HashSet<GameObject>();

		private static readonly List<Character> s_targets = new List<Character>();

		private static int s_attackMask;

		private static int s_groundMask;

		private static int s_characterMask;

		private static int s_blockMask;

		internal const float MeteorFall = 0.6f;

		internal static int AttackMask
		{
			get
			{
				if (s_attackMask == 0)
				{
					s_attackMask = LayerMask.GetMask(new string[11]
					{
						"Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "character", "character_net", "character_ghost", "hitbox", "character_noenv",
						"vehicle"
					});
				}
				return s_attackMask;
			}
		}

		internal static int GroundMask
		{
			get
			{
				if (s_groundMask == 0)
				{
					s_groundMask = LayerMask.GetMask(new string[6] { "Default", "static_solid", "Default_small", "piece", "terrain", "vehicle" });
				}
				return s_groundMask;
			}
		}

		internal static int CharacterMask
		{
			get
			{
				if (s_characterMask == 0)
				{
					s_characterMask = LayerMask.GetMask(new string[5] { "character", "character_net", "character_ghost", "hitbox", "character_noenv" });
				}
				return s_characterMask;
			}
		}

		private static int BlockMask
		{
			get
			{
				if (s_blockMask == 0)
				{
					s_blockMask = LayerMask.GetMask(new string[3] { "terrain", "static_solid", "piece" });
				}
				return s_blockMask;
			}
		}

		internal static float DamageMultiplier(Player p)
		{
			float num = Progression.DamageScale(Progression.Bosses()) * Mathf.Max(0.01f, DragonBornPlugin.DamageMultiplier.Value);
			num *= 1f + DragonSkill.DamageBonus(p);
			if (StatusEffects.HasFury(p))
			{
				num *= 1.25f;
			}
			return num;
		}

		private static HitData BaseHit(Player p)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			HitData val = new HitData
			{
				m_hitType = (HitType)2,
				m_skill = DragonSkill.HitSkill,
				m_skillRaiseAmount = 1f
			};
			val.SetAttacker((Character)(object)p);
			return val;
		}

		private static HitData MakeHit(Player p, AttackDef def, float mult, int toolTier)
		{
			HitData obj = BaseHit(p);
			obj.m_damage.m_blunt = def.Blunt * mult;
			obj.m_damage.m_slash = def.Slash * mult;
			obj.m_damage.m_pierce = def.Pierce * mult;
			obj.m_damage.m_fire = def.Fire * mult;
			obj.m_damage.m_frost = def.Frost * mult;
			obj.m_damage.m_poison = def.Poison * mult;
			obj.m_damage.m_spirit = def.Spirit * mult;
			obj.m_damage.m_chop = def.Chop * mult;
			obj.m_damage.m_pickaxe = def.Pickaxe * mult;
			obj.m_toolTier = (short)toolTier;
			obj.m_pushForce = def.Push;
			obj.m_staggerMultiplier = def.Stagger;
			obj.m_backstabBonus = 2f;
			obj.m_blockable = true;
			obj.m_dodgeable = true;
			return obj;
		}

		internal static bool IsValidTarget(Player p, Character target)
		{
			if ((Object)(object)target == (Object)null || (Object)(object)target == (Object)(object)p || target.IsDead())
			{
				return false;
			}
			if (target.IsPlayer())
			{
				if (((Character)p).IsPVPEnabled())
				{
					return target.IsPVPEnabled();
				}
				return false;
			}
			return BaseAI.IsEnemy((Character)(object)p, target);
		}

		private static List<Character> EnemiesInSphere(Player p, Vector3 center, float radius)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			s_targets.Clear();
			s_done.Clear();
			int num = Physics.OverlapSphereNonAlloc(center, radius, s_hits, CharacterMask, (QueryTriggerInteraction)0);
			for (int i = 0; i < num; i++)
			{
				Collider val = s_hits[i];
				s_hits[i] = null;
				if (!((Object)(object)val == (Object)null))
				{
					Character componentInParent = ((Component)val).GetComponentInParent<Character>();
					if (!((Object)(object)componentInParent == (Object)null) && !s_done.Contains(((Component)componentInParent).gameObject) && IsValidTarget(p, componentInParent))
					{
						s_done.Add(((Component)componentInParent).gameObject);
						s_targets.Add(componentInParent);
					}
				}
			}
			return s_targets;
		}

		private static void TryStagger(Character target, Vector3 dir)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)target == (Object)null || target.IsBoss() || target.IsDead())
			{
				return;
			}
			try
			{
				target.Stagger(dir);
			}
			catch (Exception e)
			{
				Util.LogOnce("stagger", e);
			}
		}

		private static Vector3 FlatDir(Vector3 from, Vector3 to, Vector3 fallback)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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)
			Vector3 val = to - from;
			val.y = 0f;
			if (!(((Vector3)(ref val)).sqrMagnitude > 0.0001f))
			{
				return fallback;
			}
			return ((Vector3)(ref val)).normalized;
		}

		internal static float Primary(DragonPlayer owner, Player p, DragonDef d, Vector3 origin)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			AttackDef attackDef = d?.Primary;
			if ((Object)(object)p == (Object)null || attackDef == null)
			{
				return 0f;
			}
			float mult = DamageMultiplier(p);
			CreatureAttack ca = Creatures.Get(d.Id)?.Primary;
			if (attackDef.Kind == AttackKind.Projectile)
			{
				Shoot(p, attackDef, ca, mult, origin);
				return 0f;
			}
			return AreaHit(p, attackDef, ca, mult);
		}

		private static float AreaHit(Player p, AttackDef def, CreatureAttack ca, float mult)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_0037: 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_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: 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_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)p).transform;
			Vector3 val = transform.position + transform.forward * def.Range + Vector3.up * 1f;
			int toolTier = (def.ToolTier ? Progression.ToolTier(Progression.Bosses()) : 0);
			int num = Physics.OverlapSphereNonAlloc(val, def.Radius, s_hits, AttackMask, (QueryTriggerInteraction)0);
			s_done.Clear();
			bool flag = false;
			float num2 = 0f;
			for (int i = 0; i < num; i++)
			{
				Collider val2 = s_hits[i];
				s_hits[i] = null;
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				GameObject val3 = Projectile.FindHitObject(val2);
				if ((Object)(object)val3 == (Object)null || (Object)(object)val3 == (Object)(object)((Component)p).gameObject || s_done.Contains(val3) || val3.transform.IsChildOf(transform))
				{
					continue;
				}
				IDestructible component = val3.GetComponent<IDestructible>();
				if (component == null)
				{
					continue;
				}
				Character component2 = val3.GetComponent<Character>();
				if ((Object)(object)component2 != (Object)null)
				{
					if (!IsValidTarget(p, component2))
					{
						continue;
					}
				}
				else if (!DragonBornPlugin.AttacksHitBuildings.Value && ((Object)(object)val3.GetComponent<WearNTear>() != (Object)null || (Object)(object)val3.GetComponent<Piece>() != (Object)null))
				{
					continue;
				}
				s_done.Add(val3);
				Bounds bounds = val2.bounds;
				Vector3 val4 = ((Bounds)(ref bounds)).ClosestPoint(val);
				Vector3 val5 = val4 - transform.position;
				val5.y = 0f;
				if (((Vector3)(ref val5)).sqrMagnitude < 0.0001f)
				{
					val5 = transform.forward;
				}
				HitData val6 = MakeHit(p, def, mult, toolTier);
				val6.m_point = val4;
				val6.m_dir = ((Vector3)(ref val5)).normalized;
				val6.m_hitCollider = val2;
				float num3 = def.Blunt + def.Slash + def.Pierce + def.Fire + def.Frost + def.Poison + def.Spirit;
				try
				{
					component.Damage(val6);
					flag = true;
					if ((Object)(object)component2 != (Object)null)
					{
						num2 += num3 * mult;
					}
				}
				catch (Exception e)
				{
					Util.LogOnce("damage-" + ((Object)val3).name, e);
				}
				if (ca != null)
				{
					Fx.Play(ca.HitEffect, val4, Quaternion.identity, null, 1f);
					Fx.Play(ca.ItemHitEffect, val4, Quaternion.identity, null, 1f);
				}
			}
			if (def.Push >= 50f || (flag && def.Blunt > 0f))
			{
				Util.Shake(val, 20f, 0.6f);
			}
			return num2;
		}

		private static void Shoot(Player p, AttackDef def, CreatureAttack ca, float mult, Vector3 origin)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: 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_000f: 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_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_0185: 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_0189: 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_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: 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_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)p).transform;
			Vector3 val;
			try
			{
				val = ((Humanoid)p).GetAimDir(origin);
			}
			catch
			{
				val = ((Character)p).GetLookDir();
			}
			if (((Vector3)(ref val)).sqrMagnitude < 0.01f)
			{
				val = transform.forward;
			}
			((Vector3)(ref val)).Normalize();
			GameObject val2 = ca?.Projectile;
			float num = def.ProjectileSpeed;
			if (num <= 0f && ca != null && ca.Attack != null)
			{
				num = ca.Attack.m_projectileVel;
			}
			if (num <= 0f)
			{
				num = 25f;
			}
			int num2 = Mathf.Max(1, def.Projectiles);
			Vector3 val3 = Vector3.Cross(Vector3.up, val);
			if (((Vector3)(ref val3)).sqrMagnitude < 0.001f)
			{
				val3 = transform.right;
			}
			((Vector3)(ref val3)).Normalize();
			for (int i = 0; i < num2; i++)
			{
				Vector3 val4 = val;
				if (def.Spread > 0f)
				{
					float num3 = ((num2 > 1) ? (Mathf.Lerp(0f - def.Spread, def.Spread, (float)i / (float)(num2 - 1)) + Random.Range(-2f, 2f)) : Random.Range(0f - def.Spread, def.Spread));
					float num4 = Random.Range((0f - def.Spread) * 0.35f, def.Spread * 0.35f);
					val4 = Quaternion.AngleAxis(num3, Vector3.up) * Quaternion.AngleAxis(num4, val3) * val;
				}
				HitData val5 = MakeHit(p, def, mult, 0);
				val5.m_ranged = true;
				val5.m_point = origin;
				val5.m_dir = val4;
				bool flag = false;
				if ((Object)(object)val2 != (Object)null)
				{
					try
					{
						GameObject val6 = Object.Instantiate<GameObject>(val2, origin, Quaternion.LookRotation(val4));
						IProjectile component = val6.GetComponent<IProjectile>();
						if (component != null)
						{
							ItemData val7 = ((ca.Item != null) ? ca.Item.Clone() : null);
							component.Setup((Character)(object)p, val4 * num, def.Noise, val5, val7, (ItemData)null);
							flag = true;
						}
						else
						{
							ZNetView component2 = val6.GetComponent<ZNetView>();
							if ((Object)(object)component2 != (Object)null && component2.IsValid())
							{
								component2.Destroy();
							}
							else
							{
								Object.Destroy((Object)(object)val6);
							}
						}
					}
					catch (Exception e)
					{
						Util.LogOnce("projectile-" + ((Object)val2).name, e);
					}
				}
				if (!flag)
				{
					RayHit(p, origin, val4, val5, ca);
				}
			}
		}

		private static void RayHit(Player p, Vector3 origin, Vector3 dir, HitData hit, CreatureAttack ca)
		{
			//IL_001a: 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_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: 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_015c: Unknown result type (might be due to invalid IL or missing references)
			int num = AttackMask | LayerMask.GetMask(new string[1] { "terrain" });
			RaycastHit[] array = Physics.SphereCastAll(origin, 0.4f, dir, 40f, num, (QueryTriggerInteraction)1);
			Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance));
			RaycastHit[] array2 = array;
			for (int num2 = 0; num2 < array2.Length; num2++)
			{
				RaycastHit val = array2[num2];
				if ((Object)(object)((RaycastHit)(ref val)).collider == (Object)null)
				{
					continue;
				}
				GameObject val2 = Projectile.FindHitObject(((RaycastHit)(ref val)).collider);
				if ((Object)(object)val2 == (Object)null || (Object)(object)val2 == (Object)(object)((Component)p).gameObject || val2.transform.IsChildOf(((Component)p).transform))
				{
					continue;
				}
				Vector3 val3;
				if (!(((RaycastHit)(ref val)).point == Vector3.zero))
				{
					val3 = ((RaycastHit)(ref val)).point;
				}
				else
				{
					Bounds bounds = ((RaycastHit)(ref val)).collider.bounds;
					val3 = ((Bounds)(ref bounds)).ClosestPoint(origin);
				}
				Vector3 val4 = val3;
				IDestructible component = val2.GetComponent<IDestructible>();
				Character component2 = val2.GetComponent<Character>();
				bool flag = component == null;
				if (component != null)
				{
					if ((Object)(object)component2 != (Object)null && !IsValidTarget(p, component2))
					{
						continue;
					}
					if ((Object)(object)component2 == (Object)null && !DragonBornPlugin.AttacksHitBuildings.Value && ((Object)(object)val2.GetComponent<WearNTear>() != (Object)null || (Object)(object)val2.GetComponent<Piece>() != (Object)null))
					{
						flag = true;
					}
					else
					{
						hit.m_point = val4;
						hit.m_hitCollider = ((RaycastHit)(ref val)).collider;
						try
						{
							component.Damage(hit);
						}
						catch (Exception e)
						{
							Util.LogOnce("raydamage", e);
						}
					}
				}
				if (ca != null)
				{
					Fx.Play(ca.HitEffect, val4, Quaternion.identity, null, 1f);
					Fx.Play(ca.ItemHitEffect, val4, Quaternion.identity, null, 1f);
				}
				if (flag || component != null)
				{
					break;
				}
			}
		}

		internal static float BreathRange(Player p, DragonDef d)
		{
			if (d.Breath == null)
			{
				return 0f;
			}
			return d.Breath.Range * DragonSkill.Growth(p);
		}

		internal static float BreathTick(Player p, DragonDef d, Vector3 origin, Vector3 dir, float tick)
		{
			//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_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: 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_0079: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: 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)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: 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_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: 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_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			BreathDef breathDef = d?.Breath;
			if ((Object)(object)p == (Object)null || breathDef == null || ((Vector3)(ref dir)).sqrMagnitude < 0.001f)
			{
				return 0f;
			}
			((Vector3)(ref dir)).Normalize();
			float num = BreathRange(p, d);
			float num2 = Mathf.Tan(Mathf.Clamp(breathDef.HalfAngle, 1f, 70f) * ((float)Math.PI / 180f));
			float num3 = DamageMultiplier(p);
			float num4 = breathDef.Dps * tick * num3;
			float num5 = 0f;
			List<Character> list = EnemiesInSphere(p, origin + dir * (num * 0.5f), num * 0.5f + 2.5f);
			for (int i = 0; i < list.Count; i++)
			{
				Character val = list[i];
				Vector3 centerPoint = val.GetCenterPoint();
				float num6 = Vector3.Dot(centerPoint - origin, dir);
				if (num6 < -0.5f || num6 > num + 1f)
				{
					continue;
				}
				Vector3 val2 = origin + dir * Mathf.Max(0f, num6);
				if (!(Vector3.Distance(centerPoint, val2) > Mathf.Max(0f, num6) * num2 + 0.9f) && !Physics.Linecast(origin, centerPoint, BlockMask, (QueryTriggerInteraction)1))
				{
					HitData val3 = BaseHit(p);
					if (breathDef.Element == Element.Fire)
					{
						val3.m_damage.m_fire = num4;
					}
					else
					{
						val3.m_damage.m_frost = num4;
					}
					val3.m_point = centerPoint;
					val3.m_dir = dir;
					val3.m_pushForce = breathDef.Push;
					val3.m_staggerMultiplier = 0f;
					val3.m_blockable = false;
					val3.m_dodgeable = false;
					val3.m_ranged = true;
					try
					{
						val.Damage(val3);
						num5 += num4;
					}
					catch (Exception e)
					{
						Util.LogOnce("breath-damage", e);
					}
				}
			}
			return num5;
		}

		internal static int Roar(Player p, DragonDef d)
		{
			//IL_0104: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: 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_00b2: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			RoarDef roarDef = d?.Roar;
			if ((Object)(object)p == (Object)null || roarDef == null)
			{
				return 0;
			}
			Vector3 position = ((Component)p).transform.position;
			float num = DamageMultiplier(p);
			float radius = roarDef.Radius * DragonSkill.Growth(p);
			List<Character> list = EnemiesInSphere(p, position + Vector3.up, radius);
			int num2 = 0;
			for (int i = 0; i < list.Count; i++)
			{
				Character val = list[i];
				Vector3 dir = FlatDir(position, ((Component)val).transform.position, ((Component)p).transform.forward);
				HitData val2 = BaseHit(p);
				val2.m_damage.m_blunt = 2f * num;
				val2.m_point = val.GetCenterPoint();
				val2.m_dir = dir;
				val2.m_pushForce = 40f;
				val2.m_staggerMultiplier = 4f;
				val2.m_blockable = false;
				val2.m_dodgeable = false;
				val2.m_ranged = true;
				try
				{
					val.Damage(val2);
				}
				catch (Exception e)
				{
					Util.LogOnce("roar-damage", e);
				}
				TryStagger(val, dir);
				num2++;
			}
			return num2;
		}

		internal static List<Vector3> MeteorTargets(Player p, float radius, int count)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0038: 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_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			if ((Object)(object)p == (Object)null || count <= 0)
			{
				return list;
			}
			Vector3 center = ((Component)p).transform.position;
			List<Character> list2 = new List<Character>(EnemiesInSphere(p, center + Vector3.up, radius));
			list2.Sort(delegate(Character a, Character b)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_0027: 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_0037: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val2 = ((Component)a).transform.position - center;
				float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
				val2 = ((Component)b).transform.position - center;
				return sqrMagnitude.CompareTo(((Vector3)(ref val2)).sqrMagnitude);
			});
			foreach (Character item in list2)
			{
				if (list.Count >= count)
				{
					break;
				}
				list.Add(Ground(((Component)item).transform.position));
			}
			int num = 0;
			while (list.Count < count && num++ < 40)
			{
				Vector2 insideUnitCircle = Random.insideUnitCircle;
				Vector3 pos = center + new Vector3(insideUnitCircle.x, 0f, insideUnitCircle.y) * Mathf.Lerp(3.5f, radius, ((Vector2)(ref insideUnitCircle)).magnitude);
				pos = Ground(pos);
				bool flag = false;
				foreach (Vector3 item2 in list)
				{
					Vector3 val = item2 - pos;
					if (((Vector3)(ref val)).sqrMagnitude < 4f)
					{
						flag = true;
					}
				}
				if (!flag)
				{
					list.Add(pos);
				}
			}
			return list;
		}

		internal static float MeteorDelay(int index)
		{
			return 0.45f + (float)index * 0.22f;
		}

		internal static Vector3 Ground(Vector3 pos)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(pos + Vector3.up * 30f, Vector3.down, ref val, 80f, GroundMask, (QueryTriggerInteraction)1))
			{
				return ((RaycastHit)(ref val)).point;
			}
			return pos;
		}

		internal static int Blast(Player p, Vector3 pos, float radius, float blunt, float elemental, Element element, float push, bool stagger)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0103: 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_0049: 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_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_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)
			//IL_00ae: 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)
			if ((Object)(object)p == (Object)null)
			{
				return 0;
			}
			float num = DamageMultiplier(p);
			List<Character> list = EnemiesInSphere(p, pos + Vector3.up * 0.5f, radius);
			int num2 = 0;
			for (int i = 0; i < list.Count; i++)
			{
				Character val = list[i];
				Vector3 dir = FlatDir(pos, ((Component)val).transform.position, ((Component)p).transform.forward);
				HitData val2 = BaseHit(p);
				val2.m_damage.m_blunt = blunt * num;
				if (element == Element.Fire)
				{
					val2.m_damage.m_fire = elemental * num;
				}
				else
				{
					val2.m_damage.m_frost = elemental * num;
				}
				val2.m_point = val.GetCenterPoint();
				val2.m_dir = dir;
				val2.m_pushForce = push;
				val2.m_staggerMultiplier = 3f;
				val2.m_blockable = true;
				val2.m_dodgeable = true;
				val2.m_ranged = true;
				try
				{
					val.Damage(val2);
				}
				catch (Exception e)
				{
					Util.LogOnce("blast-damage", e);
				}
				if (stagger)
				{
					TryStagger(val, dir);
				}
				num2++;
			}
			return num2;
		}

		internal static int DiveImpact(Player p, DragonDef d, Vector3 pos)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			DiveDef diveDef = d?.Dive;
			if (diveDef == null)
			{
				return 0;
			}
			return Blast(p, pos, diveDef.Radius * DragonSkill.Growth(p), diveDef.Blunt, diveDef.Elemental, diveDef.Element, 80f, stagger: true);
		}

		internal static int Meteor(Player p, DragonDef d, Vector3 pos)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			RoarDef roarDef = d?.Roar;
			if (roarDef == null)
			{
				return 0;
			}
			return Blast(p, pos, roarDef.MeteorRadius, roarDef.MeteorBlunt, roarDef.MeteorFire, Element.Fire, 50f, stagger: false);
		}

		internal static void Aura(Player p, DragonDef d)
		{
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0066: 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_0087: Expected O, but got Unknown
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Invalid comparison between Unknown and I4
			//IL_00b1: 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_00c3: 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_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)p == (Object)null || d == null || d.AuraRadius <= 0f)
			{
				return;
			}
			Vector3 center = ((Component)p).transform.position + Vector3.up;
			float radius = d.AuraRadius * DragonSkill.Growth(p);
			float num = d.AuraDamage * Progression.DamageScale(Progression.Bosses()) * Mathf.Max(0.01f, DragonBornPlugin.DamageMultiplier.Value);
			List<Character> list = EnemiesInSphere(p, center, radius);
			for (int i = 0; i < list.Count; i++)
			{
				Character val = list[i];
				HitData val2 = new HitData();
				if ((int)d.AuraType == 32)
				{
					val2.m_damage.m_fire = num;
				}
				else
				{
					val2.m_damage.m_frost = num;
				}
				val2.m_point = val.GetCenterPoint();
				val2.m_dir = FlatDir(((Component)p).transform.position, ((Component)val).transform.position, ((Component)p).transform.forward);
				val2.m_pushForce = 0f;
				val2.m_staggerMultiplier = 0f;
				val2.m_blockable = false;
				val2.m_dodgeable = false;
				val2.m_ranged = true;
				val2.m_hitType = (HitType)2;
				val2.SetAttacker((Character)(object)p);
				try
				{
					val.Damage(val2);
				}
				catch (Exception e)
				{
					Util.LogOnce("aura", e);
				}
				MorphFx.Pulse(val2.m_point, d.FxColor, d.FxColor2, 0.4f, 10, rising: true);
			}
		}
	}
	internal class CreatureAttack
	{
		public string ItemName;

		public ItemData Item;

		public Attack Attack;

		public bool IsProjectile;

		public GameObject Projectile
		{
			get
			{
				if (!IsProjectile || Attack == null)
				{
					return null;
				}
				return Attack.m_attackProjectile;
			}
		}

		public EffectList StartEffect
		{
			get
			{
				if (Attack == null)
				{
					return null;
				}
				return Attack.m_startEffect;
			}
		}

		public EffectList TriggerEffect
		{
			get
			{
				if (Attack == null)
				{
					return null;
				}
				return Attack.m_triggerEffect;
			}
		}

		public EffectList HitEffect
		{
			get
			{
				if (Attack == null)
				{
					return null;
				}
				return Attack.m_hitEffect;
			}
		}

		public EffectList ItemStartEffect
		{
			get
			{
				if (Item == null || Item.m_shared == null)
				{
					return null;
				}
				return Item.m_shared.m_startEffect;
			}
		}

		public EffectList ItemTriggerEffect
		{
			get
			{
				if (Item == null || Item.m_shared == null)
				{
					return null;
				}
				return Item.m_shared.m_triggerEffect;
			}
		}

		public EffectList ItemHitEffect
		{
			get
			{
				if (Item == null || Item.m_shared == null)
				{
					return null;
				}
				return Item.m_shared.m_hitEffect;
			}
		}

		public string PickAnimation()
		{
			if (Attack == null || string.IsNullOrEmpty(Attack.m_attackAnimation))
			{
				return null;
			}
			string attackAnimation = Attack.m_attackAnimation;
			if (Attack.m_attackChainLevels > 1)
			{
				return attackAnimation + "0";
			}
			if (Attack.m_attackRandomAnimations >= 2)
			{
				return attackAnimation + Random.Range(0, Attack.m_attackRandomAnimations);
			}
			return attackAnimation;
		}
	}
	internal class CreatureInfo
	{
		public GameObject Prefab;

		public GameObject Visual;

		public readonly List<CreatureAttack> Attacks = new List<CreatureAttack>();

		public CreatureAttack Primary;

		public CreatureAttack Breath;

		public CreatureAttack Roar;

		public CreatureAttack Meteor;

		public EffectList Alert;

		public EffectList Idle;

		public float IdleInterval = 10f;

		public float IdleChance = 0.5f;

		public EffectList Hit;

		public EffectList Jump;

		public EffectList FlyLoop;

		public readonly List<StepEffect> Steps = new List<StepEffect>();

		public readonly List<string> Feet = new List<string>();

		public bool Footless;

		public float FootlessDistance = 1.5f;

		public bool HasStepEvents;
	}
	internal static class Creatures
	{
		private static readonly Dictionary<DragonId, CreatureInfo> s_cache = new Dictionary<DragonId, CreatureInfo>();

		private static readonly HashSet<AnimationClip> s_preparedClips = new HashSet<AnimationClip>();

		internal static CreatureInfo Get(DragonId id)
		{
			if (s_cache.TryGetValue(id, out var value) && value != null && (Object)(object)value.Prefab != (Object)null)
			{
				return value;
			}
			DragonDef dragonDef = Dragons.Get(id);
			ZNetScene instance = ZNetScene.instance;
			if (dragonDef == null || (Object)(object)instance == (Object)null)
			{
				return null;
			}
			GameObject val = null;
			try
			{
				val = instance.GetPrefab(dragonDef.Prefab);
			}
			catch (Exception e)
			{
				Util.LogOnce("getprefab-" + dragonDef.Prefab, e);
			}
			if ((Object)(object)val == (Object)null)
			{
				Util.WarnOnce("noprefab-" + dragonDef.Prefab, "Creature prefab '" + dragonDef.Prefab + "' for the " + dragonDef.Name + " was not found - the dragon works, but without its model.");
				return null;
			}
			CreatureInfo creatureInfo;
			try
			{
				creatureInfo = Build(val, dragonDef);
			}
			catch (Exception e2)
			{
				Util.LogOnce("build-" + dragonDef.Prefab, e2);
				creatureInfo = new CreatureInfo
				{
					Prefab = val
				};
			}
			s_cache[id] = creatureInfo;
			return creatureInfo;
		}

		private static CreatureInfo Build(GameObject prefab, DragonDef d)
		{
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Invalid comparison between Unknown and I4
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Invalid comparison between Unknown and I4
			CreatureInfo creatureInfo = new CreatureInfo
			{
				Prefab = prefab
			};
			Transform val = prefab.transform.Find("Visual");
			if ((Object)(object)val == (Object)null)
			{
				Animator componentInChildren = prefab.GetComponentInChildren<Animator>(true);
				if ((Object)(object)componentInChildren != (Object)null && (Object)(object)((Component)componentInChildren).gameObject != (Object)(object)prefab)
				{
					val = ((Component)componentInChildren).transform;
				}
			}
			creatureInfo.Visual = (((Object)(object)val != (Object)null) ? ((Component)val).gameObject : null);
			List<GameObject> list = new List<GameObject>();
			Humanoid component = prefab.GetComponent<Humanoid>();
			if ((Object)(object)component != (Object)null)
			{
				AddItems(list, component.m_defaultItems);
				AddItems(list, component.m_randomWeapon);
				if (component.m_randomSets != null)
				{
					ItemSet[] randomSets = component.m_randomSets;
					foreach (ItemSet val2 in randomSets)
					{
						if (val2 != null)
						{
							AddItems(list, val2.m_items);
						}
					}
				}
			}
			foreach (GameObject item in list)
			{
				ItemDrop component2 = item.GetComponent<ItemDrop>();
				ItemData val3 = (((Object)(object)component2 != (Object)null) ? component2.m_itemData : null);
				Attack val4 = ((val3 != null && val3.m_shared != null) ? val3.m_shared.m_attack : null);
				if (val4 != null && (!string.IsNullOrEmpty(val4.m_attackAnimation) || !((Object)(object)val4.m_attackProjectile == (Object)null)))
				{
					bool isProjectile = (Object)(object)val4.m_attackProjectile != (Object)null && ((int)val4.m_attackType == 2 || (int)val4.m_attackType == 5);
					creatureInfo.Attacks.Add(new CreatureAttack
					{
						ItemName = ((Object)item).name.ToLowerInvariant(),
						Item = val3,
						Attack = val4,
						IsProjectile = isProjectile
					});
				}
			}
			if (d.Primary != null)
			{
				creatureInfo.Primary = PickPrimary(creatureInfo.Attacks, d.Primary);
			}
			if (d.Breath != null)
			{
				creatureInfo.Breath = PickByHints(creatureInfo.Attacks, d.Breath.Hints, allowTaunt: false) ?? creatureInfo.Primary;
			}
			if (d.Roar != null)
			{
				creatureInfo.Roar = PickByHints(creatureInfo.Attacks, d.Roar.Hints, allowTaunt: true);
			}
			if (d.Roar != null && d.Roar.Meteors > 0)
			{
				creatureInfo.Meteor = PickByHints(creatureInfo.Attacks, new string[3] { "meteor", "fireball", "rain" }, allowTaunt: false);
			}
			BaseAI component3 = prefab.GetComponent<BaseAI>();
			if ((Object)(object)component3 != (Object)null)
			{
				creatureInfo.Alert = component3.m_alertedEffects;
				creatureInfo.Idle = component3.m_idleSound;
				if (component3.m_idleSoundInterval > 0f)
				{
					creatureInfo.IdleInterval = component3.m_idleSoundInterval;
				}
				if (component3.m_idleSoundChance > 0f)
				{
					creatureInfo.IdleChance = component3.m_idleSoundChance;
				}
			}
			Character component4 = prefab.GetComponent<Character>();
			if ((Object)(object)component4 != (Object)null)
			{
				creatureInfo.Hit = component4.m_hitEffects;
				creatureInfo.Jump = component4.m_jumpEffects;
				creatureInfo.FlyLoop = component4.m_flyingContinuousEffect;
			}
			FootStep componentInChildren2 = prefab.GetComponentInChildren<FootStep>(true);
			if ((Object)(object)componentInChildren2 != (Object)null)
			{
				if (componentInChildren2.m_effects != null)
				{
					creatureInfo.Steps.AddRange(componentInChildren2.m_effects);
				}
				if (componentInChildren2.m_feet != null)
				{
					Transform[] feet = componentInChildren2.m_feet;
					foreach (Transform val5 in feet)
					{
						if ((Object)(object)val5 != (Object)null)
						{
							creatureInfo.Feet.Add(((Object)val5).name);
						}
					}
				}
				creatureInfo.Footless = componentInChildren2.m_footlessFootsteps;
				if (componentInChildren2.m_footlessTriggerDistance > 0.1f)
				{
					creatureInfo.FootlessDistance = componentInChildren2.m_footlessTriggerDistance;
				}
			}
			if ((Object)(object)creatureInfo.Visual != (Object)null)
			{
				Animator componentInChildren3 = creatureInfo.Visual.GetComponentInChildren<Animator>(true);
				if ((Object)(object)componentInChildren3 != (Object)null)
				{
					creatureInfo.HasStepEvents = PrepareClips(componentInChildren3.runtimeAnimatorController);
				}
			}
			StringBuilder stringBuilder = new StringBuilder();
			foreach (CreatureAttack attack in creatureInfo.Attacks)
			{
				stringBuilder.Append(attack.ItemName).Append(attack.IsProjectile ? "(projectile)" : "").Append(' ');
			}
			DragonBornPlugin.Log.LogInfo((object)(d.Name + " uses '" + ((Object)prefab).name + "'. Visual: " + (((Object)(object)creatureInfo.Visual != (Object)null) ? ((Object)creatureInfo.Visual).name : "missing") + ". " + string.Format("Attacks: {0}| primary={1} breath={2} ", stringBuilder, creatureInfo.Primary?.ItemName ?? "-", creatureInfo.Breath?.ItemName ?? "-") + "roar=" + (creatureInfo.Roar?.ItemName ?? "-") + " meteor=" + (creatureInfo.Meteor?.ItemName ?? "-") + " | " + $"steps={creatureInfo.Steps.Count} feet={creatureInfo.Feet.Count} stepEvents={creatureInfo.HasStepEvents} footless={creatureInfo.Footless}"));
			return creatureInfo;
		}

		private static bool PrepareClips(RuntimeAnimatorController controller)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Invalid comparison between Unknown and I4
			bool result = false;
			if ((Object)(object)controller == (Object)null)
			{
				return false;
			}
			AnimationClip[] animationClips;
			try
			{
				animationClips = controller.animationClips;
			}
			catch
			{
				return false;
			}
			if (animationClips == null)
			{
				return false;
			}
			AnimationClip[] array = animationClips;
			foreach (AnimationClip val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				try
				{
					AnimationEvent[] events = val.events;
					if (events == null || events.Length == 0)
					{
						continue;
					}
					bool flag = false;
					AnimationEvent[] array2 = events;
					foreach (AnimationEvent val2 in array2)
					{
						if (val2.functionName == "FootStep")
						{
							result = true;
						}
						if ((int)val2.messageOptions != 1)
						{
							val2.messageOptions = (SendMessageOptions)1;
							flag = true;
						}
					}
					if (flag && s_preparedClips.Add(val))
					{
						val.events = events;
					}
				}
				catch (Exception e)
				{
					Util.LogOnce("clip-" + ((Object)val).name, e);
				}
			}
			return result;
		}

		private static void AddItems(List<GameObject> list, GameObject[] items)
		{
			if (items == null)
			{
				return;
			}
			foreach (GameObject val in items)
			{
				if ((Object)(object)val != (Object)null && !list.Contains(val))
				{
					list.Add(val);
				}
			}
		}

		private static bool IsTaunt(CreatureAttack a)
		{
			if (!a.ItemName.Contains("taunt"))
			{
				return a.ItemName.Contains("idle");
			}
			return true;
		}

		private static CreatureAttack PickPrimary(List<CreatureAttack> list, AttackDef def)
		{
			if (def == null || list.Count == 0)
			{
				return null;
			}
			bool flag = def.Kind == AttackKind.Projectile;
			string[] hints = def.Hints;
			foreach (string value in hints)
			{
				foreach (CreatureAttack item in list)
				{
					if (item.IsProjectile == flag && !IsTaunt(item) && item.ItemName.Contains(value))
					{
						return item;
					}
				}
			}
			foreach (CreatureAttack item2 in list)
			{
				if (item2.IsProjectile == flag && !IsTaunt(item2))
				{
					return item2;
				}
			}
			return PickByHints(list, def.Hints, allowTaunt: false) ?? FirstNonTaunt(list);
		}

		private static CreatureAttack PickByHints(List<CreatureAttack> list, string[] hints, bool allowTaunt)
		{
			if (hints == null)
			{
				return null;
			}
			foreach (string value in hints)
			{
				foreach (CreatureAttack item in list)
				{
					if ((allowTaunt || !IsTaunt(item)) && item.ItemName.Contains(value))
					{
						return item;
					}
				}
			}
			return null;
		}

		private static CreatureAttack FirstNonTaunt(List<CreatureAttack> list)
		{
			foreach (CreatureAttack item in list)
			{
				if (!IsTaunt(item))
				{
					return item;
				}
			}
			return null;
		}
	}
	internal static class DragonMenu
	{
		private enum Tab
		{
			Dragons,
			Appearance,
			Controls
		}

		private static Tab s_tab = Tab.Dragons;

		private static DragonId s_selected = DragonId.Drake;

		private static DragonId s_lookDragon = DragonId.Drake;

		private static Vector2 s_scroll;

		private static float s_welcomeTimer;

		private static bool s_stylesReady;

		private static Font s_font;

		private static Texture2D s_texWindow;

		private static Texture2D s_texBorder;

		private static Texture2D s_texButton;

		private static Texture2D s_texButtonHover;

		private static Texture2D s_texButtonActive;

		private static Texture2D s_texSelected;

		private static Texture2D s_texLine;

		private static Texture2D s_texAccent;

		private static Texture2D s_texAccentHover;

		private static Texture2D s_texDisabled;

		private static Texture2D s_texWhite;

		private static Texture2D s_texCard;

		private static GUIStyle s_title;

		private static GUIStyle s_subtitle;

		private static GUIStyle s_header;

		private static GUIStyle s_body;

		private static GUIStyle s_small;

		private static GUIStyle s_card;

		private static GUIStyle s_cardSelected;

		private static GUIStyle s_bigButton;

		private static GUIStyle s_smallButton;

		private static GUIStyle s_disabledButton;

		private static GUIStyle s_tagline;

		private static GUIStyle s_tabOn;

		private static GUIStyle s_tabOff;

		private static GUIStyle s_bigName;

		private static GUIStyle s_center;

		private const string Gold = "#d8a657";

		private const string Green = "#a6d189";

		private const string Red = "#e78284";

		private const string Ice = "#8fd3e8";

		private const string Ember = "#7ee08a";

		private const string Grey = "#a89f91";

		private const string Text = "#eadfcc";

		internal static bool IsOpen { get; private set; }

		internal static void Open()
		{
			//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)
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && !DragonBornPlugin.Headless)
			{
				DragonPlayer local = DragonPlayer.Local;
				s_selected = (((Object)(object)local != (Object)null && local.Dragon != DragonId.None) ? local.Dragon : DragonStore.GetActive(localPlayer));
				s_lookDragon = s_selected;
				s_scroll = Vector2.zero;
				IsOpen = true;
				FreeCursor();
			}
		}

		internal static void Close()
		{
			if (!IsOpen)
			{
				return;
			}
			IsOpen = false;
			if (OtherGuiOpen())
			{
				return;
			}
			try
			{
				ZCursor.SetRequested(false);
			}
			catch
			{
			}
			try
			{
				ZCursor.LockState = (CursorLockMode)1;
			}
			catch
			{
				Cursor.lockState = (CursorLockMode)1;
			}
			try
			{
				ZCursor.Hide();
			}
			catch
			{
				Cursor.visible = false;
			}
		}

		internal static void FreeCursor()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				ZCursor.SetRequested(true);
			}
			catch
			{
			}
			try
			{
				ZCursor.LockState = (CursorLockMode)0;
			}
			catch
			{
			}
			try
			{
				ZCursor.Show();
			}
			catch
			{
			}
			if ((int)Cursor.lockState != 0)
			{
				Cursor.lockState = (CursorLockMode)0;
			}
			if (!Cursor.visible)
			{
				Cursor.visible = true;
			}
		}

		private static bool OtherGuiOpen()
		{
			try
			{
				return InventoryGui.IsVisible() || Menu.IsVisible() || Console.IsVisible() || TextInput.IsVisible() || StoreGui.IsVisible() || Minimap.IsOpen() || ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) || Hud.IsPieceSelectionVisible();
			}
			catch
			{
				return false;
			}
		}

		private static bool CanOpen(Player p)
		{
			if ((Object)(object)p == (Object)null || ((Character)p).IsDead())
			{
				return false;
			}
			try
			{
				if (((Character)p).InCutscene() || ((Character)p).InIntro() || ((Character)p).IsTeleporting())
				{
					return false;
				}
			}
			catch
			{
			}
			return !OtherGuiOpen();
		}

		internal static void Tick()
		{
			//IL_008c: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || DragonBornPlugin.Headless || (Object)(object)DragonPlayer.Local == (Object)null)
			{
				if (IsOpen)
				{
					IsOpen = false;
				}
				s_welcomeTimer = 0f;
			}
			else if (IsOpen)
			{
				if (((Character)localPlayer).IsDead() || Util.KeyDown(DragonBornPlugin.MenuKey.Value))
				{
					Close();
				}
				else if (!DragonBornPlugin.AppliedPatches.Contains("Patch_MenuUpdate") && Util.KeyDown((KeyCode)27))
				{
					Close();
				}
				else
				{
					FreeCursor();
				}
			}
			else if (Util.KeyDown(DragonBornPlugin.MenuKey.Value) && CanOpen(localPlayer))
			{
				Open();
			}
			else
			{
				if (DragonStore.Welcomed(localPlayer))
				{
					return;
				}
				if (CanOpen(localPlayer))
				{
					s_welcomeTimer += Time.deltaTime;
					if (s_welcomeTimer > 3f)
					{
						DragonStore.SetWelcomed(localPlayer);
						string text = Util.KeyName(DragonBornPlugin.TransformKey.Value);
						string text2 = Util.KeyName(DragonBornPlugin.MenuKey.Value);
						Util.Message(localPlayer, "Dragon blood stirs in your veins...", center: true);
						Util.Message(localPlayer, "Press " + text + " to become a dragon, " + text2 + " for the dragon menu.");
						if (DragonBornPlugin.ShowMenuOnFirstJoin.Value)
						{
							Open();
						}
					}
				}
				else
				{
					s_welcomeTimer = 0f;
				}
			}
		}

		private static Texture2D Tex(Color c)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false)
			{
				hideFlags = (HideFlags)61
			};
			val.SetPixel(0, 0, c);
			val.Apply();
			return val;
		}

		private static Color Hex(string hex, float alpha = 1f)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			Color result = default(Color);
			ColorUtility.TryParseHtmlString(hex, ref result);
			result.a = alpha;
			return result;
		}

		private static Font FindFont()
		{
			try
			{
				string[] obj = new string[5] { "AveriaSerifLibre-Bold", "AveriaSerifLibre-Regular", "AveriaSerifLibre", "Norsebold", "Norse" };
				Font[] array = Resources.FindObjectsOfTypeAll<Font>();
				string[] array2 = obj;
				Font[] array3;
				foreach (string b in array2)
				{
					array3 = array;
					foreach (Font val in array3)
					{
						if ((Object)(object)val != (Object)null && string.Equals(((Object)val).name, b, StringComparison.OrdinalIgnoreCase))
						{
							return val;
						}
					}
				}
				array3 = array;
				foreach (Font val2 in array3)
				{
					if ((Object)(object)val2 != (Object)null && ((Object)val2).name.IndexOf("Averia", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						return val2;
					}
				}
			}
			catch
			{
			}
			return null;
		}

		private static GUIStyle Style(GUIStyle baseStyle, int size, string color, FontStyle fontStyle = (FontStyle)0)
		{
			//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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: 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_0023: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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)
			GUIStyle val = new GUIStyle(baseStyle)
			{
				fontSize = size,
				fontStyle = fontStyle,
				richText = true,
				wordWrap = true
			};
			if ((Object)(object)s_font != (Object)null)
			{
				val.font = s_font;
			}
			Color textColor = Hex(color);
			val.normal.textColor = textColor;
			val.hover.textColor = textColor;
			val.active.textColor = textColor;
			val.focused.textColor = textColor;
			return val;
		}

		private static GUIStyle ButtonStyle(int size, Texture2D normal, Texture2D hover, Texture2D active, string textColor, TextAnchor anchor)
		{
			//IL_0014: 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_0085: Expected O, but got Unknown
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			GUIStyle obj = Style(GUI.skin.button, size, textColor, (FontStyle)1);
			obj.alignment = anchor;
			obj.wordWrap = false;
			obj.normal.background = normal;
			obj.hover.background = hover;
			obj.active.background = active;
			obj.focused.background = normal;
			obj.onNormal.background = normal;
			obj.onHover.background = hover;
			obj.onActive.background = active;
			obj.border = new RectOffset(0, 0, 0, 0);
			obj.padding = new RectOffset(12, 12, 6, 6);
			obj.margin = new RectOffset(0, 0, 3, 3);
			return obj;
		}

		private static void EnsureStyles()
		{
			//IL_0029: 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_005b: 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_008d: 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_00bf: 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_00f1: 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_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Expected O, but got Unknown
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Expected O, but got Unknown
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Expected O, but got Unknown
			//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Expected O, but got Unknown
			if (!s_stylesReady || !((Object)(object)s_texWindow != (Object)null))
			{
				s_font = FindFont();
				s_texWindow = Tex(Hex("#120f0c", 0.96f));
				s_texCard = Tex(Hex("#0d0b09", 0.7f));
				s_texBorder = Tex(Hex("#d8a657", 0.9f));
				s_texLine = Tex(Hex("#d8a657", 0.35f));
				s_texButton = Tex(Hex("#2a2118", 0.95f));
				s_texButtonHover = Tex(Hex("#3b2e20", 0.95f));
				s_texButtonActive = Tex(Hex("#4d3b26", 0.95f));
				s_texSelected = Tex(Hex("#5a4325", 0.95f));
				s_texAccent = Tex(Hex("#8a5a1c", 0.98f));
				s_texAccentHover = Tex(Hex("#a86e22", 0.98f));
				s_texDisabled = Tex(Hex("#2b2723", 0.9f));
				s_texWhite = Tex(Color.white);
				s_title = Style(GUI.skin.label, 32, "#d8a657", (FontStyle)1);
				s_title.wordWrap = false;
				s_bigName = Style(GUI.skin.label, 28, "#d8a657", (FontStyle)1);
				s_bigName.wordWrap = false;
				s_subtitle = Style(GUI.skin.label, 15, "#a89f91", (FontStyle)0);
				s_subtitle.wordWrap = false;
				s_subtitle.alignment = (TextAnchor)5;
				s_header = Style(GUI.skin.label, 15, "#d8a657", (FontStyle)1);
				s_header.margin = new RectOffset(0, 0, 10, 2);
				s_body = Style(GUI.skin.label, 15, "#eadfcc", (FontStyle)0);
				s_body.margin = new RectOffset(0, 0, 1, 1);
				s_small = Style(GUI.skin.label, 13, "#a89f91", (FontStyle)0);
				s_tagline = Style(GUI.skin.label, 16, "#d9ccb6", (FontStyle)2);
				s_center = Style(GUI.skin.label, 14, "#eadfcc", (FontStyle)0);
				s_center.alignment = (TextAnchor)4;
				s_card = ButtonStyle(18, s_texButton, s_texButtonHover, s_texButtonActive, "#eadfcc", (TextAnchor)3);
				s_card.padding = new RectOffset(66, 10, 6, 6);
				s_card.wordWrap = true;
				s_cardSelected = ButtonStyle(18, s_texSelected, s_texSelected, s_texSelected, "#d8a657", (TextAnchor)3);
				s_cardSelected.padding = new RectOffset(66, 10, 6, 6);
				s_cardSelected.wordWrap = true;
				s_bigButton = ButtonStyle(17, s_texAccent, s_texAccentHover, s_texButtonActive, "#fff4e0", (TextAnchor)4);
				s_smallButton = ButtonStyle(15, s_texButton, s_texButtonHover, s_texButtonActive, "#eadfcc", (TextAnchor)4);
				s_disabledButton = ButtonStyle(15, s_texDisabled, s_texDisabled, s_texDisabled, "#a89f91", (TextAnchor)4);
				s_tabOn = ButtonStyle(16, s_texSelected, s_texSelected, s_texSelected, "#d8a657", (TextAnchor)4);
				s_tabOff = ButtonStyle(16, s_texButton, s_texButtonHover, s_texButtonActive, "#eadfcc", (TextAnchor)4);
				s_stylesReady = true;
			}
		}

		private static void DrawSprite(Rect r, Sprite sprite)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: 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)
			if (!((Object)(object)sprite == (Object)null) && !((Object)(object)sprite.texture == (Object)null))
			{
				Texture2D texture = sprite.texture;
				Rect textureRect = sprite.textureRect;
				Rect val = default(Rect);
				((Rect)(ref val))..ctor(((Rect)(ref textureRect)).x / (float)((Texture)texture).width, ((Rect)(ref textureRect)).y / (float)((Texture)texture).height, ((Rect)(ref textureRect)).width / (float)((Texture)texture).width, ((Rect)(ref textureRect)).height / (float)((Texture)texture).height);
				GUI.DrawTextureWithTexCoords(r, (Texture)(object)texture, val, true);
			}
		}

		private static void Frame(Rect r, Texture2D tex, float t)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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)
			GUI.DrawTexture(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, ((Rect)(ref r)).width, t), (Texture)(object)tex);
			GUI.DrawTexture(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).yMax - t, ((Rect)(ref r)).width, t), (Texture)(object)tex);
			GUI.DrawTexture(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, t, ((Rect)(ref r)).height), (Texture)(object)tex);
			GUI.DrawTexture(new Rect(((Rect)(ref r)).xMax - t, ((Rect)(ref r)).y, t, ((Rect)(ref r)).height), (Texture)(object)tex);
		}

		private static void Line()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			Rect rect = GUILayoutUtility.GetRect(10f, 1f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y + 4f, ((Rect)(ref rect)).width, 1f), (Texture)(object)s_texLine);
			GUILayout.Space(8f);
		}

		private static string C(string color, string text)
		{
			return "<color=" + color + ">" + text + "</color>";
		}

		private static string ElementColor(DragonDef d)
		{
			if (d.Breath == null || d.Breath.Element != Element.Fire)
			{
				return "#8fd3e8";
			}
			return "#7ee08a";
		}

		private static string Key(KeyCode k)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return C("#d8a657", Util.KeyName(k));
		}

		internal static void Draw()
		{
			//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_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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: 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_0354: Unknown result type (might be due to invalid IL or missing references)
			if (!IsOpen || DragonBornPlugin.Headless)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			DragonPlayer local = DragonPlayer.Local;
			if (!((Object)(object)localPlayer == (Object)null) && !((Object)(object)local == (Object)null))
			{
				EnsureStyles();
				float num = Mathf.Clamp((float)Screen.height / 1080f, 0.7f, 3f) * DragonBornPlugin.MenuScale.Value;
				Matrix4x4 matrix = GUI.matrix;
				int depth = GUI.depth;
				GUI.depth = -1000;
				GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(num, num, 1f));
				float num2 = (float)Screen.width / num;
				float num3 = (float)Screen.height / num;
				Rect val = default(Rect);
				if (s_tab == Tab.Appearance)
				{
					float num4 = Mathf.Min(560f, num2 - 40f);
					float num5 = Mathf.Min(700f, num3 - 40f);
					((Rect)(ref val))..ctor(Mathf.Min(40f, (num2 - num4) * 0.5f), (num3 - num5) * 0.5f, num4, num5);
				}
				else
				{
					float num6 = Mathf.Min(1020f, num2 - 40f);
					float num7 = Mathf.Min(680f, num3 - 40f);
					((Rect)(ref val))..ctor((num2 - num6) * 0.5f, (num3 - num7) * 0.5f, num6, num7);
				}
				GUI.DrawTexture(val, (Texture)(object)s_texWindow);
				Frame(val, s_texBorder, 2f);
				Frame(new Rect(((Rect)(ref val)).x + 5f, ((Rect)(ref val)).y + 5f, ((Rect)(ref val)).width - 10f, ((Rect)(ref val)).height - 10f), s_texLine, 1f);
				GUILayout.BeginArea(new Rect(((Rect)(ref val)).x + 22f, ((Rect)(ref val)).y + 14f, ((Rect)(ref val)).width - 44f, ((Rect)(ref val)).height - 28f));
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label("DRAGONBORN", s_title, Array.Empty<GUILayoutOption>());
				GUILayout.FlexibleSpace();
				if (s_tab != Tab.Appearance)
				{
					GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
					GUILayout.Space(12f);
					int num8 = Progression.Bosses();
					string text = (DragonSkill.Available ? ("Dragon skill " + C("#d8a657", DragonSkill.Level(localPlayer).ToString("0")) + "     ") : "");
					GUILayout.Label(text + "Bosses defeated " + C("#d8a657", num8.ToString()) + "     Dragon power " + C("#d8a657", "x" + Combat.DamageMultiplier(localPlayer).ToString("0.0")), s_subtitle, Array.Empty<GUILayoutOption>());
					GUILayout.EndVertical();
				}
				GUILayout.EndHorizontal();
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				TabButton(Tab.Dragons, "Dragons");
				TabButton(Tab.Appearance, "Appearance");
				TabButton(Tab.Controls, "Controls & tips");
				GUILayout.FlexibleSpace();
				GUILayout.EndHorizontal();
				Line();
				switch (s_tab)
				{
				case Tab.Dragons:
					DrawDragons(localPlayer, local);
					break;
				case Tab.Appearance:
					DrawAppearance(localPlayer, local);
					break;
				default:
					DrawControls();
					break;
				}
				GUILayout.EndArea();
				GUI.matrix = matrix;
				GUI.depth = depth;
			}
		}

		private static void TabButton(Tab tab, string label)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			bool flag = s_tab == tab;
			if (GUILayout.Button(label, flag ? s_tabOn : s_tabOff, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Height(34f),
				GUILayout.Width((tab == Tab.Controls) ? 180f : 150f)
			}) && !flag)
			{
				s_tab = tab;
				s_scroll = Vector2.zero;
			}
			GUILayout.Space(6f);
		}

		private static void DrawDragons(Player p, DragonPlayer c)
		{
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Expected O, but got Unknown
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Invalid comparison between Unknown and I4
			//IL_011c: 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_0157: 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_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			DragonId active = DragonStore.GetActive(p);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(250f) });
			foreach (DragonDef item in Dragons.All)
			{
				GUIStyle val = ((item.Id == s_selected) ? s_cardSelected : s_card);
				string text = ((!item.IsUnlocked) ? C("#e78284", item.UnlockText) : ((c.Dragon == item.Id) ? C("#a6d189", "you are this dragon") : ((active == item.Id) ? C("#a6d189", "your dragon") : C("#a89f91", "unlocked"))));
				string text2 = item.Name + "\n<size=13>" + text + "</size>";
				Rect rect = GUILayoutUtility.GetRect(new GUIContent(text2), val, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Height(64f),
					GUILayout.ExpandWidth(true)
				});
				if (GUI.Button(rect, text2, val))
				{
					s_selected = item.Id;
					s_scroll = Vector2.zero;
				}
				if ((int)Event.current.type == 7)
				{
					Rect r = new Rect(((Rect)(ref rect)).x + 8f, ((Rect)(ref rect)).y + 6f, 52f, 52f);
					Color color = GUI.color;
					if (!item.IsUnlocked)
					{
						GUI.color = new Color(1f, 1f, 1f, 0.35f);
					}
					DrawSprite(r, Util.ItemIcon(item.Icon));
					GUI.color = color;
				}
			}
			GUILayout.Space(10f);
			GUILayout.Label(C("#d8a657", "Dragon blood") + C("#a89f91", " - always active"), s_header, Array.Empty<GUILayoutOption>());
			GUILayout.Label("The cold can't freeze you, falls hurt less and you resist frost - even in viking shape.", s_small, Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			GUILayout.Label(Key(DragonBornPlugin.TransformKey.Value) + " transform    hold " + Key(DragonBornPlugin.TransformKey.Value) + " switch    " + Key(DragonBornPlugin.MenuKey.Value) + " menu", s_small, Array.Empty<GUILayoutOption>());
			GUILayout.EndVertical();
			GUILayout.Space(18f);
			GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
			DragonDef d = Dragons.Get(s_selected) ?? Dragons.All[0];
			s_scroll = GUILayout.BeginScrollView(s_scroll, false, false, GUIStyle.none, GUI.skin.verticalScrollbar, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) });
			DrawDetails(p, d);
			GUILayout.EndScrollView();
			GUILayout.Space(6f);
			DrawDragonButtons(p, c, d, active);
			GUILayout.EndVertical();
			GUILayout.EndHorizontal();
		}

		private static void DrawDetails(Player p, DragonDef d)
		{
			string color = ElementColor(d);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(d.Name.ToUpperInvariant(), s_bigName, Array.Empty<GUILayoutOption>());
			GUILayout.Space(10f);
			GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
			GUILayout.Space(12f);
			GUILayout.Label(C(color, d.Title), s_body, Array.Empty<GUILayoutOption>());
			GUILayout.EndVertical();
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			GUILayout.Label(d.Blurb, s_tagline, Array.Empty<GUILayoutOption>());
			if (!d.IsUnlocked)
			{
				GUILayout.Label(C("#e78284", d.UnlockText + " - a new dragon awakens in your blood with every great victory."), s_body, Array.Empty<GUILayoutOption>());
			}
			float num = Progression.HealthScale(Progression.Bosses()) * (1f + DragonSkill.HealthBonus(p)) * Mathf.Max(0f, DragonBornPlugin.HealthMultiplier.Value);
			List<string> list = new List<string>
			{
				C("#a6d189", "+" + Mathf.RoundToInt(d.BaseHp * num)) + " health",
				C("#a6d189", "+" + Mathf.RoundToInt(d.Armor * num)) + " armor"
			};
			if (Mathf.Abs(d.Speed) > 0.001f)
			{
				list.Add(C((d.Speed > 0f) ? "#a6d189" : "#e78284", ((d.Speed > 0f) ? "+" : "") + Mathf.RoundToInt(d.Speed * 100f) + "%") + " speed");
			}
			if (d.Carry > 0f)
			{
				list.Add(C("#a6d189", "+" + Mathf.RoundToInt(d.Carry)) + " carry weight");
			}
			list.Add(d.Flying ? C("#8fd3e8", "flies") : C("#a89f91", "grounded"));
			GUILayout.Label("STATS", s_header, Array.Empty<GUILayoutOption>());
			GUILayout.Label("  " + string.Join("     ", list.ToArray()), s_body, Array.Empty<GUILayoutOption>());
			if (!string.IsNullOrEmpty(d.PassiveName))
			{
				GUILayout.Label("PASSIVE", s_header, Array.Empty<GUILayoutOption>());
				GUILayout.Label("  " + C(color, d.PassiveName) + " - " + d.PassiveText, s_body, Array.Empty<GUILayoutOption>());
			}
			GUILayout.Label("ABILITIES", s_header, Array.Empty<GUILayoutOption>());
			if (d.Primary != null)
			{
				GUILayout.Label("  " + C("#d8a657", "Left mouse") + "  " + C(color, d.Primary.Name) + " - " + d.Primary.Desc + C("#a89f91", $"  ({Mathf.RoundToInt(d.Primary.Stamina)} stamina)"), s_body, Array.Empty<GUILayoutOption>());
			}
			if (d.Breath != null)
			{
				GUILayout.Label("  " + C("#d8a657", "Hold right mouse") + "  " + C(color, d.Breath.Name) + " - " + d.Breath.Desc + C("#a89f91", $"  ({Mathf.RoundToInt(d.Breath.StaminaPerSecond)} stamina/s, {Mathf.RoundToInt(d.Breath.Range)} m)"), s_body, Array.Empty<GUILayoutOption>());
			}
			if (d.Roar != null)
			{
				GUILayout.Label("  " + C("#d8a657", "Middle mouse") + "  " + C(color, d.Roar.Name) + " - " + d.Roar.Desc + C("#a89f91", $"  ({Mathf.RoundToInt(d.Roar.Cooldown)} s cooldown)"), s_body, Array.Empty<GUILayoutOption>());
			}
			if (d.Dive != null)
			{
				GUILayout.Label("  " + C("#d8a657", "Middle mouse in the air") + "  " + C(color, d.Dive.Name) + " - " + d.Dive.Desc + C("#a89f91", $"  ({Mathf.RoundToInt(d.Dive.Stamina)} stamina)"), s_body, Array.Empty<GUILayoutOption>());
			}
			if (d.Flying)
			{
				GUILayout.Label("  " + C("#d8a657", "Jump twice") + "  " + C(color, "Flight") + " - Jump / Crouch to rise and sink, Run to fly fast, look down to swoop", s_body, Array.Empty<GUILayoutOption>());
			}
			GUILayout.Label("NATURE", s_header, Array.Empty<GUILayoutOption>());
			string[] resistances = d.Resistances;
			foreach (string text in resistances)
			{
				GUILayout.Label("  " + C(color, "*") + "  " + text, s_body, Array.Empty<GUILayoutOption>());
			}
		}

		private static void DrawDragonButtons(Player p, DragonPlayer c, DragonDef d, DragonId active)
		{
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (!d.IsUnlocked)
			{
				GUILayout.Button(d.UnlockText, s_disabledButton, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Height(42f),
					GUILayout.Width(280f)
				});
			}
			else if (c.Dragon == d.Id)
			{
				if (GUILayout.Button("Turn back into a viking", s_smallButton, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Height(42f),
					GUILayout.Width(280f)
				}))
				{
					c.Toggle();
				}
			}
			else if (active == d.Id && c.Dragon == DragonId.None)
			{
				if (GUILayout.Button("Transform now", s_bigButton, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Height(42f),
					GUILayout.Width(280f)
				}))
				{
					Close();
					c.Toggle();
				}
			}
			else if (GUILayout.Button((c.Dragon != DragonId.None) ? ("Become the " + d.Name + " now") : ("Make the " + d.Name + " your dragon"), s_bigButton, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Height(42f),
				GUILayout.Width(280f)
			}))
			{
				c.SelectDragon(d.Id);
				if (c.Dragon != DragonId.None)
				{
					Close();
				}
			}
			GUILayout.Space(8f);
			if (GUILayout.Button("Colors", s_smallButton, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Height(42f),
				GUILayout.Width(120f)
			}))
			{
				s_lookDragon = d.Id;
				s_tab = Tab.Appearance;
				s_scroll = Vector2.zero;
			}
			GUILayout.FlexibleSpace();
			if (GUILayout.Button("Close", s_smallButton, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Height(42f),
				GUILayout.Width(130f)
			}))
			{
				Close();
			}
			GUILayout.EndHorizontal();
		}

		private static void DrawAppearance(Player p, DragonPlayer c)
		{
			//IL_00e7: 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_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Expected O, but got Unknown
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: 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_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Invalid comparison between Unknown and I4
			//IL_04d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.Label("Pick colors and size for each of your dragons. Other players see them too.", s_small, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			foreach (DragonDef item in Dragons.All)
			{
				bool flag = s_lookDragon == item.Id;
				if (GUILayout.Button(item.Name, flag ? s_tabOn : s_tabOff, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Height(32f),
					GUILayout.Width(120f)
				}) && !flag)
				{
					s_lookDragon = item.Id;
				}
				GUILayout.Space(4f);
			}
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			DragonDef dragonDef = Dragons.Get(s_lookDragon) ?? Dragons.All[0];
			DragonLook look = DragonStore.GetLook(p, dragonDef.Id);
			DragonLook o = look;
			s_scroll = GUILayout.BeginScrollView(s_scroll, false, false, GUIStyle.none, GUI.skin.verticalScrollbar, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) });
			GUILayout.Label("PRESETS", s_header, Array.Empty<GUILayoutOption>());
			int num = 3;
			for (int i = 0; i < LookPreset.All.Length; i += num)
			{
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				for (int j = i; j < i + num && j < LookPreset.All.Length; j++)
				{
					LookPreset lookPreset = LookPreset.All[j];
					bool flag2 = look.SameColor(lookPreset.Look);
					Rect rect = GUILayoutUtility.GetRect(new GUIContent(lookPreset.Name), flag2 ? s_tabOn : s_tabOff, (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.Height(34f),
						GUILayout.Width(160f)
					});
					if (GUI.Button(rect, "    " + lookPreset.Name, flag2 ? s_tabOn : s_tabOff))
					{
						float size = look.Size;
						look = lookPreset.Look;
						look.Size = size;
					}
					if ((int)Event.current.type == 7)
					{
						Color color = GUI.color;
						GUI.color = lookPreset.Swatch;
						GUI.DrawTexture(new Rect(((Rect)(ref rect)).x + 10f, ((Rect)(ref rect)).y + 9f, 16f, 16f), (Texture)(object)s_texWhite);
						GUI.color = color;
					}
					GUILayout.Space(6f);
				}
				GUILayout.EndHorizontal();
			}
			GUILayout.Label("FINE TUNING", s_header, Array.Empty<GUILayoutOption>());
			look.Hue = Slider("Hue", look.Hue, -0.5f, 0.5f, (look.Hue >= 0f) ? ("+" + look.Hue.ToString("0.00")) : look.Hue.ToString("0.00"));
			look.Saturation = Slider("Saturation", look.Saturation, -1f, 1f, look.Saturation.ToString("+0.00;-0.00;0.00"));
			look.Value = Slider("Brightness", look.Value, -0.6f, 0.6f, look.Value.ToString("+0.00;-0.00;0.00"));
			look.Size = Slider("Size", look.Size, 0.85f, 1.2f, Mathf.RoundToInt(look.Size * 100f) + "%");
			GUILayout.Space(6f);
			GUILayout.Label((c.Dragon == dragonDef.Id) ? C("#a6d189", "You are this dragon - the changes show right away.") : C("#a89f91", "Become the " + dragonDef.Name + " to see the changes live."), s_small, Array.Empty<GUILayoutOption>());
			GUILayout.Label(C("#a89f91", "Colors use the game's own creature tinting. Your Dragon skill makes your dragon grow on top of the size you pick here."), s_small, Array.Empty<GUILayoutOption>());
			GUILayout.EndScrollView();
			if (!look.SameColor(o) || Mathf.Abs(look.Size - o.Size) > 0.0005f)
			{
				c.SetLook(dragonDef.Id, look);
			}
			GUILayout.Space(6f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("Reset", s_smallButton, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Height(40f),
				GUILayout.Width(120f)
			}))
			{
				c.SetLook(dragonDef.Id, DragonLook.Natural);
			}
			GUILayout.FlexibleSpace();
			if (GUILayout.Button("Back", s_smallButton, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Height(40f),
				GUILayout.Width(110f)
			}))
			{
				s_tab = Tab.Dragons;
				s_scroll = Vector2.zero;
			}
			if (GUILayout.Button("Close", s_smallButton, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Height(40f),
				GUILayout.Width(110f)
			}))
			{
				Close();
			}
			GUILayout.EndHorizontal();
		}

		private static float Slider(string label, float value, float min, float max, string shown)
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(label, s_body, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) });
			GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
			GUILayout.Space(9f);
			float num = GUILayout.HorizontalSlider(value, min, max, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			GUILayout.EndVertical();
			GUILayout.Space(10f);
			GUILayout.Label(C("#d8a657", shown), s_body, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) });
			GUILayout.EndHorizontal();
			if (!(Mathf.Abs(num - value) > 0.0001f))
			{
				return value;
			}
			return Mathf.Round(num * 100f) / 100f;
		}

		private static void DrawControls()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_004d: 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)
			s_scroll = GUILayout.BeginScrollView(s_scroll, false, false, GUIStyle.none, GUI.skin.verticalScrollbar, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) });
			KeyCode value = DragonBornPlugin.TransformKey.Value;
			GUILayout.Label("CONTROLS", s_header, Array.Empty<GUILayoutOption>());
			ControlRow(Key(value) + " (tap)", "become a dragon / turn back");
			ControlRow(Key(value) + " (hold)", "switch to your next dragon");
			ControlRow(Key(DragonBornPlugin.MenuKey.Value), "this menu");
			ControlRow(C("#d8a657", "Left mouse"), "dragon attack (spit, ice barrage, claw slam)");
			ControlRow(C("#d8a657", "Hold right mouse"), "breath - frost or fire as long as your stamina lasts");
			ControlRow(C("#d8a657", "Middle mouse"), "roar on the ground, dive bomb in the air");
			ControlRow(C("#d8a657", "Jump, then Jump"), "take off (Drake and Moder)");
			ControlRow(C("#d8a657", "Jump / Crouch"), "fly up / down");
			ControlRow(C("#d8a657", "Run"), "fast flight (more stamina)");
			ControlRow(C("#d8a657", "Look down"), "swoop: diving forward is faster and costs little stamina");
			GUILayout.Label("TIPS", s_header, Array.Empty<GUILayoutOption>());
			Tip("Your " + C("#d8a657", "Dragon skill") + " grows while you fight and fly as a dragon: more damage and health, cheaper flight and breath, and a bigger dragon.");
			Tip("Every boss you defeat makes your dragons stronger - Moder and Fader awaken as new dragons.");
			Tip("Roar to stagger everything around you and fill yourself with " + C("#d8a657", "Dragon's fury") + " (+25% damage).");
			Tip("Out of stamina in the air? You glide down safely. Get your stamina back and press Jump to flap again.");
			Tip("Wild Drakes are your kin while you are a dragon - they leave you alone.");
			Tip("Frost dragons are weak to fire, Fader is weak to frost. Pick the right dragon for the land you fight in.");
			Tip("Sitting, sleeping or steering a ship shows your viking for a moment - you stay a dragon.");
			Tip("Colors, model sizes, cameras and balance can all be changed in the config file (notterra.dragonborn.cfg).");
			GUILayout.EndScrollView();
			GUILayout.Space(6f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			if (GUILayout.Button("Close", s_smallButton, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Height(40f),
				GUILayout.Width(130f)
			}))
			{
				Close();
			}
			GUILayout.EndHorizontal();
		}

		private static void ControlRow(string key, string text)
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("  " + key, s_body, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(220f) });
			GUILayout.Label(text, s_body, Array.Empty<GUILayoutOption>());
			GUILayout.EndHorizontal();
		}

		private static void Tip(string text)
		{
			GUILayout.Label("  " + C("#d8a657", "*") + "  " + text, s_body, Array.Empty<GUILayoutOption>());
		}
	}
	public class DragonPlayer : MonoBehaviour
	{
		internal enum Act
		{
			Primary,
			Roar,
			DiveStart,
			DiveImpact
		}

		private enum RevertReason
		{
			Manual,
			Died,
			Silent
		}

		private struct Pending
		{
			public float Time;

			public int Kind;

			public DragonId Dragon;

			public Vector3 Pos;
		}

		internal static readonly int ZDragon = StringExtensionMethods.GetStableHashCode("dragonborn_form");

		internal static readonly int ZFly = StringExtensionMethods.GetStableHashCode("dragonborn_fly");

		internal static readonly int ZHidden = StringExtensionMethods.GetStableHashCode("dragonborn_hidden");

		internal static readonly int ZBreath = StringExtensionMethods.GetStableHashCode("dragonborn_breath");

		internal static readonly int ZAim = StringExtensionMethods.GetStableHashCode("dragonborn_aim");

		internal static readonly int ZDive = StringExtensionMethods.GetStableHashCode("dragonborn_dive");

		internal static readonly int ZHue = StringExtensionMethods.GetStableHashCode("dragonborn_hue");

		internal static readonly int ZSat = StringExtensionMethods.GetStableHashCode("dragonborn_sat");

		internal static readonly int ZVal = StringExtensionMethods.GetStableHashCode("dragonborn_val");

		internal static readonly int ZSize = StringExtensionMethods.GetStableHashCode("dragonborn_size");

		private const string RpcAct = "DragonBorn_Act";

		internal static DragonPlayer Local;

		private ZNetView m_nview;

		private DragonId m_shown;

		private bool m_firstSync = true;

		private Puppet m_puppet;

		private readonly List<Renderer> m_hidden = new List<Renderer>();

		private static readonly List<Renderer> s_tmpRenderers = new List<Renderer>();

		private float m_rescanTimer;

		private Vector3 m_lastPos;

		private Vector3 m_vel;

		private float m_lastYaw;

		private float m_turn;

		private float m_passiveFxTimer;

		private bool m_puppetHidden;

		private bool m_shownFlying;

		private BreathFx m_breathFx;

		private float m_breathAnimTimer;

		private float m_lookCheckTimer;

		private DragonLook m_shownLook = DragonLook.Natural;

		private float m_camPivot = float.NaN;

		internal bool WantPrimary;

		internal bool WantBreath;

		internal bool WantSpecial;

		private bool m_flying;

		private bool m_gliding;

		private bool m_safeFall;

		private bool m_diving;

		private float m_flyStart;

		private Vector3 m_flightVel;

		private float m_airTime;

		private float m_flySkillTimer;

		private float m_diveStart;

		private Vector3 m_diveDir;

		private bool m_breathing;

		private bool m_breathDenied;

		private float m_breathTick;

		private float m_aimSyncTimer;

		private Vector3 m_aim = Vector3.forward;

		private float m_primaryCd;

		private float m_globalCd;

		private float m_roarCd;

		private float m_diveCd;

		private float m_passiveTimer;

		private float m_auraTimer;

		private float m_effectCheckTimer;

		private bool m_hiddenSent;

		private bool m_keyHeld;

		private bool m_keyHandled;

		private float m_keyTime;

		private const float HoldTime = 0.35f;

		private float m_unlockTimer = 3f;

		private float m_camMaxApplied;

		private float m_camDistApplied;

		private float m_camOriginalMax;

		private readonly List<Pending> m_pending = new List<Pending>();

		internal Player Player { get; private set; }

		internal float CameraPivot
		{
			get
			{
				if (Dragon == DragonId.None || m_puppet == null || m_puppetHidden)
				{
					return float.NaN;
				}
				return m_camPivot;
			}
		}

		internal DragonId Dragon { get; private set; }

		internal float HpBonus { get; private set; }

		internal bool IsFlying => m_flying;

		internal bool IsBreathing => m_breathing;

		private bool Valid
		{
			get
			{
				if ((Object)(object)Player != (Object)null && (Object)(object)m_nview != (Object)null && m_nview.IsValid())
				{
					return m_nview.GetZDO() != null;
				}
				return false;
			}
		}

		private bool IsLocal
		{
			get
			{
				if ((Object)(object)Player != (Object)null)
				{
					return (Object)(object)Player == (Object)(object)Player.m_localPlayer;
				}
				return false;
			}
		}

		private ZDO Zdo
		{
			get
			{
				if (!((Object)(object)m_nview != (Object)null))
				{
					return null;
				}
				return m_nview.GetZDO();
			}
		}

		private void Awake()
		{
			//IL_0049: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			Player = ((Component)this).GetComponent<Player>();
			m_nview = ((Component)this).GetComponent<ZNetView>();
			if ((Object)(object)m_nview != (Object)null)
			{
				m_nview.Register<int, ZPackage>("DragonBorn_Act", (Action<long, int, ZPackage>)RPC_Act);
			}
			m_lastPos = ((Component)this).transform.position;
			m_lastYaw = ((Component)this).transform.eulerAngles.y;
		}

		private void Update()
		{
			if (!Valid)
			{
				return;
			}
			float deltaTime = Time.deltaTime;
			if (IsLocal)
			{
				Local = this;
				try
				{
					LocalUpdate(deltaTime);
				}
				catch (Exception e)
				{
					Util.LogOnce("local-update", e);
				}
			}
			try
			{
				SyncVisual(deltaTime);
			}
			catch (Exception e2)
			{
				Util.LogOnce("sync-visual", e2);
			}
		}

		private void LateUpdate()
		{
			if (m_puppet == null || (Object)(object)Player == (Object)null)
			{
				return;
			}
			try
			{
				AnimatePuppet(Time.deltaTime);
			}
			catch (Exception e)
			{
				Util.LogOnce("animate-puppet", e);
			}
		}

		private void OnDestroy()
		{
			if ((Object)(object)Local == (Object)(object)this)
			{
				RestoreCamera();
				Local = null;
			}
			StopBreathFx();
			if (m_puppet != null)
			{
				m_puppet.Destroy();
				m_puppet = null;
			}
		}

		internal static bool IsDragon(Player p)
		{
			if ((Object)(object)p == (Object)null)
			{
				return false;
			}
			ZNetView nview = ((Character)p).m_nview;
			if ((Object)(object)nview == (Object)null || !nview.IsValid())
			{
				return false;
			}
			ZDO zDO = nview.GetZDO();
			if (zDO != null)
			{
				return zDO.GetInt(ZDragon, 0) != 0;
			}
			return false;
		}

		internal bool InputAllowed()
		{
			if (DragonMenu.IsOpen || (Object)(object)Player == (Object)null)
			{
				return false;
			}
			try
			{
				return ((Character)Player).TakeInput();
			}
			catch
			{
				return false;
			}
		}

		private void LocalUpdate(float dt)
		{
			m_passiveTimer -= dt;
			if (m_passiveTimer <= 0f)
			{
				m_passiveTimer = 1f;
				if (!((Character)Player).IsDead())
				{
					StatusEffects.EnsureBlood(Player);
				}
			}
			if (m_primaryCd > 0f)
			{
				m_primaryCd -= dt;
			}
			if (m_globalCd > 0f)
			{
				m_globalCd -= dt;
			}
			if (m_roarCd > 0f)
			{
				m_roarCd -= dt;
			}
			if (m_diveCd > 0f)
			{
				m_diveCd -= dt;
			}
			bool flag = InputAllowed();
			TransformKey(flag, dt);
			CheckUnlocks(dt);
			if (Dragon != DragonId.None)
			{
				DragonDef dragonDef = Dragons.Get(Dragon);
				if (dragonDef == null || ((Character)Player).IsDead())
				{
					Revert(RevertReason.Died);
				}
				else
				{
					bool flag2 = ((Character)Player).IsAttached();
					if (flag2 != m_hiddenSent)
					{
						m_hiddenSent = flag2;
						SetZdoBool(ZHidden, flag2);
						if (flag2)
						{
							StopBreath();
							m_diving = false;
							StopFlying();
						}
					}
					SyncFormEffect(dragonDef, dt);
					Passives(dragonDef, dt);
					bool flag3 = flag && !flag2 && !((Character)Player).InPlaceMode() && !((Character)Player).IsTeleporting();
					UpdateBreath(dragonDef, flag3, dt);
					if (flag3 && !m_breathing && !m_diving)
					{
						if (WantSpecial)
						{
							TrySpecial(dragonDef);
						}
						else if (WantPrimary)
						{
							TryPrimary(dragonDef);
						}
					}
					WantSpecial = false;
					if (dragonDef.Flying && !m_flying && !flag2)
					{
						m_airTime = (((Character)Player).IsOnGround() ? 0f : (m_airTime + dt));
						if (flag && m_airTime > 0.12f && Util.JumpPressed())
						{
							TryTakeoff(dragonDef);
						}
					}
					if (m_flying)
					{
						m_flySkillTimer += dt;
						if (m_flySkillTimer >= 10f)
						{
							m_flySkillTimer = 0f;
							DragonSkill.Raise(Player, 0.5f);
						}
					}
				}
			}
			else
			{
				WantSpecial = false;
			}
			ProcessPending();
		}

		private void TransformKey(bool input, float dt)
		{
			//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_0016: 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)
			KeyCode value = DragonBornPlugin.TransformKey.Value;
			if (!input)
			{
				m_keyHeld = false;
			}
			else if (Util.KeyDown(value))
			{
				m_keyHeld = true;
				m_keyHandled = false;
				m_keyTime = 0f;
			}
			else
			{
				if (!m_keyHeld)
				{
					return;
				}
				if (Util.Key(value))
				{
					m_keyTime += dt;
					if (!m_keyHandled && m_keyTime >= 0.35f)
					{
						m_keyHandled = true;
						CycleDragon();
					}
				}
				else
				{
					m_keyHeld = false;
					if (!m_keyHandled)
					{
						T