Decompiled source of Staffs of the Forsaken v1.1.0

StaffsOfTheForsaken.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using StaffsOfTheForsaken.Abilities;
using StaffsOfTheForsaken.Data;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("StaffsoftheForsaken")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("HP")]
[assembly: AssemblyProduct("StaffsoftheForsaken")]
[assembly: AssemblyCopyright("Copyright © HP 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("aa26718f-a860-473f-997c-5803d75785f4")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace StaffsOfTheForsaken
{
	[HarmonyPatch(typeof(Humanoid), "StartAttack")]
	internal static class StartAttackPatch
	{
		private static readonly HashSet<string> _staffPrefabNames = new HashSet<string> { "StaffOfMeadows", "StaffOfForest", "StaffOfMire", "StaffOfMountain", "StaffOfPlains", "StaffOfMist", "StaffOfAsh", "StaffOfDeepNorth" };

		private static bool _sfxDumped;

		private static BossAbilityBase GetAbility(string prefabName)
		{
			GameObject prefab = PrefabManager.Instance.GetPrefab(prefabName);
			if ((Object)(object)prefab == (Object)null)
			{
				StaffsPlugin.Log.LogWarning((object)("[GetAbility] PrefabManager returned null for '" + prefabName + "'."));
				return null;
			}
			BossAbilityBase component = prefab.GetComponent<BossAbilityBase>();
			if ((Object)(object)component == (Object)null)
			{
				StaffsPlugin.Log.LogWarning((object)("[GetAbility] No BossAbilityBase on prefab '" + prefabName + "'."));
			}
			return component;
		}

		[HarmonyPrefix]
		private static bool Prefix(Humanoid __instance, Character target, bool secondaryAttack, ref bool __result)
		{
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: 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)
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			ItemData currentWeapon = ((Humanoid)val).GetCurrentWeapon();
			if (currentWeapon == null)
			{
				return true;
			}
			GameObject dropPrefab = currentWeapon.m_dropPrefab;
			string text = ((dropPrefab != null) ? ((Object)dropPrefab).name : null);
			if (string.IsNullOrEmpty(text))
			{
				return true;
			}
			StaffsPlugin.Log.LogInfo((object)("[StartAttack] Prefix hit — weapon='" + text + "'"));
			if (!_staffPrefabNames.Contains(text))
			{
				return true;
			}
			if (!_sfxDumped && (Object)(object)ZNetScene.instance != (Object)null && ZNetScene.instance.m_prefabs.Count > 0)
			{
				_sfxDumped = true;
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("[FxDump] Available ZNetScene prefabs:");
				foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
				{
					if ((Object)(object)prefab != (Object)null && (((Object)prefab).name.StartsWith("vfx_") || ((Object)prefab).name.StartsWith("sfx_") || ((Object)prefab).name.StartsWith("fx_")))
					{
						stringBuilder.AppendLine("  " + ((Object)prefab).name);
					}
				}
				StaffsPlugin.Log.LogInfo((object)stringBuilder.ToString());
			}
			BossAbilityBase ability = GetAbility(text);
			if ((Object)(object)ability == (Object)null)
			{
				StaffsPlugin.Log.LogWarning((object)("[StartAttack] Ability component not found for '" + text + "' — falling back to vanilla attack."));
				return true;
			}
			Vector3 aimPoint = CalculateAimPoint(val);
			bool flag = ability.TryActivate(val, aimPoint);
			__result = flag;
			return false;
		}

		private static Vector3 CalculateAimPoint(Player player)
		{
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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)
			Camera val = null;
			if (Camera.allCameras.Length != 0)
			{
				val = Camera.allCameras[0];
			}
			if ((Object)(object)val == (Object)null)
			{
				val = Camera.main;
			}
			if ((Object)(object)val != (Object)null)
			{
				Ray val2 = default(Ray);
				((Ray)(ref val2))..ctor(((Component)val).transform.position, ((Component)val).transform.forward);
				RaycastHit val3 = default(RaycastHit);
				if (Physics.Raycast(val2, ref val3, 50f, LayerMask.GetMask(new string[8] { "Default", "static_solid", "Default_small", "piece", "terrain", "character", "character_net", "creature" })))
				{
					return ((RaycastHit)(ref val3)).point;
				}
				return ((Component)val).transform.position + ((Component)val).transform.forward * 30f;
			}
			return ((Component)player).transform.position + ((Component)player).transform.forward * 15f;
		}
	}
	[CreateAssetMenu(menuName = "StaffsOfTheForsaken/CooldownEffect")]
	public class StaffCooldownEffect : StatusEffect
	{
		public float CooldownDuration { get; set; }

		public float ElapsedTime
		{
			get
			{
				return base.m_time;
			}
			set
			{
				base.m_time = value;
			}
		}

		public override void Setup(Character character)
		{
			((StatusEffect)this).Setup(character);
			base.m_ttl = CooldownDuration;
		}

		public override string GetIconText()
		{
			float num = base.m_ttl - base.m_time;
			if (num <= 0f)
			{
				return "";
			}
			return (num < 10f) ? (num.ToString("F1") + "s") : (Mathf.CeilToInt(num) + "s");
		}

		public override bool IsDone()
		{
			return base.m_time >= base.m_ttl;
		}
	}
	public static class StaffSetup
	{
		public static void RegisterAll()
		{
			try
			{
				StaffDefinition[] all = StaffRegistry.All;
				foreach (StaffDefinition staffDefinition in all)
				{
					if (staffDefinition.PrefabName == "StaffOfDeepNorth" && !StaffsPlugin.EnableDeepNorthStaffValue)
					{
						StaffsPlugin.Log.LogInfo((object)"[StaffSetup] Skipping StaffOfDeepNorth — EnableDeepNorthStaff is OFF (Experimental). Enable it in the config to craft this staff.");
					}
					else
					{
						RegisterStaff(staffDefinition);
					}
				}
				PrefabManager.OnVanillaPrefabsAvailable -= RegisterAll;
				StaffsPlugin.Log.LogInfo((object)$"Registered {StaffRegistry.All.Length} boss staffs.");
			}
			catch (Exception arg)
			{
				StaffsPlugin.Log.LogError((object)$"StaffSetup.RegisterAll failed: {arg}");
			}
		}

		private static void RegisterStaff(StaffDefinition def)
		{
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Expected O, but got Unknown
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Expected O, but got Unknown
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Expected O, but got Unknown
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Expected O, but got Unknown
			GameObject val = PrefabManager.Instance.CreateClonedPrefab(def.PrefabName, def.BasePrefab);
			if ((Object)(object)val == (Object)null)
			{
				StaffsPlugin.Log.LogError((object)("Could not clone '" + def.BasePrefab + "' for '" + def.PrefabName + "'. Verify the base prefab name exists in this version of Valheim."));
				return;
			}
			BossAbilityBase ability = (BossAbilityBase)(object)val.AddComponent(def.AbilityType);
			Sprite sprite = StaffsPlugin.GetSprite(def.IconName);
			RegisterCooldownEffect(def, sprite, ability);
			ItemDrop component = val.GetComponent<ItemDrop>();
			if ((Object)(object)component == (Object)null)
			{
				StaffsPlugin.Log.LogError((object)("No ItemDrop on cloned prefab " + def.PrefabName));
				return;
			}
			SharedData shared = component.m_itemData.m_shared;
			shared.m_name = def.ItemNameToken;
			shared.m_description = def.DescToken;
			shared.m_maxQuality = 1;
			if ((Object)(object)sprite != (Object)null)
			{
				shared.m_icons = (Sprite[])(object)new Sprite[1] { sprite };
			}
			else
			{
				StaffsPlugin.Log.LogWarning((object)("No icon found for '" + def.IconName + "' — using base staff icon."));
			}
			ApplyEmissionColor(val, def.EmissionColor);
			List<RequirementConfig> list = new List<RequirementConfig>();
			(string, int)[] materials = def.Materials;
			for (int i = 0; i < materials.Length; i++)
			{
				var (item, amount) = materials[i];
				list.Add(new RequirementConfig
				{
					Item = item,
					Amount = amount
				});
			}
			list.Add(new RequirementConfig
			{
				Item = def.TrophyPrefab,
				Amount = 1,
				AmountPerLevel = 0
			});
			ItemConfig val2 = new ItemConfig
			{
				Name = def.ItemNameToken,
				Description = def.DescToken,
				CraftingStation = def.CraftStation,
				MinStationLevel = def.StationLevel,
				Requirements = list.ToArray()
			};
			ItemManager.Instance.AddItem(new CustomItem(val, false, val2));
			StaffsPlugin.Log.LogDebug((object)("Registered: " + def.PrefabName + " (cloned from " + def.BasePrefab + ")"));
		}

		private static void RegisterCooldownEffect(StaffDefinition def, Sprite icon, BossAbilityBase ability)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			StaffCooldownEffect staffCooldownEffect = ScriptableObject.CreateInstance<StaffCooldownEffect>();
			((Object)staffCooldownEffect).name = def.CooldownEffectName;
			((StatusEffect)staffCooldownEffect).m_name = def.ItemNameToken;
			((StatusEffect)staffCooldownEffect).m_icon = icon;
			staffCooldownEffect.CooldownDuration = ability.CooldownSeconds;
			((StatusEffect)staffCooldownEffect).m_startMessageType = (MessageType)1;
			((StatusEffect)staffCooldownEffect).m_startMessage = "";
			((StatusEffect)staffCooldownEffect).m_stopMessage = "";
			ItemManager.Instance.AddStatusEffect(new CustomStatusEffect((StatusEffect)(object)staffCooldownEffect, false));
			ability.CooldownEffectName = def.CooldownEffectName;
			StaffsPlugin.Log.LogDebug((object)("Registered cooldown SE: " + def.CooldownEffectName));
		}

		private static void ApplyEmissionColor(GameObject go, Color color)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: 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_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0343: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0367: 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_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Unknown result type (might be due to invalid IL or missing references)
			//IL_039f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_047e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0485: Expected O, but got Unknown
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fd: Unknown result type (might be due to invalid IL or missing references)
			Color val = default(Color);
			((Color)(ref val))..ctor(Mathf.Clamp01(color.r), Mathf.Clamp01(color.g), Mathf.Clamp01(color.b), 1f);
			Transform val2 = go.transform.Find("attach");
			if (((Object)go).name.Contains("DeepNorth") || !((Object)go).name.Contains("GreenRoots"))
			{
			}
			Transform val3 = go.transform.Find("attach/equiped/default (1)") ?? go.transform.Find("attach/default (1)");
			if ((Object)(object)val3 == (Object)null)
			{
				if ((Object)(object)val2 == (Object)null)
				{
					StaffsPlugin.Log.LogWarning((object)("ApplyEmissionColor: no orb mesh or attach found on " + ((Object)go).name));
					return;
				}
				StaffsPlugin.Log.LogDebug((object)("ApplyEmissionColor: GreenRoots path — recoloring full attach on " + ((Object)go).name));
				Renderer[] componentsInChildren = ((Component)val2).GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val4 in componentsInChildren)
				{
					Material[] materials = val4.materials;
					foreach (Material val5 in materials)
					{
						if (val5.HasProperty("_Color"))
						{
							val5.SetColor("_Color", Color.white);
						}
						if (val5.HasProperty("_BaseColor"))
						{
							val5.SetColor("_BaseColor", Color.white);
						}
						if (val5.HasProperty("_EmissionColor"))
						{
							val5.EnableKeyword("_EMISSION");
							val5.SetColor("_EmissionColor", val * 3f);
						}
						if (val5.HasProperty("_TintColor"))
						{
							val5.SetColor("_TintColor", val);
						}
					}
					val4.materials = materials;
				}
				ParticleSystem[] componentsInChildren2 = ((Component)val2).GetComponentsInChildren<ParticleSystem>(true);
				foreach (ParticleSystem val6 in componentsInChildren2)
				{
					MainModule main = val6.main;
					float r = val.r;
					float g = val.g;
					float b = val.b;
					MinMaxGradient startColor = ((MainModule)(ref main)).startColor;
					((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(r, g, b, ((MinMaxGradient)(ref startColor)).color.a));
				}
				Light[] componentsInChildren3 = ((Component)val2).GetComponentsInChildren<Light>(true);
				foreach (Light val7 in componentsInChildren3)
				{
					val7.color = val;
					val7.intensity = 0.9f;
					val7.range = 2f;
				}
				return;
			}
			Transform val8 = go.transform.Find("attach/equiped");
			if ((Object)(object)val8 != (Object)null)
			{
				DestroyChild(val8, "flames_world");
				DestroyChild(val8, "flames");
				DestroyChild(val8, "embers");
			}
			Renderer[] componentsInChildren4 = ((Component)val3).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val9 in componentsInChildren4)
			{
				Material[] materials2 = val9.materials;
				foreach (Material val10 in materials2)
				{
					if (val10.HasProperty("_Color"))
					{
						val10.SetColor("_Color", Color.white);
					}
					if (val10.HasProperty("_BaseColor"))
					{
						val10.SetColor("_BaseColor", Color.white);
					}
					if (val10.HasProperty("_EmissionColor"))
					{
						val10.EnableKeyword("_EMISSION");
						val10.SetColor("_EmissionColor", val * 4f);
					}
					if (val10.HasProperty("_TintColor"))
					{
						val10.SetColor("_TintColor", val);
					}
				}
				val9.materials = materials2;
			}
			Transform val11 = val3.Find("effects");
			if (!((Object)(object)val11 != (Object)null))
			{
				return;
			}
			Light[] componentsInChildren5 = ((Component)val11).GetComponentsInChildren<Light>(true);
			foreach (Light val12 in componentsInChildren5)
			{
				val12.color = val;
				val12.intensity = 0.9f;
				val12.range = 1.8f;
			}
			foreach (Transform item in val11)
			{
				Transform val13 = item;
				ParticleSystem component = ((Component)val13).GetComponent<ParticleSystem>();
				if ((Object)(object)component != (Object)null)
				{
					MainModule main2 = component.main;
					((MainModule)(ref main2)).startColor = new MinMaxGradient(val);
					if (((Object)val13).name == "flare")
					{
						((MainModule)(ref main2)).startSize = new MinMaxCurve(0.8f);
						((MainModule)(ref main2)).startColor = new MinMaxGradient(new Color(val.r, val.g, val.b, 0.45f));
					}
				}
			}
		}

		private static void DestroyChild(Transform parent, string childName)
		{
			Transform val = parent.Find(childName);
			if (!((Object)(object)val == (Object)null))
			{
				Object.Destroy((Object)(object)((Component)val).gameObject);
				StaffsPlugin.Log.LogDebug((object)("Destroyed FX child: " + ((Object)parent).name + "/" + childName));
			}
		}
	}
	[BepInPlugin("YouDied.staffs_of_the_forsaken", "StaffsOfTheForsaken", "1.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class StaffsOfTheForsakenPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "YouDied.staffs_of_the_forsaken";

		public const string PluginName = "StaffsOfTheForsaken";

		public const string PluginVersion = "1.1.0";

		public static ManualLogSource Log;

		public static ConfigEntry<float> EikthyrCooldown;

		public static ConfigEntry<float> ElderCooldown;

		public static ConfigEntry<float> BonemassCooldown;

		public static ConfigEntry<float> ModerCooldown;

		public static ConfigEntry<float> YagluthCooldown;

		public static ConfigEntry<float> QueenCooldown;

		public static ConfigEntry<float> FaderCooldown;

		public static ConfigEntry<float> KallCooldown;

		public static float EikthyrCooldownValue = 30f;

		public static float ElderCooldownValue = 30f;

		public static float BonemassCooldownValue = 30f;

		public static float ModerCooldownValue = 30f;

		public static float YagluthCooldownValue = 30f;

		public static float QueenCooldownValue = 30f;

		public static float FaderCooldownValue = 30f;

		public static float KallCooldownValue = 30f;

		public static ConfigEntry<float> EikthyrDamage;

		public static ConfigEntry<float> ElderDamage;

		public static ConfigEntry<float> BonemassDamage;

		public static ConfigEntry<float> ModerDamage;

		public static ConfigEntry<float> YagluthDamage;

		public static ConfigEntry<float> QueenDamage;

		public static ConfigEntry<float> FaderDamage;

		public static ConfigEntry<float> KallDamage;

		public static ConfigEntry<bool> EnableDeepNorthStaff;

		public static bool EnableDeepNorthStaffValue = false;

		private Harmony _harmony;

		public static readonly List<BossAbilityBase> AllAbilities = new List<BossAbilityBase>();

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

		private void Awake()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)"StaffsOfTheForsaken 1.1.0 awakening…");
			BindConfig();
			((BaseUnityPlugin)this).Config.SettingChanged += OnSettingChanged;
			LoadLocalization();
			LoadIcons();
			PrefabManager.OnVanillaPrefabsAvailable += StaffSetup.RegisterAll;
			_harmony = new Harmony("YouDied.staffs_of_the_forsaken");
			_harmony.PatchAll(Assembly.GetExecutingAssembly());
			Log.LogInfo((object)"StaffsOfTheForsaken 1.1.0 loaded.");
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.SettingChanged -= OnSettingChanged;
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void BindConfig()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected O, but got Unknown
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Expected O, but got Unknown
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Expected O, but got Unknown
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Expected O, but got Unknown
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Expected O, but got Unknown
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Expected O, but got Unknown
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Expected O, but got Unknown
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Expected O, but got Unknown
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Expected O, but got Unknown
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Expected O, but got Unknown
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_034e: Expected O, but got Unknown
			//IL_0373: Unknown result type (might be due to invalid IL or missing references)
			//IL_037d: Expected O, but got Unknown
			//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ac: Expected O, but got Unknown
			//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d7: Expected O, but got Unknown
			AcceptableValueRange<float> val = new AcceptableValueRange<float>(0.5f, 30f);
			EikthyrCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Cooldowns", "EikthyrCooldown", 30f, new ConfigDescription("Staff of the Meadows cooldown (seconds)", (AcceptableValueBase)(object)val, Array.Empty<object>()));
			ElderCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Cooldowns", "ElderCooldown", 30f, new ConfigDescription("Staff of the Forest cooldown (seconds)", (AcceptableValueBase)(object)val, Array.Empty<object>()));
			BonemassCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Cooldowns", "BonemassCooldown", 30f, new ConfigDescription("Staff of the Mire cooldown (seconds)", (AcceptableValueBase)(object)val, Array.Empty<object>()));
			ModerCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Cooldowns", "ModerCooldown", 30f, new ConfigDescription("Staff of the Mountain cooldown (seconds)", (AcceptableValueBase)(object)val, Array.Empty<object>()));
			YagluthCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Cooldowns", "YagluthCooldown", 30f, new ConfigDescription("Staff of the Plains cooldown (seconds)", (AcceptableValueBase)(object)val, Array.Empty<object>()));
			QueenCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Cooldowns", "QueenCooldown", 30f, new ConfigDescription("Staff of the Mist cooldown (seconds)", (AcceptableValueBase)(object)val, Array.Empty<object>()));
			FaderCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Cooldowns", "FaderCooldown", 30f, new ConfigDescription("Staff of the Ash cooldown (seconds)", (AcceptableValueBase)(object)val, Array.Empty<object>()));
			KallCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Cooldowns", "KallCooldown", 30f, new ConfigDescription("Staff of the Deep North cooldown (seconds)", (AcceptableValueBase)(object)val, Array.Empty<object>()));
			EikthyrCooldownValue = SnapCooldown(EikthyrCooldown.Value);
			ElderCooldownValue = SnapCooldown(ElderCooldown.Value);
			BonemassCooldownValue = SnapCooldown(BonemassCooldown.Value);
			ModerCooldownValue = SnapCooldown(ModerCooldown.Value);
			YagluthCooldownValue = SnapCooldown(YagluthCooldown.Value);
			QueenCooldownValue = SnapCooldown(QueenCooldown.Value);
			FaderCooldownValue = SnapCooldown(FaderCooldown.Value);
			KallCooldownValue = SnapCooldown(KallCooldown.Value);
			AcceptableValueRange<float> val2 = new AcceptableValueRange<float>(1f, 500f);
			EikthyrDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "EikthyrDamage", 75f, new ConfigDescription("Staff of the Meadows lightning damage", (AcceptableValueBase)(object)val2, Array.Empty<object>()));
			ElderDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "ElderDamage", 60f, new ConfigDescription("Staff of the Forest pierce damage", (AcceptableValueBase)(object)val2, Array.Empty<object>()));
			BonemassDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "BonemassDamage", 80f, new ConfigDescription("Staff of the Mire total poison damage", (AcceptableValueBase)(object)val2, Array.Empty<object>()));
			ModerDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "ModerDamage", 70f, new ConfigDescription("Staff of the Mountain max frost damage", (AcceptableValueBase)(object)val2, Array.Empty<object>()));
			YagluthDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "YagluthDamage", 65f, new ConfigDescription("Staff of the Plains fire+lightning damage per enemy", (AcceptableValueBase)(object)val2, Array.Empty<object>()));
			QueenDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "QueenDamage", 50f, new ConfigDescription("Staff of the Mist (unused — Seekers deal their own damage)", (AcceptableValueBase)(object)val2, Array.Empty<object>()));
			FaderDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "FaderDamage", 90f, new ConfigDescription("Staff of the Ash fire damage per meteor", (AcceptableValueBase)(object)val2, Array.Empty<object>()));
			KallDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "KallDamage", 85f, new ConfigDescription("Staff of the Deep North frost damage", (AcceptableValueBase)(object)val2, Array.Empty<object>()));
			EnableDeepNorthStaff = ((BaseUnityPlugin)this).Config.Bind<bool>("Experimental", "EnableDeepNorthStaff", false, new ConfigDescription("Enable the Staff of the Deep North (EXPERIMENTAL — may be buggy). NOTE: Changing this setting requires a full game restart to take effect. Save the config file, close Valheim completely, then relaunch.", (AcceptableValueBase)null, Array.Empty<object>()));
			EnableDeepNorthStaffValue = EnableDeepNorthStaff.Value;
		}

		private static float SnapCooldown(float raw)
		{
			return Mathf.Clamp(Mathf.Round(raw * 2f) / 2f, 0.5f, 30f);
		}

		private void OnSettingChanged(object sender, SettingChangedEventArgs args)
		{
			ConfigDefinition definition = args.ChangedSetting.Definition;
			if (definition.Section != "Cooldowns")
			{
				return;
			}
			float raw = 30f;
			if (args.ChangedSetting.BoxedValue is float num)
			{
				raw = num;
			}
			float num2 = SnapCooldown(raw);
			switch (definition.Key)
			{
			case "EikthyrCooldown":
				EikthyrCooldownValue = num2;
				break;
			case "ElderCooldown":
				ElderCooldownValue = num2;
				break;
			case "BonemassCooldown":
				BonemassCooldownValue = num2;
				break;
			case "ModerCooldown":
				ModerCooldownValue = num2;
				break;
			case "YagluthCooldown":
				YagluthCooldownValue = num2;
				break;
			case "QueenCooldown":
				QueenCooldownValue = num2;
				break;
			case "FaderCooldown":
				FaderCooldownValue = num2;
				break;
			case "KallCooldown":
				KallCooldownValue = num2;
				break;
			}
			foreach (BossAbilityBase allAbility in AllAbilities)
			{
				allAbility?.ResetCooldown(num2);
			}
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				return;
			}
			SEMan sEMan = ((Character)Player.m_localPlayer).GetSEMan();
			if (sEMan == null)
			{
				return;
			}
			foreach (StatusEffect statusEffect in sEMan.GetStatusEffects())
			{
				if (statusEffect is StaffCooldownEffect staffCooldownEffect)
				{
					staffCooldownEffect.CooldownDuration = num2;
					if (staffCooldownEffect.ElapsedTime > staffCooldownEffect.CooldownDuration)
					{
						staffCooldownEffect.ElapsedTime = staffCooldownEffect.CooldownDuration;
					}
				}
			}
			Log.LogInfo((object)$"[Config] {definition.Key} updated → {num2}s");
		}

		private void LoadLocalization()
		{
			try
			{
				string text = "StaffsOfTheForsaken.Localization.localization.json";
				using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(text);
				if (stream == null)
				{
					Log.LogError((object)("[Localization] Embedded resource not found: " + text));
					return;
				}
				string json;
				using (StreamReader streamReader = new StreamReader(stream))
				{
					json = streamReader.ReadToEnd();
				}
				Dictionary<string, string> dictionary = ParseLocalizationJson(json);
				if (dictionary != null && dictionary.Count > 0)
				{
					CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
					string text2 = "English";
					localization.AddTranslation(ref text2, dictionary);
					Log.LogInfo((object)$"[Localization] Loaded {dictionary.Count} English tokens.");
				}
				else
				{
					Log.LogWarning((object)"[Localization] JSON parsed but no tokens found.");
				}
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"[Localization] Failed to load: {arg}");
			}
		}

		private Dictionary<string, string> ParseLocalizationJson(string json)
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			int num = json.IndexOf('{', json.IndexOf('{') + 1);
			int num2 = json.LastIndexOf('}');
			if (num < 0 || num2 < 0 || num2 <= num)
			{
				return dictionary;
			}
			string text = json.Substring(num + 1, num2 - num - 1);
			string[] array = text.Split(new char[1] { '\n' });
			foreach (string text2 in array)
			{
				string text3 = text2.Trim().TrimEnd(new char[1] { ',' });
				if (!text3.StartsWith("\""))
				{
					continue;
				}
				int num3 = text3.IndexOf("\":", 1);
				if (num3 >= 0)
				{
					string key = text3.Substring(1, num3 - 1);
					string text4 = text3.Substring(num3 + 2).Trim();
					if (text4.StartsWith("\"") && text4.EndsWith("\""))
					{
						string value = text4.Substring(1, text4.Length - 2);
						dictionary[key] = value;
					}
				}
			}
			return dictionary;
		}

		private void LoadIcons()
		{
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			string[] array = new string[8] { "staff_meadows", "staff_forest", "staff_mire", "staff_mountain", "staff_plains", "staff_mist", "staff_ash", "staff_deepnorth" };
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string text = Path.Combine(Path.GetTempPath(), "StaffsOfTheForsaken_icons");
			Directory.CreateDirectory(text);
			string[] array2 = array;
			foreach (string text2 in array2)
			{
				try
				{
					string text3 = "StaffsOfTheForsaken.Assets.icons." + text2 + ".png";
					using Stream stream = executingAssembly.GetManifestResourceStream(text3);
					if (stream == null)
					{
						Log.LogWarning((object)("[Icons] Embedded resource not found: " + text3));
						continue;
					}
					string text4 = Path.Combine(text, text2 + ".png");
					using (FileStream destination = new FileStream(text4, FileMode.Create, FileAccess.Write))
					{
						stream.CopyTo(destination);
					}
					Texture2D val = AssetUtils.LoadTexture(text4, true);
					if ((Object)(object)val == (Object)null)
					{
						Log.LogWarning((object)("[Icons] AssetUtils.LoadTexture returned null for: " + text4));
						continue;
					}
					((Object)val).name = text2;
					Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
					((Object)val2).name = text2;
					_sprites[text2] = val2;
					Log.LogInfo((object)$"[Icons] Loaded: {text2} ({((Texture)val).width}x{((Texture)val).height})");
				}
				catch (Exception arg)
				{
					Log.LogError((object)$"[Icons] Failed to load {text2}: {arg}");
				}
			}
		}

		public static Sprite GetSprite(string name)
		{
			_sprites.TryGetValue(name, out var value);
			return value;
		}
	}
	internal static class StaffsPlugin
	{
		public static ManualLogSource Log => StaffsOfTheForsakenPlugin.Log;

		public static float EikthyrCooldownValue => StaffsOfTheForsakenPlugin.EikthyrCooldownValue;

		public static float ElderCooldownValue => StaffsOfTheForsakenPlugin.ElderCooldownValue;

		public static float BonemassCooldownValue => StaffsOfTheForsakenPlugin.BonemassCooldownValue;

		public static float ModerCooldownValue => StaffsOfTheForsakenPlugin.ModerCooldownValue;

		public static float YagluthCooldownValue => StaffsOfTheForsakenPlugin.YagluthCooldownValue;

		public static float QueenCooldownValue => StaffsOfTheForsakenPlugin.QueenCooldownValue;

		public static float FaderCooldownValue => StaffsOfTheForsakenPlugin.FaderCooldownValue;

		public static float KallCooldownValue => StaffsOfTheForsakenPlugin.KallCooldownValue;

		public static ConfigEntry<float> EikthyrDamage => StaffsOfTheForsakenPlugin.EikthyrDamage;

		public static ConfigEntry<float> ElderDamage => StaffsOfTheForsakenPlugin.ElderDamage;

		public static ConfigEntry<float> BonemassDamage => StaffsOfTheForsakenPlugin.BonemassDamage;

		public static ConfigEntry<float> ModerDamage => StaffsOfTheForsakenPlugin.ModerDamage;

		public static ConfigEntry<float> YagluthDamage => StaffsOfTheForsakenPlugin.YagluthDamage;

		public static ConfigEntry<float> FaderDamage => StaffsOfTheForsakenPlugin.FaderDamage;

		public static ConfigEntry<float> KallDamage => StaffsOfTheForsakenPlugin.KallDamage;

		public static bool EnableDeepNorthStaffValue => StaffsOfTheForsakenPlugin.EnableDeepNorthStaffValue;

		public static Sprite GetSprite(string name)
		{
			return StaffsOfTheForsakenPlugin.GetSprite(name);
		}
	}
}
namespace StaffsOfTheForsaken.Data
{
	public class StaffDefinition
	{
		public string PrefabName;

		public string BasePrefab;

		public string ItemNameToken;

		public string DescToken;

		public Color EmissionColor;

		public string IconName;

		public string CraftStation;

		public int StationLevel;

		public (string prefab, int amount)[] Materials;

		public string TrophyPrefab;

		public Type AbilityType;

		public string CooldownEffectName;
	}
	public static class StaffRegistry
	{
		public static readonly StaffDefinition[] All = new StaffDefinition[8]
		{
			new StaffDefinition
			{
				PrefabName = "StaffOfMeadows",
				BasePrefab = "StaffFireball",
				ItemNameToken = "$item_staff_meadows",
				DescToken = "$item_staff_meadows_desc",
				EmissionColor = new Color(0.05f, 0.45f, 1f),
				IconName = "staff_meadows",
				CraftStation = "piece_workbench",
				StationLevel = 3,
				Materials = new(string, int)[2]
				{
					("Wood", 10),
					("Resin", 10)
				},
				TrophyPrefab = "TrophyEikthyr",
				AbilityType = typeof(EikthyrChargeAbility),
				CooldownEffectName = "SE_StaffOfMeadows"
			},
			new StaffDefinition
			{
				PrefabName = "StaffOfForest",
				BasePrefab = "StaffFireball",
				ItemNameToken = "$item_staff_forest",
				DescToken = "$item_staff_forest_desc",
				EmissionColor = new Color(1f, 0.75f, 0f),
				IconName = "staff_forest",
				CraftStation = "piece_workbench",
				StationLevel = 4,
				Materials = new(string, int)[2]
				{
					("RoundLog", 10),
					("TrollHide", 10)
				},
				TrophyPrefab = "TrophyTheElder",
				AbilityType = typeof(ElderShootAbility),
				CooldownEffectName = "SE_StaffOfForest"
			},
			new StaffDefinition
			{
				PrefabName = "StaffOfMire",
				BasePrefab = "StaffFireball",
				ItemNameToken = "$item_staff_mire",
				DescToken = "$item_staff_mire_desc",
				EmissionColor = new Color(0.35f, 1.1f, 0f),
				IconName = "staff_mire",
				CraftStation = "piece_workbench",
				StationLevel = 5,
				Materials = new(string, int)[2]
				{
					("ElderBark", 10),
					("Root", 10)
				},
				TrophyPrefab = "TrophyBonemass",
				AbilityType = typeof(BonemassAoEAbility),
				CooldownEffectName = "SE_StaffOfMire"
			},
			new StaffDefinition
			{
				PrefabName = "StaffOfMountain",
				BasePrefab = "StaffFireball",
				ItemNameToken = "$item_staff_mountain",
				DescToken = "$item_staff_mountain_desc",
				EmissionColor = new Color(0.8f, 0.95f, 1f),
				IconName = "staff_mountain",
				CraftStation = "piece_workbench",
				StationLevel = 5,
				Materials = new(string, int)[2]
				{
					("FineWood", 10),
					("Obsidian", 10)
				},
				TrophyPrefab = "TrophyDragonQueen",
				AbilityType = typeof(ModerColdBreathAbility),
				CooldownEffectName = "SE_StaffOfMountain"
			},
			new StaffDefinition
			{
				PrefabName = "StaffOfPlains",
				BasePrefab = "StaffFireball",
				ItemNameToken = "$item_staff_plains",
				DescToken = "$item_staff_plains_desc",
				EmissionColor = new Color(1f, 0f, 0.8f),
				IconName = "staff_plains",
				CraftStation = "piece_workbench",
				StationLevel = 5,
				Materials = new(string, int)[2]
				{
					("LoxPelt", 10),
					("Needle", 10)
				},
				TrophyPrefab = "TrophyGoblinKing",
				AbilityType = typeof(YagluthNovaAbility),
				CooldownEffectName = "SE_StaffOfPlains"
			},
			new StaffDefinition
			{
				PrefabName = "StaffOfMist",
				BasePrefab = "StaffIceShards",
				ItemNameToken = "$item_staff_mist",
				DescToken = "$item_staff_mist_desc",
				EmissionColor = new Color(0.55f, 0f, 1f),
				IconName = "staff_mist",
				CraftStation = "piece_magetable",
				StationLevel = 1,
				Materials = new(string, int)[2]
				{
					("YggdrasilWood", 10),
					("Mandible", 10)
				},
				TrophyPrefab = "TrophySeekerQueen",
				AbilityType = typeof(QueenSpitAbility),
				CooldownEffectName = "SE_StaffOfMist"
			},
			new StaffDefinition
			{
				PrefabName = "StaffOfAsh",
				BasePrefab = "StaffIceShards",
				ItemNameToken = "$item_staff_ash",
				DescToken = "$item_staff_ash_desc",
				EmissionColor = new Color(1f, 0.05f, 0.05f),
				IconName = "staff_ash",
				CraftStation = "piece_magetable",
				StationLevel = 2,
				Materials = new(string, int)[2]
				{
					("Blackwood", 10),
					("MorgenSinew", 10)
				},
				TrophyPrefab = "TrophyFader",
				AbilityType = typeof(FaderFissureAbility),
				CooldownEffectName = "SE_StaffOfAsh"
			},
			new StaffDefinition
			{
				PrefabName = "StaffOfDeepNorth",
				BasePrefab = "StaffGreenRoots",
				ItemNameToken = "$item_staff_deepnorth",
				DescToken = "$item_staff_deepnorth_desc",
				EmissionColor = new Color(0.05f, 0.3f, 0.85f),
				IconName = "staff_deepnorth",
				CraftStation = "piece_blackforge",
				StationLevel = 4,
				Materials = new(string, int)[2]
				{
					("Gold", 10),
					("Frostwood", 10)
				},
				TrophyPrefab = "CrownJewel",
				AbilityType = typeof(KallFrozenTendrilAbility),
				CooldownEffectName = "SE_StaffOfDeepNorth"
			}
		};
	}
}
namespace StaffsOfTheForsaken.Abilities
{
	internal static class AbilityUtils
	{
		public static Vector3 CameraForwardFlat()
		{
			//IL_0045: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			Camera val = null;
			if (Camera.allCameras.Length != 0)
			{
				val = Camera.allCameras[0];
			}
			if ((Object)(object)val == (Object)null)
			{
				val = Camera.main;
			}
			if ((Object)(object)val == (Object)null)
			{
				return Vector3.forward;
			}
			Vector3 forward = ((Component)val).transform.forward;
			Vector3 val2 = new Vector3(forward.x, 0f, forward.z);
			return ((Vector3)(ref val2)).normalized;
		}

		public static Vector3 OrbTip(Player player)
		{
			//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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			Transform val = ((Component)player).transform.Find("Visual/Armature/Hips/Spine/Spine1/Spine2/RightShoulder/RightArm/RightForeArm/RightHand");
			if ((Object)(object)val != (Object)null)
			{
				return val.position + val.up * 0.5f;
			}
			return ((Component)player).transform.position + Vector3.up * 1.6f;
		}

		public static void PlayAttackAnim(Player player)
		{
		}
	}
	public class EikthyrChargeAbility : BossAbilityBase
	{
		private const float InnerRadius = 2f;

		private const float OuterRadius = 10f;

		private const float WaveSpeed = 8f;

		private const float TickInterval = 0.12f;

		protected override float CooldownTime => StaffsPlugin.EikthyrCooldownValue;

		protected override void Execute(Player player, Vector3 aimPoint)
		{
			//IL_002e: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			StaffsPlugin.Log.LogInfo((object)("[EikthyrExecute] Enter. ZNetScene=" + (((Object)(object)ZNetScene.instance != (Object)null) ? "ok" : "NULL") + ", " + $"aimPoint={aimPoint}"));
			AbilityUtils.PlayAttackAnim(player);
			Vector3 val = BossAbilityBase.SnapToGround(aimPoint);
			float value = StaffsPlugin.EikthyrDamage.Value;
			StaffsPlugin.Log.LogInfo((object)$"[EikthyrExecute] About to SpawnFX. origin={val}, dmg={value}");
			BossAbilityBase.SpawnFX("fx_eikthyr_stomp", val, 1.5f);
			BossAbilityBase.DealAoESafe(val, 2f, new DamageTypes
			{
				m_lightning = value
			}, player);
			StartCoroutineOn(player, ExpandingShockwave(val, value, player));
		}

		private IEnumerator ExpandingShockwave(Vector3 origin, float dmg, Player player)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			float elapsed = 0f;
			float travelTime = 1f;
			float lastRadius = 2f;
			ZDOID playerID = ((Character)player).GetZDOID();
			DamageTypes ringDmg = new DamageTypes
			{
				m_lightning = dmg
			};
			while (elapsed < travelTime)
			{
				yield return (object)new WaitForSeconds(0.12f);
				elapsed += 0.12f;
				float currentRadius = Mathf.Lerp(2f, 10f, Mathf.Clamp01(elapsed / travelTime));
				Collider[] hits = Physics.OverlapSphere(origin, currentRadius, LayerMask.GetMask(new string[4] { "character", "character_net", "Default_small", "creature" }));
				Collider[] array = hits;
				foreach (Collider col in array)
				{
					Character ch = ((Component)col).GetComponentInParent<Character>();
					if (!((Object)(object)ch == (Object)null) && !ch.IsDead() && !(ch is Player) && !(ch.GetZDOID() == playerID) && (int)ch.m_faction != 0)
					{
						float dist = Vector3.Distance(origin, ((Component)ch).transform.position);
						if (!(dist < lastRadius))
						{
							HitData val = new HitData
							{
								m_damage = ringDmg,
								m_point = ((Component)ch).transform.position
							};
							Vector3 val2 = ((Component)ch).transform.position - origin;
							val.m_dir = ((Vector3)(ref val2)).normalized;
							val.m_attacker = playerID;
							ch.Damage(val);
							BossAbilityBase.ApplyStatus(ch, "Lightning");
						}
					}
				}
				lastRadius = currentRadius;
			}
		}
	}
	public class ElderShootAbility : BossAbilityBase
	{
		private const int VineCount = 25;

		private const float VineSpeed = 30f;

		private const float MinSpread = 10f;

		private const float MaxSpread = 20f;

		protected override float CooldownTime => StaffsPlugin.ElderCooldownValue;

		protected override void Execute(Player player, Vector3 aimPoint)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			StaffsPlugin.Log.LogInfo((object)("[ElderExecute] Enter. ZNetScene=" + (((Object)(object)ZNetScene.instance != (Object)null) ? "ok" : "NULL")));
			AbilityUtils.PlayAttackAnim(player);
			Vector3 val = AbilityUtils.OrbTip(player);
			BossAbilityBase.SpawnFX("fx_gdking_rootspawn", val);
			BossAbilityBase.SpawnFX("sfx_gdking_shoot_start", val);
			float value = StaffsPlugin.ElderDamage.Value;
			for (int i = 0; i < 25; i++)
			{
				BossAbilityBase.FireProjectile("gdking_root_projectile", val, aimPoint, 30f, player, Random.Range(10f, 20f));
			}
			BossAbilityBase.DealAoESafe(aimPoint, 6f, new DamageTypes
			{
				m_pierce = value
			}, player);
			BossAbilityBase.SpawnFX("fx_gdking_rootspawn", BossAbilityBase.SnapToGround(aimPoint), 1.5f);
		}
	}
	public class BonemassAoEAbility : BossAbilityBase
	{
		private const float CloudRadius = 9f;

		private const float CloudDuration = 10f;

		private const float TickInterval = 1f;

		protected override float CooldownTime => StaffsPlugin.BonemassCooldownValue;

		protected override void Execute(Player player, Vector3 aimPoint)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: 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_00d4: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			StaffsPlugin.Log.LogInfo((object)("[BonemassExecute] Enter. ZNetScene=" + (((Object)(object)ZNetScene.instance != (Object)null) ? "ok" : "NULL")));
			AbilityUtils.PlayAttackAnim(player);
			Vector3 val = BossAbilityBase.SnapToGround(aimPoint);
			BossAbilityBase.SpawnFX("vfx_sledge_hit", val, 3f);
			BossAbilityBase.SpawnFX("sfx_Bonemass_alert", val);
			BossAbilityBase.SpawnFX("sfx_Bonemass_Hit", val);
			float value = StaffsPlugin.BonemassDamage.Value;
			float poison = value * 0.4f;
			float tickDmg = value * 0.6f / 10f;
			ZDOID zDOID = ((Character)player).GetZDOID();
			BossAbilityBase.DealAoEByID(val, 9f, new DamageTypes
			{
				m_poison = poison
			}, zDOID);
			ApplyStatusInRadius(val, 9f, zDOID);
			StartCoroutineOn(player, PoisonCloud(val, tickDmg, zDOID));
		}

		private IEnumerator PoisonCloud(Vector3 center, float tickDmg, ZDOID playerID)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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)
			float elapsed = 0f;
			while (elapsed < 10f)
			{
				yield return (object)new WaitForSeconds(1f);
				elapsed += 1f;
				BossAbilityBase.DealAoEByID(center, 9f, new DamageTypes
				{
					m_poison = tickDmg
				}, playerID);
				ApplyStatusInRadius(center, 9f, playerID);
			}
		}

		private static void ApplyStatusInRadius(Vector3 center, float radius, ZDOID casterID)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Invalid comparison between Unknown and I4
			Collider[] array = Physics.OverlapSphere(center, radius, LayerMask.GetMask(new string[3] { "character", "character_net", "creature" }));
			HashSet<Character> hashSet = new HashSet<Character>();
			Collider[] array2 = array;
			foreach (Collider val in array2)
			{
				Character componentInParent = ((Component)val).GetComponentInParent<Character>();
				if (!((Object)(object)componentInParent == (Object)null) && !componentInParent.IsDead() && !(componentInParent is Player) && (int)componentInParent.m_faction != 0 && hashSet.Add(componentInParent))
				{
					BossAbilityBase.ApplyStatus(componentInParent, "Poison");
				}
			}
		}
	}
	public class ModerColdBreathAbility : BossAbilityBase
	{
		private const float BeamLength = 30f;

		private const float BeamHalfAngle = 40f;

		protected override float CooldownTime => StaffsPlugin.ModerCooldownValue;

		protected override void Execute(Player player, Vector3 aimPoint)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_008c: 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_0097: 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_00a2: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Invalid comparison between Unknown and I4
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Expected O, but got Unknown
			StaffsPlugin.Log.LogInfo((object)("[ModerExecute] Enter. ZNetScene=" + (((Object)(object)ZNetScene.instance != (Object)null) ? "ok" : "NULL")));
			AbilityUtils.PlayAttackAnim(player);
			Vector3 val = ((Component)player).transform.position + Vector3.up * 1.5f;
			Vector3 val2 = aimPoint - val;
			if (((Vector3)(ref val2)).sqrMagnitude < 0.001f)
			{
				val2 = ((Component)player).transform.forward;
			}
			Vector3 normalized = ((Vector3)(ref val2)).normalized;
			BossAbilityBase.SpawnFX("vfx_dragon_coldbreath", val + normalized * 3f, 1.2f, Quaternion.LookRotation(normalized));
			BossAbilityBase.SpawnFX("sfx_dragon_coldbreath_start", val);
			float value = StaffsPlugin.ModerDamage.Value;
			ZDOID zDOID = ((Character)player).GetZDOID();
			Collider[] array = Physics.OverlapSphere(val, 30f, LayerMask.GetMask(new string[4] { "character", "character_net", "Default_small", "creature" }));
			HashSet<Character> hashSet = new HashSet<Character>();
			Collider[] array2 = array;
			foreach (Collider val3 in array2)
			{
				Character componentInParent = ((Component)val3).GetComponentInParent<Character>();
				if (!((Object)(object)componentInParent == (Object)null) && !componentInParent.IsDead() && !(componentInParent is Player) && (int)componentInParent.m_faction != 0 && hashSet.Add(componentInParent))
				{
					Vector3 val4 = ((Component)componentInParent).transform.position - val;
					Vector3 normalized2 = ((Vector3)(ref val4)).normalized;
					if (!(Vector3.Angle(normalized, normalized2) > 40f))
					{
						float num = Vector3.Distance(val, ((Component)componentInParent).transform.position);
						float num2 = Mathf.Lerp(1f, 0.5f, num / 30f);
						componentInParent.Damage(new HitData
						{
							m_damage = new DamageTypes
							{
								m_frost = value * num2
							},
							m_point = ((Component)componentInParent).transform.position,
							m_dir = normalized,
							m_attacker = zDOID
						});
						BossAbilityBase.ApplyStatus(componentInParent, "Frost");
					}
				}
			}
		}
	}
	public class YagluthNovaAbility : BossAbilityBase
	{
		private const float NovaRadius = 10f;

		private const float ExpandTime = 0.8f;

		private const float LingerDuration = 10f;

		private const float LingerTickRate = 1f;

		private const float LingerDmgTotal = 100f;

		private const float MinDistance = 8f;

		protected override float CooldownTime => StaffsPlugin.YagluthCooldownValue;

		protected override void Execute(Player player, Vector3 aimPoint)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			StaffsPlugin.Log.LogInfo((object)("[YagluthExecute] Enter. ZNetScene=" + (((Object)(object)ZNetScene.instance != (Object)null) ? "ok" : "NULL")));
			AbilityUtils.PlayAttackAnim(player);
			Vector3 val = BossAbilityBase.SnapToGround(aimPoint);
			BossAbilityBase.SpawnFX("fx_goblinking_nova", val, 1.5f);
			StartCoroutineOn(player, NovaExpand(val, player));
		}

		private IEnumerator NovaExpand(Vector3 center, Player player)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			float dmg = StaffsPlugin.YagluthDamage.Value;
			int steps = 5;
			float stepTime = 0.8f / (float)steps;
			ZDOID playerID = ((Character)player).GetZDOID();
			HashSet<Character> novaHit = new HashSet<Character>();
			for (int i = 1; i <= steps; i++)
			{
				yield return (object)new WaitForSeconds(stepTime);
				float ringRadius = 10f * ((float)i / (float)steps);
				float ringWidth = 10f / (float)steps * 1.5f;
				Collider[] cols = Physics.OverlapSphere(center, ringRadius, LayerMask.GetMask(new string[4] { "character", "character_net", "Default_small", "creature" }));
				Collider[] array = cols;
				foreach (Collider c in array)
				{
					Character ch = ((Component)c).GetComponentInParent<Character>();
					if (!((Object)(object)ch == (Object)null) && !ch.IsDead() && !(ch.GetZDOID() == playerID) && (int)ch.m_faction != 0 && novaHit.Add(ch) && !(Vector3.Distance(center, ((Component)ch).transform.position) < ringRadius - ringWidth))
					{
						HitData val = new HitData
						{
							m_damage = new DamageTypes
							{
								m_fire = dmg,
								m_lightning = dmg
							},
							m_point = ((Component)ch).transform.position
						};
						Vector3 val2 = ((Component)ch).transform.position - center;
						val.m_dir = ((Vector3)(ref val2)).normalized;
						val.m_attacker = playerID;
						ch.Damage(val);
						BossAbilityBase.ApplyStatus(ch, "Burning");
						BossAbilityBase.ApplyStatus(ch, "Lightning");
					}
				}
			}
			StartCoroutineOn(player, LingerFire(center, player));
		}

		private IEnumerator LingerFire(Vector3 center, Player player)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			float tickDmg = 10f;
			float elapsed = 0f;
			ZDOID playerID = ((Character)player).GetZDOID();
			while (elapsed < 10f)
			{
				yield return (object)new WaitForSeconds(1f);
				elapsed += 1f;
				Collider[] cols = Physics.OverlapSphere(center, 7f, LayerMask.GetMask(new string[4] { "character", "character_net", "Default_small", "creature" }));
				Collider[] array = cols;
				foreach (Collider c in array)
				{
					Character ch = ((Component)c).GetComponentInParent<Character>();
					if (!((Object)(object)ch == (Object)null) && !ch.IsDead() && !(ch is Player) && !(ch.GetZDOID() == playerID) && (int)ch.m_faction != 0)
					{
						HitData val = new HitData
						{
							m_damage = new DamageTypes
							{
								m_fire = tickDmg
							},
							m_point = ((Component)ch).transform.position
						};
						Vector3 val2 = ((Component)ch).transform.position - center;
						val.m_dir = ((Vector3)(ref val2)).normalized;
						val.m_attacker = playerID;
						ch.Damage(val);
					}
				}
			}
		}
	}
	public class QueenSpitAbility : BossAbilityBase
	{
		private const int MinSeekers = 3;

		private const int MaxSeekers = 5;

		private const float SpawnRadius = 4f;

		protected override float CooldownTime => StaffsPlugin.QueenCooldownValue;

		protected override void Execute(Player player, Vector3 aimPoint)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: 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_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			StaffsPlugin.Log.LogInfo((object)("[QueenExecute] Enter. ZNetScene=" + (((Object)(object)ZNetScene.instance != (Object)null) ? "ok" : "NULL")));
			AbilityUtils.PlayAttackAnim(player);
			Vector3 val = BossAbilityBase.SnapToGround(aimPoint);
			BossAbilityBase.SpawnFX("sfx_HiveQueen_acitspit", val);
			int num = Random.Range(3, 6);
			for (int i = 0; i < num; i++)
			{
				float num2 = 360f / (float)num * (float)i * ((float)Math.PI / 180f);
				Vector3 val2 = BossAbilityBase.SnapToGround(val + new Vector3(Mathf.Cos(num2), 0f, Mathf.Sin(num2)) * 4f);
				ZNetScene instance = ZNetScene.instance;
				GameObject val3 = ((instance != null) ? instance.GetPrefab("Seeker") : null);
				if (!((Object)(object)val3 == (Object)null))
				{
					GameObject val4 = Object.Instantiate<GameObject>(val3, val2, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f));
					Character component = val4.GetComponent<Character>();
					if ((Object)(object)component != (Object)null)
					{
						component.m_faction = (Faction)0;
					}
					MonsterAI component2 = val4.GetComponent<MonsterAI>();
					if ((Object)(object)component2 != (Object)null)
					{
						component2.m_attackPlayerObjects = false;
					}
				}
			}
		}
	}
	public class FaderFissureAbility : BossAbilityBase
	{
		private const int MeteorCount = 3;

		private const float ImpactRadius = 5f;

		private const float WarnDelay = 2f;

		private const float SpreadRadius = 3f;

		protected override float CooldownTime => StaffsPlugin.FaderCooldownValue;

		protected override void Execute(Player player, Vector3 aimPoint)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: 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_00cc: 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)
			StaffsPlugin.Log.LogInfo((object)("[FaderExecute] Enter. ZNetScene=" + (((Object)(object)ZNetScene.instance != (Object)null) ? "ok" : "NULL")));
			AbilityUtils.PlayAttackAnim(player);
			Vector3 val = BossAbilityBase.SnapToGround(aimPoint);
			ZDOID zDOID = ((Character)player).GetZDOID();
			float value = StaffsPlugin.FaderDamage.Value;
			BossAbilityBase.SpawnFX("fx_Fader_Fissure_Prespawn", val, 0.5f);
			BossAbilityBase.SpawnFX("sfx_fader_fissure", val);
			for (int i = 0; i < 3; i++)
			{
				Vector2 val2 = Random.insideUnitCircle * 3f;
				Vector3 pos = BossAbilityBase.SnapToGround(val + new Vector3(val2.x, 0f, val2.y));
				StartCoroutineOn(player, MeteorImpact(pos, value, zDOID));
			}
		}

		private IEnumerator MeteorImpact(Vector3 pos, float dmg, ZDOID playerID)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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)
			BossAbilityBase.SpawnFX("fx_Fader_Fissure_Prespawn", pos, 0.8f);
			yield return (object)new WaitForSeconds(2f);
			GameObject fxGo = BossAbilityBase.SpawnFX("Fader_Fissure_AOE", pos);
			if ((Object)(object)fxGo != (Object)null)
			{
				Aoe[] componentsInChildren = fxGo.GetComponentsInChildren<Aoe>(true);
				foreach (Aoe aoe in componentsInChildren)
				{
					aoe.m_damage = default(DamageTypes);
					aoe.m_hitOwner = false;
					aoe.m_hitFriendly = false;
					aoe.m_hitEnemy = false;
				}
			}
			Collider[] cols = Physics.OverlapSphere(pos, 5f, LayerMask.GetMask(new string[4] { "character", "character_net", "Default_small", "creature" }));
			HashSet<Character> seen = new HashSet<Character>();
			Collider[] array = cols;
			foreach (Collider c in array)
			{
				Character ch = ((Component)c).GetComponentInParent<Character>();
				if (!((Object)(object)ch == (Object)null) && !ch.IsDead() && !(ch is Player) && (int)ch.m_faction != 0 && seen.Add(ch))
				{
					HitData val = new HitData
					{
						m_damage = new DamageTypes
						{
							m_fire = dmg,
							m_blunt = dmg * 0.5f
						},
						m_point = ((Component)ch).transform.position
					};
					Vector3 val2 = ((Component)ch).transform.position - pos;
					val.m_dir = ((Vector3)(ref val2)).normalized;
					val.m_attacker = playerID;
					ch.Damage(val);
					BossAbilityBase.ApplyStatus(ch, "Burning");
				}
			}
		}
	}
	public class KallFrozenTendrilAbility : BossAbilityBase
	{
		private const int RootCount = 8;

		private const float RootSpawnRadius = 7f;

		private const float RootStagger = 0.15f;

		private const float RootDamageRadius = 3f;

		private const float LightningDelay = 1.4f;

		private const int MaxChainJumps = 6;

		private const float ChainRange = 12f;

		private const float ChainJumpDelay = 0.18f;

		private const float LightningSearchRadius = 20f;

		protected override float CooldownTime => StaffsPlugin.KallCooldownValue;

		protected override void Execute(Player player, Vector3 aimPoint)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_004f: 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_007b: 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_00e3: 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_00ee: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			StaffsPlugin.Log.LogInfo((object)("[KallExecute] Enter. ZNetScene=" + (((Object)(object)ZNetScene.instance != (Object)null) ? "ok" : "NULL")));
			AbilityUtils.PlayAttackAnim(player);
			Vector3 pos = AbilityUtils.OrbTip(player);
			Vector3 val = BossAbilityBase.SnapToGround(aimPoint);
			ZDOID zDOID = ((Character)player).GetZDOID();
			float value = StaffsPlugin.KallDamage.Value;
			BossAbilityBase.SpawnFX("fx_frozenking_tendrils_summoning", pos);
			BossAbilityBase.SpawnFX("sfx_frozenking_tendril_summon", pos);
			Vector3[] array = (Vector3[])(object)new Vector3[8];
			for (int i = 0; i < 8; i++)
			{
				float num = 45f * (float)i * ((float)Math.PI / 180f);
				float num2 = 7f * (0.6f + Random.value * 0.8f);
				Vector3 val2 = new Vector3(Mathf.Cos(num), 0f, Mathf.Sin(num)) * num2;
				array[i] = BossAbilityBase.SnapToGround(val + val2);
			}
			StartCoroutineOn(player, RootPhase(array, value, zDOID));
		}

		private IEnumerator RootPhase(Vector3[] positions, float dmg, ZDOID playerID)
		{
			//IL_001c: 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)
			float frostPerRoot = dmg * 0.5f / 8f;
			for (int i = 0; i < positions.Length; i++)
			{
				Vector3 pos = positions[i];
				BossAbilityBase.SpawnFX("fx_frozenking_tendrilspawn", pos);
				BossAbilityBase.SpawnFX("fx_frozenking_chain_ground_impact_1", pos, 0.8f);
				BossAbilityBase.SpawnFX("sfx_frozenking_tendril_grow", pos);
				BossAbilityBase.DealAoEByID(pos, 3f, new DamageTypes
				{
					m_frost = frostPerRoot
				}, playerID);
				Collider[] cols = Physics.OverlapSphere(pos, 3f, LayerMask.GetMask(new string[3] { "character", "character_net", "creature" }));
				Collider[] array = cols;
				foreach (Collider c in array)
				{
					Character ch = ((Component)c).GetComponentInParent<Character>();
					if (!((Object)(object)ch == (Object)null) && !ch.IsDead() && !(ch is Player) && (int)ch.m_faction != 0)
					{
						BossAbilityBase.ApplyStatus(ch, "Frost");
					}
				}
				if (i < positions.Length - 1)
				{
					yield return (object)new WaitForSeconds(0.15f);
				}
			}
			float remainingDelay = 1.4f - (float)(positions.Length - 1) * 0.15f;
			if (remainingDelay > 0f)
			{
				yield return (object)new WaitForSeconds(remainingDelay);
			}
			Vector3 center = positions[4];
			Character firstTarget = FindClosestEnemy(center, 20f, playerID);
			if ((Object)(object)firstTarget != (Object)null)
			{
				float lightningDmg = dmg * 0.5f;
				yield return ChainLightning(firstTarget, lightningDmg, playerID);
			}
		}

		private IEnumerator ChainLightning(Character startTarget, float totalDmg, ZDOID playerID)
		{
			//IL_001c: 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)
			float dmgPerJump = totalDmg / 6f;
			HashSet<Character> alreadyHit = new HashSet<Character>();
			Character current = startTarget;
			for (int jump = 0; jump < 6; jump++)
			{
				if ((Object)(object)current == (Object)null)
				{
					break;
				}
				if (current.IsDead())
				{
					break;
				}
				if (!alreadyHit.Add(current))
				{
					break;
				}
				BossAbilityBase.SpawnFX("fx_chainlightning_hit", ((Component)current).transform.position);
				current.Damage(new HitData
				{
					m_damage = new DamageTypes
					{
						m_frost = dmgPerJump * 0.5f,
						m_lightning = dmgPerJump * 0.5f
					},
					m_point = ((Component)current).transform.position,
					m_dir = Vector3.up,
					m_attacker = playerID
				});
				BossAbilityBase.ApplyStatus(current, "Frost");
				BossAbilityBase.ApplyStatus(current, "Lightning");
				Character next = FindNextChainTarget(current, alreadyHit, 12f, playerID);
				if ((Object)(object)next == (Object)null)
				{
					break;
				}
				Vector3 arcMid = (((Component)current).transform.position + ((Component)next).transform.position) * 0.5f;
				BossAbilityBase.SpawnFX("fx_chainlightning_spread", arcMid);
				yield return (object)new WaitForSeconds(0.18f);
				current = next;
			}
			if ((Object)(object)current != (Object)null && !current.IsDead() && alreadyHit.Contains(current))
			{
				BossAbilityBase.SpawnFX("fx_chainlightning_hit", ((Component)current).transform.position, 1.2f);
			}
		}

		private static Character FindClosestEnemy(Vector3 center, float radius, ZDOID casterID)
		{
			//IL_0001: 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)
			//IL_0087: Invalid comparison between Unknown and I4
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			Collider[] array = Physics.OverlapSphere(center, radius, LayerMask.GetMask(new string[4] { "character", "character_net", "Default_small", "creature" }));
			Character result = null;
			float num = float.MaxValue;
			Collider[] array2 = array;
			foreach (Collider val in array2)
			{
				Character componentInParent = ((Component)val).GetComponentInParent<Character>();
				if (!((Object)(object)componentInParent == (Object)null) && !componentInParent.IsDead() && !(componentInParent is Player) && (int)componentInParent.m_faction != 0 && !(componentInParent.GetZDOID() == casterID))
				{
					float num2 = Vector3.Distance(center, ((Component)componentInParent).transform.position);
					if (num2 < num)
					{
						num = num2;
						result = componentInParent;
					}
				}
			}
			return result;
		}

		private static Character FindNextChainTarget(Character from, HashSet<Character> exclude, float range, ZDOID casterID)
		{
			//IL_0007: 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_0091: Invalid comparison between Unknown and I4
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: 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)
			Collider[] array = Physics.OverlapSphere(((Component)from).transform.position, range, LayerMask.GetMask(new string[4] { "character", "character_net", "Default_small", "creature" }));
			Character result = null;
			float num = float.MaxValue;
			Collider[] array2 = array;
			foreach (Collider val in array2)
			{
				Character componentInParent = ((Component)val).GetComponentInParent<Character>();
				if (!((Object)(object)componentInParent == (Object)null) && !componentInParent.IsDead() && !(componentInParent is Player) && (int)componentInParent.m_faction != 0 && !(componentInParent.GetZDOID() == casterID) && !exclude.Contains(componentInParent))
				{
					float num2 = Vector3.Distance(((Component)from).transform.position, ((Component)componentInParent).transform.position);
					if (num2 < num)
					{
						num = num2;
						result = componentInParent;
					}
				}
			}
			return result;
		}
	}
	public abstract class BossAbilityBase : MonoBehaviour
	{
		private float _lastCastTime = -999f;

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

		protected virtual float CooldownTime => 10f;

		public float CooldownSeconds => CooldownTime;

		public string CooldownEffectName { get; set; }

		public void ResetCooldown(float newDuration)
		{
			float time = Time.time;
			float num = _lastCastTime + CooldownTime - time;
			if (!(num <= 0f))
			{
				float num2 = CooldownTime - num;
				float num3 = Mathf.Clamp(newDuration - num2, 0f, newDuration);
				_lastCastTime = time - (newDuration - num3);
			}
		}

		public bool TryActivate(Player player, Vector3 aimPoint)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			float time = Time.time;
			if (time < _lastCastTime + CooldownTime)
			{
				StaffsPlugin.Log.LogInfo((object)($"[TryActivate] blocked: now={time:F1} lastCast={_lastCastTime:F1} " + $"cooldown={CooldownTime}s remaining={_lastCastTime + CooldownTime - time:F1}s"));
				return false;
			}
			_lastCastTime = time;
			if ((Object)(object)ZNetScene.instance == (Object)null)
			{
				StaffsPlugin.Log.LogWarning((object)"[TryActivate] ZNetScene.instance is null at cast time — FX will not appear. Try casting again once fully loaded.");
			}
			if (!string.IsNullOrEmpty(CooldownEffectName))
			{
				ObjectDB instance = ObjectDB.instance;
				StatusEffect val = ((instance != null) ? instance.GetStatusEffect(StringExtensionMethods.GetStableHashCode(CooldownEffectName)) : null);
				if ((Object)(object)val != (Object)null)
				{
					SEMan sEMan = ((Character)player).GetSEMan();
					if (sEMan != null)
					{
						sEMan.AddStatusEffect(val, true, 0, 0f, (short)(-1));
					}
				}
			}
			StaffsPlugin.Log.LogInfo((object)("[TryActivate] firing ability on player=" + ((Object)player).name + ", " + $"coroutine owner active={((Behaviour)player).isActiveAndEnabled}, " + $"cooldown={CooldownTime}s"));
			Action executeAction = delegate
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				Execute(player, aimPoint);
			};
			((MonoBehaviour)player).StartCoroutine(DelayedExecuteStatic(executeAction));
			return true;
		}

		private static IEnumerator DelayedExecuteStatic(Action executeAction)
		{
			StaffsPlugin.Log.LogInfo((object)"[DelayedExecuteStatic] waiting 0.5s...");
			yield return (object)new WaitForSeconds(0.5f);
			StaffsPlugin.Log.LogInfo((object)"[DelayedExecuteStatic] calling Execute now.");
			try
			{
				executeAction();
			}
			catch (Exception ex)
			{
				Exception ex2 = ex;
				StaffsPlugin.Log.LogError((object)$"[DelayedExecuteStatic] Execute threw an exception: {ex2}");
			}
		}

		protected abstract void Execute(Player player, Vector3 aimPoint);

		protected void StartCoroutineOn(Player player, IEnumerator routine)
		{
			((MonoBehaviour)player).StartCoroutine(routine);
		}

		protected void DealAoE(Vector3 center, float radius, DamageTypes damage, Player caster, bool friendlyFire = false)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Expected O, but got Unknown
			Collider[] array = Physics.OverlapSphere(center, radius, LayerMask.GetMask(new string[3] { "character", "character_net", "Default_small" }));
			Collider[] array2 = array;
			foreach (Collider val in array2)
			{
				Character componentInParent = ((Component)val).GetComponentInParent<Character>();
				if (!((Object)(object)componentInParent == (Object)null) && !componentInParent.IsDead() && (friendlyFire || !((Object)(object)componentInParent == (Object)(object)caster)))
				{
					HitData val2 = new HitData
					{
						m_damage = damage,
						m_point = ((Component)componentInParent).transform.position
					};
					Vector3 val3 = ((Component)componentInParent).transform.position - center;
					val2.m_dir = ((Vector3)(ref val3)).normalized;
					val2.m_attacker = ((Character)caster).GetZDOID();
					HitData val4 = val2;
					componentInParent.Damage(val4);
				}
			}
		}

		protected static void DealAoESafe(Vector3 center, float radius, DamageTypes damage, Player caster)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			DealAoEByID(center, radius, damage, ((Character)caster).GetZDOID());
		}

		protected static void DealAoEByID(Vector3 center, float radius, DamageTypes damage, ZDOID casterID)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Invalid comparison between Unknown and I4
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: 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_00d6: 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_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_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Expected O, but got Unknown
			Collider[] array = Physics.OverlapSphere(center, radius, LayerMask.GetMask(new string[4] { "character", "character_net", "Default_small", "creature" }));
			HashSet<Character> hashSet = new HashSet<Character>();
			Collider[] array2 = array;
			foreach (Collider val in array2)
			{
				Character componentInParent = ((Component)val).GetComponentInParent<Character>();
				if (!((Object)(object)componentInParent == (Object)null) && !componentInParent.IsDead() && !(componentInParent is Player) && (int)componentInParent.m_faction != 0 && hashSet.Add(componentInParent))
				{
					HitData val2 = new HitData
					{
						m_damage = damage,
						m_point = ((Component)componentInParent).transform.position
					};
					Vector3 val3 = ((Component)componentInParent).transform.position - center;
					val2.m_dir = ((Vector3)(ref val3)).normalized;
					val2.m_attacker = casterID;
					componentInParent.Damage(val2);
				}
			}
		}

		protected static void ApplyStatus(Character target, string effectName)
		{
			ObjectDB instance = ObjectDB.instance;
			StatusEffect val = ((instance != null) ? instance.GetStatusEffect(StringExtensionMethods.GetStableHashCode(effectName)) : null);
			if (!((Object)(object)val == (Object)null))
			{
				SEMan sEMan = target.GetSEMan();
				if (sEMan != null)
				{
					sEMan.AddStatusEffect(val, true, 0, 0f, (short)(-1));
				}
			}
		}

		protected static GameObject SpawnFX(string prefabName, Vector3 pos, float scale = 1f, Quaternion? rot = null)
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: 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)
			if ((Object)(object)ZNetScene.instance == (Object)null)
			{
				StaffsPlugin.Log.LogWarning((object)("[SpawnFX] ZNetScene.instance is null — cannot spawn " + prefabName));
				return null;
			}
			GameObject prefab = ZNetScene.instance.GetPrefab(prefabName);
			if ((Object)(object)prefab == (Object)null)
			{
				StaffsPlugin.Log.LogWarning((object)("[SpawnFX] FX prefab not found: " + prefabName));
				return null;
			}
			Quaternion val = (Quaternion)(((??)rot) ?? Quaternion.identity);
			GameObject val2 = Object.Instantiate<GameObject>(prefab, pos, val);
			if (scale != 1f)
			{
				val2.transform.localScale = Vector3.one * scale;
			}
			ZNetView component = val2.GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null)
			{
				((Behaviour)component).enabled = false;
			}
			TimedDestruction component2 = val2.GetComponent<TimedDestruction>();
			if ((Object)(object)component2 != (Object)null && component2.m_timeout < 2f)
			{
				component2.m_timeout = 2f;
			}
			ParticleSystem[] componentsInChildren = val2.GetComponentsInChildren<ParticleSystem>(true);
			StaffsPlugin.Log.LogInfo((object)($"[SpawnFX] {prefabName} — active={val2.activeInHierarchy}, " + "znv=" + (((Object)(object)component != (Object)null) ? "disabled" : "none") + ", td=" + (((Object)(object)component2 != (Object)null) ? (component2.m_timeout + "s") : "none") + ", " + $"ps={componentsInChildren.Length}"));
			ParticleSystem[] array = componentsInChildren;
			foreach (ParticleSystem val3 in array)
			{
				if (!val3.isPlaying)
				{
					val3.Play(true);
				}
			}
			return val2;
		}

		protected static void FireProjectile(string prefabName, Vector3 origin, Vector3 target, float speed, Player owner, float spread = 0f)
		{
			//IL_0063: 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_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Expected O, but got Unknown
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ZNetScene.instance == (Object)null)
			{
				StaffsPlugin.Log.LogWarning((object)("[FireProjectile] ZNetScene.instance is null — cannot spawn " + prefabName));
				return;
			}
			GameObject prefab = ZNetScene.instance.GetPrefab(prefabName);
			if ((Object)(object)prefab == (Object)null)
			{
				StaffsPlugin.Log.LogWarning((object)("[FireProjectile] Projectile prefab not found: " + prefabName));
				return;
			}
			Vector3 val = target - origin;
			if (((Vector3)(ref val)).sqrMagnitude < 0.001f)
			{
				val = Vector3.forward;
			}
			val = ((Vector3)(ref val)).normalized;
			if (spread > 0f)
			{
				val = Quaternion.Euler(Random.Range(0f - spread, spread), Random.Range(0f - spread, spread), 0f) * val;
			}
			GameObject val2 = Object.Instantiate<GameObject>(prefab, origin, Quaternion.LookRotation(val));
			ZNetView component = val2.GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null)
			{
				((Behaviour)component).enabled = false;
			}
			Projectile val3 = default(Projectile);
			if (val2.TryGetComponent<Projectile>(ref val3))
			{
				HitData val4 = new HitData();
				val4.m_attacker = ((Character)owner).GetZDOID();
				val3.Setup((Character)(object)owner, val * speed, -1f, val4, (ItemData)null, (ItemData)null);
			}
			Rigidbody val5 = default(Rigidbody);
			if (val2.TryGetComponent<Rigidbody>(ref val5))
			{
				val5.velocity = val * speed;
			}
		}

		protected static Vector3 SnapToGround(Vector3 pos, float searchHeight = 50f)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(pos.x, pos.y + searchHeight, pos.z);
			RaycastHit val2 = default(RaycastHit);
			if (Physics.Raycast(val, Vector3.down, ref val2, searchHeight * 2f, LayerMask.GetMask(new string[2] { "terrain", "Default" })))
			{
				return ((RaycastHit)(ref val2)).point;
			}
			((Vector3)(ref val))..ctor(pos.x, 500f, pos.z);
			if (Physics.Raycast(val, Vector3.down, ref val2, 1000f, LayerMask.GetMask(new string[2] { "terrain", "Default" })))
			{
				return ((RaycastHit)(ref val2)).point;
			}
			return pos;
		}

		protected static void PlayAudioClip(string clipName, Vector3 pos, float volume = 1f, float pitch = 1f)
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			if (!s_clipCache.TryGetValue(clipName, out var value) || (Object)(object)value == (Object)null)
			{
				foreach (AssetBundle allLoadedAssetBundle in AssetBundle.GetAllLoadedAssetBundles())
				{
					if (!allLoadedAssetBundle.isStreamedSceneAssetBundle)
					{
						try
						{
							value = allLoadedAssetBundle.LoadAsset<AudioClip>(clipName);
						}
						catch
						{
							continue;
						}
						if ((Object)(object)value != (Object)null)
						{
							break;
						}
					}
				}
				s_clipCache[clipName] = value;
			}
			if ((Object)(object)value == (Object)null)
			{
				StaffsPlugin.Log.LogWarning((object)("AudioClip not found in loaded bundles: " + clipName));
			}
			else
			{
				AudioSource.PlayClipAtPoint(value, pos, volume);
			}
		}
	}
}