Decompiled source of Ent1tyRacesBETA v2.0.0

plugins\Ent1tyRaces.dll

Decompiled 20 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using Ent1tyRaces.Commands;
using Ent1tyRaces.Races;
using Ent1tyRaces.UI;
using HarmonyLib;
using Jotunn;
using Jotunn.Entities;
using Jotunn.Managers;
using TMPro;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Ent1tyRaces")]
[assembly: AssemblyDescription("Human, Dragonborn, and Vampire races for Valheim")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Ent1tyRaces")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Ent1tyRaces
{
	public enum BreathElement
	{
		Fire,
		Poison,
		Lightning,
		Ice
	}
	public enum ElfType
	{
		High,
		Wood,
		Drow
	}
	public enum GenasiType
	{
		Air,
		Earth,
		Fire,
		Water
	}
	public enum GiantType
	{
		Cloud,
		Fire,
		Frost,
		Hill,
		Stone,
		Storm
	}
	public enum GnomeType
	{
		Forest,
		Rock
	}
	[BepInPlugin("com.ent1ty303.ent1tyraces", "Ent1tyRaces", "2.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Ent1tyRacesPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.ent1ty303.ent1tyraces";

		public const string PluginName = "Ent1tyRaces";

		public const string PluginVersion = "2.0.0";

		private Harmony _harmony;

		public static Ent1tyRacesPlugin Instance { get; private set; }

		private void Awake()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			Instance = this;
			_harmony = new Harmony("com.ent1ty303.ent1tyraces");
			ApplyPatchesSafely();
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new RaceCommand());
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new BreathCommand());
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new TypeCommand());
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new LegacyCommand());
			((Component)this).gameObject.AddComponent<VampireDayNightIndicator>();
			Logger.LogInfo((object)"Ent1tyRaces v2.0.0 loaded OK. Chat: /race dwarf | /type forest | /legacy abyssal");
		}

		private void ApplyPatchesSafely()
		{
			foreach (Type item in from t in Assembly.GetExecutingAssembly().GetTypes()
				where t.GetCustomAttributes(typeof(HarmonyPatch), inherit: false).Length != 0
				select t)
			{
				try
				{
					_harmony.CreateClassProcessor(item).Patch();
					Logger.LogInfo((object)("Ent1tyRaces: patched " + item.Name));
				}
				catch (Exception ex)
				{
					Logger.LogWarning((object)("Ent1tyRaces: skipped " + item.Name + " — " + ex.Message));
				}
			}
		}

		private void OnDestroy()
		{
			Instance = null;
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	public enum RaceType
	{
		Human,
		Dragonborn,
		Vampire,
		Elf,
		Aarakocra,
		Giant,
		Genasi,
		Dwarf,
		Gnome,
		Halfling,
		Orc,
		Tiefling,
		Aasimar
	}
	public enum TieflingLegacy
	{
		Abyssal,
		Chthonic,
		Infernal
	}
}
namespace Ent1tyRaces.UI
{
	internal class VampireDayNightIndicator : MonoBehaviour
	{
		private RectTransform _iconRoot;

		private TMP_Text _iconText;

		private void LateUpdate()
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)EnvMan.instance == (Object)null)
			{
				HideIcon();
				return;
			}
			RaceType race = RaceManager.GetRace(localPlayer);
			if (race != RaceType.Vampire && race != RaceType.Dwarf && !ElfTypeManager.IsDrow(localPlayer) && !GenasiTypeManager.Is(localPlayer, GenasiType.Fire))
			{
				HideIcon();
				return;
			}
			if (VampireVisionState.LastEnv != null)
			{
				if (GenasiTypeManager.Is(localPlayer, GenasiType.Fire))
				{
					VampireVision.ApplyRedNightVision(VampireVisionState.LastEnv);
				}
				else
				{
					VampireVision.ApplyMiddayVision(VampireVisionState.LastEnv);
				}
			}
			if (race == RaceType.Vampire)
			{
				UpdateDayNightIcon();
			}
			else
			{
				HideIcon();
			}
		}

		private void UpdateDayNightIcon()
		{
			//IL_00a9: 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)
			if (!((Object)(object)Hud.instance?.m_healthText == (Object)null) && !((Object)(object)Hud.instance.m_healthPanel == (Object)null))
			{
				EnsureIcon();
				((Component)_iconRoot).gameObject.SetActive(true);
				if (EnvMan.IsDay())
				{
					_iconText.text = "☀";
					((Graphic)_iconText).color = new Color(1f, 0.86f, 0.25f, 1f);
				}
				else
				{
					_iconText.text = "N";
					((Graphic)_iconText).color = new Color(0.78f, 0.84f, 1f, 1f);
				}
			}
		}

		private void EnsureIcon()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_iconRoot != (Object)null))
			{
				TMP_Text healthText = Hud.instance.m_healthText;
				GameObject val = new GameObject("Ent1tyRaces_VampireDayNight");
				_iconRoot = val.AddComponent<RectTransform>();
				((Transform)_iconRoot).SetParent((Transform)(object)Hud.instance.m_healthPanel, false);
				((Transform)_iconRoot).SetAsLastSibling();
				_iconRoot.anchorMin = new Vector2(0f, 1f);
				_iconRoot.anchorMax = new Vector2(0f, 1f);
				_iconRoot.pivot = new Vector2(0f, 1f);
				_iconRoot.anchoredPosition = new Vector2(-28f, -4f);
				_iconRoot.sizeDelta = new Vector2(24f, 24f);
				_iconText = (TMP_Text)(object)val.AddComponent<TextMeshProUGUI>();
				_iconText.font = healthText.font;
				_iconText.fontSharedMaterial = healthText.fontSharedMaterial;
				_iconText.fontSize = healthText.fontSize * 0.95f;
				_iconText.alignment = (TextAlignmentOptions)514;
				((Graphic)_iconText).raycastTarget = false;
				_iconText.fontStyle = (FontStyles)1;
			}
		}

		private void HideIcon()
		{
			if ((Object)(object)_iconRoot != (Object)null)
			{
				((Component)_iconRoot).gameObject.SetActive(false);
			}
		}

		private void OnDestroy()
		{
			if ((Object)(object)_iconRoot != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_iconRoot).gameObject);
			}
		}
	}
}
namespace Ent1tyRaces.Races
{
	internal static class AarakocraFlight
	{
		private const float SeaLevel = 30f;

		private const float MaxAltitudeAboveSea = 120f;

		private const float AshlandsFallMultiplier = 5f;

		private const float FlyMoveStaminaPerSecond = 7f;

		private const float FlyRunStaminaMult = 1.45f;

		private static readonly HashSet<Player> FlyingPlayers = new HashSet<Player>();

		private static readonly FieldInfo CurrentVelField = AccessTools.Field(typeof(Character), "m_currentVel");

		private static readonly FieldInfo LastGroundTouchField = AccessTools.Field(typeof(Character), "m_lastGroundTouch");

		private static readonly FieldInfo MaxAirAltitudeField = AccessTools.Field(typeof(Character), "m_maxAirAltitude");

		private static readonly int SlowFallHash = StringExtensionMethods.GetStableHashCode("SlowFall");

		private static readonly FieldInfo WaterLevelField = AccessTools.Field(typeof(Character), "m_waterLevel");

		private static readonly RaycastHit[] SolidHits = (RaycastHit[])(object)new RaycastHit[32];

		private static int _solidRayMask;

		public static bool IsFlying(Player player)
		{
			if ((Object)(object)player != (Object)null)
			{
				return FlyingPlayers.Contains(player);
			}
			return false;
		}

		public static void Toggle(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			if (IsFlightEnvironmentBlocked(player, out var message))
			{
				if (IsFlying(player))
				{
					DisableFlight(player, message);
				}
				else
				{
					((Character)player).Message((MessageType)2, message, 0, (Sprite)null);
				}
			}
			else if (FlyingPlayers.Contains(player))
			{
				DisableFlight(player, "You fold your wings.");
			}
			else
			{
				EnableFlight(player);
			}
		}

		public static void Update(Player player)
		{
			if ((Object)(object)player == (Object)null || RaceManager.GetRace(player) != RaceType.Aarakocra)
			{
				return;
			}
			if (IsTooHigh(player))
			{
				if (IsFlying(player))
				{
					DisableFlight(player, "Too high for flying.");
				}
				RemoveFeatherFall(player);
			}
			else if (IsInAshlands(player) && !IsAboveAshlandsLand(player))
			{
				if (IsFlying(player))
				{
					DisableFlight(player, "The heat is too heavy for flight");
				}
				if (((Character)player).InWater() || ((Character)player).IsSwimming())
				{
					EnsureFeatherFall(player);
					return;
				}
				RemoveFeatherFall(player);
				ApplyAshlandsOceanPlunge(player);
			}
			else
			{
				EnsureFeatherFall(player);
				if (IsFlying(player) && IsFlightEnvironmentBlocked(player, out var message))
				{
					DisableFlight(player, message);
				}
			}
		}

		public static bool TryHandleMotion(Character character, float dt)
		{
			Player val = (Player)(object)((character is Player) ? character : null);
			if (val == null || !IsFlying(val))
			{
				return false;
			}
			if (RaceManager.GetRace(val) != RaceType.Aarakocra)
			{
				FlyingPlayers.Remove(val);
				return false;
			}
			if (IsTooHigh(val))
			{
				DisableFlight(val, "Too high for flying.");
				RemoveFeatherFall(val);
				return false;
			}
			if (IsFlightEnvironmentBlocked(val, out var message))
			{
				DisableFlight(val, message);
				return false;
			}
			ApplyFlightPhysics(val, dt);
			return true;
		}

		private static void EnableFlight(Player player)
		{
			//IL_002b: 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)
			FlyingPlayers.Add(player);
			Rigidbody component = ((Component)player).GetComponent<Rigidbody>();
			if ((Object)(object)component != (Object)null)
			{
				component.useGravity = false;
				component.isKinematic = true;
				component.linearVelocity = Vector3.zero;
				component.angularVelocity = Vector3.zero;
			}
			((Character)player).Message((MessageType)1, "Wings unfurled.", 0, (Sprite)null);
		}

		private static void ApplyFlightPhysics(Player player, float dt)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: 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)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			Rigidbody component = ((Component)player).GetComponent<Rigidbody>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			float num = (((Character)player).IsRunning() ? ((float)Character.m_debugFlySpeed * 2.5f) : ((float)Character.m_debugFlySpeed));
			Vector3 val = ((Character)player).GetMoveDir() * num;
			bool num2 = ZInput.GetButton("Jump") || ZInput.GetButton("JoyJump");
			bool flag = ZInput.GetKey((KeyCode)306, true) || ZInput.GetButtonPressedTimer("JoyCrouch") > 0.33f;
			if (num2)
			{
				val.y = num;
			}
			else if (flag)
			{
				val.y = 0f - num;
			}
			if ((((Character)player).InWater() || ((Character)player).IsSwimming()) && val.y < 0f)
			{
				val.y = 0f;
			}
			if (((Vector3)(ref val)).sqrMagnitude > 0.01f)
			{
				float num3 = 7f * dt;
				if (((Character)player).IsRunning())
				{
					num3 *= 1.45f;
				}
				if (!((Character)player).HaveStamina(num3 + 0.05f))
				{
					val = Vector3.zero;
					if (Time.frameCount % 90 == 0)
					{
						((Character)player).Message((MessageType)1, "Too weary to flap.", 0, (Sprite)null);
					}
				}
				else
				{
					((Character)player).UseStamina(num3);
				}
			}
			Vector3 val2 = val;
			Vector3 val3 = ((Component)player).transform.position + val2 * dt;
			if (GetAltitudeAboveSea(val3) >= 120f)
			{
				val3.y = 150f;
				DisableFlight(player, "Too high for flying.");
				RemoveFeatherFall(player);
			}
			component.useGravity = false;
			component.isKinematic = true;
			((Component)player).transform.position = val3;
			component.linearVelocity = Vector3.zero;
			component.angularVelocity = Vector3.zero;
			CurrentVelField?.SetValue(player, val2);
			LastGroundTouchField?.SetValue(player, 0f);
			MaxAirAltitudeField?.SetValue(player, val3.y);
		}

		private static void ApplyAshlandsOceanPlunge(Player player)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_0069: 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)
			Rigidbody component = ((Component)player).GetComponent<Rigidbody>();
			if (!((Object)(object)component == (Object)null))
			{
				if (component.isKinematic)
				{
					component.isKinematic = false;
				}
				component.useGravity = true;
				Vector3 linearVelocity = component.linearVelocity;
				linearVelocity.y += Physics.gravity.y * 4f * Time.deltaTime;
				if (linearVelocity.y > 0f)
				{
					linearVelocity.y = 0f;
				}
				component.linearVelocity = linearVelocity;
				CurrentVelField?.SetValue(player, linearVelocity);
			}
		}

		private static void DisableFlight(Player player, string message)
		{
			if (!((Object)(object)player == (Object)null))
			{
				bool num = FlyingPlayers.Remove(player);
				Rigidbody component = ((Component)player).GetComponent<Rigidbody>();
				if ((Object)(object)component != (Object)null)
				{
					component.isKinematic = false;
					component.useGravity = true;
				}
				if (num && !string.IsNullOrEmpty(message))
				{
					((Character)player).Message((MessageType)2, message, 0, (Sprite)null);
				}
			}
		}

		private static void EnsureFeatherFall(Player player)
		{
			if (IsTooHigh(player))
			{
				RemoveFeatherFall(player);
				return;
			}
			SEMan sEMan = ((Character)player).GetSEMan();
			if (sEMan != null && !sEMan.HaveStatusEffect(SlowFallHash))
			{
				sEMan.AddStatusEffect(SlowFallHash, true, 0, 0f);
			}
		}

		public static void RemoveFeatherFall(Player player)
		{
			if (player != null)
			{
				SEMan sEMan = ((Character)player).GetSEMan();
				if (sEMan != null)
				{
					sEMan.RemoveStatusEffect(SlowFallHash, true);
				}
			}
		}

		private static float GetAltitudeAboveSea(Vector3 position)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return position.y - 30f;
		}

		private static bool IsTooHigh(Player player)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player != (Object)null)
			{
				return GetAltitudeAboveSea(((Component)player).transform.position) >= 120f;
			}
			return false;
		}

		private static bool IsFlightEnvironmentBlocked(Player player, out string message)
		{
			message = null;
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			if (IsInAshlands(player) && !IsAboveAshlandsLand(player))
			{
				message = "The heat is too heavy for flight";
				return true;
			}
			return false;
		}

		private static float EstimateWaterSurfaceY(Player player)
		{
			if (WaterLevelField?.GetValue(player) is float num && num > -9000f)
			{
				return num;
			}
			return 30f;
		}

		private static bool IsInAshlands(Player player)
		{
			//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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			Vector3 position = ((Component)player).transform.position;
			return WorldGenerator.IsAshlands(position.x, position.z);
		}

		public static bool IsAboveAshlandsLand(Player player)
		{
			//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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			Vector3 position = ((Component)player).transform.position;
			if (!WorldGenerator.IsAshlands(position.x, position.z))
			{
				return true;
			}
			if ((Object)(object)ZoneSystem.instance == (Object)null)
			{
				return false;
			}
			Vector3 val = position;
			if (ZoneSystem.instance.IsLava(ref val, false) || ZoneSystem.IsLavaPreHeightmap(position, 0.6f))
			{
				return true;
			}
			float num = 30f;
			if (WorldGenerator.instance != null && WorldGenerator.instance.GetHeight(position.x, position.z) > num + 0.5f)
			{
				return true;
			}
			if (ZoneSystem.instance.GetGroundHeight(position) > num + 0.25f)
			{
				return true;
			}
			return HasFlyableSolidAboveWater(position, num);
		}

		private static int GetSolidRayMask()
		{
			if (_solidRayMask == 0)
			{
				_solidRayMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "piece", "terrain" });
			}
			return _solidRayMask;
		}

		private static bool HasFlyableSolidAboveWater(Vector3 position, float waterLevel)
		{
			//IL_0000: 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_0018: 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_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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			int num = Physics.RaycastNonAlloc(new Vector3(position.x, Mathf.Max(position.y, waterLevel) + 500f, position.z), Vector3.down, SolidHits, 5000f, GetSolidRayMask(), (QueryTriggerInteraction)1);
			float num2 = float.NegativeInfinity;
			float num3 = float.NegativeInfinity;
			for (int i = 0; i < num; i++)
			{
				RaycastHit val = SolidHits[i];
				if ((Object)(object)((RaycastHit)(ref val)).collider == (Object)null || IsWaterCollider(((RaycastHit)(ref val)).collider))
				{
					continue;
				}
				if ((Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Heightmap>() != (Object)null)
				{
					if (((RaycastHit)(ref val)).point.y > num3)
					{
						num3 = ((RaycastHit)(ref val)).point.y;
					}
				}
				else if (((RaycastHit)(ref val)).point.y > num2)
				{
					num2 = ((RaycastHit)(ref val)).point.y;
				}
			}
			if (num2 >= waterLevel - 0.5f)
			{
				return true;
			}
			return num3 > waterLevel + 0.25f;
		}

		private static bool IsWaterCollider(Collider collider)
		{
			if ((Object)(object)collider == (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)collider).GetComponentInParent<WaterVolume>() != (Object)null)
			{
				return true;
			}
			string name = ((Object)collider).name;
			if (string.IsNullOrEmpty(name))
			{
				return false;
			}
			string text = name.ToLowerInvariant();
			if (!text.Contains("water"))
			{
				return text.Contains("liquid");
			}
			return true;
		}
	}
	internal static class AarakocraTalons
	{
		private const string BonusKey = "Ent1ty303.TalonDamage";

		private const string AbsorbedKey = "Ent1ty303.TalonAbsorbed";

		public static string GetLastAbsorbedKnifeId(Player player)
		{
			if (!PlayerDataStore.TryGetString(player, "Ent1ty303.TalonAbsorbed", out var value) || string.IsNullOrEmpty(value))
			{
				return null;
			}
			string[] array = value.Split(new char[1] { '|' });
			for (int num = array.Length - 1; num >= 0; num--)
			{
				if (!string.IsNullOrEmpty(array[num]))
				{
					return array[num];
				}
			}
			return null;
		}

		public static void Update(Player player)
		{
			if (!((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && RaceManager.GetRace(player) == RaceType.Aarakocra && (ZInput.GetKeyDown((KeyCode)308, true) || ZInput.GetKeyDown((KeyCode)307, true)))
			{
				TryAbsorbKnife(player);
			}
		}

		public static void TryAbsorbKnife(Player player)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			ItemData currentWeapon = ((Humanoid)player).GetCurrentWeapon();
			if (currentWeapon?.m_shared == null || (int)currentWeapon.m_shared.m_skillType != 2)
			{
				((Character)player).Message((MessageType)2, "Hold a knife to absorb into your talons.", 0, (Sprite)null);
				return;
			}
			if (IsButcherKnife(currentWeapon))
			{
				((Character)player).Message((MessageType)2, "Talons refuse the butcher's blade.", 0, (Sprite)null);
				return;
			}
			string name = currentWeapon.m_shared.m_name;
			if (HasAbsorbed(player, name))
			{
				((Character)player).Message((MessageType)2, "Those talons already remember this blade.", 0, (Sprite)null);
				return;
			}
			float knifeTotalDamage = GetKnifeTotalDamage(currentWeapon);
			if (knifeTotalDamage <= 0f)
			{
				((Character)player).Message((MessageType)2, "This knife has no edge to absorb.", 0, (Sprite)null);
				return;
			}
			float num = GetTalonBonus(player) + knifeTotalDamage;
			PlayerDataStore.SetFloat(player, "Ent1ty303.TalonDamage", num);
			MarkAbsorbed(player, name);
			AarakocraTalonVisuals.RememberKnife(player, currentWeapon);
			((Humanoid)player).UnequipItem(currentWeapon, true);
			((Humanoid)player).GetInventory().RemoveOneItem(currentWeapon);
			((Character)player).Message((MessageType)2, $"Talons drink the steel. Unarmed +{knifeTotalDamage:0.#} (total +{num:0.#}).", 0, (Sprite)null);
		}

		private static bool IsButcherKnife(ItemData weapon)
		{
			if (weapon?.m_shared == null)
			{
				return false;
			}
			string obj = (((Object)(object)weapon.m_dropPrefab != (Object)null) ? ((Object)weapon.m_dropPrefab).name : string.Empty);
			string text = weapon.m_shared.m_name ?? string.Empty;
			if (obj.IndexOf("KnifeButcher", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("butcher", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return text.IndexOf("knife_butcher", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return true;
		}

		private static float GetKnifeTotalDamage(ItemData weapon)
		{
			//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)
			if (weapon == null)
			{
				return 0f;
			}
			try
			{
				DamageTypes damage = weapon.GetDamage();
				return ((DamageTypes)(ref damage)).GetTotalDamage();
			}
			catch
			{
				return ((DamageTypes)(ref weapon.m_shared.m_damages)).GetTotalDamage();
			}
		}

		private static bool HasAbsorbed(Player player, string knifeId)
		{
			if (!PlayerDataStore.TryGetString(player, "Ent1ty303.TalonAbsorbed", out var value) || string.IsNullOrEmpty(value))
			{
				return false;
			}
			string[] array = value.Split(new char[1] { '|' });
			for (int i = 0; i < array.Length; i++)
			{
				if (array[i] == knifeId)
				{
					return true;
				}
			}
			return false;
		}

		private static void MarkAbsorbed(Player player, string knifeId)
		{
			if (PlayerDataStore.TryGetString(player, "Ent1ty303.TalonAbsorbed", out var value) && !string.IsNullOrEmpty(value))
			{
				PlayerDataStore.SetString(player, "Ent1ty303.TalonAbsorbed", value + "|" + knifeId);
			}
			else
			{
				PlayerDataStore.SetString(player, "Ent1ty303.TalonAbsorbed", knifeId);
			}
		}

		public static float GetTalonBonus(Player player)
		{
			if ((Object)(object)player == (Object)null || RaceManager.GetRace(player) != RaceType.Aarakocra)
			{
				return 0f;
			}
			if (!PlayerDataStore.TryGetFloat(player, "Ent1ty303.TalonDamage", out var value))
			{
				return 0f;
			}
			return value;
		}

		public static void ApplyUnarmedBonus(Player player, HitData hit)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			if (hit != null && !((Object)(object)player == (Object)null) && (int)hit.m_skill == 11)
			{
				float talonBonus = GetTalonBonus(player);
				if (!(talonBonus <= 0f))
				{
					hit.m_damage.m_slash += talonBonus * 0.5f;
					hit.m_damage.m_pierce += talonBonus * 0.5f;
				}
			}
		}
	}
	internal static class AarakocraTalonVisuals
	{
		private const string LastKnifeKey = "Ent1ty303.TalonLastKnife";

		private static readonly MethodInfo AttachItemMethod = AccessTools.Method(typeof(VisEquipment), "AttachItem", new Type[5]
		{
			typeof(int),
			typeof(int),
			typeof(Transform),
			typeof(bool),
			typeof(bool)
		}, (Type[])null);

		private static GameObject _rightKnife;

		private static GameObject _leftKnife;

		private static string _loadedPrefab;

		private static bool _visible;

		public static void RememberKnife(Player player, ItemData weapon)
		{
			if (!((Object)(object)player == (Object)null) && !((Object)(object)weapon?.m_dropPrefab == (Object)null))
			{
				PlayerDataStore.SetString(player, "Ent1ty303.TalonLastKnife", ((Object)weapon.m_dropPrefab).name);
			}
		}

		public static void Update(Player player)
		{
			if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			if (RaceManager.GetRace(player) != RaceType.Aarakocra)
			{
				Hide();
			}
			else if (!((Character)player).InAttack() || !DragonbornBreathInput.IsUnarmed(player) || ResolveKnifePrefab(player) == null)
			{
				if (_visible)
				{
					SetVisible(visible: false);
				}
			}
			else
			{
				EnsureAttached(player);
				SetVisible(visible: true);
			}
		}

		private static string ResolveKnifePrefab(Player player)
		{
			if (PlayerDataStore.TryGetString(player, "Ent1ty303.TalonLastKnife", out var value) && !string.IsNullOrEmpty(value) && (Object)(object)ObjectDB.instance != (Object)null && (Object)(object)ObjectDB.instance.GetItemPrefab(value) != (Object)null)
			{
				return value;
			}
			string lastAbsorbedKnifeId = AarakocraTalons.GetLastAbsorbedKnifeId(player);
			if (string.IsNullOrEmpty(lastAbsorbedKnifeId) || (Object)(object)ObjectDB.instance == (Object)null)
			{
				return null;
			}
			string text = FindKnifePrefabBySharedName(lastAbsorbedKnifeId);
			if (string.IsNullOrEmpty(text))
			{
				return null;
			}
			PlayerDataStore.SetString(player, "Ent1ty303.TalonLastKnife", text);
			return text;
		}

		private static string FindKnifePrefabBySharedName(string sharedName)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Invalid comparison between Unknown and I4
			foreach (GameObject item in ObjectDB.instance.m_items)
			{
				if (!((Object)(object)item == (Object)null))
				{
					ItemDrop component = item.GetComponent<ItemDrop>();
					if (component?.m_itemData?.m_shared != null && (int)component.m_itemData.m_shared.m_skillType == 2 && component.m_itemData.m_shared.m_name == sharedName)
					{
						return ((Object)item).name;
					}
				}
			}
			return null;
		}

		private static void EnsureAttached(Player player)
		{
			string text = ResolveKnifePrefab(player);
			if (!string.IsNullOrEmpty(text))
			{
				VisEquipment componentInChildren = ((Component)player).GetComponentInChildren<VisEquipment>();
				if (!((Object)(object)componentInChildren == (Object)null) && !((Object)(object)componentInChildren.m_rightHand == (Object)null) && !((Object)(object)componentInChildren.m_leftHand == (Object)null) && (!(_loadedPrefab == text) || !((Object)(object)_rightKnife != (Object)null) || !((Object)(object)_leftKnife != (Object)null)))
				{
					Hide();
					int stableHashCode = StringExtensionMethods.GetStableHashCode(text);
					_rightKnife = Attach(componentInChildren, stableHashCode, componentInChildren.m_rightHand);
					_leftKnife = Attach(componentInChildren, stableHashCode, componentInChildren.m_leftHand);
					_loadedPrefab = text;
					TuneTalonTransform(_rightKnife, mirror: false);
					TuneTalonTransform(_leftKnife, mirror: true);
				}
			}
		}

		private static GameObject Attach(VisEquipment vis, int hash, Transform hand)
		{
			if (AttachItemMethod == null)
			{
				return null;
			}
			object? obj = AttachItemMethod.Invoke(vis, new object[5] { hash, 0, hand, false, false });
			return (GameObject)((obj is GameObject) ? obj : null);
		}

		private static void TuneTalonTransform(GameObject knife, bool mirror)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)knife == (Object)null))
			{
				knife.transform.localPosition = new Vector3(mirror ? (-0.02f) : 0.02f, 0.02f, 0.06f);
				knife.transform.localRotation = Quaternion.Euler(-20f, mirror ? (-90f) : 90f, 180f);
				knife.transform.localScale = Vector3.one * 0.85f;
			}
		}

		private static void SetVisible(bool visible)
		{
			_visible = visible;
			if ((Object)(object)_rightKnife != (Object)null)
			{
				_rightKnife.SetActive(visible);
			}
			if ((Object)(object)_leftKnife != (Object)null)
			{
				_leftKnife.SetActive(visible);
			}
		}

		private static void Hide()
		{
			if ((Object)(object)_rightKnife != (Object)null)
			{
				Object.Destroy((Object)(object)_rightKnife);
				_rightKnife = null;
			}
			if ((Object)(object)_leftKnife != (Object)null)
			{
				Object.Destroy((Object)(object)_leftKnife);
				_leftKnife = null;
			}
			_loadedPrefab = null;
			_visible = false;
		}
	}
	internal static class AasimarWisp
	{
		private static GameObject _ball;

		private static Light _light;

		private static readonly int DemisterHash = StringExtensionMethods.GetStableHashCode("Demister");

		public static void Update(Player player)
		{
			//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_00b3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			if (RaceManager.GetRace(player) != RaceType.Aasimar)
			{
				Remove(player);
				return;
			}
			SEMan sEMan = ((Character)player).GetSEMan();
			if (sEMan != null)
			{
				sEMan.RemoveStatusEffect(DemisterHash, true);
			}
			EnsureBall(player);
			if (!((Object)(object)_ball == (Object)null))
			{
				float time = Time.time;
				Vector3 val = default(Vector3);
				((Vector3)(ref val))..ctor(Mathf.Cos(time * 1.4f) * 1.1f, 1.3f + Mathf.Sin(time * 2.1f) * 0.25f, Mathf.Sin(time * 1.4f) * 1.1f);
				_ball.transform.position = ((Component)player).transform.position + val;
			}
		}

		public static void Remove(Player player)
		{
			if (player != null)
			{
				SEMan sEMan = ((Character)player).GetSEMan();
				if (sEMan != null)
				{
					sEMan.RemoveStatusEffect(DemisterHash, true);
				}
			}
			if ((Object)(object)_ball != (Object)null)
			{
				Object.Destroy((Object)(object)_ball);
				_ball = null;
				_light = null;
			}
		}

		private static void EnsureBall(Player player)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			if ((Object)(object)_ball != (Object)null)
			{
				return;
			}
			_ball = GameObject.CreatePrimitive((PrimitiveType)0);
			((Object)_ball).name = "Ent1tyRaces_AasimarWisp";
			Object.Destroy((Object)(object)_ball.GetComponent<Collider>());
			_ball.transform.localScale = Vector3.one * 0.22f;
			MeshRenderer component = _ball.GetComponent<MeshRenderer>();
			if ((Object)(object)component != (Object)null)
			{
				Shader val = Shader.Find("Sprites/Default") ?? Shader.Find("Standard");
				if ((Object)(object)val != (Object)null)
				{
					((Renderer)component).material = new Material(val)
					{
						color = Color.white
					};
				}
			}
			_light = _ball.AddComponent<Light>();
			_light.color = Color.white;
			_light.intensity = 1.4f;
			_light.range = 10f;
			Object.DontDestroyOnLoad((Object)(object)_ball);
		}
	}
	internal static class AasimarHealBreath
	{
		private const float AoeRadius = 4f;

		private const float AoeRange = 8f;

		public static void Update(Player player)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: 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_0107: 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_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || RaceManager.GetRace(player) != RaceType.Aasimar || !DragonbornBreathInput.AreBreathButtonsHeld() || !DragonbornBreathInput.IsAttackPressed())
			{
				return;
			}
			DragonbornBreathCombat.ForceBlockDown((Humanoid)(object)player);
			DragonbornBreathCombat.CancelUnarmedAttack((Humanoid)(object)player);
			float breathElementDamage = DragonbornBreath.GetBreathElementDamage(player);
			if (breathElementDamage <= 0f)
			{
				return;
			}
			float num = 12f;
			if (!((Character)player).HaveStamina(num + 0.1f))
			{
				((Character)player).Message((MessageType)2, "Not enough stamina to heal.", 0, (Sprite)null);
				return;
			}
			((Character)player).UseStamina(num);
			Vector3 eyePoint = ((Character)player).GetEyePoint();
			Vector3 lookDir = ((Character)player).GetLookDir();
			Vector3 val = eyePoint + lookDir * 4f;
			SpawnHealFx(eyePoint);
			((Character)player).Heal(breathElementDamage * 0.35f, true);
			List<Character> list = new List<Character>();
			Character.GetCharactersInRange(val, 4f, list);
			foreach (Character item in list)
			{
				if (!((Object)(object)item == (Object)null) && !item.IsDead() && !((Object)(object)item == (Object)(object)player) && (item is Player || item.IsTamed()))
				{
					Vector3 val2 = item.GetCenterPoint() - eyePoint;
					if (!(((Vector3)(ref val2)).magnitude > 8f) && !(Vector3.Dot(((Vector3)(ref val2)).normalized, lookDir) < 0.2f))
					{
						item.Heal(breathElementDamage, true);
					}
				}
			}
		}

		private static void SpawnHealFx(Vector3 pos)
		{
			//IL_004e: 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)
			if (!((Object)(object)ZNetScene.instance == (Object)null))
			{
				GameObject val = ZNetScene.instance.GetPrefab("vfx_Potion_health_medium") ?? ZNetScene.instance.GetPrefab("vfx_HealthUpgrade") ?? ZNetScene.instance.GetPrefab("fx_guardstone_activate");
				if ((Object)(object)val != (Object)null)
				{
					Object.Instantiate<GameObject>(val, pos, Quaternion.identity);
				}
			}
		}
	}
	internal static class AasimarFlight
	{
		private static readonly int SlowFallHash = StringExtensionMethods.GetStableHashCode("SlowFall");

		private static readonly FieldInfo BodyField = AccessTools.Field(typeof(Character), "m_body");

		private static readonly FieldInfo LastGroundNormalField = AccessTools.Field(typeof(Character), "m_lastGroundNormal");

		private static readonly FieldInfo MoveDirField = AccessTools.Field(typeof(Character), "m_moveDir");

		private static int _airJumpsLeft = 1;

		public static void Update(Player player)
		{
			if (!((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && RaceManager.GetRace(player) == RaceType.Aasimar)
			{
				EnsureFeatherFall(player);
				if (((Character)player).IsOnGround())
				{
					_airJumpsLeft = 1;
				}
			}
		}

		public static bool TryAirJump(Player player)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: 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_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: 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_0103: 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_010a: 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_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || RaceManager.GetRace(player) != RaceType.Aasimar || ((Character)player).IsOnGround())
			{
				return false;
			}
			if (_airJumpsLeft <= 0)
			{
				return false;
			}
			if (!((Character)player).HaveStamina(((Character)player).m_jumpStaminaUsage * 0.4f))
			{
				return false;
			}
			((Character)player).UseStamina(((Character)player).m_jumpStaminaUsage * 0.4f);
			object? obj = BodyField?.GetValue(player);
			Rigidbody val = (Rigidbody)((obj is Rigidbody) ? obj : null);
			if (val == null)
			{
				return false;
			}
			Vector3 val2 = ((LastGroundNormalField?.GetValue(player) is Vector3 val3) ? val3 : Vector3.up);
			Vector3 val4 = ((MoveDirField?.GetValue(player) is Vector3 val5) ? val5 : Vector3.zero);
			Vector3 linearVelocity = val.linearVelocity;
			linearVelocity.y = 0f;
			Vector3 val6 = linearVelocity;
			Vector3 val7 = val2 + Vector3.up;
			linearVelocity = val6 + ((Vector3)(ref val7)).normalized * ((Character)player).m_jumpForce;
			linearVelocity += val4 * ((Character)player).m_jumpForceForward;
			val.linearVelocity = linearVelocity;
			_airJumpsLeft--;
			return true;
		}

		public static void RemoveFeatherFall(Player player)
		{
			if (player != null)
			{
				SEMan sEMan = ((Character)player).GetSEMan();
				if (sEMan != null)
				{
					sEMan.RemoveStatusEffect(SlowFallHash, true);
				}
			}
		}

		private static void EnsureFeatherFall(Player player)
		{
			SEMan sEMan = ((Character)player).GetSEMan();
			if (sEMan != null && !sEMan.HaveStatusEffect(SlowFallHash))
			{
				sEMan.AddStatusEffect(SlowFallHash, true, 0, 0f);
			}
		}
	}
	internal static class BodyScale
	{
		public const float Giant = 2f;

		public const float SlightlySmall = 0.75f;

		public const float VerySmall = 0.5f;

		public const float Normal = 1f;

		public static float GetScale(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return 1f;
			}
			return RaceManager.GetRace(player) switch
			{
				RaceType.Giant => 2f, 
				RaceType.Dwarf => 0.75f, 
				RaceType.Gnome => 0.75f, 
				RaceType.Tiefling => 0.75f, 
				RaceType.Halfling => 0.5f, 
				_ => 1f, 
			};
		}

		public static void Update(Player player)
		{
			//IL_0011: 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_001c: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)player == (Object)null))
			{
				float scale = GetScale(player);
				Vector3 val = Vector3.one * scale;
				Vector3 val2 = ((Component)player).transform.localScale - val;
				if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f)
				{
					((Component)player).transform.localScale = val;
				}
			}
		}
	}
	internal static class BreathDamageApplicator
	{
		internal const float BreathHitMarker = -4242f;

		internal const float MountainShiftYellowMarker = 1f;

		private static readonly MethodInfo BlockAttackMethod = AccessTools.Method(typeof(Character), "BlockAttack", new Type[2]
		{
			typeof(HitData),
			typeof(Character)
		}, (Type[])null);

		private static readonly MethodInfo GetWeakSpotMethod = AccessTools.Method(typeof(Character), "GetWeakSpot", new Type[1] { typeof(short) }, (Type[])null);

		private static readonly MethodInfo DamageArmorDurabilityMethod = AccessTools.Method(typeof(Character), "DamageArmorDurability", new Type[1] { typeof(HitData) }, (Type[])null);

		private static readonly FieldInfo BaseAiField = AccessTools.Field(typeof(Character), "m_baseAI");

		public static void MarkBreathHit(HitData hit)
		{
			if (hit != null)
			{
				hit.m_pushForce = -4242f;
			}
		}

		public static bool IsBreathHit(HitData hit)
		{
			if (hit != null)
			{
				return Mathf.Approximately(hit.m_pushForce, -4242f);
			}
			return false;
		}

		public static void ApplyBreathTick(Player attacker, Character target, HitData hit, BreathElement element, float tickDamage, bool mountainShiftYellow)
		{
			if (!((Object)(object)attacker == (Object)null) && !((Object)(object)target == (Object)null) && hit != null && !(tickDamage <= 0f))
			{
				ElementResistance.SetElementDamage(hit, element, tickDamage);
				MarkBreathHit(hit);
				hit.m_healthReturn = (mountainShiftYellow ? 1f : 0f);
				target.Damage(hit);
			}
		}

		public static void ApplyBreathDamage(Character target, HitData hit)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)target == (Object)null || hit == null || !target.m_nview.IsOwner())
			{
				return;
			}
			Character attacker = hit.GetAttacker();
			if (GetHealthBlocked(target, hit, attacker))
			{
				return;
			}
			if ((Object)(object)attacker != (Object)null && !attacker.IsPlayer())
			{
				float difficultyDamageScalePlayer = Game.instance.GetDifficultyDamageScalePlayer(((Component)target).transform.position);
				hit.ApplyModifier(difficultyDamageScalePlayer);
				hit.ApplyModifier(Game.m_enemyDamageRate);
			}
			target.GetSEMan().OnDamaged(hit, attacker);
			object? obj = BaseAiField?.GetValue(target);
			BaseAI val = (BaseAI)((obj is BaseAI) ? obj : null);
			if ((Object)(object)val != (Object)null && val.IsAggravatable() && !val.IsAggravated() && (Object)(object)attacker != (Object)null && attacker.IsPlayer() && hit.GetTotalDamage() > 0f)
			{
				BaseAI.AggravateAllInArea(((Component)target).transform.position, 20f, (AggravatedReason)0);
			}
			if (hit.m_blockable && target.IsBlocking())
			{
				BlockAttackMethod?.Invoke(target, new object[2] { hit, attacker });
				return;
			}
			Player val2 = (Player)(object)((target is Player) ? target : null);
			if (val2 != null)
			{
				target.AddAdrenaline(val2.m_nonBlockDamageAdrenaline);
			}
			object? obj2 = GetWeakSpotMethod?.Invoke(target, new object[1] { hit.m_weakSpot });
			WeakSpot val3 = (WeakSpot)((obj2 is WeakSpot) ? obj2 : null);
			DamageModifiers damageModifiers = target.GetDamageModifiers(val3);
			DamageModifier val4 = default(DamageModifier);
			hit.ApplyResistance(damageModifiers, ref val4);
			if (target.IsPlayer())
			{
				hit.ApplyArmor(target.GetBodyArmor());
				DamageArmorDurabilityMethod?.Invoke(target, new object[1] { hit });
			}
			else if (Game.m_worldLevel > 0)
			{
				hit.ApplyArmor((float)(Game.m_worldLevel * Game.instance.m_worldLevelEnemyBaseAC));
			}
			float totalDamage = hit.GetTotalDamage();
			DamageModifier val5 = val4;
			if (Mathf.Approximately(hit.m_healthReturn, 1f))
			{
				val5 = (DamageModifier)2;
			}
			else
			{
				Player val6 = (Player)(object)((attacker is Player) ? attacker : null);
				if (val6 != null)
				{
					val5 = MountainShiftDisplay.GetDisplayModifier(val6, hit, val4);
				}
			}
			target.ApplyDamage(hit, false, true, val5);
			MountainShiftDamageText.Show((Player)(object)((attacker is Player) ? attacker : null), hit, val4, hit.m_point, totalDamage, target.IsPlayer() || target.IsTamed());
		}

		private static bool GetHealthBlocked(Character target, HitData hit, Character attacker)
		{
			if (target.GetHealth() <= 0f || target.IsDead() || target.IsTeleporting() || target.InCutscene() || (hit.m_dodgeable && target.IsDodgeInvincible()) || (hit.HaveAttacker() && (Object)(object)attacker == (Object)null))
			{
				return true;
			}
			if (target.IsPlayer() && !target.IsPVPEnabled() && (Object)(object)attacker != (Object)null && attacker.IsPlayer())
			{
				return !hit.m_ignorePVP;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Character), "RPC_Damage", new Type[]
	{
		typeof(long),
		typeof(HitData)
	})]
	internal static class DragonbornBreathRpcDamagePatch
	{
		private static bool Prefix(Character __instance, HitData hit)
		{
			if (!BreathDamageApplicator.IsBreathHit(hit))
			{
				return true;
			}
			BreathDamageApplicator.ApplyBreathDamage(__instance, hit);
			return false;
		}
	}
	internal struct BreathStrikeTarget
	{
		public Character Target;

		public HitData Template;

		public BreathElement Element;

		public float TotalDamage;

		public bool MountainShiftYellow;
	}
	internal static class BreathDamageOverTime
	{
		public const int TickCount = 5;

		private static readonly Dictionary<Player, Coroutine> ActiveRoutines = new Dictionary<Player, Coroutine>();

		public static void StartBurst(Player attacker, List<BreathStrikeTarget> strikes)
		{
			if ((Object)(object)attacker == (Object)null || strikes == null || strikes.Count == 0)
			{
				return;
			}
			if ((Object)(object)Ent1tyRacesPlugin.Instance == (Object)null)
			{
				ApplyBurstImmediate(attacker, strikes);
				return;
			}
			if (ActiveRoutines.TryGetValue(attacker, out var value) && value != null)
			{
				((MonoBehaviour)Ent1tyRacesPlugin.Instance).StopCoroutine(value);
			}
			Coroutine value2 = ((MonoBehaviour)Ent1tyRacesPlugin.Instance).StartCoroutine(BurstRoutine(attacker, strikes));
			ActiveRoutines[attacker] = value2;
		}

		private static IEnumerator BurstRoutine(Player attacker, List<BreathStrikeTarget> strikes)
		{
			try
			{
				float interval = 0.2f;
				for (int tick = 0; tick < 5; tick++)
				{
					if ((Object)(object)attacker == (Object)null)
					{
						break;
					}
					ApplyTickToTargets(attacker, strikes);
					if (tick < 4)
					{
						yield return (object)new WaitForSeconds(interval);
					}
				}
			}
			finally
			{
				if ((Object)(object)attacker != (Object)null && ActiveRoutines.TryGetValue(attacker, out var value) && value != null)
				{
					ActiveRoutines.Remove(attacker);
				}
			}
		}

		private static void ApplyBurstImmediate(Player attacker, List<BreathStrikeTarget> strikes)
		{
			for (int i = 0; i < 5; i++)
			{
				ApplyTickToTargets(attacker, strikes);
			}
		}

		private static void ApplyTickToTargets(Player attacker, List<BreathStrikeTarget> strikes)
		{
			foreach (BreathStrikeTarget strike in strikes)
			{
				if (!((Object)(object)strike.Target == (Object)null) && !strike.Target.IsDead() && BreathTargetFilter.CanBreathDamage(attacker, strike.Target))
				{
					float tickDamage = strike.TotalDamage / 5f;
					HitData hit = strike.Template.Clone();
					BreathDamageApplicator.ApplyBreathTick(attacker, strike.Target, hit, strike.Element, tickDamage, strike.MountainShiftYellow);
				}
			}
		}
	}
	public static class BreathManager
	{
		private const string CustomBreathKey = "Ent1ty303.BreathElement";

		public static BreathElement GetBreathElement(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return BreathElement.Fire;
			}
			if (PlayerDataStore.TryGetInt(player, "Ent1ty303.BreathElement", out var value) && Enum.IsDefined(typeof(BreathElement), value))
			{
				return (BreathElement)value;
			}
			return BreathElement.Fire;
		}

		public static bool TrySetBreathElement(Player player, BreathElement element, out string message)
		{
			message = null;
			if ((Object)(object)player == (Object)null)
			{
				message = "Load a character first.";
				return false;
			}
			if (RaceManager.GetRace(player) != RaceType.Dragonborn)
			{
				message = "Only Dragonborn can attune a breath element.";
				return false;
			}
			PlayerDataStore.SetInt(player, "Ent1ty303.BreathElement", (int)element);
			message = element switch
			{
				BreathElement.Fire => "Your breath burns with flame.", 
				BreathElement.Poison => "Your breath hisses with venom.", 
				BreathElement.Lightning => "Your breath crackles with thunder.", 
				BreathElement.Ice => "Your breath freezes the air.", 
				_ => $"Breath attuned to {element}.", 
			};
			if (((Character)player).IsOwner())
			{
				((Character)player).Message((MessageType)2, message, 0, (Sprite)null);
			}
			return true;
		}

		public static BreathElement ParseBreathElement(string value)
		{
			if (string.IsNullOrWhiteSpace(value))
			{
				return BreathElement.Fire;
			}
			switch (value.Trim().ToLowerInvariant())
			{
			case "fire":
				return BreathElement.Fire;
			case "poison":
				return BreathElement.Poison;
			case "lightning":
				return BreathElement.Lightning;
			case "ice":
			case "frost":
				return BreathElement.Ice;
			default:
			{
				BreathElement result;
				return Enum.TryParse<BreathElement>(value, ignoreCase: true, out result) ? result : BreathElement.Fire;
			}
			}
		}
	}
	internal static class BreathTargetFilter
	{
		public static bool CanBreathDamage(Player attacker, Character target)
		{
			//IL_0068: 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)
			if ((Object)(object)attacker == (Object)null || (Object)(object)target == (Object)null || (Object)(object)target == (Object)(object)attacker || target.IsDead())
			{
				return false;
			}
			if (target.IsPlayer())
			{
				Player val = (Player)(object)((target is Player) ? target : null);
				if (val == null)
				{
					return false;
				}
				return ((Character)val).IsPVPEnabled();
			}
			if (target.IsTamed())
			{
				if (IsPlayersTame(attacker, target))
				{
					return false;
				}
				if (!BaseAI.IsEnemy((Character)(object)attacker, target))
				{
					return false;
				}
			}
			if (!BaseAI.IsEnemy((Character)(object)attacker, target) && target.GetFaction() == ((Character)attacker).GetFaction())
			{
				return false;
			}
			return true;
		}

		private static bool IsPlayersTame(Player player, Character target)
		{
			long playerID = player.GetPlayerID();
			long sessionPlayerId = GetSessionPlayerId(player);
			long owner = target.GetOwner();
			if (owner != 0L && (owner == playerID || owner == sessionPlayerId))
			{
				return true;
			}
			ZNetView component = ((Component)target).GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && component.IsValid())
			{
				long num = component.GetZDO().GetLong("owner", 0L);
				if (num != 0L && (num == playerID || num == sessionPlayerId))
				{
					return true;
				}
			}
			return false;
		}

		private static long GetSessionPlayerId(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return 0L;
			}
			if ((Object)(object)ZNet.instance != (Object)null)
			{
				return ZNet.GetUID();
			}
			return player.GetPlayerID();
		}
	}
	internal static class CloudGiantJump
	{
		private const float JumpStaminaMult = 0.45f;

		private const int MaxAirJumps = 1;

		private static readonly FieldInfo BodyField = AccessTools.Field(typeof(Character), "m_body");

		private static readonly FieldInfo LastGroundNormalField = AccessTools.Field(typeof(Character), "m_lastGroundNormal");

		private static readonly FieldInfo MoveDirField = AccessTools.Field(typeof(Character), "m_moveDir");

		private static int _airJumpsLeft = 1;

		private static float _savedJumpStamina = -1f;

		public static void Update(Player player)
		{
			if (!((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && GiantTypeManager.Is(player, GiantType.Cloud) && ((Character)player).IsOnGround())
			{
				_airJumpsLeft = 1;
			}
		}

		public static bool IsCloud(Player player)
		{
			return GiantTypeManager.Is(player, GiantType.Cloud);
		}

		public static void BeginReducedJumpStamina(Character character)
		{
			if (_savedJumpStamina < 0f)
			{
				_savedJumpStamina = character.m_jumpStaminaUsage;
				character.m_jumpStaminaUsage *= 0.45f;
			}
		}

		public static void EndReducedJumpStamina(Character character)
		{
			if (_savedJumpStamina >= 0f)
			{
				character.m_jumpStaminaUsage = _savedJumpStamina;
				_savedJumpStamina = -1f;
			}
		}

		public static bool TryAirJump(Player player)
		{
			if (!IsCloud(player) || ((Character)player).IsOnGround() || ((Character)player).IsDead() || ((Character)player).IsEncumbered())
			{
				return false;
			}
			if (_airJumpsLeft <= 0)
			{
				return false;
			}
			float num = ((Character)player).m_jumpStaminaUsage * 0.45f;
			if (!((Character)player).HaveStamina(num * 0.5f))
			{
				Hud instance = Hud.instance;
				if (instance != null)
				{
					instance.StaminaBarEmptyFlash();
				}
				return false;
			}
			((Character)player).UseStamina(num);
			ApplyJumpVelocity(player);
			_airJumpsLeft--;
			return true;
		}

		private static void ApplyJumpVelocity(Player player)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_00eb: 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_00f9: 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_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_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			object? obj = BodyField?.GetValue(player);
			Rigidbody val = (Rigidbody)((obj is Rigidbody) ? obj : null);
			if (val != null)
			{
				Vector3 val2 = ((LastGroundNormalField?.GetValue(player) is Vector3 val3) ? val3 : Vector3.up);
				Vector3 val4 = ((MoveDirField?.GetValue(player) is Vector3 val5) ? val5 : Vector3.zero);
				float skillFactor = ((Character)player).GetSkillFactor((SkillType)100);
				float num = 1f + skillFactor * 0.4f;
				Vector3 val6 = val.linearVelocity;
				Vector3 val7 = val2 + Vector3.up;
				Vector3 normalized = ((Vector3)(ref val7)).normalized;
				float num2 = ((Character)player).m_jumpForce * num * 1f;
				float num3 = Vector3.Dot(normalized, val6);
				if (num3 < num2)
				{
					val6 += normalized * (num2 - num3);
				}
				val6 += val4 * ((Character)player).m_jumpForceForward * num * 1f;
				((Character)player).ForceJump(val6, true);
				((Character)player).RaiseSkill((SkillType)100, 1f);
			}
		}
	}
	internal static class CloudGiantTeleport
	{
		private const float MaxRange = 28f;

		private const float CooldownSeconds = 4f;

		private static float _nextReadyTime;

		private static readonly RaycastHit[] Hits = (RaycastHit[])(object)new RaycastHit[32];

		public static void Update(Player player)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && GiantTypeManager.Is(player, GiantType.Cloud) && DragonbornBreathInput.AreBreathButtonsHeld() && DragonbornBreathInput.IsAttackPressed())
			{
				if (Time.time < _nextReadyTime)
				{
					((Character)player).Message((MessageType)2, "Clouds still gathering...", 0, (Sprite)null);
					return;
				}
				if (!TryFindTeleportPoint(player, out var destination))
				{
					((Character)player).Message((MessageType)2, "No landing in sight.", 0, (Sprite)null);
					return;
				}
				GiantBody.BlinkTo(player, destination);
				_nextReadyTime = Time.time + 4f;
				((Character)player).Message((MessageType)2, "You step through the mist.", 0, (Sprite)null);
				SpawnCloudFx(destination);
			}
		}

		private static bool TryFindTeleportPoint(Player player, out Vector3 destination)
		{
			//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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: 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)
			//IL_00fb: 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_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			destination = ((Component)player).transform.position;
			Vector3 eyePoint = ((Character)player).GetEyePoint();
			Vector3 lookDir = ((Character)player).GetLookDir();
			Vector3 normalized = ((Vector3)(ref lookDir)).normalized;
			int num = Physics.RaycastNonAlloc(eyePoint, normalized, Hits, 28f, -1, (QueryTriggerInteraction)1);
			float num2 = 28f;
			Vector3 val = eyePoint + normalized * 28f;
			Vector3 val2 = Vector3.up;
			for (int i = 0; i < num; i++)
			{
				RaycastHit val3 = Hits[i];
				if (!((Object)(object)((RaycastHit)(ref val3)).collider == (Object)null) && !((RaycastHit)(ref val3)).collider.isTrigger && !((Object)(object)((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent<Character>() == (Object)(object)player) && ((RaycastHit)(ref val3)).distance > 0.75f && ((RaycastHit)(ref val3)).distance < num2)
				{
					num2 = ((RaycastHit)(ref val3)).distance;
					val = ((RaycastHit)(ref val3)).point;
					val2 = ((RaycastHit)(ref val3)).normal;
				}
			}
			destination = val + val2 * 0.35f + Vector3.up * 0.1f;
			RaycastHit val4 = default(RaycastHit);
			if (Physics.Raycast(destination + Vector3.up * 2f, Vector3.down, ref val4, 8f, -1, (QueryTriggerInteraction)1) && (Object)(object)((Component)((RaycastHit)(ref val4)).collider).GetComponentInParent<Character>() != (Object)(object)player)
			{
				destination = ((RaycastHit)(ref val4)).point + Vector3.up * 0.15f;
			}
			return true;
		}

		private static void SpawnCloudFx(Vector3 pos)
		{
			//IL_004e: 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)
			if (!((Object)(object)ZNetScene.instance == (Object)null))
			{
				GameObject val = ZNetScene.instance.GetPrefab("vfx_odin_despawn") ?? ZNetScene.instance.GetPrefab("vfx_WishbonePing") ?? ZNetScene.instance.GetPrefab("vfx_Frost");
				if ((Object)(object)val != (Object)null)
				{
					Object.Instantiate<GameObject>(val, pos, Quaternion.identity);
				}
			}
		}
	}
	public static class DragonbornBreath
	{
		private const float AoeRadius = 4f;

		private const float AoeRange = 8f;

		public const float FxLifetimeSeconds = 1f;

		private static readonly Dictionary<BreathElement, string[]> ElementFxPrefabs = new Dictionary<BreathElement, string[]>
		{
			{
				BreathElement.Fire,
				new string[2] { "vfx_torch_hit", "vfx_fireball_explosion" }
			},
			{
				BreathElement.Poison,
				new string[2] { "vfx_Poison", "vfx_poisonarrow_hit" }
			},
			{
				BreathElement.Lightning,
				new string[3] { "fx_lightningweapon_hit", "fx_chainlightning_hit", "fx_lightningstaffprojectile_hit" }
			},
			{
				BreathElement.Ice,
				new string[3] { "vfx_Frost", "vfx_Freezing", "vfx_frostarrow_hit" }
			}
		};

		public static bool TryExecute(Player player, Attack attack)
		{
			//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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_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_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			//IL_00f7: 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_0105: 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_010e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			float breathStaminaCost = GetBreathStaminaCost(player, attack);
			if (!((Character)player).HaveStamina(breathStaminaCost + 0.1f))
			{
				return false;
			}
			((Character)player).UseStamina(breathStaminaCost);
			BreathElement breathElement = BreathManager.GetBreathElement(player);
			TrinketBonus equippedBonus = TrinketBonusRegistry.GetEquippedBonus(player);
			float num = GetUnarmedDamage(player) + equippedBonus.ElementDamage;
			Vector3 eyePoint = ((Character)player).GetEyePoint();
			Vector3 lookDir = ((Character)player).GetLookDir();
			Vector3 val = eyePoint + lookDir * 4f;
			SpawnElementFx(breathElement, eyePoint, lookDir);
			List<Character> list = new List<Character>();
			Character.GetCharactersInRange(val, 4f, list);
			List<BreathStrikeTarget> list2 = new List<BreathStrikeTarget>();
			foreach (Character item in list)
			{
				if (!BreathTargetFilter.CanBreathDamage(player, item))
				{
					continue;
				}
				Vector3 val2 = item.GetCenterPoint() - eyePoint;
				if (!(((Vector3)(ref val2)).magnitude > 8f) && !(Vector3.Dot(((Vector3)(ref val2)).normalized, lookDir) < 0.2f))
				{
					HitData val3 = new HitData();
					val3.m_skill = (SkillType)11;
					val3.m_point = item.GetCenterPoint();
					val3.m_dir = lookDir;
					val3.m_pushForce = 0f;
					val3.SetAttacker((Character)(object)player);
					float shiftedDamage = num;
					if (equippedBonus.MountainResShift)
					{
						ApplyMountainResistanceShift(player, breathElement, shiftedDamage, out shiftedDamage);
					}
					list2.Add(new BreathStrikeTarget
					{
						Target = item,
						Template = val3,
						Element = breathElement,
						TotalDamage = shiftedDamage,
						MountainShiftYellow = MountainShiftDisplay.ShouldShowResistanceShiftYellow(player, breathElement)
					});
				}
			}
			BreathDamageOverTime.StartBurst(player, list2);
			return true;
		}

		private static float GetBreathStaminaCost(Player player, Attack attack)
		{
			if (attack != null)
			{
				return attack.m_attackStamina;
			}
			ItemData currentWeapon = ((Humanoid)player).GetCurrentWeapon();
			if (currentWeapon?.m_shared?.m_attack != null)
			{
				return currentWeapon.m_shared.m_attack.m_attackStamina;
			}
			return 10f;
		}

		private static void ApplyMountainResistanceShift(Player player, BreathElement element, float baseDamage, out float shiftedDamage)
		{
			shiftedDamage = baseDamage;
			float resistancePercent = ElementResistance.GetResistancePercent(player, element);
			if (!(resistancePercent <= 0f))
			{
				shiftedDamage = baseDamage * (1f + resistancePercent / 100f);
			}
		}

		public static float GetOceanArmorBonus(Player player)
		{
			if (RaceManager.GetRace(player) != RaceType.Dragonborn)
			{
				return 0f;
			}
			if (!TrinketBonusRegistry.GetEquippedBonus(player).OceanArmor)
			{
				return 0f;
			}
			return 30f;
		}

		public static float GetUnarmedDamage(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return 10f;
			}
			float skillFactor = ((Character)player).GetSkillFactor((SkillType)11);
			return 10f + skillFactor * 20f;
		}

		public static float GetBreathElementDamage(Player player)
		{
			return GetUnarmedDamage(player) + TrinketBonusRegistry.GetEquippedBonus(player).ElementDamage;
		}

		private static void SpawnElementFx(BreathElement element, Vector3 origin, Vector3 direction)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)ZNetScene.instance == (Object)null))
			{
				float[] array = new float[3] { 1.5f, 3.5f, 5.5f };
				foreach (float num in array)
				{
					SpawnFxBurst(element, origin + direction * num, direction);
				}
			}
		}

		private static void SpawnFxBurst(BreathElement element, Vector3 position, Vector3 direction)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if (!ElementFxPrefabs.TryGetValue(element, out var value))
			{
				return;
			}
			string[] array = value;
			foreach (string text in array)
			{
				GameObject prefab = ZNetScene.instance.GetPrefab(text);
				if (!((Object)(object)prefab == (Object)null))
				{
					ScheduleFxCleanup(Object.Instantiate<GameObject>(prefab, position, Quaternion.LookRotation(direction)));
					break;
				}
			}
		}

		private static void ScheduleFxCleanup(GameObject instance)
		{
			if (!((Object)(object)instance == (Object)null))
			{
				TimedDestruction component = instance.GetComponent<TimedDestruction>();
				if ((Object)(object)component != (Object)null)
				{
					component.m_timeout = 1f;
					component.Trigger();
				}
				else
				{
					Object.Destroy((Object)(object)instance, 1f);
				}
			}
		}
	}
	internal static class DragonbornBreathInput
	{
		public static bool IsBlockHeld()
		{
			if (!ZInput.GetButton("Block") && !ZInput.GetButton("SecondaryAttack") && !ZInput.GetButton("Guard"))
			{
				return Input.GetMouseButton(1);
			}
			return true;
		}

		public static bool IsAttackHeld()
		{
			if (!ZInput.GetButton("Attack"))
			{
				return Input.GetMouseButton(0);
			}
			return true;
		}

		public static bool IsAttackPressed()
		{
			if (!ZInput.GetButtonDown("Attack"))
			{
				return Input.GetMouseButtonDown(0);
			}
			return true;
		}

		public static bool AreBreathButtonsHeld()
		{
			if (IsBlockHeld())
			{
				return IsAttackHeld();
			}
			return false;
		}

		public static bool IsUnarmed(Player player)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Invalid comparison between Unknown and I4
			ItemData val = ((player != null) ? ((Humanoid)player).GetCurrentWeapon() : null);
			if (val?.m_shared == null)
			{
				return true;
			}
			return (int)val.m_shared.m_skillType == 11;
		}

		public static bool ShouldSuppressTowerShieldBlock(Player player)
		{
			if ((Object)(object)player == (Object)null || !AreBreathButtonsHeld())
			{
				return false;
			}
			if (RaceManager.GetRace(player) != RaceType.Dragonborn)
			{
				return ElfTypeManager.IsHighElf(player);
			}
			return true;
		}
	}
	internal static class DragonbornBreathCombat
	{
		private static readonly int BlockingAnimHash = ZSyncAnimation.GetHash("blocking");

		public static void CancelUnarmedAttack(Humanoid humanoid)
		{
			if (!((Object)(object)humanoid == (Object)null))
			{
				humanoid.m_currentAttack = null;
				if ((Object)(object)((Character)humanoid).m_zanim != (Object)null)
				{
					((Character)humanoid).m_zanim.SetBool("attack", false);
				}
			}
		}

		public static void ForceBlockDown(Humanoid humanoid)
		{
			if (!((Object)(object)humanoid == (Object)null))
			{
				((Character)humanoid).m_blocking = false;
				humanoid.m_blockTimer = 0f;
				if ((Object)(object)((Character)humanoid).m_zanim != (Object)null)
				{
					((Character)humanoid).m_zanim.SetBool(BlockingAnimHash, false);
				}
				if ((Object)(object)((Character)humanoid).m_nview != (Object)null && ((Character)humanoid).m_nview.IsValid())
				{
					((Character)humanoid).m_nview.GetZDO().Set(ZDOVars.s_isBlockingHash, false);
				}
				Traverse.Create((object)humanoid).Field("m_internalBlockingState").SetValue((object)false);
			}
		}

		public static void RefreshTowerShieldBlockVisual(Player player)
		{
			if ((Object)(object)player == (Object)null || !DragonbornShieldHelper.HasTowerShieldEquipped((Humanoid)(object)player) || !DragonbornBreathInput.IsBlockHeld() || DragonbornBreathInput.ShouldSuppressTowerShieldBlock(player))
			{
				return;
			}
			((Character)player).m_blocking = true;
			if (((Character)player).IsBlocking())
			{
				if ((Object)(object)((Character)player).m_zanim != (Object)null)
				{
					((Character)player).m_zanim.SetBool(BlockingAnimHash, true);
				}
				if ((Object)(object)((Character)player).m_nview != (Object)null && ((Character)player).m_nview.IsValid())
				{
					((Character)player).m_nview.GetZDO().Set(ZDOVars.s_isBlockingHash, true);
				}
				Traverse.Create((object)player).Field("m_internalBlockingState").SetValue((object)true);
			}
		}
	}
	internal static class DragonbornShieldHelper
	{
		private static readonly string[] TowerShieldPrefabNames = new string[6] { "ShieldWoodTower", "ShieldBoneTower", "ShieldIronTower", "ShieldBlackmetalTower", "ShieldFlametalTower", "ShieldSerpentscale" };

		public static ItemData GetEquippedShield(Humanoid humanoid)
		{
			if ((Object)(object)humanoid == (Object)null)
			{
				return null;
			}
			ItemData currentBlocker = humanoid.GetCurrentBlocker();
			if (currentBlocker != null)
			{
				return currentBlocker;
			}
			return humanoid.GetLeftItem();
		}

		public static bool HasTowerShieldEquipped(Humanoid humanoid)
		{
			return IsTowerShield(GetEquippedShield(humanoid));
		}

		public static bool IsTowerShield(ItemData shield)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Invalid comparison between Unknown and I4
			if (shield?.m_shared == null)
			{
				return false;
			}
			if ((int)shield.m_shared.m_itemType != 5)
			{
				return false;
			}
			string text = (((Object)(object)shield.m_dropPrefab != (Object)null) ? ((Object)shield.m_dropPrefab).name : string.Empty);
			string text2 = shield.m_shared.m_name ?? string.Empty;
			string[] towerShieldPrefabNames = TowerShieldPrefabNames;
			foreach (string value in towerShieldPrefabNames)
			{
				if (text.Equals(value, StringComparison.OrdinalIgnoreCase) || text2.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return true;
				}
			}
			if (text.IndexOf("Tower", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("tower", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return true;
			}
			if (text.IndexOf("Serpentscale", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return text2.IndexOf("serpentscale", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return true;
		}
	}
	internal static class DrowShadowArmor
	{
		private const float ArmorPerHit = 3f;

		private const float DurationSeconds = 5f;

		private static float _stackedArmor;

		private static float _expiresAt;

		public static void TriggerOnHit(Player player)
		{
			if (!((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && ElfTypeManager.IsDrow(player))
			{
				if (Time.time >= _expiresAt)
				{
					_stackedArmor = 0f;
				}
				_stackedArmor += 3f;
				_expiresAt = Time.time + 5f;
			}
		}

		public static float GetArmorBonus(Player player)
		{
			if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || !ElfTypeManager.IsDrow(player))
			{
				return 0f;
			}
			if (Time.time >= _expiresAt)
			{
				_stackedArmor = 0f;
				return 0f;
			}
			return _stackedArmor;
		}
	}
	internal static class DwarfCrater
	{
		private const float Radius = 1f;

		private const float Depth = 0.35f;

		private static readonly MethodInfo DoOperationMethod = AccessTools.Method(typeof(TerrainComp), "DoOperation", new Type[2]
		{
			typeof(Vector3),
			typeof(Settings)
		}, (Type[])null);

		public static void TryOnHit(Player attacker, Character target)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Expected O, but got Unknown
			//IL_00f7: 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_010a: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)attacker == (Object)null) && !((Object)(object)target == (Object)null) && !((Object)(object)attacker != (Object)(object)Player.m_localPlayer) && RaceManager.GetRace(attacker) == RaceType.Dwarf && Input.GetMouseButton(2))
			{
				Vector3 position = ((Component)target).transform.position;
				float num = (((Object)(object)ZoneSystem.instance != (Object)null) ? ZoneSystem.instance.GetGroundHeight(position) : position.y);
				object obj = TerrainComp.FindTerrainCompiler(position);
				if (obj == null)
				{
					Heightmap obj2 = Heightmap.FindHeightmap(position);
					obj = ((obj2 != null) ? obj2.GetAndCreateTerrainCompiler() : null);
				}
				TerrainComp val = (TerrainComp)obj;
				if (!((Object)(object)val == (Object)null) && !(DoOperationMethod == null))
				{
					Settings val2 = new Settings
					{
						m_level = true,
						m_levelRadius = 1f,
						m_levelOffset = 0f,
						m_square = false,
						m_raise = false,
						m_smooth = true,
						m_smoothRadius = 1.35f,
						m_smoothPower = 3f,
						m_paintCleared = false
					};
					DoOperationMethod.Invoke(val, new object[2]
					{
						(object)new Vector3(position.x, num - 0.35f, position.z),
						val2
					});
				}
			}
		}
	}
	internal static class ElementResistance
	{
		public static DamageType ToDamageType(BreathElement element)
		{
			//IL_001b: 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_0028: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			return (DamageType)(element switch
			{
				BreathElement.Poison => 256, 
				BreathElement.Lightning => 128, 
				BreathElement.Ice => 64, 
				_ => 32, 
			});
		}

		public static void SetElementDamage(HitData hit, BreathElement element, float amount)
		{
			if (hit != null)
			{
				hit.m_damage.m_damage = 0f;
				hit.m_damage.m_blunt = 0f;
				hit.m_damage.m_slash = 0f;
				hit.m_damage.m_pierce = 0f;
				hit.m_damage.m_fire = 0f;
				hit.m_damage.m_frost = 0f;
				hit.m_damage.m_lightning = 0f;
				hit.m_damage.m_poison = 0f;
				hit.m_damage.m_spirit = 0f;
				switch (element)
				{
				case BreathElement.Poison:
					hit.m_damage.m_poison = amount;
					break;
				case BreathElement.Fire:
					hit.m_damage.m_fire = amount;
					break;
				case BreathElement.Lightning:
					hit.m_damage.m_lightning = amount;
					break;
				case BreathElement.Ice:
					hit.m_damage.m_frost = amount;
					break;
				default:
					hit.m_damage.m_damage = amount;
					break;
				}
			}
		}

		public static void MultiplyElementDamage(ref HitData hit, BreathElement element, float multiplier)
		{
			if (hit != null && !(multiplier <= 1f))
			{
				switch (element)
				{
				case BreathElement.Poison:
					hit.m_damage.m_poison *= multiplier;
					break;
				case BreathElement.Fire:
					hit.m_damage.m_fire *= multiplier;
					break;
				case BreathElement.Lightning:
					hit.m_damage.m_lightning *= multiplier;
					break;
				case BreathElement.Ice:
					hit.m_damage.m_frost *= multiplier;
					break;
				default:
					hit.m_damage.m_damage *= multiplier;
					break;
				}
			}
		}

		public static float GetResistancePercent(Player player, BreathElement element)
		{
			//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_004e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null)
			{
				return 0f;
			}
			DamageType damageType = ToDamageType(element);
			float num = 0f;
			if (((Humanoid)player).GetInventory() != null)
			{
				foreach (ItemData equippedItem in ((Humanoid)player).GetInventory().GetEquippedItems())
				{
					if (equippedItem?.m_shared != null)
					{
						float itemResistanceModifier = GetItemResistanceModifier(equippedItem, damageType);
						if (itemResistanceModifier > 0f)
						{
							num += itemResistanceModifier;
						}
					}
				}
			}
			num += GetStatusEffectResistance(player, element);
			return Mathf.Max(0f, num);
		}

		private static float GetItemResistanceModifier(ItemData item, DamageType damageType)
		{
			//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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			if (item.m_shared.m_damageModifiers == null)
			{
				return num;
			}
			foreach (DamageModPair damageModifier in item.m_shared.m_damageModifiers)
			{
				if (damageModifier.m_type == damageType)
				{
					num += DamageModifierToResistPercent(damageModifier.m_modifier);
				}
			}
			return num;
		}

		private static float DamageModifierToResistPercent(DamageModifier modifier)
		{
			//IL_0000: 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_0024: Expected I4, but got Unknown
			return (modifier - 1) switch
			{
				6 => 25f, 
				0 => 50f, 
				4 => 75f, 
				2 => 100f, 
				3 => 100f, 
				_ => 0f, 
			};
		}

		private static float GetStatusEffectResistance(Player player, BreathElement element)
		{
			SEMan sEMan = ((Character)player).GetSEMan();
			if (sEMan == null)
			{
				return 0f;
			}
			switch (element)
			{
			case BreathElement.Fire:
			{
				float num = 0f;
				if (sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("Potion_barleywine")))
				{
					num += 50f;
				}
				if (sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("SetEffect_WolfArmor")))
				{
					num += 20f;
				}
				if (sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("SetEffect_FenringArmor")))
				{
					num += 25f;
				}
				return num;
			}
			case BreathElement.Poison:
				if (sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("Potion_poisonresist")))
				{
					return 50f;
				}
				return 0f;
			case BreathElement.Ice:
				if (sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("SetEffect_WolfArmor")))
				{
					return 20f;
				}
				return 0f;
			default:
				return 0f;
			}
		}
	}
	public static class ElfTypeManager
	{
		private const string CustomElfTypeKey = "Ent1ty303.ElfType";

		public static ElfType GetElfType(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return ElfType.High;
			}
			if (PlayerDataStore.TryGetInt(player, "Ent1ty303.ElfType", out var value) && Enum.IsDefined(typeof(ElfType), value))
			{
				return (ElfType)value;
			}
			return ElfType.High;
		}

		public static bool TrySetElfType(Player player, ElfType elfType, out string message)
		{
			message = null;
			if ((Object)(object)player == (Object)null)
			{
				message = "Load a character first.";
				return false;
			}
			if (RaceManager.GetRace(player) != RaceType.Elf)
			{
				message = "Only Elves can choose a lineage.";
				return false;
			}
			PlayerDataStore.SetInt(player, "Ent1ty303.ElfType", (int)elfType);
			message = elfType switch
			{
				ElfType.High => "Sunfire answers you. RMB+LMB unarmed fires a wide light beam.", 
				ElfType.Wood => "The forest claims you. Free run stamina; near trees you fade — bows bite deep.", 
				ElfType.Drow => "The Underdark smiles. Free sneak stamina; night and poison listen.", 
				_ => $"Lineage set to {elfType}.", 
			};
			if (((Character)player).IsOwner())
			{
				((Character)player).Message((MessageType)2, message, 0, (Sprite)null);
			}
			return true;
		}

		public static ElfType ParseElfType(string value)
		{
			if (string.IsNullOrWhiteSpace(value))
			{
				return ElfType.High;
			}
			string text = value.Trim().ToLowerInvariant();
			if (text != null)
			{
				int length = text.Length;
				if (length != 4)
				{
					if (length == 7)
					{
						char c = text[0];
						if (c != 'd')
						{
							if (c != 'h')
							{
								if (c == 'w' && text == "woodelf")
								{
									goto IL_00eb;
								}
							}
							else if (text == "highelf")
							{
								goto IL_00e7;
							}
						}
						else if (text == "darkelf")
						{
							goto IL_00ef;
						}
					}
				}
				else
				{
					char c = text[1];
					if ((uint)c <= 105u)
					{
						if (c != 'a')
						{
							if (c == 'i' && text == "high")
							{
								goto IL_00e7;
							}
						}
						else if (text == "dark")
						{
							goto IL_00ef;
						}
					}
					else if (c != 'o')
					{
						if (c == 'r' && text == "drow")
						{
							goto IL_00ef;
						}
					}
					else if (text == "wood")
					{
						goto IL_00eb;
					}
				}
			}
			ElfType result;
			return Enum.TryParse<ElfType>(value, ignoreCase: true, out result) ? result : ElfType.High;
			IL_00eb:
			return ElfType.Wood;
			IL_00ef:
			return ElfType.Drow;
			IL_00e7:
			return ElfType.High;
		}

		public static bool IsHighElf(Player player)
		{
			if (RaceManager.GetRace(player) == RaceType.Elf)
			{
				return GetElfType(player) == ElfType.High;
			}
			return false;
		}

		public static bool IsWoodElf(Player player)
		{
			if (RaceManager.GetRace(player) == RaceType.Elf)
			{
				return GetElfType(player) == ElfType.Wood;
			}
			return false;
		}

		public static bool IsDrow(Player player)
		{
			if (RaceManager.GetRace(player) == RaceType.Elf)
			{
				return GetElfType(player) == ElfType.Drow;
			}
			return false;
		}
	}
	internal class FrostAuraFollower : MonoBehaviour
	{
		private Character _target;

		private float _hardExpireAt;

		public static void Attach(Character target, float maxSeconds = 8f)
		{
			//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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)target == (Object)null))
			{
				FrostAuraFollower componentInChildren = ((Component)target).GetComponentInChildren<FrostAuraFollower>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					componentInChildren._hardExpireAt = Time.time + maxSeconds;
					componentInChildren.RefreshParticles();
					return;
				}
				GameObject val = new GameObject("Ent1tyRaces_FrostAura");
				val.transform.SetParent(((Component)target).transform, false);
				val.transform.localPosition = Vector3.up * (target.GetHeight() * 0.45f);
				FrostAuraFollower frostAuraFollower = val.AddComponent<FrostAuraFollower>();
				frostAuraFollower._target = target;
				frostAuraFollower._hardExpireAt = Time.time + maxSeconds;
				frostAuraFollower.BuildParticles();
			}
		}

		private void RefreshParticles()
		{
			ParticleSystem component = ((Component)this).GetComponent<ParticleSystem>();
			if ((Object)(object)component != (Object)null && !component.isPlaying)
			{
				component.Play();
			}
		}

		private void BuildParticles()
		{
			//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_0021: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Expected O, but got Unknown
			ParticleSystem obj = ((Component)this).gameObject.AddComponent<ParticleSystem>();
			MainModule main = obj.main;
			((MainModule)(ref main)).loop = true;
			((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(1.1f);
			((MainModule)(ref main)).startSpeed = new MinMaxCurve(0.15f, 0.55f);
			((MainModule)(ref main)).startSize = new MinMaxCurve(0.08f, 0.22f);
			((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(0.75f, 0.92f, 1f, 0.75f), new Color(0.45f, 0.75f, 1f, 0.35f));
			((MainModule)(ref main)).maxParticles = 48;
			((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1;
			((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(-0.05f);
			EmissionModule emission = obj.emission;
			((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(22f);
			ShapeModule shape = obj.shape;
			((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0;
			((ShapeModule)(ref shape)).radius = Mathf.Max(0.45f, ((Object)(object)_target != (Object)null) ? (_target.GetRadius() * 0.9f) : 0.6f);
			ParticleSystemRenderer component = ((Component)this).gameObject.GetComponent<ParticleSystemRenderer>();
			if ((Object)(object)component != (Object)null)
			{
				Shader val = Shader.Find("Particles/Standard Unlit") ?? Shader.Find("Particles/Additive") ?? Shader.Find("Sprites/Default");
				if ((Object)(object)val != (Object)null)
				{
					((Renderer)component).material = new Material(val);
				}
			}
		}

		private void LateUpdate()
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_target == (Object)nu