Decompiled source of EntityRaces v2.3.5

plugins\Ent1tyRaces.dll

Decompiled 21 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using System.Text;
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.EventSystems;
using UnityEngine.Events;
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.3.5")]
	[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.3.5";

		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.3.5 loaded OK. Create: race/type/legacy/breath | Admin: /race /type /legacy /breath (devcommands)");
		}

		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 static class CharacterCreateRaceUI
	{
		private static GameObject _root;

		private static TMP_Dropdown _dropdown;

		private static GameObject _subtypeRoot;

		private static TMP_Text _subtypeLabel;

		private static TMP_Dropdown _subtypeDropdown;

		private static TMP_Text _hoverText;

		private static GameObject _hoverPanel;

		private static bool _suppressChange;

		private static bool _suppressSubtypeChange;

		private static RaceType _pendingRace = RaceType.Human;

		private static string _pendingSubtype = string.Empty;

		private static readonly List<RaceType> Options = new List<RaceType>();

		private static readonly List<string> SubtypeKeys = new List<string>();

		private static readonly Color DecayedGold = RaceUiSkin.DecayedGold;

		private static GameObject _raceRow;

		private static Image _rootPlate;

		private const string UiBuildTag = "Ent1tyRaces_CharacterRaceCreate_v6";

		public static RaceType PendingRace => _pendingRace;

		public static void ShowForCreation()
		{
			FejdStartup instance = FejdStartup.instance;
			if (!((Object)(object)instance == (Object)null))
			{
				GameObject newCharacterPanel = instance.m_newCharacterPanel;
				if ((Object)(object)newCharacterPanel == (Object)null || !newCharacterPanel.activeInHierarchy)
				{
					Hide();
					return;
				}
				_pendingRace = RaceType.Human;
				_pendingSubtype = string.Empty;
				EnsureUi(newCharacterPanel.transform);
				PositionBelowHairTone(newCharacterPanel.transform);
				RefreshDropdown();
				RefreshSubtypeUi();
			}
		}

		public static void Hide()
		{
			if ((Object)(object)_root != (Object)null)
			{
				_root.SetActive(false);
			}
			HideHover();
		}

		public static void ApplyPendingToPreview(Player preview)
		{
			if (!((Object)(object)preview == (Object)null))
			{
				RaceManager.ApplyRaceForNewCharacter(preview, _pendingRace);
				if (NeedsSubtype(_pendingRace) && !string.IsNullOrEmpty(_pendingSubtype))
				{
					RaceManager.ApplySubtypeForNewCharacter(preview, _pendingRace, _pendingSubtype);
				}
			}
		}

		public static void LockAndPersistIfNeeded()
		{
			FejdStartup instance = FejdStartup.instance;
			if ((Object)(object)instance == (Object)null || ((Object)(object)instance.m_newCharacterPanel != (Object)null && instance.m_newCharacterPanel.activeInHierarchy))
			{
				return;
			}
			Player previewPlayer = instance.GetPreviewPlayer();
			if ((Object)(object)previewPlayer == (Object)null || RaceManager.IsRaceChoiceLocked(previewPlayer))
			{
				Hide();
				return;
			}
			RaceManager.LockRaceChoice(previewPlayer);
			List<PlayerProfile> value = Traverse.Create((object)instance).Field("m_profiles").GetValue<List<PlayerProfile>>();
			int value2 = Traverse.Create((object)instance).Field("m_profileIndex").GetValue<int>();
			if (value != null && value2 >= 0 && value2 < value.Count)
			{
				PlayerProfile obj = value[value2];
				obj.SavePlayerData(previewPlayer);
				obj.Save();
			}
			Hide();
		}

		public static bool NeedsSubtype(RaceType race)
		{
			switch (race)
			{
			case RaceType.Dragonborn:
			case RaceType.Elf:
			case RaceType.Giant:
			case RaceType.Genasi:
			case RaceType.Gnome:
			case RaceType.Tiefling:
				return true;
			default:
				return false;
			}
		}

		private static void PositionBelowHairTone(Transform panel)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_0108: 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_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: 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_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_root == (Object)null))
			{
				RectTransform component = _root.GetComponent<RectTransform>();
				float num = (NeedsSubtype(_pendingRace) ? 88f : 44f);
				component.sizeDelta = new Vector2(Mathf.Max(component.sizeDelta.x, 340f), num);
				PlayerCustomizaton componentInChildren = ((Component)panel).GetComponentInChildren<PlayerCustomizaton>(true);
				Slider val = (((Object)(object)componentInChildren != (Object)null) ? componentInChildren.m_hairTone : null);
				if ((Object)(object)val == (Object)null)
				{
					((Transform)component).SetParent(panel, false);
					component.anchorMin = new Vector2(0.5f, 0f);
					component.anchorMax = new Vector2(0.5f, 0f);
					component.pivot = new Vector2(0.5f, 0f);
					component.anchoredPosition = new Vector2(0f, 100f);
					return;
				}
				Transform transform = ((Component)val).transform;
				RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
				Transform val3 = (((Object)(object)((Transform)val2).parent != (Object)null) ? ((Transform)val2).parent : panel);
				((Transform)component).SetParent(val3, false);
				component.anchorMin = val2.anchorMin;
				component.anchorMax = val2.anchorMax;
				component.pivot = new Vector2(0.5f, 1f);
				component.sizeDelta = new Vector2(Mathf.Max(val2.sizeDelta.x, 340f), num);
				float num2 = 52f;
				float y = val2.anchoredPosition.y;
				Rect rect = val2.rect;
				float num3 = y - ((Rect)(ref rect)).height - num2;
				component.anchoredPosition = new Vector2(val2.anchoredPosition.x, num3);
				((Transform)component).SetAsLastSibling();
			}
		}

		private static void EnsureUi(Transform parent)
		{
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_00d0: 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_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Expected O, but got Unknown
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Expected O, but got Unknown
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_030c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_0336: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0370: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_root != (Object)null && ((Object)_root).name != "Ent1tyRaces_CharacterRaceCreate_v6")
			{
				Object.Destroy((Object)(object)_root);
				_root = null;
				_dropdown = null;
				_subtypeRoot = null;
				_subtypeDropdown = null;
				_subtypeLabel = null;
				_hoverPanel = null;
				_hoverText = null;
				_raceRow = null;
				_rootPlate = null;
			}
			if ((Object)(object)_root != (Object)null)
			{
				_root.SetActive(true);
				return;
			}
			TMP_FontAsset font = FindMenuFont(parent);
			_root = new GameObject("Ent1tyRaces_CharacterRaceCreate_v6", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			RectTransform component = _root.GetComponent<RectTransform>();
			((Transform)component).SetParent(parent, false);
			component.sizeDelta = new Vector2(340f, 44f);
			_rootPlate = _root.GetComponent<Image>();
			RaceUiSkin.ApplyPanel(_rootPlate);
			((Graphic)_rootPlate).raycastTarget = false;
			GameObject val = new GameObject("Rim", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			RectTransform component2 = val.GetComponent<RectTransform>();
			((Transform)component2).SetParent((Transform)(object)component, false);
			component2.anchorMin = Vector2.zero;
			component2.anchorMax = Vector2.one;
			component2.offsetMin = new Vector2(-4f, -4f);
			component2.offsetMax = new Vector2(4f, 4f);
			((Transform)component2).SetAsFirstSibling();
			RaceUiSkin.ApplyRim(val.GetComponent<Image>());
			((Graphic)val.GetComponent<Image>()).raycastTarget = false;
			_raceRow = new GameObject("RaceRow", new Type[1] { typeof(RectTransform) });
			RectTransform component3 = _raceRow.GetComponent<RectTransform>();
			((Transform)component3).SetParent((Transform)(object)component, false);
			component3.anchorMin = new Vector2(0f, 1f);
			component3.anchorMax = new Vector2(1f, 1f);
			component3.pivot = new Vector2(0.5f, 1f);
			component3.anchoredPosition = new Vector2(0f, -4f);
			component3.sizeDelta = new Vector2(-20f, 36f);
			CreateLabel(component3, "Label", "Race", new Vector2(10f, 0f), font, DecayedGold);
			GameObject obj = BuildDropdownSkeleton(component3, "RaceDropdown", font, out _dropdown);
			PopulateRaceOptions();
			((UnityEvent<int>)(object)_dropdown.onValueChanged).AddListener((UnityAction<int>)OnRaceChanged);
			BuildHoverPanel(component, font);
			obj.AddComponent<RaceDropdownHoverHook>().Bind(_dropdown, ShowRaceHover, HideHover);
			_subtypeRoot = new GameObject("SubtypeRow", new Type[1] { typeof(RectTransform) });
			RectTransform component4 = _subtypeRoot.GetComponent<RectTransform>();
			((Transform)component4).SetParent((Transform)(object)component, false);
			component4.anchorMin = new Vector2(0f, 1f);
			component4.anchorMax = new Vector2(1f, 1f);
			component4.pivot = new Vector2(0.5f, 1f);
			component4.anchoredPosition = new Vector2(0f, -44f);
			component4.sizeDelta = new Vector2(-20f, 36f);
			_subtypeLabel = CreateLabel(component4, "SubtypeLabel", "Type", new Vector2(10f, 0f), font, DecayedGold);
			GameObject obj2 = BuildDropdownSkeleton(component4, "SubtypeDropdown", font, out _subtypeDropdown);
			((UnityEvent<int>)(object)_subtypeDropdown.onValueChanged).AddListener((UnityAction<int>)OnSubtypeChanged);
			obj2.AddComponent<SubtypeDropdownHoverHook>().Bind(_subtypeDropdown, () => _pendingRace, () => SubtypeKeys, ShowSubtypeHover, HideHover);
			_subtypeRoot.SetActive(false);
		}

		private static TMP_Text CreateLabel(RectTransform parent, string name, string text, Vector2 anchored, TMP_FontAsset font, Color color, float width = 88f)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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)
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			RectTransform component = val.GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)parent, false);
			component.anchorMin = new Vector2(0f, 0.5f);
			component.anchorMax = new Vector2(0f, 0.5f);
			component.pivot = new Vector2(0f, 0.5f);
			component.anchoredPosition = anchored;
			component.sizeDelta = new Vector2(width, 32f);
			TMP_Text val2 = (TMP_Text)(object)val.AddComponent<TextMeshProUGUI>();
			val2.text = text;
			val2.fontSize = 18f;
			val2.alignment = (TextAlignmentOptions)4097;
			((Graphic)val2).color = color;
			val2.enableWordWrapping = false;
			val2.overflowMode = (TextOverflowModes)0;
			if ((Object)(object)font != (Object)null)
			{
				val2.font = font;
			}
			return val2;
		}

		private static GameObject BuildDropdownSkeleton(RectTransform parent, string name, TMP_FontAsset font, out TMP_Dropdown dropdown)
		{
			//IL_0000: 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_002c: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = DefaultControls.CreateDropdown(GetDefaultResources());
			((Object)val).name = name;
			RectTransform component = val.GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)parent, false);
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.offsetMin = new Vector2(102f, 0f);
			component.offsetMax = Vector2.zero;
			Object.DestroyImmediate((Object)(object)val.GetComponent<Dropdown>());
			Text[] componentsInChildren = val.GetComponentsInChildren<Text>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
			dropdown = val.AddComponent<TMP_Dropdown>();
			WireTmpDropdownParts(val, dropdown, font);
			PaintParchment(val);
			return val;
		}

		private static void PaintParchment(GameObject dropGo)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			Image[] componentsInChildren = dropGo.GetComponentsInChildren<Image>(true);
			foreach (Image val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string name = ((Object)((Component)val).gameObject).name;
					if (name.Contains("Arrow") || name.Contains("Checkmark") || name.Contains("Item Checkmark"))
					{
						val.sprite = RaceUiSkin.BrassField;
						((Graphic)val).color = DecayedGold;
						val.type = (Type)0;
					}
					else if (name.Contains("Item") && !name.Contains("Label"))
					{
						RaceUiSkin.ApplyField(val);
						((Graphic)val).color = new Color(0.75f, 0.65f, 0.45f, 1f);
					}
					else
					{
						RaceUiSkin.ApplyField(val);
					}
				}
			}
		}

		private static void WireTmpDropdownParts(GameObject dropGo, TMP_Dropdown dropdown, TMP_FontAsset font)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: 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_011b: Unknown result type (might be due to invalid IL or missing references)
			Transform val = dropGo.transform.Find("Label");
			if ((Object)(object)val != (Object)null)
			{
				TMP_Text val2 = (TMP_Text)(object)(((Component)val).gameObject.GetComponent<TextMeshProUGUI>() ?? ((Component)val).gameObject.AddComponent<TextMeshProUGUI>());
				val2.fontSize = 18f;
				((Graphic)val2).color = DecayedGold;
				val2.alignment = (TextAlignmentOptions)4097;
				if ((Object)(object)font != (Object)null)
				{
					val2.font = font;
				}
				dropdown.captionText = val2;
			}
			Transform val3 = dropGo.transform.Find("Template/Viewport/Content/Item/Item Label");
			if ((Object)(object)val3 != (Object)null)
			{
				TMP_Text val4 = (TMP_Text)(object)(((Component)val3).gameObject.GetComponent<TextMeshProUGUI>() ?? ((Component)val3).gameObject.AddComponent<TextMeshProUGUI>());
				val4.fontSize = 17f;
				((Graphic)val4).color = DecayedGold;
				if ((Object)(object)font != (Object)null)
				{
					val4.font = font;
				}
				dropdown.itemText = val4;
			}
			Transform val5 = dropGo.transform.Find("Template");
			if ((Object)(object)val5 != (Object)null)
			{
				RectTransform val6 = (dropdown.template = (RectTransform)(object)((val5 is RectTransform) ? val5 : null));
				if ((Object)(object)val6 != (Object)null)
				{
					val6.sizeDelta = new Vector2(val6.sizeDelta.x, 180f);
				}
				ScrollRect component = ((Component)val5).GetComponent<ScrollRect>();
				if ((Object)(object)component != (Object)null)
				{
					component.scrollSensitivity = 45f;
					component.movementType = (MovementType)2;
					component.inertia = true;
				}
				((Component)val5).gameObject.SetActive(false);
			}
		}

		private static void BuildHoverPanel(RectTransform rootRt, TMP_FontAsset font)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_004d: 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_0077: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: 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_010f: 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_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			_hoverPanel = new GameObject("RaceHoverPanel", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			RectTransform component = _hoverPanel.GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)rootRt, false);
			component.anchorMin = new Vector2(1f, 1f);
			component.anchorMax = new Vector2(1f, 1f);
			component.pivot = new Vector2(0f, 1f);
			component.anchoredPosition = new Vector2(14f, 0f);
			component.sizeDelta = new Vector2(420f, 160f);
			RaceUiSkin.ApplyPanel(_hoverPanel.GetComponent<Image>());
			((Graphic)_hoverPanel.GetComponent<Image>()).raycastTarget = false;
			GameObject val = new GameObject("HoverRim", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			RectTransform component2 = val.GetComponent<RectTransform>();
			((Transform)component2).SetParent((Transform)(object)component, false);
			component2.anchorMin = Vector2.zero;
			component2.anchorMax = Vector2.one;
			component2.offsetMin = new Vector2(-4f, -4f);
			component2.offsetMax = new Vector2(4f, 4f);
			((Transform)component2).SetAsFirstSibling();
			RaceUiSkin.ApplyRim(val.GetComponent<Image>());
			((Graphic)val.GetComponent<Image>()).raycastTarget = false;
			GameObject val2 = new GameObject("HoverText", new Type[1] { typeof(RectTransform) });
			RectTransform component3 = val2.GetComponent<RectTransform>();
			((Transform)component3).SetParent((Transform)(object)component, false);
			component3.anchorMin = Vector2.zero;
			component3.anchorMax = Vector2.one;
			component3.offsetMin = new Vector2(14f, 12f);
			component3.offsetMax = new Vector2(-14f, -12f);
			_hoverText = (TMP_Text)(object)val2.AddComponent<TextMeshProUGUI>();
			_hoverText.fontSize = 15f;
			_hoverText.alignment = (TextAlignmentOptions)257;
			((Graphic)_hoverText).color = DecayedGold;
			_hoverText.enableWordWrapping = true;
			_hoverText.overflowMode = (TextOverflowModes)0;
			((Graphic)_hoverText).raycastTarget = false;
			_hoverText.margin = Vector4.zero;
			if ((Object)(object)font != (Object)null)
			{
				_hoverText.font = font;
			}
			_hoverPanel.SetActive(false);
		}

		private static void PopulateRaceOptions()
		{
			Options.Clear();
			Options.AddRange(RaceManager.AllSelectableRaces);
			_dropdown.ClearOptions();
			List<string> list = new List<string>();
			foreach (RaceType option in Options)
			{
				list.Add(RaceManager.GetRacePrettyName(option));
			}
			_dropdown.AddOptions(list);
		}

		private static void RefreshDropdown()
		{
			if (!((Object)(object)_dropdown == (Object)null))
			{
				int num = Options.IndexOf(_pendingRace);
				if (num < 0)
				{
					num = 0;
					_pendingRace = Options[0];
				}
				_suppressChange = true;
				_dropdown.value = num;
				_dropdown.RefreshShownValue();
				_suppressChange = false;
				((Selectable)_dropdown).interactable = true;
				if ((Object)(object)_root != (Object)null)
				{
					_root.SetActive(true);
				}
			}
		}

		private static void RefreshSubtypeUi()
		{
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_subtypeRoot == (Object)null || (Object)(object)_subtypeDropdown == (Object)null)
			{
				return;
			}
			if (!NeedsSubtype(_pendingRace))
			{
				_subtypeRoot.SetActive(false);
				_pendingSubtype = string.Empty;
				if ((Object)(object)FejdStartup.instance != (Object)null)
				{
					PositionBelowHairTone(FejdStartup.instance.m_newCharacterPanel.transform);
				}
				return;
			}
			_subtypeRoot.SetActive(true);
			if ((Object)(object)_subtypeLabel != (Object)null)
			{
				TMP_Text subtypeLabel = _subtypeLabel;
				subtypeLabel.text = _pendingRace switch
				{
					RaceType.Tiefling => "Legacy", 
					RaceType.Dragonborn => "Breath", 
					_ => "Type", 
				};
				((Graphic)_subtypeLabel).color = DecayedGold;
			}
			SubtypeKeys.Clear();
			List<string> list = new List<string>();
			GetSubtypeOptions(_pendingRace, SubtypeKeys, list);
			_suppressSubtypeChange = true;
			_subtypeDropdown.ClearOptions();
			_subtypeDropdown.AddOptions(list);
			int num = Mathf.Max(0, SubtypeKeys.IndexOf(_pendingSubtype));
			if (string.IsNullOrEmpty(_pendingSubtype) || num < 0)
			{
				num = 0;
			}
			_pendingSubtype = SubtypeKeys[num];
			_subtypeDropdown.value = num;
			_subtypeDropdown.RefreshShownValue();
			_suppressSubtypeChange = false;
			if ((Object)(object)FejdStartup.instance != (Object)null)
			{
				PositionBelowHairTone(FejdStartup.instance.m_newCharacterPanel.transform);
			}
		}

		private static void GetSubtypeOptions(RaceType race, List<string> keys, List<string> labels)
		{
			switch (race)
			{
			case RaceType.Elf:
				keys.AddRange(new string[3] { "high", "wood", "drow" });
				labels.AddRange(new string[3] { "High", "Wood", "Drow" });
				break;
			case RaceType.Giant:
				keys.AddRange(new string[6] { "cloud", "fire", "frost", "hill", "stone", "storm" });
				labels.AddRange(new string[6] { "Cloud", "Fire", "Frost", "Hill", "Stone", "Storm" });
				break;
			case RaceType.Genasi:
				keys.AddRange(new string[4] { "air", "earth", "fire", "water" });
				labels.AddRange(new string[4] { "Air", "Earth", "Fire", "Water" });
				break;
			case RaceType.Gnome:
				keys.AddRange(new string[2] { "forest", "rock" });
				labels.AddRange(new string[2] { "Forest", "Rock" });
				break;
			case RaceType.Tiefling:
				keys.AddRange(new string[3] { "abyssal", "chthonic", "infernal" });
				labels.AddRange(new string[3] { "Abyssal", "Chthonic", "Infernal" });
				break;
			case RaceType.Dragonborn:
				keys.AddRange(new string[4] { "fire", "poison", "lightning", "ice" });
				labels.AddRange(new string[4] { "Fire", "Poison", "Lightning", "Ice" });
				break;
			case RaceType.Vampire:
			case RaceType.Aarakocra:
			case RaceType.Dwarf:
			case RaceType.Halfling:
			case RaceType.Orc:
				break;
			}
		}

		private static void OnRaceChanged(int index)
		{
			if (!_suppressChange && !((Object)(object)_dropdown == (Object)null) && index >= 0 && index < Options.Count)
			{
				_pendingRace = Options[index];
				_pendingSubtype = string.Empty;
				RefreshSubtypeUi();
				HideHover();
			}
		}

		private static void OnSubtypeChanged(int index)
		{
			if (!_suppressSubtypeChange && index >= 0 && index < SubtypeKeys.Count)
			{
				_pendingSubtype = SubtypeKeys[index];
			}
		}

		public static void ShowRaceHover(RaceType race)
		{
			ShowHoverText(RaceDescriptions.GetHoverText(race));
		}

		public static void ShowSubtypeHover(RaceType race, string subtypeKey)
		{
			ShowHoverText(RaceDescriptions.GetSubtypeHoverText(race, subtypeKey));
		}

		public static void ShowHover(RaceType race)
		{
			ShowRaceHover(race);
		}

		private static void ShowHoverText(string text)
		{
			//IL_0031: 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_0093: 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)
			if (!((Object)(object)_hoverPanel == (Object)null) && !((Object)(object)_hoverText == (Object)null))
			{
				RectTransform component = _hoverPanel.GetComponent<RectTransform>();
				component.anchoredPosition = new Vector2(14f, 0f);
				_hoverText.text = text ?? string.Empty;
				_hoverPanel.SetActive(true);
				Canvas.ForceUpdateCanvases();
				Rect rect = component.rect;
				float num = Mathf.Max(80f, ((Rect)(ref rect)).width - 28f);
				float num2 = Mathf.Clamp(_hoverText.GetPreferredValues(_hoverText.text, num, 0f).y + 28f, 120f, 520f);
				component.sizeDelta = new Vector2(420f, num2);
				ClampHoverOnScreen();
			}
		}

		private static void ClampHoverOnScreen()
		{
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_hoverPanel == (Object)null || (Object)(object)_root == (Object)null)
			{
				return;
			}
			RectTransform component = _hoverPanel.GetComponent<RectTransform>();
			Canvas componentInParent = _root.GetComponentInParent<Canvas>();
			if ((Object)(object)component == (Object)null || (Object)(object)componentInParent == (Object)null)
			{
				return;
			}
			Transform transform = ((Component)componentInParent).transform;
			RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			if (!((Object)(object)val == (Object)null))
			{
				Vector3[] array = (Vector3[])(object)new Vector3[4];
				component.GetWorldCorners(array);
				Vector3[] array2 = (Vector3[])(object)new Vector3[4];
				val.GetWorldCorners(array2);
				float num = 8f;
				float num2 = 0f;
				float num3 = 0f;
				if (array[2].x > array2[2].x - num)
				{
					num2 = array2[2].x - num - array[2].x;
				}
				if (array[0].x + num2 < array2[0].x + num)
				{
					num2 += array2[0].x + num - (array[0].x + num2);
				}
				if (array[0].y < array2[0].y + num)
				{
					num3 = array2[0].y + num - array[0].y;
				}
				if (Mathf.Abs(num2) > 0.5f || Mathf.Abs(num3) > 0.5f)
				{
					Vector3 val2 = ((Transform)component).parent.InverseTransformVector(new Vector3(num2, num3, 0f));
					component.anchoredPosition += new Vector2(val2.x, val2.y);
				}
			}
		}

		public static void HideHover()
		{
			if ((Object)(object)_hoverPanel != (Object)null)
			{
				_hoverPanel.SetActive(false);
			}
		}

		private static TMP_FontAsset FindMenuFont(Transform parent)
		{
			TMP_Text componentInChildren = ((Component)parent).GetComponentInChildren<TMP_Text>(true);
			if (!((Object)(object)componentInChildren != (Object)null))
			{
				return null;
			}
			return componentInChildren.font;
		}

		private static Resources GetDefaultResources()
		{
			//IL_001f: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			Texture2D whiteTexture = Texture2D.whiteTexture;
			Sprite val = Sprite.Create(whiteTexture, new Rect(0f, 0f, (float)((Texture)whiteTexture).width, (float)((Texture)whiteTexture).height), new Vector2(0.5f, 0.5f), 100f);
			return new Resources
			{
				standard = val,
				background = val,
				inputField = val,
				knob = val,
				checkmark = val,
				dropdown = val,
				mask = val
			};
		}
	}
	internal class RaceDropdownHoverHook : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
	{
		private TMP_Dropdown _dropdown;

		private Action<RaceType> _onHover;

		private Action _onExit;

		private bool _wired;

		public void Bind(TMP_Dropdown dropdown, Action<RaceType> onHover, Action onExit)
		{
			_dropdown = dropdown;
			_onHover = onHover;
			_onExit = onExit;
		}

		private void Update()
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			if ((Object)(object)_dropdown == (Object)null)
			{
				return;
			}
			Transform template = (Transform)(object)_dropdown.template;
			if ((Object)(object)template == (Object)null || !((Component)template).gameObject.activeInHierarchy)
			{
				_wired = false;
			}
			else
			{
				if (_wired)
				{
					return;
				}
				_wired = true;
				Transform val = template.Find("Viewport/Content");
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				RaceType[] allSelectableRaces = RaceManager.AllSelectableRaces;
				int num = 0;
				foreach (Transform item in val)
				{
					Transform val2 = item;
					if (((Object)val2).name.Contains("Item"))
					{
						RaceType race = ((num < allSelectableRaces.Length) ? allSelectableRaces[num] : RaceType.Human);
						num++;
						(((Component)val2).gameObject.GetComponent<RaceOptionHover>() ?? ((Component)val2).gameObject.AddComponent<RaceOptionHover>()).Setup(race, _onHover, _onExit);
					}
				}
			}
		}

		public void OnPointerEnter(PointerEventData eventData)
		{
			if (!((Object)(object)_dropdown == (Object)null) && ((Selectable)_dropdown).interactable)
			{
				int value = _dropdown.value;
				RaceType[] allSelectableRaces = RaceManager.AllSelectableRaces;
				if (value >= 0 && value < allSelectableRaces.Length)
				{
					_onHover?.Invoke(allSelectableRaces[value]);
				}
			}
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			TMP_Dropdown dropdown = _dropdown;
			if ((Object)(object)((dropdown != null) ? dropdown.template : null) == (Object)null || !((Component)_dropdown.template).gameObject.activeInHierarchy)
			{
				_onExit?.Invoke();
			}
		}
	}
	internal class RaceOptionHover : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
	{
		private RaceType _race;

		private Action<RaceType> _onHover;

		private Action _onExit;

		public void Setup(RaceType race, Action<RaceType> onHover, Action onExit)
		{
			_race = race;
			_onHover = onHover;
			_onExit = onExit;
		}

		public void OnPointerEnter(PointerEventData eventData)
		{
			_onHover?.Invoke(_race);
		}

		public void OnPointerExit(PointerEventData eventData)
		{
		}
	}
	internal class SubtypeDropdownHoverHook : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
	{
		private TMP_Dropdown _dropdown;

		private Func<RaceType> _getRace;

		private Func<List<string>> _getKeys;

		private Action<RaceType, string> _onHover;

		private Action _onExit;

		private bool _wired;

		public void Bind(TMP_Dropdown dropdown, Func<RaceType> getRace, Func<List<string>> getKeys, Action<RaceType, string> onHover, Action onExit)
		{
			_dropdown = dropdown;
			_getRace = getRace;
			_getKeys = getKeys;
			_onHover = onHover;
			_onExit = onExit;
		}

		private void Update()
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			if ((Object)(object)_dropdown == (Object)null)
			{
				return;
			}
			Transform template = (Transform)(object)_dropdown.template;
			if ((Object)(object)template == (Object)null || !((Component)template).gameObject.activeInHierarchy)
			{
				_wired = false;
			}
			else
			{
				if (_wired)
				{
					return;
				}
				_wired = true;
				Transform val = template.Find("Viewport/Content");
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				List<string> list = _getKeys?.Invoke() ?? new List<string>();
				int num = 0;
				foreach (Transform item in val)
				{
					Transform val2 = item;
					if (((Object)val2).name.Contains("Item"))
					{
						string key = ((num < list.Count) ? list[num] : string.Empty);
						num++;
						(((Component)val2).gameObject.GetComponent<SubtypeOptionHover>() ?? ((Component)val2).gameObject.AddComponent<SubtypeOptionHover>()).Setup(key, () => _getRace?.Invoke() ?? RaceType.Human, _onHover, _onExit);
					}
				}
			}
		}

		public void OnPointerEnter(PointerEventData eventData)
		{
			if (!((Object)(object)_dropdown == (Object)null) && ((Selectable)_dropdown).interactable)
			{
				List<string> list = _getKeys?.Invoke() ?? new List<string>();
				int value = _dropdown.value;
				if (value >= 0 && value < list.Count)
				{
					_onHover?.Invoke(_getRace?.Invoke() ?? RaceType.Human, list[value]);
				}
			}
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			TMP_Dropdown dropdown = _dropdown;
			if ((Object)(object)((dropdown != null) ? dropdown.template : null) == (Object)null || !((Component)_dropdown.template).gameObject.activeInHierarchy)
			{
				_onExit?.Invoke();
			}
		}
	}
	internal class SubtypeOptionHover : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
	{
		private string _key;

		private Func<RaceType> _getRace;

		private Action<RaceType, string> _onHover;

		private Action _onExit;

		public void Setup(string key, Func<RaceType> getRace, Action<RaceType, string> onHover, Action onExit)
		{
			_key = key;
			_getRace = getRace;
			_onHover = onHover;
			_onExit = onExit;
		}

		public void OnPointerEnter(PointerEventData eventData)
		{
			_onHover?.Invoke(_getRace?.Invoke() ?? RaceType.Human, _key);
		}

		public void OnPointerExit(PointerEventData eventData)
		{
		}
	}
	internal static class RaceUiSkin
	{
		public static readonly Color DecayedGold = new Color(0.82f, 0.62f, 0.28f, 1f);

		public static readonly Color DecayedGoldDim = new Color(0.55f, 0.4f, 0.14f, 1f);

		private static Sprite _iconSprite;

		private static Sprite _brassSprite;

		private static Sprite _panelSprite;

		private static bool _triedLoad;

		public static Sprite StonePanel
		{
			get
			{
				if (!((Object)(object)_panelSprite != (Object)null))
				{
					return _panelSprite = BuildStoneTile(256);
				}
				return _panelSprite;
			}
		}

		public static Sprite BrassField
		{
			get
			{
				if (!((Object)(object)_brassSprite != (Object)null))
				{
					return _brassSprite = BuildBrassTile(192);
				}
				return _brassSprite;
			}
		}

		public static Sprite IconAccent => EnsureIconLoaded();

		private static Sprite EnsureIconLoaded()
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			//IL_00d5: 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)
			if (_triedLoad)
			{
				return _iconSprite;
			}
			_triedLoad = true;
			try
			{
				string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? "";
				string[] array = new string[3]
				{
					Path.Combine(path, "icon.png"),
					Path.Combine(path, "..", "icon.png"),
					Path.Combine(path, "Ent1tyRaces", "icon.png")
				};
				for (int i = 0; i < array.Length; i++)
				{
					string fullPath = Path.GetFullPath(array[i]);
					if (File.Exists(fullPath))
					{
						byte[] bytes = File.ReadAllBytes(fullPath);
						Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
						if (TryLoadPng(val, bytes))
						{
							((Texture)val).wrapMode = (TextureWrapMode)1;
							((Texture)val).filterMode = (FilterMode)1;
							_iconSprite = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
							Logger.LogInfo((object)("Ent1tyRaces: UI skin loaded icon from " + fullPath));
							return _iconSprite;
						}
						Object.Destroy((Object)(object)val);
					}
				}
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("Ent1tyRaces: could not load icon.png for UI skin (" + ex.Message + ")"));
			}
			return null;
		}

		private static bool TryLoadPng(Texture2D tex, byte[] bytes)
		{
			try
			{
				MethodInfo methodInfo = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule")?.GetMethod("LoadImage", new Type[2]
				{
					typeof(Texture2D),
					typeof(byte[])
				});
				if (methodInfo == null)
				{
					return false;
				}
				return (bool)methodInfo.Invoke(null, new object[2] { tex, bytes });
			}
			catch
			{
				return false;
			}
		}

		private static Sprite BuildStoneTile(int size)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_0162: 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_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(size, size, (TextureFormat)4, false);
			((Texture)val).wrapMode = (TextureWrapMode)0;
			((Texture)val).filterMode = (FilterMode)1;
			Color[] array = (Color[])(object)new Color[size * size];
			Color val2 = default(Color);
			Color val3 = default(Color);
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					float num = FractalNoise((float)j * 0.09f, (float)i * 0.09f);
					float num2 = FractalNoise((float)j * 0.55f + 11f, (float)i * 0.55f + 3f);
					float num3 = FractalNoise((float)j * 0.21f + 20f, (float)i * 0.21f + 7f);
					float num4 = Mathf.Lerp(0.04f, 0.16f, num * 0.7f + num2 * 0.3f);
					float num5 = ((float)j - (float)size * 0.5f) / (float)size;
					float num6 = ((float)i - (float)size * 0.5f) / (float)size;
					float num7 = Mathf.Abs(Mathf.Sin(Mathf.Sqrt(num5 * num5 + num6 * num6) * 28f + num3));
					float num8 = Mathf.SmoothStep(0.92f, 1f, num7) * 0.04f;
					((Color)(ref val2))..ctor(num4 - num8, num4 * 0.96f - num8, num4 * 0.88f - num8, 1f);
					float num9 = Mathf.SmoothStep(0.68f, 0.9f, num3);
					((Color)(ref val3))..ctor(0.42f, 0.3f, 0.1f, 1f);
					array[i * size + j] = Color.Lerp(val2, val3, num9 * 0.18f);
				}
			}
			for (int k = 0; k < size; k++)
			{
				for (int l = 0; l < size; l++)
				{
					float num10 = (float)l / (float)(size - 1) * 2f - 1f;
					float num11 = (float)k / (float)(size - 1) * 2f - 1f;
					float num12 = Mathf.Max(Mathf.Abs(num10), Mathf.Abs(num11));
					float num13 = Mathf.SmoothStep(0.5f, 1f, num12) * 0.4f;
					Color val4 = array[k * size + l];
					val4.r *= 1f - num13;
					val4.g *= 1f - num13;
					val4.b *= 1f - num13;
					array[k * size + l] = val4;
				}
			}
			val.SetPixels(array);
			val.Apply(false, false);
			return Sprite.Create(val, new Rect(0f, 0f, (float)size, (float)size), new Vector2(0.5f, 0.5f), 100f);
		}

		private static Sprite BuildBrassTile(int size)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(size, size, (TextureFormat)4, false);
			((Texture)val).wrapMode = (TextureWrapMode)0;
			((Texture)val).filterMode = (FilterMode)1;
			Color[] array = (Color[])(object)new Color[size * size];
			Color val2 = default(Color);
			Color val3 = default(Color);
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					float num = FractalNoise((float)j * 0.13f, (float)i * 0.13f);
					float num2 = FractalNoise((float)j * 0.41f + 3f, (float)i * 0.41f + 9f);
					float num3 = FractalNoise((float)j * 0.9f, (float)i * 0.08f + 40f);
					((Color)(ref val2))..ctor(0.78f, 0.58f, 0.24f, 1f);
					((Color)(ref val3))..ctor(0.52f, 0.38f, 0.14f, 1f);
					Color val4 = Color.Lerp(new Color(0.22f, 0.15f, 0.05f, 1f), Color.Lerp(val3, val2, num), Mathf.Pow(num, 0.85f));
					if (num2 > 0.66f)
					{
						val4 = Color.Lerp(val4, new Color(0.08f, 0.06f, 0.02f, 1f), (num2 - 0.66f) * 2.8f);
					}
					if (num3 > 0.78f)
					{
						val4 = Color.Lerp(val4, val2, (num3 - 0.78f) * 1.2f);
					}
					array[i * size + j] = val4;
				}
			}
			val.SetPixels(array);
			val.Apply(false, false);
			return Sprite.Create(val, new Rect(0f, 0f, (float)size, (float)size), new Vector2(0.5f, 0.5f), 100f);
		}

		private static float FractalNoise(float x, float y)
		{
			float num = 0f;
			float num2 = 0.5f;
			float num3 = 1f;
			for (int i = 0; i < 5; i++)
			{
				num += num2 * Mathf.PerlinNoise(x * num3, y * num3);
				num3 *= 2.03f;
				num2 *= 0.5f;
			}
			return Mathf.Clamp01(num);
		}

		public static void ApplyPanel(Image image, bool useIconBackdrop = false)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)image == (Object)null))
			{
				Sprite val = (useIconBackdrop ? EnsureIconLoaded() : null);
				if ((Object)(object)val != (Object)null)
				{
					image.sprite = val;
					image.type = (Type)0;
					image.preserveAspect = false;
					((Graphic)image).color = new Color(0.45f, 0.4f, 0.32f, 0.98f);
				}
				else
				{
					image.sprite = StonePanel;
					image.type = (Type)2;
					image.pixelsPerUnitMultiplier = 1.15f;
					((Graphic)image).color = Color.white;
				}
			}
		}

		public static void ApplyField(Image image)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)image == (Object)null))
			{
				image.sprite = BrassField;
				image.type = (Type)2;
				image.pixelsPerUnitMultiplier = 1.25f;
				((Graphic)image).color = Color.white;
			}
		}

		public static void ApplyRim(Image image)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)image == (Object)null))
			{
				image.sprite = BrassField;
				image.type = (Type)2;
				image.pixelsPerUnitMultiplier = 0.9f;
				((Graphic)image).color = new Color(0.55f, 0.4f, 0.14f, 1f);
			}
		}
	}
	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_00de: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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.18f;
			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 = new Color(0.75f, 0.82f, 1f, 0.28f)
					};
				}
			}
			_light = _ball.AddComponent<Light>();
			_light.color = new Color(0.92f, 0.95f, 1f, 1f);
			_light.intensity = 4.2f;
			_light.range = 22f;
			_light.shadows = (LightShadows)0;
			Object.DontDestroyOnLoad((Object)(object)_ball);
		}
	}
	internal static class AasimarHealBreath
	{
		private const float AoeRadius = 4f;

		private const float AoeRange = 8f;

		private const float BreathCooldown = 1f;

		private static float _nextBreath;

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

		public static bool TryStartFromAttack(Player player)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0091: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: 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_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || RaceManager.GetRace(player) != RaceType.Aasimar)
			{
				return false;
			}
			if (!DragonbornBreathInput.AreBreathButtonsHeld())
			{
				return false;
			}
			if (Time.time < _nextBreath)
			{
				return true;
			}
			float breathElementDamage = DragonbornBreath.GetBreathElementDamage(player);
			if (breathElementDamage <= 0f)
			{
				return true;
			}
			float breathStaminaCostPublic = DragonbornBreath.GetBreathStaminaCostPublic(player);
			if (!((Character)player).HaveStamina(breathStaminaCostPublic + 0.1f))
			{
				((Character)player).Message((MessageType)2, "Not enough stamina to heal.", 0, (Sprite)null);
				return true;
			}
			DragonbornBreathCombat.ForceBlockDown((Humanoid)(object)player);
			DragonbornBreathCombat.CancelUnarmedAttack((Humanoid)(object)player);
			((Character)player).UseStamina(breathStaminaCostPublic);
			Vector3 eyePoint = ((Character)player).GetEyePoint();
			Vector3 lookDir = ((Character)player).GetLookDir();
			Vector3 val = eyePoint + lookDir * 4f;
			DragonbornBreath.SpawnBreathFx(BreathElement.Poison, eyePoint, lookDir);
			List<Character> list = new List<Character> { (Character)(object)player };
			List<Character> list2 = new List<Character>();
			Character.GetCharactersInRange(val, 4f, list2);
			foreach (Character item in list2)
			{
				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))
					{
						list.Add(item);
					}
				}
			}
			StartHealBurst(player, list, breathElementDamage);
			_nextBreath = Time.time + 1f;
			return true;
		}

		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 && DragonbornBreathInput.ShouldSuppressTowerShieldBlock(player))
			{
				DragonbornBreathCombat.ForceBlockDown((Humanoid)(object)player);
				if (DragonbornBreathInput.IsAttackPressed())
				{
					DragonbornBreathCombat.CancelUnarmedAttack((Humanoid)(object)player);
				}
			}
		}

		private static void StartHealBurst(Player caster, List<Character> targets, float totalHeal)
		{
			if ((Object)(object)Ent1tyRacesPlugin.Instance == (Object)null)
			{
				float amount = totalHeal / 5f;
				for (int i = 0; i < 5; i++)
				{
					ApplyHealTick(targets, amount);
				}
			}
			else
			{
				if (ActiveHeals.TryGetValue(caster, out var value) && value != null)
				{
					((MonoBehaviour)Ent1tyRacesPlugin.Instance).StopCoroutine(value);
				}
				ActiveHeals[caster] = ((MonoBehaviour)Ent1tyRacesPlugin.Instance).StartCoroutine(HealBurstRoutine(caster, targets, totalHeal));
			}
		}

		private static IEnumerator HealBurstRoutine(Player caster, List<Character> targets, float totalHeal)
		{
			try
			{
				float interval = 0.2f;
				float perTick = totalHeal / 5f;
				for (int tick = 0; tick < 5; tick++)
				{
					ApplyHealTick(targets, perTick);
					if (tick < 4)
					{
						yield return (object)new WaitForSeconds(interval);
					}
				}
			}
			finally
			{
				if ((Object)(object)caster != (Object)null)
				{
					ActiveHeals.Remove(caster);
				}
			}
		}

		private static void ApplyHealTick(List<Character> targets, float amount)
		{
			if (amount <= 0f || targets == null)
			{
				return;
			}
			foreach (Character target in targets)
			{
				if (!((Object)(object)target == (Object)null) && !target.IsDead())
				{
					target.Heal(amount, true);
				}
			}
		}
	}
	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;

		private static int _prevAlmanacJumpCount;

		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;
					_prevAlmanacJumpCount = 0;
				}
			}
		}

		public static void TryAlmanacCompatibleAirJump(Player player)
		{
			if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || RaceManager.GetRace(player) != RaceType.Aasimar)
			{
				return;
			}
			if (((Character)player).IsOnGround())
			{
				_airJumpsLeft = 1;
				_prevAlmanacJumpCount = AlmanacAirJumpBridge.GetJumpCount();
				return;
			}
			if (IsUnderwaterOrSwimming(player) || _airJumpsLeft <= 0)
			{
				_prevAlmanacJumpCount = AlmanacAirJumpBridge.GetJumpCount();
				return;
			}
			if (!ZInput.GetButtonDown("Jump") && !ZInput.GetButtonDown("JoyJump"))
			{
				_prevAlmanacJumpCount = AlmanacAirJumpBridge.GetJumpCount();
				return;
			}
			int jumpCount = AlmanacAirJumpBridge.GetJumpCount();
			int airBenderMaxJumps = AlmanacAirJumpBridge.GetAirBenderMaxJumps();
			if (jumpCount > _prevAlmanacJumpCount)
			{
				_prevAlmanacJumpCount = jumpCount;
				return;
			}
			_prevAlmanacJumpCount = jumpCount;
			if (!AlmanacAirJumpBridge.HasAirBenderAltActive() && (airBenderMaxJumps <= 0 || jumpCount >= airBenderMaxJumps))
			{
				TryAirJump(player);
			}
		}

		public static bool TryAirJump(Player player)
		{
			//IL_009b: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: 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)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: 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_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: 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_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_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: 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_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: 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 (IsUnderwaterOrSwimming(player) || _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;
		}

		private static bool IsUnderwaterOrSwimming(Player player)
		{
			if (((Character)player).IsSwimming())
			{
				return true;
			}
			return GenasiWaterSwimPose.IsHeadUnderLiquid(player);
		}

		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 AlmanacAirJumpBridge
	{
		private const string AlmanacAsm = "AlmanacClasses";

		private const string AirBenderTypeName = "AlmanacClasses.Classes.Abilities.Core.AirBender";

		private const string PlayerManagerTypeName = "AlmanacClasses.Classes.PlayerManager";

		private static bool _resolved;

		private static bool _present;

		private static FieldInfo _jumpCountField;

		private static FieldInfo _talentsField;

		private static MethodInfo _getLevelMethod;

		private static FieldInfo _passiveActiveField;

		public static bool IsAlmanacPresent
		{
			get
			{
				EnsureResolved();
				return _present;
			}
		}

		public static void EnsureResolved()
		{
			if (_resolved)
			{
				return;
			}
			_resolved = true;
			try
			{
				Assembly assembly = null;
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly2 in assemblies)
				{
					if (assembly2.GetName().Name == "AlmanacClasses")
					{
						assembly = assembly2;
						break;
					}
				}
				if (assembly == null)
				{
					return;
				}
				Type type = assembly.GetType("AlmanacClasses.Classes.Abilities.Core.AirBender");
				Type type2 = assembly.GetType("AlmanacClasses.Classes.PlayerManager");
				if (!(type == null) && !(type2 == null))
				{
					_jumpCountField = type.GetField("JumpCount", BindingFlags.Static | BindingFlags.NonPublic);
					_talentsField = type2.GetField("m_playerTalents", BindingFlags.Static | BindingFlags.Public);
					if (!(_jumpCountField == null) && !(_talentsField == null))
					{
						_present = true;
					}
				}
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("Ent1tyRaces: Almanac jump bridge failed (" + ex.Message + ")"));
				_present = false;
			}
		}

		public static int GetJumpCount()
		{
			EnsureResolved();
			if (!_present || _jumpCountField == null)
			{
				return 0;
			}
			try
			{
				return (int)_jumpCountField.GetValue(null);
			}
			catch
			{
				return 0;
			}
		}

		public static int GetAirBenderMaxJumps()
		{
			EnsureResolved();
			if (!_present || _talentsField == null)
			{
				return 0;
			}
			try
			{
				if (!(_talentsField.GetValue(null) is IDictionary dictionary))
				{
					return 0;
				}
				if (!dictionary.Contains("AirBender"))
				{
					return 0;
				}
				object obj = dictionary["AirBender"];
				if (obj == null)
				{
					return 0;
				}
				if (_passiveActiveField == null)
				{
					_passiveActiveField = obj.GetType().GetField("m_passiveActive", BindingFlags.Instance | BindingFlags.Public);
				}
				if (_passiveActiveField != null)
				{
					object value = _passiveActiveField.GetValue(obj);
					if (value is bool && !(bool)value)
					{
						return 0;
					}
				}
				if (_getLevelMethod == null)
				{
					_getLevelMethod = obj.GetType().GetMethod("GetLevel", BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null);
				}
				if (_getLevelMethod == null)
				{
					return 0;
				}
				return (_getLevelMethod.Invoke(obj, null) is int num) ? Mathf.Max(0, num) : 0;
			}
			catch
			{
				return 0;
			}
		}

		public static bool HasAirBenderAltActive()
		{
			EnsureResolved();
			if (!_present || _talentsField == null)
			{
				return false;
			}
			try
			{
				if (!(_talentsField.GetValue(null) is IDictionary dictionary) || !dictionary.Contains("AirBenderAlt"))
				{
					return false;
				}
				object obj = dictionary["AirBenderAlt"];
				if (obj == null)
				{
					return false;
				}
				object obj2 = obj.GetType().GetField("m_passiveActive", BindingFlags.Instance | BindingFlags.Public)?.GetValue(obj);
				bool flag = default(bool);
				int num;
				if (obj2 is bool)
				{
					flag = (bool)obj2;
					num = 1;
				}
				else
				{
					num = 0;
				}
				return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
			}
			catch
			{
				return false;
			}
		}
	}
	internal static class BodyScale
	{
		public const float Giant = 2f;

		public const float SlightlySmall = 0.75f;

		public const float GnomeScale = 0.5f;

		public const float TieflingScale = 0.95f;

		public const float HalflingScale = 0.65f;

		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.5f, 
				RaceType.Tiefling => 0.95f, 
				RaceType.Halfling => 0.65f, 
				_ => 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[])nu