Decompiled source of Fifth Edition Fantasy v1.1.1

FifthEditionFantasy.dll

Decompiled 6 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
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 System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.UI;
using Valheim.SettingsGui;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("JotunnModStub")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("JotunnModStub")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("1.1.1")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = "")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.1.0")]
namespace FairyRace;

public static class FefAbilityCd
{
	private class Entry
	{
		public float ReadyAt;

		public float Total;

		public string Resource;
	}

	public const string ClassPrimary = "C1";

	public const string ClassSecondary = "C2";

	public const string RacePrimary = "R1";

	public const string RaceSecondary = "R2";

	public static ConfigEntry<bool> ShowTiles;

	public static string Slot;

	private static readonly Dictionary<string, Entry> s_entries = new Dictionary<string, Entry>();

	private static string s_ownerKey;

	private static readonly Regex ClassKeyRx = new Regex("\\b([ZX]): (?:toggle |open the )?(.+?)(?: - | \\(|\\. |, once|$)");

	private static readonly Regex RaceKeyRx = new Regex("Active \\(([HJ])[^)]*\\): (.+?)(?: - | \\(\\d|\\. |$)");

	private static string s_namesFor;

	private static readonly Dictionary<string, string> s_names = new Dictionary<string, string>();

	public static void Init(ConfigFile cfg)
	{
		ShowTiles = cfg.Bind<bool>("FairyHud", "ShowAbilityTiles", true, "Show your class and race ability keys next to the spell quickbar, with their cooldowns and uses left.");
	}

	private static Entry Get(string slot)
	{
		if (!s_entries.TryGetValue(slot, out var value))
		{
			value = (s_entries[slot] = new Entry());
		}
		return value;
	}

	public static void Started(float seconds)
	{
		if (Slot != null && !(seconds <= 0f))
		{
			Entry entry = Get(Slot);
			entry.ReadyAt = Time.time + seconds;
			entry.Total = seconds;
		}
	}

	public static void Clear(string slot)
	{
		if (s_entries.TryGetValue(slot, out var value))
		{
			value.ReadyAt = 0f;
			value.Total = 0f;
		}
	}

	public static void UsesResource(string resource)
	{
		if (Slot != null && !string.IsNullOrEmpty(resource) && !(resource == "atwill") && !(resource == "slot1"))
		{
			Get(Slot).Resource = resource;
		}
	}

	public static void CheckOwner(Player p)
	{
		string text = PlayerClass.Get(p) + "|" + Race.Get(p);
		if (!(text == s_ownerKey))
		{
			s_ownerKey = text;
			s_entries.Clear();
		}
	}

	public static float Remaining(string slot)
	{
		Entry value;
		return s_entries.TryGetValue(slot, out value) ? Mathf.Max(0f, value.ReadyAt - Time.time) : 0f;
	}

	public static float Fraction(string slot)
	{
		if (!s_entries.TryGetValue(slot, out var value) || value.Total <= 0f)
		{
			return 0f;
		}
		return Mathf.Clamp01((value.ReadyAt - Time.time) / value.Total);
	}

	public static string Resource(string slot)
	{
		Entry value;
		return s_entries.TryGetValue(slot, out value) ? value.Resource : null;
	}

	public static Dictionary<string, string> Names(Player p)
	{
		string text = PlayerClass.Get(p);
		string text2 = Race.Get(p);
		string text3 = text + "|" + text2;
		if (text3 == s_namesFor)
		{
			return s_names;
		}
		s_namesFor = text3;
		s_names.Clear();
		if (!string.IsNullOrEmpty(text))
		{
			string input = FairyClassAbilities.ClassAbilityDescription(text) ?? "";
			foreach (Match item in ClassKeyRx.Matches(input))
			{
				string key = ((item.Groups[1].Value == "Z") ? "C1" : "C2");
				if (!s_names.ContainsKey(key))
				{
					s_names[key] = item.Groups[2].Value.Replace(" picker", "").Trim();
				}
			}
		}
		if (text2 == "Fairy")
		{
			s_names["R1"] = "Druidcraft";
			s_names["R2"] = "Faerie Fire";
		}
		else if (!string.IsNullOrEmpty(text2))
		{
			string input2 = FairyRaceAbilities.AbilityDescription(text2) ?? "";
			foreach (Match item2 in RaceKeyRx.Matches(input2))
			{
				string key2 = ((item2.Groups[1].Value == "H") ? "R1" : "R2");
				if (!s_names.ContainsKey(key2))
				{
					s_names[key2] = item2.Groups[2].Value.Trim();
				}
			}
		}
		return s_names;
	}

	public static string KeyLabel(string slot)
	{
		bool flag = FairyPad.GamepadActive();
		return slot switch
		{
			"C1" => flag ? FairyPad.Describe(FairyPad.ClassPrimary) : FairyKeybinds.Describe(FairyRacePlugin.ClassPrimaryKey), 
			"C2" => flag ? FairyPad.Describe(FairyPad.ClassSecondary) : FairyKeybinds.Describe(FairyRacePlugin.ClassSecondaryKey), 
			"R1" => flag ? FairyPad.Describe(FairyPad.RacePrimary) : FairyKeybinds.Describe(FairyRacePlugin.EnlargeKey), 
			_ => flag ? FairyPad.Describe(FairyPad.RaceSecondary) : FairyKeybinds.Describe(FairyRacePlugin.ReduceKey), 
		};
	}
}
public class FairyTraits : MonoBehaviour
{
	private class FairyWispLight : MonoBehaviour
	{
		public Transform Anchor;

		public float OrbitRadius = 0.6f;

		public float OrbitSpeed = 2.2f;

		public float HeightOffset = 1.6f;

		private float _phase;

		private Light _light;

		private void Awake()
		{
			//IL_0049: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Expected O, but got Unknown
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			_phase = Random.Range(0f, (float)Math.PI * 2f);
			_light = ((Component)this).gameObject.AddComponent<Light>();
			_light.type = (LightType)2;
			_light.color = new Color(1f, 0.92f, 0.7f);
			_light.range = 6f;
			_light.intensity = 1.5f;
			GameObject val = GameObject.CreatePrimitive((PrimitiveType)0);
			((Object)val).name = "FairyWispOrb";
			val.transform.SetParent(((Component)this).transform, false);
			val.transform.localScale = Vector3.one * 0.15f;
			Collider component = val.GetComponent<Collider>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			MeshRenderer component2 = val.GetComponent<MeshRenderer>();
			if ((Object)(object)component2 != (Object)null)
			{
				MaterialPropertyBlock val2 = new MaterialPropertyBlock();
				((Renderer)component2).GetPropertyBlock(val2);
				val2.SetColor("_Color", _light.color);
				val2.SetColor("_EmissionColor", _light.color * 2f);
				((Renderer)component2).SetPropertyBlock(val2);
			}
		}

		private void Update()
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Anchor == (Object)null)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			_phase += Time.deltaTime * OrbitSpeed;
			Vector3 val = new Vector3(Mathf.Cos(_phase), 0.3f + Mathf.Sin(_phase * 1.6f) * 0.3f, Mathf.Sin(_phase)) * OrbitRadius;
			((Component)this).transform.position = Anchor.position + Vector3.up * HeightOffset + val;
			_light.intensity = 1.3f + Mathf.Abs(Mathf.Sin(_phase * 2.5f)) * 0.6f;
		}
	}

	private class CoreAbilityIcon
	{
		public readonly string Label;

		public readonly string IconName;

		public readonly FairyAbility Ability;

		public CoreAbilityIcon(string label, string iconName, FairyAbility ability)
		{
			Label = label;
			IconName = iconName;
			Ability = ability;
		}
	}

	private static GUIStyle s_tileKey;

	private static GUIStyle s_tileName;

	private static GUIStyle s_tileState;

	private static readonly string[] TileOrder = new string[4] { "C1", "C2", "R1", "R2" };

	public static readonly FairyAbility[] ConcentrationSpells = new FairyAbility[10]
	{
		FairyAbility.Bless,
		FairyAbility.Hex,
		FairyAbility.Moonbeam,
		FairyAbility.SpiritGuardians,
		FairyAbility.CallLightning,
		FairyAbility.Fly,
		FairyAbility.Haste,
		FairyAbility.Blur,
		FairyAbility.GreaterInvisibility,
		FairyAbility.Stoneskin
	};

	private static readonly int BlessZdo = StringExtensionMethods.GetStableHashCode("fef_bless_until");

	private float _nextBlessMirror;

	private float _shieldUntil;

	private float _blurUntil;

	private float _stoneskinUntil;

	private float _hasteUntil;

	private float _flyUntil;

	private float _greaterInvisUntil;

	private float _blessUntil;

	private float _aidUntil;

	private float _shillelaghUntil;

	private float _smiteArmedUntil;

	private float _spiritGuardiansUntil;

	private float _spiritGuardiansNextTick;

	private float _callLightningUntil;

	private float _callLightningNextTick;

	private float _spiritualWeaponUntil;

	private float _spiritualWeaponNextTick;

	private float _moonbeamUntil;

	private float _moonbeamNextTick;

	private Vector3 _moonbeamPos;

	private readonly Dictionary<Character, float> _hexedUntil = new Dictionary<Character, float>();

	private static readonly int FairyStunHash = StringExtensionMethods.GetStableHashCode("SE_FairyStun");

	private static readonly int FairySlowHash = StringExtensionMethods.GetStableHashCode("SE_FairyFrostSlow");

	public const float ProduceFlameHoldSeconds = 600f;

	private static readonly string[] BadEffects = new string[8] { "Poison", "Burning", "Frost", "Wet", "Smoked", "Tared", "Spirit", "Lightning" };

	private static GUIStyle s_wheelLabel;

	private static GUIStyle s_wheelTitle;

	private Player _player;

	private readonly HashSet<FairyAbility> _spent = new HashSet<FairyAbility>();

	public const float FaerieFireEitr = 40f;

	public const float EnlargeEitr = 30f;

	public const float FairySmallBaseline = 0.7f;

	public const float EnlargeMultiplier = 1.35f;

	public const float ReduceMultiplier = 0.55f;

	public const float NormalMultiplier = 1f;

	private int _spellCycleIndex = -1;

	private readonly Dictionary<FairyAbility, float> _cantripReadyAt = new Dictionary<FairyAbility, float>();

	private readonly Dictionary<FairyAbility, float> _cantripCooldownTotal = new Dictionary<FairyAbility, float>();

	private const float CantripCooldown = 4f;

	private const float BladeWardCooldown = 12f;

	private float _bladeWardExpiresAt;

	private float _mageArmorExpiresAt;

	private float _passWithoutTraceExpiresAt;

	private float _invisibleExpiresAt;

	private float _jumpBlessExpiresAt;

	private float _expeditiousExpiresAt;

	private float _longstriderExpiresAt;

	private float _featherFallExpiresAt;

	public float JumpLandingSafeUntil;

	private readonly Dictionary<Character, Faction> _charmedOriginalFaction = new Dictionary<Character, Faction>();

	private readonly Dictionary<Character, float> _charmedExpiresAt = new Dictionary<Character, float>();

	private float _charmCleanupNextAt;

	private float _cycleKeyDownAt = -1f;

	private float _padCycleDownAt = -1f;

	private bool _pickerLatched;

	private const float PickerHoldSeconds = 0.3f;

	private static GUIStyle s_pickerCell;

	private static GUIStyle s_pickerCellSel;

	private static GUIStyle s_pickerHeader;

	private static GUIStyle s_pickerRowLabel;

	private static GUIStyle s_pickerTitle;

	private static readonly FieldInfo CharacterBodyField = typeof(Character).GetField("m_body", BindingFlags.Instance | BindingFlags.NonPublic);

	private float _nextCooldownMessage;

	public const float SlotModeRecast = 2f;

	private readonly HashSet<Renderer> _invisibilityHiddenRenderers = new HashSet<Renderer>();

	private static readonly int FrostSlowHash = StringExtensionMethods.GetStableHashCode("SE_FairyFrostSlow");

	private static readonly int VanillaPoisonHash = StringExtensionMethods.GetStableHashCode("SE_Poison");

	private static readonly FieldInfo TerrainCompOperationsField = typeof(TerrainComp).GetField("m_operations", BindingFlags.Instance | BindingFlags.NonPublic);

	private static readonly FieldInfo TerrainCompNviewField = typeof(TerrainComp).GetField("m_nview", BindingFlags.Instance | BindingFlags.NonPublic);

	private const string MoldEarthRaiseName = "FairyMoldEarthRaise";

	private const string MoldEarthDigName = "FairyMoldEarthDig";

	private static ObjectDB _moldEarthRegisteredFor;

	private static Settings _moldEarthRaiseSettings;

	private static Settings _moldEarthDigSettings;

	private const float MistyStepEitr = 15f;

	private const float PassWithoutTraceEitr = 20f;

	private const float SpeakWithAnimalsEitr = 10f;

	private const float InvisibilityEitr = 25f;

	private const float MageArmorEitr = 15f;

	private const float JumpEitr = 8f;

	private const float ExpeditiousRetreatEitr = 12f;

	private const float LongstriderEitr = 10f;

	private const float FeatherFallEitr = 8f;

	private const float CureWoundsEitr = 12f;

	private const float CureWoundsHeal = 30f;

	private const float GoodberrySpellEitr = 10f;

	private const int GoodberryCount = 4;

	private const float CharmPersonEitr = 25f;

	private static GUIStyle s_spellHudBoxStyle;

	private static GUIStyle s_spellHudLineStyle;

	private static GUIStyle s_spellHudSelectedStyle;

	private static GUIStyle s_spellHudHeaderStyle;

	private const float IconSize = 18f;

	private static readonly CoreAbilityIcon[] CoreAbilityIcons = new CoreAbilityIcon[3]
	{
		new CoreAbilityIcon("Druidcraft (G)", "icon_spell_druidcraft", FairyAbility.Druidcraft),
		new CoreAbilityIcon("Faerie Fire (K)", "icon_spell_faeriefire_cast", FairyAbility.FaerieFire),
		new CoreAbilityIcon("Enlarge/Reduce (H/J)", "icon_spell_enlargereduce", FairyAbility.EnlargeReduce)
	};

	private static readonly Dictionary<string, Texture2D> s_iconTextureCache = new Dictionary<string, Texture2D>();

	private static bool s_iconsUnavailableLogged;

	private const string GoodberrySpellIconName = "icon_spell_goodberry";

	private static Material s_cooldownRadialMat;

	private static bool s_cooldownRadialMatMissingLogged;

	private static GUIStyle s_cooldownTextStyle;

	private static HotkeyBar s_hotkeyBar;

	private static bool s_hotkeyBarAnchorValid;

	private static float s_hotkeyBarRightX;

	private static float s_hotkeyBarTopWorldY;

	private static float s_hotkeyBarBottomWorldY;

	private static float s_nextHotkeyBarLookup;

	private static GUIStyle s_quickbarSlotStyle;

	private static readonly Dictionary<string, Sprite> s_iconSpriteCache = new Dictionary<string, Sprite>();

	public FairyAbility? Concentrating { get; private set; }

	public bool ShieldActive => Time.time < _shieldUntil;

	public bool BlurActive => Time.time < _blurUntil;

	public bool StoneskinActive => Time.time < _stoneskinUntil;

	public bool HasteActive => Time.time < _hasteUntil;

	public bool FlyActive => Time.time < _flyUntil;

	public bool GreaterInvisibilityActive => Time.time < _greaterInvisUntil;

	public bool BlessActive => Time.time < _blessUntil;

	public bool ShillelaghActive => Time.time < _shillelaghUntil;

	public bool AidActive => Time.time < _aidUntil;

	public bool Enlarged { get; private set; }

	public bool Reduced { get; private set; }

	public bool PrestidigitationActive { get; private set; }

	public bool MinorIllusionActive { get; private set; }

	public float CurrentScale { get; private set; } = 0.7f;

	public bool BladeWardActive => Time.time < _bladeWardExpiresAt;

	public bool MageArmorActive => Time.time < _mageArmorExpiresAt;

	public bool PassWithoutTraceActive => Time.time < _passWithoutTraceExpiresAt;

	public bool InvisibleActive => Time.time < _invisibleExpiresAt;

	public bool JumpBlessActive => Time.time < _jumpBlessExpiresAt;

	public bool ExpeditiousRetreatActive => Time.time < _expeditiousExpiresAt;

	public bool LongstriderActive => Time.time < _longstriderExpiresAt;

	public static bool SpellPickerOpen { get; private set; }

	public int KnownSpellCountForTest => KnownSpells().Count;

	public bool DebugFreeCast { get; private set; }

	public bool FreeCastInProgress { get; private set; }

	public bool LastCastSpent { get; internal set; }

	private void DrawAbilityTiles(float x, float top, float barHeight)
	{
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Expected O, but got Unknown
		//IL_0117: 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_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Expected O, but got Unknown
		//IL_016f: 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_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Expected O, but got Unknown
		//IL_0234: Unknown result type (might be due to invalid IL or missing references)
		if ((FefAbilityCd.ShowTiles != null && !FefAbilityCd.ShowTiles.Value) || InventoryGui.IsVisible() || Minimap.IsOpen())
		{
			return;
		}
		FefAbilityCd.CheckOwner(_player);
		Dictionary<string, string> dictionary = FefAbilityCd.Names(_player);
		if (dictionary.Count == 0)
		{
			return;
		}
		float num = (barHeight - 6f) * 0.5f;
		float num2 = Mathf.Max(num * 4.2f, 150f);
		int num3 = Mathf.Clamp(Mathf.RoundToInt(num * 0.42f), 11, 28);
		if (s_tileKey == null || s_tileKey.fontSize != num3)
		{
			Font val = FifthEdHud.ValheimFont();
			s_tileKey = new GUIStyle(GUI.skin.label)
			{
				fontSize = num3,
				fontStyle = (FontStyle)1,
				alignment = (TextAnchor)4,
				clipping = (TextClipping)1
			};
			s_tileKey.normal.textColor = new Color(1f, 0.82f, 0.45f);
			s_tileName = new GUIStyle(GUI.skin.label)
			{
				fontSize = num3,
				alignment = (TextAnchor)3,
				clipping = (TextClipping)1,
				wordWrap = false
			};
			s_tileName.normal.textColor = new Color(0.95f, 0.92f, 0.85f);
			s_tileState = new GUIStyle(s_tileName)
			{
				alignment = (TextAnchor)5,
				fontStyle = (FontStyle)1
			};
			if ((Object)(object)val != (Object)null)
			{
				s_tileKey.font = val;
				s_tileName.font = val;
				s_tileState.font = val;
			}
		}
		int num4 = 0;
		Rect r = default(Rect);
		for (int i = 0; i < 2; i++)
		{
			bool flag = false;
			for (int j = 0; j < 2; j++)
			{
				string text = TileOrder[i * 2 + j];
				if (dictionary.TryGetValue(text, out var value))
				{
					flag = true;
					((Rect)(ref r))..ctor(x + (float)num4 * (num2 + 6f), top + (float)j * (num + 6f), num2, num);
					DrawAbilityTile(r, text, value, this);
				}
			}
			if (flag)
			{
				num4++;
			}
		}
	}

	private void DrawAbilityTile(Rect r, string slot, string name, FairyTraits traits)
	{
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_0171: Unknown result type (might be due to invalid IL or missing references)
		//IL_0196: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0220: Unknown result type (might be due to invalid IL or missing references)
		//IL_0253: 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_02c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0360: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
		float num = FefAbilityCd.Fraction(slot);
		float num2 = FefAbilityCd.Remaining(slot);
		if (Race.IsFairy(_player) && (slot == "R1" || slot == "R2"))
		{
			FairyAbility ability = ((!(slot == "R1")) ? FairyAbility.FaerieFire : FairyAbility.Druidcraft);
			num = traits.GetCantripCooldownFraction(ability);
			num2 = traits.GetCantripCooldownRemaining(ability);
		}
		string text = "";
		bool flag = false;
		string text2 = FefAbilityCd.Resource(slot);
		if (text2 != null && FifthEd.SlotsMode && FifthEd.ResourceMax(_player, text2) > 0)
		{
			int num3 = FifthEd.ResourceLeft(_player, text2);
			text = num3 + "/" + FifthEd.ResourceMax(_player, text2);
			flag = num3 <= 0;
		}
		if (num2 > 0.05f)
		{
			text = ((num2 >= 10f) ? (Mathf.CeilToInt(num2) + "s") : (num2.ToString("0.0") + "s"));
			flag = true;
		}
		Color color = GUI.color;
		GUI.color = new Color(0f, 0f, 0f, 0.55f);
		GUI.DrawTexture(r, (Texture)(object)FefImgui.White);
		GUI.color = new Color(0.55f, 0.42f, 0.25f, 0.9f);
		GUI.DrawTexture(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, ((Rect)(ref r)).width, 1f), (Texture)(object)FefImgui.White);
		GUI.DrawTexture(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).yMax - 1f, ((Rect)(ref r)).width, 1f), (Texture)(object)FefImgui.White);
		GUI.DrawTexture(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, 1f, ((Rect)(ref r)).height), (Texture)(object)FefImgui.White);
		GUI.DrawTexture(new Rect(((Rect)(ref r)).xMax - 1f, ((Rect)(ref r)).y, 1f, ((Rect)(ref r)).height), (Texture)(object)FefImgui.White);
		if (num > 0f)
		{
			GUI.color = new Color(0f, 0f, 0f, 0.6f);
			GUI.DrawTexture(new Rect(((Rect)(ref r)).x + 1f, ((Rect)(ref r)).y + 1f, (((Rect)(ref r)).width - 2f) * num, ((Rect)(ref r)).height - 2f), (Texture)(object)FefImgui.White);
		}
		GUI.color = (Color)(flag ? new Color(1f, 1f, 1f, 0.55f) : Color.white);
		float num4 = ((Rect)(ref r)).height * 1.25f;
		GUI.Label(new Rect(((Rect)(ref r)).x + 2f, ((Rect)(ref r)).y, num4, ((Rect)(ref r)).height), FefAbilityCd.KeyLabel(slot), s_tileKey);
		float num5 = ((text.Length > 0) ? (((Rect)(ref r)).height * 1.6f) : 0f);
		GUI.Label(new Rect(((Rect)(ref r)).x + num4 + 2f, ((Rect)(ref r)).y, ((Rect)(ref r)).width - num4 - num5 - 8f, ((Rect)(ref r)).height), name, s_tileName);
		if (text.Length > 0)
		{
			GUI.Label(new Rect(((Rect)(ref r)).xMax - num5 - 6f, ((Rect)(ref r)).y, num5, ((Rect)(ref r)).height), text, s_tileState);
		}
		GUI.color = color;
	}

	private bool ConcentrationActive(FairyAbility a)
	{
		float now = Time.time;
		return a switch
		{
			FairyAbility.Bless => now < _blessUntil, 
			FairyAbility.Hex => _hexedUntil.Values.Any((float t) => now < t), 
			FairyAbility.Moonbeam => now < _moonbeamUntil, 
			FairyAbility.SpiritGuardians => now < _spiritGuardiansUntil, 
			FairyAbility.CallLightning => now < _callLightningUntil, 
			FairyAbility.Fly => now < _flyUntil, 
			FairyAbility.Haste => now < _hasteUntil, 
			FairyAbility.Blur => now < _blurUntil, 
			FairyAbility.GreaterInvisibility => now < _greaterInvisUntil, 
			FairyAbility.Stoneskin => now < _stoneskinUntil, 
			_ => false, 
		};
	}

	public void EndConcentration(bool message)
	{
		if (Concentrating.HasValue)
		{
			FairyAbility value = Concentrating.Value;
			Concentrating = null;
			switch (value)
			{
			case FairyAbility.Bless:
				_blessUntil = 0f;
				break;
			case FairyAbility.Hex:
				_hexedUntil.Clear();
				break;
			case FairyAbility.Moonbeam:
				_moonbeamUntil = 0f;
				break;
			case FairyAbility.SpiritGuardians:
				_spiritGuardiansUntil = 0f;
				break;
			case FairyAbility.CallLightning:
				_callLightningUntil = 0f;
				break;
			case FairyAbility.Fly:
				_flyUntil = 0f;
				break;
			case FairyAbility.Haste:
				_hasteUntil = 0f;
				break;
			case FairyAbility.Blur:
				_blurUntil = 0f;
				break;
			case FairyAbility.GreaterInvisibility:
				_greaterInvisUntil = 0f;
				break;
			case FairyAbility.Stoneskin:
				_stoneskinUntil = 0f;
				break;
			}
			SEMan sEMan = ((Character)_player).GetSEMan();
			if (sEMan != null)
			{
				sEMan.RemoveStatusEffect(StringExtensionMethods.GetStableHashCode("SE_FairySpellBuff_" + value), true);
			}
			if (message)
			{
				((Character)_player).Message((MessageType)2, "You lose concentration on " + SpellDisplayName(value) + "!", 0, (Sprite)null, false);
			}
		}
	}

	internal void AfterCast(FairyAbility cast, bool wasActiveBefore)
	{
		if (ConcentrationSpells.Contains(cast) && ConcentrationActive(cast) && (!wasActiveBefore || Concentrating != cast))
		{
			if (Concentrating.HasValue && Concentrating.Value != cast)
			{
				EndConcentration(message: false);
			}
			Concentrating = cast;
		}
	}

	internal bool IsConcentrationSpellActive(FairyAbility a)
	{
		return ConcentrationActive(a);
	}

	internal void ConcentrationTick()
	{
		if (Concentrating.HasValue && !ConcentrationActive(Concentrating.Value))
		{
			Concentrating = null;
		}
	}

	internal void ConcentrationCheck(float damage)
	{
		if (Concentrating.HasValue && !(damage < 8f))
		{
			float num = Mathf.Max(1f, ((Character)_player).GetMaxHealth());
			float num2 = Mathf.Clamp01(damage / (num * 0.6f));
			if (FeatsExtra.Has(_player, FairyFeat.BattleMage))
			{
				num2 *= 0.4f;
			}
			if (Random.value < num2)
			{
				EndConcentration(message: true);
			}
		}
	}

	private void CastFindFamiliar()
	{
		if (FairyFamiliar.Has(_player))
		{
			FairyFamiliar.Set(_player, on: false);
			Say("Your familiar fades away.");
		}
		else if (Spend(FairyAbility.FindFamiliar))
		{
			FairyFamiliar.Set(_player, on: true);
			Say("A spirit raven answers your call!");
			FairyJournal.Log(_player, "Called a familiar");
		}
	}

	private void CastFindSteed()
	{
		if (FairySteed.DismissMine(_player))
		{
			Say("Your steed returns to the spirit realm.");
		}
		else if (Spend(FairyAbility.FindSteed) && FairySteed.Summon(_player))
		{
			Say("A spectral steed appears, saddled and ready.");
		}
	}

	public void RestoreFreeCasts()
	{
		_spent.Clear();
	}

	internal void MirrorBless()
	{
		if (!(Time.time < _nextBlessMirror) && !((Object)(object)((Character)(_player?)).m_nview == (Object)null) && ((Character)_player).m_nview.IsValid() && ((Character)_player).m_nview.IsOwner())
		{
			_nextBlessMirror = Time.time + 1f;
			double num = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetTimeSeconds() : ((double)Time.time));
			float num2 = (BlessActive ? ((float)(num + (double)(_blessUntil - Time.time))) : 0f);
			ZDO zDO = ((Character)_player).m_nview.GetZDO();
			if (Mathf.Abs(zDO.GetFloat(BlessZdo, 0f) - num2) > 0.5f)
			{
				zDO.Set(BlessZdo, num2);
			}
		}
	}

	internal static bool RemoteBlessActive(Player caster)
	{
		ZDO val = (((Object)(object)((Character)(caster?)).m_nview != (Object)null && ((Character)caster).m_nview.IsValid()) ? ((Character)caster).m_nview.GetZDO() : null);
		double num = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetTimeSeconds() : ((double)Time.time));
		return val != null && (double)val.GetFloat(BlessZdo, 0f) > num;
	}

	public bool IsHexed(Character c)
	{
		float value;
		return (Object)(object)c != (Object)null && _hexedUntil.TryGetValue(c, out value) && Time.time < value;
	}

	public static bool FlySpellActive(Player p)
	{
		FairyTraits fairyTraits = (((Object)(object)p != (Object)null) ? ((Component)p).GetComponent<FairyTraits>() : null);
		return (Object)(object)fairyTraits != (Object)null && fairyTraits.FlyActive;
	}

	public static bool BlessedBy(Player p)
	{
		//IL_0036: 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)
		foreach (Player allPlayer in Player.GetAllPlayers())
		{
			FairyTraits component = ((Component)allPlayer).GetComponent<FairyTraits>();
			if ((Object)(object)component != (Object)null && component.BlessActive && Vector3.Distance(((Component)allPlayer).transform.position, ((Component)p).transform.position) <= 12f)
			{
				return true;
			}
		}
		return false;
	}

	private float SpellEitr(int spellLevel)
	{
		return (spellLevel <= 0) ? 0f : (8f + (float)spellLevel * 7f);
	}

	private void Say(string text)
	{
		((Character)_player).Message((MessageType)2, text, 0, (Sprite)null, false);
	}

	private IEnumerable<Character> Enemies(Vector3 pos, float radius)
	{
		//IL_000f: 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)
		foreach (Character c in Character.GetAllCharacters().ToList())
		{
			if (!((Object)(object)c == (Object)null) && !((Object)(object)c == (Object)(object)_player) && !c.IsPlayer() && !c.IsDead() && !c.IsTamed() && (int)c.m_faction != 0)
			{
				float r = radius + c.GetRadius();
				Vector3 val = ((Component)c).transform.position - pos;
				if (!(((Vector3)(ref val)).sqrMagnitude > r * r))
				{
					yield return c;
				}
			}
		}
	}

	private IEnumerable<Character> EnemiesInCone(float range, float halfAngle)
	{
		Vector3 origin = ((Character)_player).GetEyePoint();
		Vector3 fwd = ((Character)_player).GetLookDir();
		foreach (Character c in Enemies(((Component)_player).transform.position, range).ToList())
		{
			Vector3 to = c.GetCenterPoint() - origin;
			if (Vector3.Angle(fwd, to) <= halfAngle)
			{
				yield return c;
			}
		}
	}

	private IEnumerable<Character> EnemiesInLine(float length, float width)
	{
		Vector3 origin = ((Character)_player).GetEyePoint();
		Vector3 fwd = ((Character)_player).GetLookDir();
		foreach (Character c in Enemies(origin + fwd * (length * 0.5f), length * 0.5f + width).ToList())
		{
			Vector3 to = c.GetCenterPoint() - origin;
			float along = Vector3.Dot(to, fwd);
			if (!(along < 0f) && !(along > length))
			{
				Vector3 val = to - fwd * along;
				if (((Vector3)(ref val)).magnitude <= width + 0.5f)
				{
					yield return c;
				}
			}
		}
	}

	private Vector3 TargetPoint(float range)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: 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_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		Vector3 eyePoint = ((Character)_player).GetEyePoint();
		Vector3 lookDir = ((Character)_player).GetLookDir();
		int mask = LayerMask.GetMask(new string[7] { "Default", "static_solid", "terrain", "piece", "character", "character_net", "character_ghost" });
		RaycastHit val = default(RaycastHit);
		if (Physics.Raycast(eyePoint + lookDir * 1f, lookDir, ref val, range, mask))
		{
			return ((RaycastHit)(ref val)).point;
		}
		Vector3 val2 = eyePoint + lookDir * range;
		float num = default(float);
		if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGroundHeight(val2, ref num))
		{
			val2.y = Mathf.Max(num, val2.y - 30f);
		}
		return val2;
	}

	private void Hit(Character c, DamageTypes dmg, float push = 0f, float stagger = 1f)
	{
		//IL_001c: 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_0022: 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_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Expected O, but got Unknown
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: 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_0068: 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_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)
		if ((Object)(object)c == (Object)null || c.IsDead())
		{
			return;
		}
		HitData val = new HitData
		{
			m_damage = dmg,
			m_point = c.GetCenterPoint(),
			m_pushForce = push,
			m_staggerMultiplier = stagger
		};
		Vector3 val2 = ((Component)c).transform.position - ((Component)_player).transform.position;
		val.m_dir = ((Vector3)(ref val2)).normalized;
		if ((Object)(object)((Character)_player).m_nview != (Object)null && ((Character)_player).m_nview.IsValid())
		{
			val.m_attacker = ((Character)_player).m_nview.GetZDO().m_uid;
		}
		if ((Object)(object)((Component)_player).GetComponent<FairySubclassState>() != (Object)null)
		{
			string text = Subclass.Get(_player);
			if (text == "Evocation" || text == "Siegesmith")
			{
				SubclassMechanics.ScaleAll(ref val.m_damage, 1.25f);
			}
			else if (text == "Draconic" && PlayerLevel.Level(_player) >= 6)
			{
				val.m_damage.m_fire *= 1.25f;
			}
		}
		c.Damage(val);
	}

	private void Bolt(float dmgSpeed, float lifetime, Color tint, DamageTypes dmg, string sprite, Action<Character> onHit = null, float push = 0f, float stagger = 1f, Vector3? dirOverride = null, Vector3? originOverride = null)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: 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_0061: 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)
		Vector3 val = (Vector3)(((??)dirOverride) ?? ((Character)_player).GetLookDir());
		Vector3 position = (Vector3)(((??)originOverride) ?? (((Character)_player).GetEyePoint() + val * 2f));
		FairySpellProjectile.Spawn(position, val, dmgSpeed, lifetime, 0.35f, 0.3f, tint, dmg, (Character)(object)_player, onHit, push, stagger, sprite);
	}

	private bool CastExtraSpell(FairyAbility a)
	{
		switch (a)
		{
		case FairyAbility.SacredFlame:
			CastSacredFlame();
			return true;
		case FairyAbility.ShockingGrasp:
			CastShockingGrasp();
			return true;
		case FairyAbility.ChillTouch:
			CastChillTouch();
			return true;
		case FairyAbility.RimeTouch:
			CastFrostbite();
			return true;
		case FairyAbility.DeathKnell:
			CastTollTheDead();
			return true;
		case FairyAbility.RadiantBurst:
			CastWordOfRadiance();
			return true;
		case FairyAbility.ProduceFlame:
			CastProduceFlame();
			return true;
		case FairyAbility.Shillelagh:
			CastShillelagh();
			return true;
		case FairyAbility.AcidSplash:
			CastAcidSplash();
			return true;
		case FairyAbility.MagicMissile:
			CastMagicMissile();
			return true;
		case FairyAbility.BurningHands:
			CastBurningHands();
			return true;
		case FairyAbility.Thunderwave:
			CastThunderwave();
			return true;
		case FairyAbility.HealingWord:
			CastHealingWord();
			return true;
		case FairyAbility.Shield:
			CastShield();
			return true;
		case FairyAbility.GuidingBolt:
			CastGuidingBolt();
			return true;
		case FairyAbility.Hex:
			CastHex();
			return true;
		case FairyAbility.Bless:
			CastBless();
			return true;
		case FairyAbility.ThunderStrike:
			CastThunderousSmite();
			return true;
		case FairyAbility.IceKnife:
			CastIceKnife();
			return true;
		case FairyAbility.ScorchingRay:
			CastScorchingRay();
			return true;
		case FairyAbility.Shatter:
			CastShatter();
			return true;
		case FairyAbility.Moonbeam:
			CastMoonbeam();
			return true;
		case FairyAbility.SpiritualWeapon:
			CastSpiritualWeapon();
			return true;
		case FairyAbility.Blur:
			CastBlur();
			return true;
		case FairyAbility.LesserRestoration:
			CastLesserRestoration();
			return true;
		case FairyAbility.Aid:
			CastAid();
			return true;
		case FairyAbility.HoldPerson:
			CastHoldPerson();
			return true;
		case FairyAbility.Fireball:
			CastFireball();
			return true;
		case FairyAbility.LightningBolt:
			CastLightningBolt();
			return true;
		case FairyAbility.Haste:
			CastHaste();
			return true;
		case FairyAbility.Fly:
			CastFly();
			return true;
		case FairyAbility.SpiritGuardians:
			CastSpiritGuardians();
			return true;
		case FairyAbility.CallLightning:
			CastCallLightning();
			return true;
		case FairyAbility.MassHealingWord:
			CastMassHealingWord();
			return true;
		case FairyAbility.IceStorm:
			CastIceStorm();
			return true;
		case FairyAbility.GreaterInvisibility:
			CastGreaterInvisibility();
			return true;
		case FairyAbility.Stoneskin:
			CastStoneskin();
			return true;
		case FairyAbility.ConeOfCold:
			CastConeOfCold();
			return true;
		case FairyAbility.MassCureWounds:
			CastMassCureWounds();
			return true;
		case FairyAbility.FlameStrike:
			CastFlameStrike();
			return true;
		case FairyAbility.ChainLightning:
			CastChainLightning();
			return true;
		case FairyAbility.HealSpell:
			CastHealSpell();
			return true;
		case FairyAbility.Sunbeam:
			CastSunbeam();
			return true;
		case FairyAbility.FindFamiliar:
			CastFindFamiliar();
			return true;
		case FairyAbility.FindSteed:
			CastFindSteed();
			return true;
		default:
			return false;
		}
	}

	private bool Spend(FairyAbility a)
	{
		return TrySpend(a, SpellEitr(SpellAccess.SpellLevel(a)));
	}

	private bool Cantrip(FairyAbility a)
	{
		return TryStartCantripCooldown(a, 4f);
	}

	private void CastSacredFlame()
	{
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: 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)
		Character val = FindNearestInCone(20f, 20f, includePlayers: false);
		if ((Object)(object)val == (Object)null)
		{
			Say("$fairy_spell_no_target");
		}
		else if (Cantrip(FairyAbility.SacredFlame))
		{
			Hit(val, new DamageTypes
			{
				m_fire = 10f * LevelScale(),
				m_damage = 5f * LevelScale(),
				m_spirit = 6f * LevelScale()
			});
			FairySpellFx.Column(((Component)val).transform.position, new Color(1f, 0.9f, 0.5f), 1.2f);
			Say("Radiant flame descends on your foe!");
		}
	}

	private void CastShockingGrasp()
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		Character val = FindNearestInCone(3.5f, 50f, includePlayers: false);
		if ((Object)(object)val == (Object)null)
		{
			Say("$fairy_spell_no_target");
		}
		else if (Cantrip(FairyAbility.ShockingGrasp))
		{
			Hit(val, new DamageTypes
			{
				m_lightning = 24f * LevelScale()
			}, 15f, 2f);
			FairySpellFx.Flash(val.GetCenterPoint(), new Color(0.5f, 0.7f, 1f), 3f, 0.25f);
			Say("Lightning crackles from your hand!");
		}
	}

	private void CastChillTouch()
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		if (Cantrip(FairyAbility.ChillTouch))
		{
			Bolt(24f, 1.2f, new Color(0.45f, 0.9f, 0.6f), new DamageTypes
			{
				m_damage = 16f * LevelScale(),
				m_spirit = 6f * LevelScale()
			}, "eldritchblast");
			Say("A ghostly, skeletal hand reaches out!");
		}
	}

	private void CastFrostbite()
	{
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: 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)
		Character val = FindNearestInCone(18f, 25f, includePlayers: false);
		if ((Object)(object)val == (Object)null)
		{
			Say("$fairy_spell_no_target");
		}
		else if (Cantrip(FairyAbility.RimeTouch))
		{
			Hit(val, new DamageTypes
			{
				m_frost = 14f * LevelScale()
			});
			SEMan sEMan = val.GetSEMan();
			if (sEMan != null)
			{
				sEMan.AddStatusEffect(FairySlowHash, true, 0, 0f, (short)(-1));
			}
			FairySpellFx.Flash(val.GetCenterPoint(), new Color(0.6f, 0.85f, 1f), 3f, 0.4f);
			Say("Numbing frost forms on your foe!");
		}
	}

	private void CastTollTheDead()
	{
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: 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)
		Character val = FindNearestInCone(18f, 25f, includePlayers: false);
		if ((Object)(object)val == (Object)null)
		{
			Say("$fairy_spell_no_target");
		}
		else if (Cantrip(FairyAbility.DeathKnell))
		{
			float num = ((val.GetHealthPercentage() < 0.999f) ? 24f : 16f) * LevelScale();
			Hit(val, new DamageTypes
			{
				m_damage = num,
				m_spirit = num * 0.4f
			});
			FairySpellFx.Flash(val.GetCenterPoint(), new Color(0.4f, 0.3f, 0.6f), 3f, 0.5f);
			Say("A dolorous bell tolls!");
		}
	}

	private void CastWordOfRadiance()
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: 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)
		List<Character> list = Enemies(((Component)_player).transform.position, 5f).ToList();
		if (list.Count == 0)
		{
			Say("$fairy_spell_no_target");
		}
		else
		{
			if (!Cantrip(FairyAbility.RadiantBurst))
			{
				return;
			}
			foreach (Character item in list)
			{
				Hit(item, new DamageTypes
				{
					m_fire = 14f * LevelScale()
				});
			}
			FairySpellFx.Nova(((Component)_player).transform.position + Vector3.up, new Color(1f, 0.9f, 0.5f), 5f);
			Say("Burning radiance bursts from you!");
		}
	}

	private void CastProduceFlame()
	{
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: 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_0128: Unknown result type (might be due to invalid IL or missing references)
		if (!FairyHandFlame.IsHeld(_player))
		{
			if (SpellReady(FairyAbility.ProduceFlame))
			{
				FairyHandFlame.Conjure(_player, 600f);
				ApplyTimedBuffVisual(FairyAbility.ProduceFlame, 600f);
				Say("A flickering flame dances in your palm. Cast again to hurl it.");
			}
		}
		else if (Cantrip(FairyAbility.ProduceFlame))
		{
			Vector3 lookDir = ((Character)_player).GetLookDir();
			Vector3 value = FairyHandFlame.HandPosition(_player) + lookDir * 0.6f;
			FairyHandFlame.Extinguish(_player);
			SEMan sEMan = ((Character)_player).GetSEMan();
			if (sEMan != null)
			{
				sEMan.RemoveStatusEffect(StringExtensionMethods.GetStableHashCode("SE_FairySpellBuff_" + FairyAbility.ProduceFlame), true);
			}
			Color tint = new Color(1f, 0.55f, 0.1f);
			DamageTypes dmg = new DamageTypes
			{
				m_fire = 18f * LevelScale()
			};
			Vector3? originOverride = value;
			Bolt(24f, 1.2f, tint, dmg, "firebolt", null, 0f, 1f, null, originOverride);
			Say("You hurl the flame!");
		}
	}

	private void CastShillelagh()
	{
		if (TryStartCantripCooldown(FairyAbility.Shillelagh, 10f))
		{
			float num = 60f * LevelScale();
			_shillelaghUntil = Time.time + num;
			ApplyTimedBuffVisual(FairyAbility.Shillelagh, num);
			Say("Your weapon thrums with nature's might.");
		}
	}

	private void CastAcidSplash()
	{
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		if (!Cantrip(FairyAbility.AcidSplash))
		{
			return;
		}
		Bolt(22f, 1.2f, new Color(0.6f, 1f, 0.2f), new DamageTypes
		{
			m_poison = 12f * LevelScale()
		}, "poisonspray", delegate(Character t)
		{
			//IL_001b: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			foreach (Character item in (from e in Enemies(((Component)t).transform.position, 2.5f)
				where (Object)(object)e != (Object)(object)t
				select e).ToList())
			{
				Hit(item, new DamageTypes
				{
					m_poison = 12f * LevelScale()
				});
			}
		});
		Say("A bubble of acid arcs out!");
	}

	private void CastMagicMissile()
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_0167: Unknown result type (might be due to invalid IL or missing references)
		List<Character> list = (from c in Enemies(((Component)_player).transform.position, 25f)
			where Vector3.Angle(((Character)_player).GetLookDir(), c.GetCenterPoint() - ((Character)_player).GetEyePoint()) < 70f
			orderby Vector3.Distance(((Component)c).transform.position, ((Component)_player).transform.position)
			select c).Take(3).ToList();
		if (list.Count == 0)
		{
			Say("$fairy_spell_no_target");
		}
		else if (Spend(FairyAbility.MagicMissile))
		{
			int num = 3 + ((PlayerLevel.Level(_player) >= 5) ? 1 : 0) + ((PlayerLevel.Level(_player) >= 9) ? 1 : 0);
			for (int num2 = 0; num2 < num; num2++)
			{
				Character val = list[num2 % list.Count];
				Vector3 val2 = ((Character)_player).GetEyePoint() + ((Character)_player).GetLookDir() * 1.5f + Random.insideUnitSphere * 0.4f;
				Vector3 val3 = val.GetCenterPoint() - val2;
				Vector3 normalized = ((Vector3)(ref val3)).normalized;
				Bolt(40f, 1.5f, new Color(0.7f, 0.5f, 1f), new DamageTypes
				{
					m_damage = 9f * LevelScale()
				}, "eldritchblast", null, 0f, 1f, normalized, val2);
			}
			Say("Glowing darts of force streak out!");
		}
	}

	private void CastBurningHands()
	{
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		List<Character> list = EnemiesInCone(7f, 35f).ToList();
		if (list.Count == 0)
		{
			Say("$fairy_spell_no_target");
		}
		else
		{
			if (!Spend(FairyAbility.BurningHands))
			{
				return;
			}
			foreach (Character item in list)
			{
				Hit(item, new DamageTypes
				{
					m_fire = 26f * LevelScale()
				});
			}
			FairySpellFx.Cone(((Character)_player).GetEyePoint(), ((Character)_player).GetLookDir(), new Color(1f, 0.45f, 0.1f), 7f);
			Say("A sheet of flame fans out from your fingertips!");
		}
	}

	private void CastThunderwave()
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: 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)
		List<Character> list = Enemies(((Component)_player).transform.position, 5f).ToList();
		if (list.Count == 0)
		{
			Say("$fairy_spell_no_target");
		}
		else
		{
			if (!Spend(FairyAbility.Thunderwave))
			{
				return;
			}
			foreach (Character item in list)
			{
				Hit(item, new DamageTypes
				{
					m_blunt = 22f * LevelScale()
				}, 80f, 3f);
				PushAwayFromCaster(item, 12f, 4f);
			}
			FairySpellFx.Nova(((Component)_player).transform.position + Vector3.up, new Color(0.6f, 0.75f, 1f), 5f);
			Say("A wave of thunderous force sweeps out!");
		}
	}

	private void CastHealingWord()
	{
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		Player val = FindAllyInFrontOrSelf(20f);
		if (FullHealth((Character)(object)val))
		{
			Say("Already at full health.");
		}
		else if (Spend(FairyAbility.HealingWord))
		{
			((Character)val).Heal(18f * LevelScale(), true);
			FairySpellFx.Flash(((Character)val).GetCenterPoint(), new Color(0.5f, 1f, 0.6f), 2.5f, 0.6f);
			Say("A word of healing!");
		}
	}

	private void CastShield()
	{
		if (Spend(FairyAbility.Shield))
		{
			float num = 8f * (Subclass.Is(_player, "Abjuration") ? 2f : 1f);
			_shieldUntil = Time.time + num;
			ApplyTimedBuffVisual(FairyAbility.Shield, num);
			Say("An invisible barrier of force springs up!");
		}
	}

	private void CastGuidingBolt()
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		if (Spend(FairyAbility.GuidingBolt))
		{
			Bolt(30f, 1.4f, new Color(1f, 0.95f, 0.6f), new DamageTypes
			{
				m_fire = 16f * LevelScale(),
				m_spirit = 16f * LevelScale()
			}, "firebolt", delegate(Character t)
			{
				FairyVfx.SpawnOutline(t);
			});
			Say("A flash of light streaks toward your foe!");
		}
	}

	private void CastHex()
	{
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		Character val = FindNearestInCone(20f, 25f, includePlayers: false);
		if ((Object)(object)val == (Object)null)
		{
			Say("$fairy_spell_no_target");
		}
		else if (Spend(FairyAbility.Hex))
		{
			_hexedUntil[val] = Time.time + 60f * LevelScale();
			FairySpellFx.Flash(val.GetCenterPoint(), new Color(0.5f, 0.1f, 0.6f), 3f, 0.8f);
			Say("You place a hex on your foe.");
		}
	}

	private void CastBless()
	{
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		if (Spend(FairyAbility.Bless))
		{
			float num = 60f * LevelScale();
			_blessUntil = Time.time + num;
			ApplyTimedBuffVisual(FairyAbility.Bless, num);
			FairySpellFx.Nova(((Component)_player).transform.position + Vector3.up, new Color(1f, 0.95f, 0.7f), 4f);
			Say("You and nearby allies are blessed!");
		}
	}

	private void CastThunderousSmite()
	{
		if (Spend(FairyAbility.ThunderStrike))
		{
			_smiteArmedUntil = Time.time + 30f;
			ApplyTimedBuffVisual(FairyAbility.ThunderStrike, 30f);
			Say("Your weapon rings with thunder...");
		}
	}

	public bool TryConsumeThunderousSmite()
	{
		if (Time.time >= _smiteArmedUntil)
		{
			return false;
		}
		_smiteArmedUntil = 0f;
		SEMan sEMan = ((Character)_player).GetSEMan();
		if (sEMan != null)
		{
			sEMan.RemoveStatusEffect(StringExtensionMethods.GetStableHashCode("SE_FairySpellBuff_" + FairyAbility.ThunderStrike), true);
		}
		return true;
	}

	private void CastIceKnife()
	{
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		if (!Spend(FairyAbility.IceKnife))
		{
			return;
		}
		Bolt(30f, 1.2f, new Color(0.7f, 0.9f, 1f), new DamageTypes
		{
			m_pierce = 16f * LevelScale()
		}, "rayoffrost", delegate(Character t)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			foreach (Character item in Enemies(((Component)t).transform.position, 3f).ToList())
			{
				Hit(item, new DamageTypes
				{
					m_frost = 12f * LevelScale()
				});
			}
			FairySpellFx.Nova(t.GetCenterPoint(), new Color(0.7f, 0.9f, 1f), 3f);
		});
		Say("A shard of ice flies out and explodes!");
	}

	private void CastScorchingRay()
	{
		if (Spend(FairyAbility.ScorchingRay))
		{
			((MonoBehaviour)this).StartCoroutine(ScorchingRayRoutine());
			Say("Three rays of fire blaze out!");
		}
	}

	private IEnumerator ScorchingRayRoutine()
	{
		for (int i = 0; i < 3; i++)
		{
			Bolt(dirOverride: Quaternion.AngleAxis((float)(i - 1) * 4f, Vector3.up) * ((Character)_player).GetLookDir(), dmgSpeed: 34f, lifetime: 1.2f, tint: new Color(1f, 0.35f, 0.05f), dmg: new DamageTypes
			{
				m_fire = 16f * LevelScale()
			}, sprite: "firebolt");
			yield return (object)new WaitForSeconds(0.15f);
		}
	}

	private void CastShatter()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = TargetPoint(20f);
		List<Character> list = Enemies(val, 4f).ToList();
		if (list.Count == 0)
		{
			Say("$fairy_spell_no_target");
		}
		else
		{
			if (!Spend(FairyAbility.Shatter))
			{
				return;
			}
			foreach (Character item in list)
			{
				Hit(item, new DamageTypes
				{
					m_blunt = 32f * LevelScale()
				}, 20f, 2f);
			}
			FairySpellFx.Nova(val + Vector3.up * 0.5f, new Color(0.75f, 0.8f, 1f), 4f);
			Say("A painfully loud ringing noise erupts!");
		}
	}

	private void CastMoonbeam()
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		if (Spend(FairyAbility.Moonbeam))
		{
			_moonbeamPos = TargetPoint(18f);
			_moonbeamUntil = Time.time + 10f * LevelScale();
			_moonbeamNextTick = 0f;
			FairySpellFx.Column(_moonbeamPos, new Color(0.75f, 0.85f, 1f), 10f * LevelScale(), 3f);
			Say("A silvery beam of pale light shines down!");
		}
	}

	private void CastSpiritualWeapon()
	{
		if (Spend(FairyAbility.SpiritualWeapon))
		{
			float num = 30f * LevelScale();
			_spiritualWeaponUntil = Time.time + num;
			_spiritualWeaponNextTick = 0f;
			ApplyTimedBuffVisual(FairyAbility.SpiritualWeapon, num);
			Say("A spectral weapon appears at your side!");
		}
	}

	private void CastBlur()
	{
		if (Spend(FairyAbility.Blur))
		{
			float num = 30f * LevelScale();
			_blurUntil = Time.time + num;
			ApplyTimedBuffVisual(FairyAbility.Blur, num);
			Say("Your body becomes blurred and shifting.");
		}
	}

	private void CastLesserRestoration()
	{
		//IL_00b8: 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)
		Player val = FindAllyInFrontOrSelf(6f);
		SEMan sEMan = ((Character)val).GetSEMan();
		List<StatusEffect> list = ((sEMan == null) ? new List<StatusEffect>() : sEMan.GetStatusEffects().Where(IsAffliction).ToList());
		if (list.Count == 0)
		{
			Say("There's nothing to cure.");
		}
		else
		{
			if (!Spend(FairyAbility.LesserRestoration))
			{
				return;
			}
			int num = 0;
			foreach (StatusEffect item in list)
			{
				sEMan.RemoveStatusEffect(item.NameHash(), true);
				num++;
			}
			FairySpellFx.Flash(((Character)val).GetCenterPoint(), new Color(0.6f, 1f, 0.8f), 2.5f, 0.6f);
			Say((num > 0) ? "Afflictions wash away." : "There was nothing to cure.");
		}
	}

	private static bool IsAffliction(StatusEffect se)
	{
		if ((Object)(object)se == (Object)null)
		{
			return false;
		}
		string n = ((Object)se).name ?? "";
		return BadEffects.Any((string b) => n.IndexOf(b, StringComparison.OrdinalIgnoreCase) >= 0) || n == "SE_FairyFrostSlow" || n == "SE_FairyStun";
	}

	private static bool FullHealth(Character c)
	{
		return (Object)(object)c == (Object)null || c.GetHealth() >= c.GetMaxHealth() - 0.5f;
	}

	private bool AnyoneHurt(float radius)
	{
		return Player.GetAllPlayers().Any((Player pl) => Vector3.Distance(((Component)pl).transform.position, ((Component)_player).transform.position) <= radius && !FullHealth((Character)(object)pl));
	}

	private void CastAid()
	{
		if (Spend(FairyAbility.Aid))
		{
			float num = 600f;
			_aidUntil = Time.time + num;
			ApplyTimedBuffVisual(FairyAbility.Aid, num);
			((Character)_player).Heal(20f, true);
			Say("Your allies are bolstered with toughness and resolve.");
		}
	}

	public static bool AidedBy(Player p)
	{
		//IL_0036: 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)
		foreach (Player allPlayer in Player.GetAllPlayers())
		{
			FairyTraits component = ((Component)allPlayer).GetComponent<FairyTraits>();
			if ((Object)(object)component != (Object)null && component.AidActive && Vector3.Distance(((Component)allPlayer).transform.position, ((Component)p).transform.position) <= 15f)
			{
				return true;
			}
		}
		return false;
	}

	private void CastHoldPerson()
	{
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		Character val = FindNearestInCone(18f, 25f, includePlayers: false);
		if ((Object)(object)val == (Object)null)
		{
			Say("$fairy_spell_no_target");
		}
		else if (val.IsBoss())
		{
			Say("The creature is too powerful to hold.");
		}
		else if (Spend(FairyAbility.HoldPerson))
		{
			((MonoBehaviour)this).StartCoroutine(HoldRoutine(val, 6f * LevelScale()));
			FairySpellFx.Flash(val.GetCenterPoint(), new Color(0.8f, 0.8f, 1f), 3f, 0.8f);
			Say("Your foe is paralyzed!");
		}
	}

	private IEnumerator HoldRoutine(Character t, float seconds)
	{
		float until = Time.time + seconds;
		while ((Object)(object)t != (Object)null && !t.IsDead() && Time.time < until)
		{
			SEMan sEMan = t.GetSEMan();
			if (sEMan != null)
			{
				sEMan.AddStatusEffect(FairyStunHash, true, 0, 0f, (short)(-1));
			}
			yield return (object)new WaitForSeconds(1f);
		}
	}

	private void CastFireball()
	{
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		if (Spend(FairyAbility.Fireball))
		{
			Bolt(26f, 2f, new Color(1f, 0.4f, 0.05f), new DamageTypes
			{
				m_fire = 10f
			}, "firebolt", delegate(Character t)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				FireballBurst(t.GetCenterPoint());
			});
			Say("A bright streak flashes toward your foe and blossoms into flame!");
		}
	}

	private void FireballBurst(Vector3 p)
	{
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		foreach (Character item in Enemies(p, 6f).ToList())
		{
			Hit(item, new DamageTypes
			{
				m_fire = 45f * LevelScale()
			}, 30f, 2f);
		}
		FairySpellFx.Explosion(p, new Color(1f, 0.45f, 0.1f), 6f);
	}

	private void CastLightningBolt()
	{
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		List<Character> list = EnemiesInLine(30f, 1.5f).ToList();
		if (list.Count == 0)
		{
			Say("$fairy_spell_no_target");
		}
		else
		{
			if (!Spend(FairyAbility.LightningBolt))
			{
				return;
			}
			foreach (Character item in list)
			{
				Hit(item, new DamageTypes
				{
					m_lightning = 45f * LevelScale()
				}, 0f, 2f);
			}
			FairySpellFx.Line(((Character)_player).GetEyePoint(), ((Character)_player).GetLookDir(), new Color(0.6f, 0.75f, 1f), 30f);
			Say("A stroke of lightning blasts out in a line!");
		}
	}

	private void CastHaste()
	{
		if (Spend(FairyAbility.Haste))
		{
			float num = 30f * LevelScale();
			_hasteUntil = Time.time + num;
			ApplyTimedBuffVisual(FairyAbility.Haste, num);
			Say("Time seems to slow around you - you are hasted!");
		}
	}

	private void CastFly()
	{
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		if (Spend(FairyAbility.Fly))
		{
			float num = 60f * LevelScale();
			_flyUntil = Time.time + num;
			ApplyTimedBuffVisual(FairyAbility.Fly, num);
			KeyboardShortcut value = FairyRacePlugin.FlyKey.Value;
			Say("You can fly! Press " + ((object)((KeyboardShortcut)(ref value)).MainKey/*cast due to .constrained prefix*/).ToString() + " to take off.");
		}
	}

	private void CastSpiritGuardians()
	{
		if (Spend(FairyAbility.SpiritGuardians))
		{
			float num = 30f * LevelScale();
			_spiritGuardiansUntil = Time.time + num;
			_spiritGuardiansNextTick = 0f;
			ApplyTimedBuffVisual(FairyAbility.SpiritGuardians, num);
			Say("Spirits flit around you, guarding you!");
		}
	}

	private void CastCallLightning()
	{
		if (Spend(FairyAbility.CallLightning))
		{
			float num = 30f * LevelScale();
			_callLightningUntil = Time.time + num;
			_callLightningNextTick = 0f;
			ApplyTimedBuffVisual(FairyAbility.CallLightning, num);
			Say("A storm cloud gathers above you!");
		}
	}

	private void CastMassHealingWord()
	{
		//IL_0055: 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_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		if (!AnyoneHurt(20f))
		{
			Say("Everyone nearby is already at full health.");
		}
		else
		{
			if (!Spend(FairyAbility.MassHealingWord))
			{
				return;
			}
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				if (Vector3.Distance(((Component)allPlayer).transform.position, ((Component)_player).transform.position) <= 20f)
				{
					((Character)allPlayer).Heal(25f * LevelScale(), true);
					FairySpellFx.Flash(((Character)allPlayer).GetCenterPoint(), new Color(0.5f, 1f, 0.6f), 2.5f, 0.6f);
				}
			}
			Say("Words of restoration ring out!");
		}
	}

	private void CastIceStorm()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		Vector3 pos = TargetPoint(25f);
		List<Character> list = Enemies(pos, 6f).ToList();
		if (list.Count == 0)
		{
			Say("$fairy_spell_no_target");
		}
		else
		{
			if (!Spend(FairyAbility.IceStorm))
			{
				return;
			}
			foreach (Character item in list)
			{
				Hit(item, new DamageTypes
				{
					m_blunt = 20f * LevelScale(),
					m_frost = 30f * LevelScale()
				});
				SEMan sEMan = item.GetSEMan();
				if (sEMan != null)
				{
					sEMan.AddStatusEffect(FairySlowHash, true, 0, 0f, (short)(-1));
				}
			}
			FairySpellFx.Explosion(pos, new Color(0.7f, 0.9f, 1f), 6f);
			Say("Hailstones and freezing rain pound down!");
		}
	}

	private void CastGreaterInvisibility()
	{
		if (Spend(FairyAbility.GreaterInvisibility))
		{
			float num = 30f * LevelScale();
			_greaterInvisUntil = Time.time + num;
			_invisibleExpiresAt = Time.time + num;
			ApplyTimedBuffVisual(FairyAbility.GreaterInvisibility, num);
			Say("You vanish - and stay vanished even while you fight.");
		}
	}

	private void CastStoneskin()
	{
		if (Spend(FairyAbility.Stoneskin))
		{
			float num = 60f * LevelScale();
			_stoneskinUntil = Time.time + num;
			ApplyTimedBuffVisual(FairyAbility.Stoneskin, num);
			Say("Your flesh turns hard as stone.");
		}
	}

	private void CastConeOfCold()
	{
		//IL_0063: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		List<Character> list = EnemiesInCone(12f, 35f).ToList();
		if (list.Count == 0)
		{
			Say("$fairy_spell_no_target");
		}
		else
		{
			if (!Spend(FairyAbility.ConeOfCold))
			{
				return;
			}
			foreach (Character item in list)
			{
				Hit(item, new DamageTypes
				{
					m_frost = 55f * LevelScale()
				});
				SEMan sEMan = item.GetSEMan();
				if (sEMan != null)
				{
					sEMan.AddStatusEffect(FairySlowHash, true, 0, 0f, (short)(-1));
				}
			}
			FairySpellFx.Cone(((Character)_player).GetEyePoint(), ((Character)_player).GetLookDir(), new Color(0.7f, 0.9f, 1f), 12f);
			Say("A blast of cold air erupts from your hands!");
		}
	}

	private void CastMassCureWounds()
	{
		//IL_0055: 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_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		if (!AnyoneHurt(15f))
		{
			Say("Everyone nearby is already at full health.");
		}
		else
		{
			if (!Spend(FairyAbility.MassCureWounds))
			{
				return;
			}
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				if (Vector3.Distance(((Component)allPlayer).transform.position, ((Component)_player).transform.position) <= 15f)
				{
					((Character)allPlayer).Heal(45f * LevelScale(), true);
					FairySpellFx.Flash(((Character)allPlayer).GetCenterPoint(), new Color(0.5f, 1f, 0.6f), 3f, 0.8f);
				}
			}
			Say("A wave of healing energy washes out!");
		}
	}

	private void CastFlameStrike()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: 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)
		Vector3 val = TargetPoint(25f);
		List<Character> list = Enemies(val, 4f).ToList();
		if (list.Count == 0)
		{
			Say("$fairy_spell_no_target");
		}
		else
		{
			if (!Spend(FairyAbility.FlameStrike))
			{
				return;
			}
			foreach (Character item in list)
			{
				Hit(item, new DamageTypes
				{
					m_fire = 30f * LevelScale(),
					m_spirit = 30f * LevelScale()
				}, 0f, 2f);
			}
			FairySpellFx.Column(val, new Color(1f, 0.6f, 0.2f), 1.5f, 4f);
			FairySpellFx.Explosion(val, new Color(1f, 0.6f, 0.2f), 4f);
			Say("A column of divine fire roars down!");
		}
	}

	private void CastChainLightning()
	{
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: 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_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		Character first = FindNearestInCone(30f, 25f, includePlayers: false);
		if ((Object)(object)first == (Object)null)
		{
			Say("$fairy_spell_no_target");
		}
		else
		{
			if (!Spend(FairyAbility.ChainLightning))
			{
				return;
			}
			List<Character> list = new List<Character> { first };
			IEnumerable<Character> collection = (from c in Enemies(((Component)first).transform.position, 12f)
				where (Object)(object)c != (Object)(object)first
				orderby Vector3.Distance(((Component)c).transform.position, ((Component)first).transform.position)
				select c).Take(3);
			list.AddRange(collection);
			Vector3 val = ((Character)_player).GetEyePoint();
			foreach (Character item in list)
			{
				Hit(item, new DamageTypes
				{
					m_lightning = 45f * LevelScale()
				}, 0f, 2f);
				Vector3 origin = val;
				Vector3 val2 = item.GetCenterPoint() - val;
				FairySpellFx.Line(origin, ((Vector3)(ref val2)).normalized, new Color(0.6f, 0.75f, 1f), Vector3.Distance(val, item.GetCenterPoint()));
				val = item.GetCenterPoint();
			}
			Say("Lightning arcs from foe to foe!");
		}
	}

	private void CastHealSpell()
	{
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		Player val = FindAllyInFrontOrSelf(10f);
		SEMan sEMan = ((Character)val).GetSEMan();
		if (FullHealth((Character)(object)val) && (sEMan == null || !sEMan.GetStatusEffects().Any(IsAffliction)))
		{
			Say("Already at full health, with nothing to cure.");
		}
		else
		{
			if (!Spend(FairyAbility.HealSpell))
			{
				return;
			}
			((Character)val).Heal(100f * LevelScale(), true);
			SEMan sEMan2 = ((Character)val).GetSEMan();
			if (sEMan2 != null)
			{
				foreach (StatusEffect se in sEMan2.GetStatusEffects().ToList())
				{
					if ((Object)(object)se != (Object)null && BadEffects.Any((string b) => (((Object)se).name ?? "").IndexOf(b, StringComparison.OrdinalIgnoreCase) >= 0))
					{
						sEMan2.RemoveStatusEffect(se.NameHash(), true);
					}
				}
			}
			FairySpellFx.Column(((Component)val).transform.position, new Color(0.6f, 1f, 0.7f), 1.5f);
			Say("A surge of positive energy heals and cleanses!");
		}
	}

	private void CastSunbeam()
	{
		//IL_0063: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		List<Character> list = EnemiesInLine(30f, 1.5f).ToList();
		if (list.Count == 0)
		{
			Say("$fairy_spell_no_target");
		}
		else
		{
			if (!Spend(FairyAbility.Sunbeam))
			{
				return;
			}
			foreach (Character item in list)
			{
				Hit(item, new DamageTypes
				{
					m_fire = 50f * LevelScale()
				});
				SEMan sEMan = item.GetSEMan();
				if (sEMan != null)
				{
					sEMan.AddStatusEffect(FairySlowHash, true, 0, 0f, (short)(-1));
				}
			}
			FairySpellFx.Line(((Character)_player).GetEyePoint(), ((Character)_player).GetLookDir(), new Color(1f, 0.95f, 0.6f), 30f);
			Say("A beam of brilliant sunlight flashes out!");
		}
	}

	private void TickExtraSpells()
	{
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_025c: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_0300: Unknown result type (might be due to invalid IL or missing references)
		//IL_0358: Unknown result type (might be due to invalid IL or missing references)
		//IL_0383: Unknown result type (might be due to invalid IL or missing references)
		//IL_03af: Unknown result type (might be due to invalid IL or missing references)
		float now = Time.time;
		if (now < _spiritGuardiansUntil && now >= _spiritGuardiansNextTick)
		{
			_spiritGuardiansNextTick = now + 2f;
			foreach (Character item in Enemies(((Component)_player).transform.position, 5f).ToList())
			{
				Hit(item, new DamageTypes
				{
					m_damage = 8f * LevelScale(),
					m_spirit = 5f * LevelScale()
				});
				SEMan sEMan = item.GetSEMan();
				if (sEMan != null)
				{
					sEMan.AddStatusEffect(FairySlowHash, true, 0, 0f, (short)(-1));
				}
			}
			FairySpellFx.Flash(((Component)_player).transform.position + Vector3.up, new Color(1f, 0.95f, 0.7f), 5f, 0.4f);
		}
		if (now < _callLightningUntil && now >= _callLightningNextTick)
		{
			Character val = (from c in Enemies(((Component)_player).transform.position, 20f)
				orderby Vector3.Distance(((Component)c).transform.position, ((Component)_player).transform.position)
				select c).FirstOrDefault();
			if ((Object)(object)val != (Object)null)
			{
				_callLightningNextTick = now + 3f;
				Hit(val, new DamageTypes
				{
					m_lightning = 30f * LevelScale()
				}, 0f, 2f);
				FairySpellFx.Column(((Component)val).transform.position, new Color(0.6f, 0.75f, 1f), 0.4f, 0.8f);
			}
		}
		if (now < _spiritualWeaponUntil && now >= _spiritualWeaponNextTick)
		{
			Character val2 = (from c in Enemies(((Component)_player).transform.position, 10f)
				orderby Vector3.Distance(((Component)c).transform.position, ((Component)_player).transform.position)
				select c).FirstOrDefault();
			if ((Object)(object)val2 != (Object)null)
			{
				_spiritualWeaponNextTick = now + 2f;
				Hit(val2, new DamageTypes
				{
					m_damage = 10f * LevelScale(),
					m_spirit = 5f * LevelScale()
				}, 0f, 1.5f);
				FairySpellFx.Flash(val2.GetCenterPoint(), new Color(1f, 0.95f, 0.6f), 2f, 0.3f);
			}
		}
		if (now < _moonbeamUntil && now >= _moonbeamNextTick)
		{
			_moonbeamNextTick = now + 1f;
			foreach (Character item2 in Enemies(_moonbeamPos, 3f).ToList())
			{
				Hit(item2, new DamageTypes
				{
					m_damage = 7f * LevelScale(),
					m_spirit = 4f * LevelScale()
				});
			}
		}
		if (_hexedUntil.Count <= 0 || Time.frameCount % 300 != 0)
		{
			return;
		}
		foreach (Character item3 in (from kv in _hexedUntil
			where (Object)(object)kv.Key == (Object)null || now >= kv.Value
			select kv.Key).ToList())
		{
			_hexedUntil.Remove(item3);
		}
	}

	public void SubclassMistyEscape()
	{
		TeleportSelfForward(-8f, "$fairy_spell_mistystep_cast");
		_invisibleExpiresAt = Time.time + 5f;
		_greaterInvisUntil = Time.time + 5f;
		ApplyTimedBuffVisual(FairyAbility.Invisibility, 5f);
		((Character)_player).Message((MessageType)2, "Misty Escape!", 0, (Sprite)null, false);
	}

	public void GrantTimedSpellEffect(FairyAbility a, float seconds)
	{
		float num = Time.time + seconds;
		switch (a)
		{
		default:
			return;
		case FairyAbility.Shield:
			_shieldUntil = num;
			break;
		case FairyAbility.Stoneskin:
			_stoneskinUntil = num;
			break;
		case FairyAbility.Blur:
			_blurUntil = num;
			break;
		case FairyAbility.Haste:
			_hasteUntil = num;
			break;
		case FairyAbility.Fly:
			_flyUntil = num;
			break;
		}
		ApplyTimedBuffVisual(a, seconds);
	}

	public void SubclassBlink(float range)
	{
		TeleportSelfForward(range, "$fairy_spell_mistystep_cast");
	}

	public void SubclassHaste(float seconds)
	{
		_hasteUntil = Time.time + seconds;
		ApplyTimedBuffVisual(FairyAbility.Haste, seconds);
	}

	public void SubclassBlur(float seconds)
	{
		_blurUntil = Time.time + seconds;
		ApplyTimedBuffVisual(FairyAbility.Blur, seconds);
	}

	public static string IconFor(FairyAbility a)
	{
		string text = "icon_spell_" + ((a == FairyAbility.HealSpell) ? "heal" : a.ToString().ToLowerInvariant());
		if (FairyEmbeddedIcons.Has(text))
		{
			return text;
		}
		if (FairySrdMigration.AbilityIcons.TryGetValue(a.ToString(), out var value) && FairyEmbeddedIcons.Has(value))
		{
			return value;
		}
		return LegacyIconFor(a);
	}

	private static string LegacyIconFor(FairyAbility a)
	{
		switch (a)
		{
		case FairyAbility.SacredFlame:
		case FairyAbility.RadiantBurst:
		case FairyAbility.ProduceFlame:
		case FairyAbility.BurningHands:
		case FairyAbility.GuidingBolt:
		case FairyAbility.ScorchingRay:
		case FairyAbility.Fireball:
		case FairyAbility.FlameStrike:
		case FairyAbility.Sunbeam:
			return "icon_spell_firebolt";
		case FairyAbility.RimeTouch:
		case FairyAbility.IceKnife:
		case FairyAbility.IceStorm:
		case FairyAbility.ConeOfCold:
			return "icon_spell_rayoffrost";
		case FairyAbility.AcidSplash:
			return "icon_spell_poisonspray";
		case FairyAbility.ShockingGrasp:
		case FairyAbility.Thunderwave:
		case FairyAbility.ThunderStrike:
		case FairyAbility.Shatter:
		case FairyAbility.LightningBolt:
		case FairyAbility.CallLightning:
		case FairyAbility.ChainLightning:
			return "icon_spell_eldritchblast";
		case FairyAbility.ChillTouch:
		case FairyAbility.DeathKnell:
		case FairyAbility.MagicMissile:
		case FairyAbility.Hex:
		case FairyAbility.Moonbeam:
		case FairyAbility.SpiritualWeapon:
		case FairyAbility.SpiritGuardians:
			return "icon_spell_eldritchblast";
		case FairyAbility.HealingWord:
		case FairyAbility.LesserRestoration:
		case FairyAbility.Aid:
		case FairyAbility.MassHealingWord:
		case FairyAbility.MassCureWounds:
		case FairyAbility.HealSpell:
			return "icon_spell_curewounds";
		case FairyAbility.Shield:
		case FairyAbility.Bless:
		case FairyAbility.Stoneskin:
			return "icon_spell_magearmor";
		case FairyAbility.Blur:
		case FairyAbility.GreaterInvisibility:
			return "icon_spell_invisibility";
		case FairyAbility.Haste:
			return "icon_spell_expretreat";
		case FairyAbility.Fly:
			return "icon_spell_featherfall";
		case FairyAbility.Shillelagh:
			return "icon_spell_thornwhip";
		case FairyAbility.HoldPerson:
			return "icon_spell_charmperson";
		default:
			return "icon_spell_bladeward";
		}
	}

	private void WheelAim()
	{
		List<FairySpellDef> list = KnownSpells();
		if (list.Count == 0)
		{
			return;
		}
		float num = 0f;
		float num2 = 0f;
		try
		{
			num = ZInput.GetJoyRightStickX();
			num2 = 0f - ZInput.GetJoyRightStickY();
		}
		catch
		{
		}
		if (!(num * num + num2 * num2 < 0.20249999f))
		{
			float num3 = Mathf.Atan2(num, num2) * 57.29578f;
			if (num3 < 0f)
			{
				num3 += 360f;
			}
			int spellCycleIndex = Mathf.RoundToInt(num3 / (360f / (float)list.Count)) % list.Count;
			_spellCycleIndex = spellCycleIndex;
		}
	}

	private void DrawSpellWheel(List<FairySpellDef> known)
	{
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_0140: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: 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_0180: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Expected O, but got Unknown
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: 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_007a: Expected O, but got Unknown
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0245: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0404: Unknown result type (might be due to invalid IL or missing references)
		//IL_0421: Unknown result type (might be due to invalid IL or missing references)
		//IL_044a: Unknown result type (might be due to invalid IL or missing references)
		//IL_034e: Unknown result type (might be due to invalid IL or missing references)
		//IL_035b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0372: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0281: Unknown result type (might be due to invalid IL or missing references)
		//IL_0286: Unknown result type (might be due to invalid IL or missing references)
		//IL_029a: Unknown result type (might be due to invalid IL or missing references)
		//IL_029f: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_0304: Unknown result type (might be due to invalid IL or missing references)
		if (s_wheelLabel == null)
		{
			s_wheelLabel = new GUIStyle(GUI.skin.label)
			{
				fontSize = 20,
				fontStyle = (FontStyle)1,
				alignment = (TextAnchor)4
			};
			s_wheelLabel.normal.textColor = Color.yellow;
			s_wheelTitle = new GUIStyle(GUI.skin.label)
			{
				fontSize = 15,
				alignment = (TextAnchor)4
			};
			s_wheelTitle.normal.textColor = new Color(0.85f, 0.85f, 0.85f);
		}
		int count = known.Count;
		float sw;
		float sh;
		Matrix4x4 matrix = FairyGuiScale.Push(out sw, out sh);
		Vector2 val = default(Vector2);
		((Vector2)(ref val))..ctor(sw / 2f, sh / 2f);
		float num = Mathf.Clamp(120f + (float)count * 9f, 160f, Mathf.Min(sh, sw) * 0.38f);
		float num2 = Mathf.Clamp(num * 2f * (float)Math.PI / (float)Mathf.Max(count, 1) * 0.75f, 36f, 72f);
		Color color = GUI.color;
		GUI.color = new Color(0f, 0f, 0f, 0.55f);
		GUI.DrawTexture(new Rect(val.x - num - num2, val.y - num - num2, (num + num2) * 2f, (num + num2) * 2f), (Texture)(object)Texture2D.whiteTexture);
		GUI.color = color;
		Rect val3 = default(Rect);
		Rect val5 = default(Rect);
		for (int i = 0; i < count; i++)
		{
			float num3 = (float)i * 360f / (float)count * ((float)Math.PI / 180f);
			Vector2 val2 = val + new Vector2(Mathf.Sin(num3), 0f - Mathf.Cos(num3)) * num;
			bool flag = i == _spellCycleIndex;
			float num4 = (flag ? (num2 * 1.3f) : num2);
			((Rect)(ref val3))..ctor(val2.x - num4 / 2f, val2.y - num4 / 2f, num4, num4);
			Sprite val4 = IconSpriteFor(known[i].IconName);
			if (!flag)
			{
				GUI.color = new Color(1f, 1f, 1f, 0.7f);
			}
			if ((Object)(object)val4 != (Object)null && (Object)(object)val4.texture != (Object)null)
			{
				Texture2D texture = val4.texture;
				Rect textureRect = val4.textureRect;
				float num5 = ((Rect)(ref textureRect)).x / (float)((Texture)texture).width;
				textureRect = val4.textureRect;
				float num6 = ((Rect)(ref textureRect)).y / (float)((Texture)texture).height;
				textureRect = val4.textureRect;
				float num7 = ((Rect)(ref textureRect)).width / (float)((Texture)texture).width;
				textureRect = val4.textureRect;
				((Rect)(ref val5))..ctor(num5, num6, num7, ((Rect)(ref textureRect)).height / (float)((Texture)texture).height);
				GUI.DrawTextureWithTexCoords(val3, (Texture)(object)texture, val5);
			}
			else
			{
				GUI.Box(val3, "?");
			}
			GUI.color = color;
		}
		if (_spellCycleIndex >= 0 && _spellCycleIndex < count)
		{
			FairySpellDef fairySpellDef = known[_spellCycleIndex];
			GUI.Label(new Rect(val.x - 200f, val.y - 30f, 400f, 30f), Localization.instance.Localize(fairySpellDef.DisplayNameToken), s_wheelLabel);
			int num8 = SpellAccess.SpellLevel(fairySpellDef.Id);
			GUI.Label(new Rect(val.x - 200f, val.y + 2f, 400f, 24f), (num8 == 0) ? "Cantrip" : ("Level " + num8 + " spell"), s_wheelTitle);
		}
		GUI.Label(new Rect(val.x - 250f, val.y + num + num2 * 0.8f, 500f, 24f), "Right stick: aim    " + FairyPad.Describe(FairyPad.CastSpell) + ": cast    B: close", s_wheelTitle);
		GUI.matrix = matrix;
	}

	private void Awake()
	{
		_player = ((Component)this).GetComponent<Player>();
	}

	private void OnDisable()
	{
		if ((Object)(object)_player != (Object)null)
		{
			_player.SetGhostMode(false);
		}
	}

	private void Update()
	{
		//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_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: 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 (FairyBagOfHolding.SearchFocused)
		{
			MaintainActiveSpellEffects();
			return;
		}
		UpdateSpellPicker();
		KeyboardShortcut value;
		if (FairyRacePlugin.PrevSpellKey != null)
		{
			value = FairyRacePlugin.PrevSpellKey.Value;
			if ((int)((KeyboardShortcut)(ref value)).MainKey != 0)
			{
				value = FairyRacePlugin.PrevSpellKey.Value;
				if (Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey) && !InventoryGui.IsVisible())
				{
					CycleSpellBack();
				}
			}
		}
		if (FairyPad.Down(FairyPad.PrevSpell) && !InventoryGui.IsVisible())
		{
			CycleSpellBack();
		}
		value = FairyRacePlugin.CastSpellKey.Value;
		if (Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey) || FairyPad.Down(FairyPad.CastSpell))
		{
			CastSelectedSpell();
			if (_pickerLatched)
			{
				SpellPickerOpen = false;
				_pickerLatched = false;
			}
		}
		MaintainActiveSpellEffects();
	}

	private void UpdateSpellPicker()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
		KeyboardShortcut value = FairyRacePlugin.CycleSpellKey.Value;
		KeyCode mainKey = ((KeyboardShortcut)(ref value)).MainKey;
		if (InventoryGui.IsVisible() || Menu.IsVisible() || ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) || Console.IsVisible() || TextInput.IsVisible())
		{
			_cycleKeyDownAt = -1f;
			_padCycleDownAt = -1f;
			SpellPickerOpen = false;
			_pickerLatched = false;
		}
		else
		{
			if (UpdatePadSpellPicker())
			{
				return;
			}
			bool flag = Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305);
			if (Input.GetKeyDown(mainKey) && flag)
			{
				bool flag2 = (SpellPickerOpen = (!SpellPickerOpen || !_pickerLatched) && KnownSpells().Count > 0);
				_pickerLatched = flag2;
				_cycleKeyDownAt = -1f;
				if (flag2 && _spellCycleIndex < 0)
				{
					_spellCycleIndex = 0;
				}
				return;
			}
			if (_pickerLatched && FefEscGuard.Pressed())
			{
				SpellPickerOpen = false;
				_pickerLatched = false;
				return;
			}
			if (Input.GetKeyDown(mainKey))
			{
				_cycleKeyDownAt = Time.time;
			}
			if (_cycleKeyDownAt >= 0f && Input.GetKey(mainKey) && !SpellPickerOpen && Time.time - _cycleKeyDownAt >= 0.3f && KnownSpells().Count > 0)
			{
				SpellPickerOpen = true;
				if (_spellCycleIndex < 0)
				{
					_spellCycleIndex = 0;
				}
			}
			if (SpellPickerOpen)
			{
				List<FairySpellDef> list = KnownSpells();
				if (list.Count == 0)
				{
					SpellPickerOpen = false;
					return;
				}
				float y = Input.mouseScrollDelta.y;
				if (y < -0.01f)
				{
					_spellCycleIndex = (_spellCycleIndex + 1) % list.Count;
				}
				else if (y > 0.01f)
				{
					_spellCycleIndex = (_spellCycleIndex - 1 + list.Count) % list.Count;
				}
				int lvl;
				for (lvl = 0; lvl <= 6; lvl++)
				{
					if (Input.GetKeyDown((KeyCode)(48 + lvl)) || Input.GetKeyDown((KeyCode)(256 + lvl)))
					{
						int num = list.FindIndex((FairySpellDef d) => SpellAccess.SpellLevel(d.Id) == lvl);
						if (num >= 0)
						{
							_spellCycleIndex = num;
						}
					}
				}
			}
			if (!Input.GetKeyUp(mainKey) || _pickerLatched)
			{
				return;
			}
			bool flag4 = !SpellPickerOpen && _cycleKeyDownAt >= 0f;
			SpellPickerOpen = false;
			_cycleKeyDownAt = -1f;
			if (flag4)
			{
				if (Input.GetKe