Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Staffs of the Forsaken v1.1.0
StaffsOfTheForsaken.dll
Decompiled 3 days agousing 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); } } } }