Decompiled source of Boss Invokes Forsaken Powers v0.5.3

BossInvokesForsakenPowers.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
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("BossInvokesForsakenPowers")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BossInvokesForsakenPowers")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("7f9e6c78-1f81-4f96-9a19-350efdb6ec15")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace BossInvokesForsakenPowers;

[BepInPlugin("Severon.BossInvokesForsakenPower", "Boss Invokes Forsaken Powers", "0.5.3")]
[BepInProcess("Valheim.exe")]
public class BossInvokesForsakenPowers : BaseUnityPlugin
{
	public enum WeaknessLevel
	{
		Neutral,
		SlightlyWeak,
		Weak,
		VeryWeak
	}

	[HarmonyPatch(typeof(Character), "OnEnable")]
	private class CaptureBoss
	{
		private static void Postfix(Character __instance)
		{
			if (__instance.m_boss)
			{
				Controller.RegisterBoss(__instance);
			}
		}
	}

	[HarmonyPatch(typeof(Character), "OnDeath")]
	private class RemoveBoss
	{
		private static void Postfix(Character __instance)
		{
			if (__instance.m_boss)
			{
				Controller.DeregisterBoss(__instance);
			}
		}
	}

	[HarmonyPatch(typeof(Character), "Damage")]
	private class PlayerWeaknessPatch
	{
		private static void Prefix(Character __instance, ref HitData hit)
		{
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			SEMan sEMan = ((Character)val).GetSEMan();
			List<StatusEffect> list = ((sEMan != null) ? sEMan.GetStatusEffects() : null);
			if (list == null)
			{
				return;
			}
			foreach (StatusEffect item in list)
			{
				if (item.NameHash() == SE_BonemassCurse.NameHash())
				{
					float weaknessMultiplier = GetWeaknessMultiplier(BonemassPhysicalWeakness.Value);
					hit.m_damage.m_blunt *= weaknessMultiplier;
					hit.m_damage.m_slash *= weaknessMultiplier;
					hit.m_damage.m_pierce *= weaknessMultiplier;
					break;
				}
				if (item.NameHash() == SE_DragonCurse.NameHash())
				{
					float weaknessMultiplier2 = GetWeaknessMultiplier(DragonFrostWeakness.Value);
					hit.m_damage.m_frost *= weaknessMultiplier2;
					break;
				}
				if (item.NameHash() == SE_GoblinKingCurse.NameHash())
				{
					float weaknessMultiplier3 = GetWeaknessMultiplier(GoblinKingLightningWeakness.Value);
					hit.m_damage.m_lightning *= weaknessMultiplier3;
					break;
				}
				if (item.NameHash() == SE_SeekerQueenCurse.NameHash())
				{
					float weaknessMultiplier4 = GetWeaknessMultiplier(SeekerQueenPoisonWeakness.Value);
					hit.m_damage.m_poison *= weaknessMultiplier4;
					break;
				}
				if (item.NameHash() == SE_FaderCurse.NameHash())
				{
					float weaknessMultiplier5 = GetWeaknessMultiplier(FaderFireWeakness.Value);
					hit.m_damage.m_fire *= weaknessMultiplier5;
					break;
				}
			}
		}

		private static float GetWeaknessMultiplier(WeaknessLevel level)
		{
			return level switch
			{
				WeaknessLevel.Neutral => 1f, 
				WeaknessLevel.SlightlyWeak => 1.25f, 
				WeaknessLevel.Weak => 1.5f, 
				WeaknessLevel.VeryWeak => 2f, 
				_ => 1f, 
			};
		}
	}

	[HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")]
	private class RegisterSE
	{
		[CompilerGenerated]
		private sealed class <DelayedRegister>d__1 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public ObjectDB db;

			private float <runStamCost>5__1;

			private float <jumpStamCost>5__2;

			private float <swimStamCost>5__3;

			private float <healthRegen>5__4;

			private float <blockStamCost>5__5;

			private float <movementSpeed>5__6;

			private float <attackDamage>5__7;

			private float <eitrRegen>5__8;

			private float <adrenalineGain>5__9;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DelayedRegister>d__1(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<runStamCost>5__1 = RunStamModifier.Value * 100f - 100f;
					<jumpStamCost>5__2 = JumpStamModifier.Value * 100f - 100f;
					<swimStamCost>5__3 = SwimStamModifier.Value * 100f - 100f;
					<healthRegen>5__4 = HealthRegenModifier.Value * 100f - 100f;
					<blockStamCost>5__5 = BlockStamModifier.Value * 100f - 100f;
					<movementSpeed>5__6 = MovementSpeedModifier.Value * 100f - 100f;
					<attackDamage>5__7 = AttackDamageModifier.Value * 100f - 100f;
					<eitrRegen>5__8 = EitrRegenModifier.Value * 100f - 100f;
					<adrenalineGain>5__9 = AdrenalineGainModifier.Value * 100f - 100f;
					SE_EikthyrCurse = CreateSE<SE_EikthyrCurseSE>(db, "SE_EikthyrCurse", "$se_eikthyr_name", "Forsaken Curse: Eikthyr", "The lightning from the mighty stag god courses through your body. Your ability to move around is impeded.\n\nRun stamina usage: <color=orange>+" + <runStamCost>5__1 + "%</color>\nJump stamina usage: <color=orange>+" + <jumpStamCost>5__2 + "%</color>\nSwim stamina usage: <color=orange>+" + <swimStamCost>5__3 + "%</color>\nEffect duration: <color=orange>" + CurseDuration.Value + "</color>", CurseDuration.Value);
					SE_GDKingCurse = CreateSE<SE_GDKingCurseSE>(db, "SE_GDKingCurse", "$se_gdking_name", "Forsaken Curse: The Elder", "The power of the forest begins to sap you. You feel your vitality no longer sustaining you.\n\nHealth regen: <color=orange>" + <healthRegen>5__4 + "%</color>\nEffect duration: <color=orange>" + CurseDuration.Value + "</color>", CurseDuration.Value);
					SE_BonemassCurse = CreateSE<SE_BonemassCurseSE>(db, "SE_BonemassCurse", "$se_bonemass_name", "Forsaken Curse: Bonemass", "The sludge of the mass clings to your body. Making you more vulnerable to physical attacks and requiring greater effort to block incoming blows. \n\nDamage modifier: <color=orange>" + GetWeaknessText(BonemassPhysicalWeakness.Value) + "</color> VS <color=orange>Blunt</color>\nDamage modifier: <color=orange>" + GetWeaknessText(BonemassPhysicalWeakness.Value) + "</color> VS <color=orange>Slash</color>\nDamage modifier: <color=orange>" + GetWeaknessText(BonemassPhysicalWeakness.Value) + "</color> VS <color=orange>Pierce</color>\nBlock stamina cost: <color=orange>+" + <blockStamCost>5__5 + "%</color>\nEffect duration: <color=orange>" + CurseDuration.Value + "</color>", CurseDuration.Value);
					SE_DragonCurse = CreateSE<SE_DragonCurseSE>(db, "SE_DragonCurse", "$se_moder_name", "Forsaken Curse: Moder", "The extreme mountain winds freeze your limbs and makes your load heavy.\n\nDamage modifier: <color=orange>" + GetWeaknessText(DragonFrostWeakness.Value) + "</color> VS <color=orange>Frost</color>\nMovement speed: <color=orange>" + <movementSpeed>5__6 + "%</color>\nEffect duration: <color=orange>" + CurseDuration.Value + "</color>", CurseDuration.Value);
					SE_GoblinKingCurse = CreateSE<SE_GoblinKingCurseSE>(db, "SE_GoblinKingCurse", "$se_yagluth_name", "Forsaken Curse: Yagluth", "The fallen king is jealous of your power and seeks to claim it for his own. You feel your own power wane.\n\nDamage modifier: <color=orange>" + GetWeaknessText(GoblinKingLightningWeakness.Value) + "</color> VS <color=orange>Lightning</color>\nBlunt: <color=orange>" + <attackDamage>5__7 + "%</color>\nSlash: <color=orange>" + <attackDamage>5__7 + "%</color>\nPierce: <color=orange>" + <attackDamage>5__7 + "%</color>\nChop: <color=orange>" + <attackDamage>5__7 + "%</color>\nPickaxe: <color=orange>" + <attackDamage>5__7 + "%</color>\nFire: <color=orange>" + <attackDamage>5__7 + "%</color>\nFrost: <color=orange>" + <attackDamage>5__7 + "%</color>\nLightning: <color=orange>" + <attackDamage>5__7 + "%</color>\nPoison: <color=orange>" + <attackDamage>5__7 + "%</color>\nSpirit: <color=orange>" + <attackDamage>5__7 + "%</color>\nEffect duration: <color=orange>" + CurseDuration.Value + "</color>", CurseDuration.Value);
					SE_SeekerQueenCurse = CreateSE<SE_SeekerQueenCurseSE>(db, "SE_SeekerQueenCurse", "$se_queen_name", "Forsaken Curse: The Queen", "Her Majesty's magic weaves through you. Draining your ability to regain precious eitr with nausating effect.\n\nEitr regen: <color=orange>" + <eitrRegen>5__8 + "%</color>\nDamage modifier: <color=orange>" + GetWeaknessText(SeekerQueenPoisonWeakness.Value) + "</color> VS <color=orange>Poison</color>\nEffect duration: <color=orange>" + CurseDuration.Value + "</color>", CurseDuration.Value);
					SE_FaderCurse = CreateSE<SE_FaderCurseSE>(db, "SE_FaderCurse", "$se_fader_name", "Forsaken Curse: Fader", "The Emerald Flame seeks to break your will. You feel a sense of hopelessness.\n\nDamage modifier: <color=orange>" + GetWeaknessText(FaderFireWeakness.Value) + "</color> VS <color=orange>Fire</color>\nAdrenaline gain: <color=orange>" + <adrenalineGain>5__9 + "%</color>\nEffect duration: <color=orange>" + CurseDuration.Value + "</color>", CurseDuration.Value);
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private static void Postfix(ObjectDB __instance)
		{
			((MonoBehaviour)__instance).StartCoroutine(DelayedRegister(__instance));
		}

		[IteratorStateMachine(typeof(<DelayedRegister>d__1))]
		public static IEnumerator DelayedRegister(ObjectDB db)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DelayedRegister>d__1(0)
			{
				db = db
			};
		}

		private static StatusEffect CreateSE<T>(ObjectDB db, string objName, string baseName, string displayName, string tooltip, float ttl) where T : StatusEffect
		{
			StatusEffect val = db.m_StatusEffects.Find((StatusEffect x) => ((Object)x).name == objName);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			T val2 = ScriptableObject.CreateInstance<T>();
			((Object)(object)val2).name = objName;
			((StatusEffect)val2).m_name = displayName;
			((StatusEffect)val2).m_tooltip = tooltip;
			((StatusEffect)val2).m_ttl = ttl;
			if (objName == "SE_GDKingCurse" && (Object)(object)((StatusEffect)val2).m_icon == (Object)null)
			{
				StatusEffect val3 = db.m_StatusEffects.Find((StatusEffect x) => ((Object)x).name == "GP_TheElder");
				if ((Object)(object)val3 != (Object)null)
				{
					((StatusEffect)val2).m_icon = val3.m_icon;
					((StatusEffect)val2).m_startEffects = val3.m_startEffects;
				}
			}
			else
			{
				foreach (StatusEffect statusEffect in db.m_StatusEffects)
				{
					if (statusEffect.m_name == baseName)
					{
						((StatusEffect)val2).m_icon = statusEffect.m_icon;
						((StatusEffect)val2).m_startEffects = statusEffect.m_startEffects;
						break;
					}
				}
			}
			db.m_StatusEffects.Add((StatusEffect)(object)val2);
			return (StatusEffect)(object)val2;
		}
	}

	public class SE_EikthyrCurseSE : StatusEffect
	{
		public override void ModifyRunStaminaDrain(float baseDrain, ref float drain, Vector3 dir)
		{
			drain *= RunStamModifier.Value;
		}

		public override void ModifyJumpStaminaUsage(float baseUse, ref float staminaUse)
		{
			staminaUse *= JumpStamModifier.Value;
		}

		public override void ModifySwimStaminaUsage(float baseUse, ref float staminaUse)
		{
			staminaUse *= SwimStamModifier.Value;
		}
	}

	public class SE_GDKingCurseSE : StatusEffect
	{
		public override void ModifyHealthRegen(ref float regenMultiplier)
		{
			regenMultiplier *= HealthRegenModifier.Value;
		}
	}

	public class SE_BonemassCurseSE : StatusEffect
	{
		public override void ModifyBlockStaminaUsage(float baseStaminaUse, ref float staminaUse)
		{
			staminaUse *= BlockStamModifier.Value;
		}
	}

	public class SE_DragonCurseSE : StatusEffect
	{
		public override void ModifySpeed(float baseSpeed, ref float speed, Character character, Vector3 dir)
		{
			speed *= MovementSpeedModifier.Value;
		}
	}

	public class SE_GoblinKingCurseSE : StatusEffect
	{
		public override void ModifyAttack(SkillType skill, ref HitData hitData)
		{
			((DamageTypes)(ref hitData.m_damage)).Modify(AttackDamageModifier.Value);
		}
	}

	public class SE_SeekerQueenCurseSE : StatusEffect
	{
		public override void ModifyEitrRegen(ref float eitrRegen)
		{
			eitrRegen *= EitrRegenModifier.Value;
		}
	}

	public class SE_FaderCurseSE : StatusEffect
	{
		public override void ModifyAdrenaline(float baseValue, ref float use)
		{
			use *= AdrenalineGainModifier.Value;
		}
	}

	[HarmonyPatch(typeof(MonsterAI), "UpdateAI")]
	private class MonsterAIUpdatePatch
	{
		private static void Postfix(MonsterAI __instance)
		{
			object? obj = charField?.GetValue(__instance);
			Character val = (Character)((obj is Character) ? obj : null);
			if ((Object)(object)val != (Object)null && val.m_boss)
			{
				Controller.UpdateBossAI(val);
			}
		}
	}

	[HarmonyPatch(typeof(MonsterAI), "DoAttack")]
	private class MonsterAIAttackPatch
	{
		private static void Prefix(MonsterAI __instance)
		{
			object? obj = charField?.GetValue(__instance);
			Character val = (Character)((obj is Character) ? obj : null);
			if (!((Object)(object)val == (Object)null) && val.m_boss)
			{
				Controller.TryUseAbility(val);
			}
		}
	}

	public class BossController
	{
		private Dictionary<ZDOID, BossAbilityState> bossStates = new Dictionary<ZDOID, BossAbilityState>();

		public void RegisterBoss(Character boss)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			ZDOID zDOID = boss.GetZDOID();
			bool flag = false;
			ZDOID key = zDOID;
			if (!bossStates.ContainsKey(key))
			{
				bossStates[key] = new BossAbilityState();
			}
		}

		public void DeregisterBoss(Character boss)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			ZDOID zDOID = boss.GetZDOID();
			bool flag = false;
			bossStates.Remove(zDOID);
		}

		public void TickCooldowns()
		{
			foreach (BossAbilityState value in bossStates.Values)
			{
				if (value.CooldownTimer > 0f)
				{
					value.CooldownTimer -= Time.deltaTime;
				}
			}
		}

		public void UpdateBossAI(Character boss)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			ZDOID zDOID = boss.GetZDOID();
			bool flag = false;
			if (!bossStates.TryGetValue(zDOID, out var value))
			{
				return;
			}
			float num = boss.GetHealth() / boss.GetMaxHealth();
			if (!value.ThresholdTriggered && num < HealthThreshold.Value)
			{
				value.ThresholdTriggered = true;
				value.IsReady = true;
				List<Player> list = new List<Player>();
				Player.GetPlayersInRange(((Component)boss).transform.position, 45f, list);
				foreach (Player item in list)
				{
					((Character)item).Message((MessageType)2, boss.m_name + " is ready to use their Forsaken Power!", 0, (Sprite)null);
				}
			}
			if (!(value.CooldownTimer <= 0f) || !value.CooldownFinished)
			{
				return;
			}
			value.CooldownFinished = false;
			value.IsReady = true;
			List<Player> list2 = new List<Player>();
			Player.GetPlayersInRange(((Component)boss).transform.position, 45f, list2);
			foreach (Player item2 in list2)
			{
				((Character)item2).Message((MessageType)2, boss.m_name + " is ready to use their Forsaken Power!", 0, (Sprite)null);
			}
		}

		public bool TryUseAbility(Character boss)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			ZDOID zDOID = boss.GetZDOID();
			bool flag = false;
			if (!bossStates.TryGetValue(zDOID, out var value))
			{
				return false;
			}
			if (!value.IsReady)
			{
				return false;
			}
			if (value.CooldownTimer > 0f)
			{
				return false;
			}
			if (Random.value > 0.67f)
			{
				return false;
			}
			Debug.Log((object)("[ForsakenPower] " + boss.m_name + " USING FORSAKEN POWER"));
			ApplyDebuff(boss);
			value.StartCooldown(ForsakenAbilityCooldown.Value);
			List<Player> list = new List<Player>();
			Player.GetPlayersInRange(((Component)boss).transform.position, 45f, list);
			foreach (Player item in list)
			{
				((Character)item).Message((MessageType)2, boss.m_name + " unleashes their Forsaken Power!", 0, (Sprite)null);
			}
			return true;
		}

		private void ApplyDebuff(Character boss)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			StatusEffect sEForBoss = GetSEForBoss(boss);
			if ((Object)(object)sEForBoss == (Object)null)
			{
				return;
			}
			List<Player> list = new List<Player>();
			Player.GetPlayersInRange(((Component)boss).transform.position, 45f, list);
			foreach (Player item in list)
			{
				StatusEffect val = sEForBoss.Clone();
				((Character)item).GetSEMan().AddStatusEffect(val, true, 0, 0f);
				val.Setup((Character)(object)item);
			}
		}

		private StatusEffect GetSEForBoss(Character boss)
		{
			return (StatusEffect)(boss.m_name switch
			{
				"$enemy_eikthyr" => SE_EikthyrCurse, 
				"$enemy_gdking" => SE_GDKingCurse, 
				"$enemy_bonemass" => SE_BonemassCurse, 
				"$enemy_dragon" => SE_DragonCurse, 
				"$enemy_goblinking" => SE_GoblinKingCurse, 
				"$enemy_seekerqueen" => SE_SeekerQueenCurse, 
				"$enemy_fader" => SE_FaderCurse, 
				_ => null, 
			});
		}
	}

	public class BossAbilityState
	{
		public bool ThresholdTriggered = false;

		public bool IsReady = false;

		public float CooldownTimer = 0f;

		public bool CooldownFinished = false;

		public void StartCooldown(float duration)
		{
			IsReady = false;
			CooldownTimer = duration;
			CooldownFinished = true;
		}
	}

	public static BossController Controller;

	private readonly Harmony harmony = new Harmony("Severon.BossInvokesForsakenPowers");

	public static StatusEffect SE_EikthyrCurse;

	public static StatusEffect SE_GDKingCurse;

	public static StatusEffect SE_BonemassCurse;

	public static StatusEffect SE_DragonCurse;

	public static StatusEffect SE_GoblinKingCurse;

	public static StatusEffect SE_SeekerQueenCurse;

	public static StatusEffect SE_FaderCurse;

	public static ConfigEntry<float> CurseDuration;

	public static ConfigEntry<float> ForsakenAbilityCooldown;

	public static ConfigEntry<float> HealthThreshold;

	public static ConfigEntry<float> RunStamModifier;

	public static ConfigEntry<float> JumpStamModifier;

	public static ConfigEntry<float> SwimStamModifier;

	public static ConfigEntry<float> HealthRegenModifier;

	public static ConfigEntry<float> BlockStamModifier;

	public static ConfigEntry<float> MovementSpeedModifier;

	public static ConfigEntry<float> AttackDamageModifier;

	public static ConfigEntry<float> EitrRegenModifier;

	public static ConfigEntry<float> AdrenalineGainModifier;

	public static ConfigEntry<WeaknessLevel> BonemassPhysicalWeakness;

	public static ConfigEntry<WeaknessLevel> DragonFrostWeakness;

	public static ConfigEntry<WeaknessLevel> GoblinKingLightningWeakness;

	public static ConfigEntry<WeaknessLevel> SeekerQueenPoisonWeakness;

	public static ConfigEntry<WeaknessLevel> FaderFireWeakness;

	private static readonly FieldInfo charField = typeof(MonsterAI).GetField("m_character", BindingFlags.Instance | BindingFlags.NonPublic);

	private void Awake()
	{
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Expected O, but got Unknown
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Expected O, but got Unknown
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Expected O, but got Unknown
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Expected O, but got Unknown
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Expected O, but got Unknown
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_0191: Expected O, but got Unknown
		//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ce: Expected O, but got Unknown
		//IL_0221: Unknown result type (might be due to invalid IL or missing references)
		//IL_022b: Expected O, but got Unknown
		//IL_027e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0288: Expected O, but got Unknown
		//IL_02db: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e5: Expected O, but got Unknown
		//IL_0338: Unknown result type (might be due to invalid IL or missing references)
		//IL_0342: Expected O, but got Unknown
		//IL_0395: Unknown result type (might be due to invalid IL or missing references)
		//IL_039f: Expected O, but got Unknown
		harmony.PatchAll();
		Controller = new BossController();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Boss Invokes Forsaken Powers Loaded");
		CurseDuration = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Curse Duration", 45f, new ConfigDescription("The duration of the Forsaken Curse in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(30f, 600f), Array.Empty<object>()));
		ForsakenAbilityCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Forsaken Ability Cooldown", 90f, new ConfigDescription("The cooldown period before the Forsaken Curse is available to use in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(30f, 2400f), Array.Empty<object>()));
		HealthThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Health Threshold", 0.9f, new ConfigDescription("The health threshold the boss needs to be under before they start using their Forsaken Curse.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 1f), Array.Empty<object>()));
		RunStamModifier = ((BaseUnityPlugin)this).Config.Bind<float>("Eikthyr", "Run Stamaina Modifier", 2f, new ConfigDescription("The additional cost to stamina when running. (1 is no cost change)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
		JumpStamModifier = ((BaseUnityPlugin)this).Config.Bind<float>("Eikthyr", "Jump Stamina Modifier", 2f, new ConfigDescription("The additional cost to stamina when jumping. (1 is no cost change)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
		SwimStamModifier = ((BaseUnityPlugin)this).Config.Bind<float>("Eikthyr", "Swim Stamina Modifier", 2f, new ConfigDescription("The additional cost to stamina when swimming. (1 is no cost change)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
		HealthRegenModifier = ((BaseUnityPlugin)this).Config.Bind<float>("The Elder", "Health Regen Modifier", 0.5f, new ConfigDescription("The rate health regen is reduced to. (1 is no change, 0 is no health regen)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
		BonemassPhysicalWeakness = ((BaseUnityPlugin)this).Config.Bind<WeaknessLevel>("Bonemass", "Physical Weakness", WeaknessLevel.SlightlyWeak, "How vulnerable players are to physical damage.");
		BlockStamModifier = ((BaseUnityPlugin)this).Config.Bind<float>("Bonemass", "Block Stamina Modifier", 2f, new ConfigDescription("The additional cost to blocking. (1 is no cost change)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
		DragonFrostWeakness = ((BaseUnityPlugin)this).Config.Bind<WeaknessLevel>("Moder", "Frost Weakness", WeaknessLevel.Weak, "How vulnerable players are to frost damage.");
		MovementSpeedModifier = ((BaseUnityPlugin)this).Config.Bind<float>("Moder", "Movement Speed Modifier", 0.9f, new ConfigDescription("The rate movement speed is reduced to (1 is no change, 0 is no movement)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 1f), Array.Empty<object>()));
		GoblinKingLightningWeakness = ((BaseUnityPlugin)this).Config.Bind<WeaknessLevel>("Yagluth", "Lightning Weakness", WeaknessLevel.Weak, "How vulnerable players are to lightning damage.");
		AttackDamageModifier = ((BaseUnityPlugin)this).Config.Bind<float>("Yagluth", "Attack Damage Modifier", 0.75f, new ConfigDescription("The rate attack damage is reduced to (1 is no change, 0 is no attack damage)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 1f), Array.Empty<object>()));
		SeekerQueenPoisonWeakness = ((BaseUnityPlugin)this).Config.Bind<WeaknessLevel>("The Queen", "Poison Weakness", WeaknessLevel.Weak, "How vulnerable players are to poison damage.");
		EitrRegenModifier = ((BaseUnityPlugin)this).Config.Bind<float>("The Queen", "Eitr Regen Modifier", 0.5f, new ConfigDescription("The rate eitr regen is reduced to (1 is no change, 0 is no eitr regen)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
		FaderFireWeakness = ((BaseUnityPlugin)this).Config.Bind<WeaknessLevel>("Fader", "Fire Weakness", WeaknessLevel.Weak, "How vulnerable players are to fire damage.");
		AdrenalineGainModifier = ((BaseUnityPlugin)this).Config.Bind<float>("Fader", "Adrenaline Gain Modifier", 0f, new ConfigDescription("The rate adrenaline is gained to (1 is no change, 0 is no adrenaline gain)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
		CurseDuration.SettingChanged += delegate
		{
			UpdateStatusEffectValues();
		};
		RunStamModifier.SettingChanged += delegate
		{
			UpdateStatusEffectValues();
		};
		JumpStamModifier.SettingChanged += delegate
		{
			UpdateStatusEffectValues();
		};
		SwimStamModifier.SettingChanged += delegate
		{
			UpdateStatusEffectValues();
		};
		HealthRegenModifier.SettingChanged += delegate
		{
			UpdateStatusEffectValues();
		};
		BlockStamModifier.SettingChanged += delegate
		{
			UpdateStatusEffectValues();
		};
		MovementSpeedModifier.SettingChanged += delegate
		{
			UpdateStatusEffectValues();
		};
		AttackDamageModifier.SettingChanged += delegate
		{
			UpdateStatusEffectValues();
		};
		EitrRegenModifier.SettingChanged += delegate
		{
			UpdateStatusEffectValues();
		};
		AdrenalineGainModifier.SettingChanged += delegate
		{
			UpdateStatusEffectValues();
		};
		BonemassPhysicalWeakness.SettingChanged += delegate
		{
			UpdateStatusEffectValues();
		};
		DragonFrostWeakness.SettingChanged += delegate
		{
			UpdateStatusEffectValues();
		};
		GoblinKingLightningWeakness.SettingChanged += delegate
		{
			UpdateStatusEffectValues();
		};
		SeekerQueenPoisonWeakness.SettingChanged += delegate
		{
			UpdateStatusEffectValues();
		};
		FaderFireWeakness.SettingChanged += delegate
		{
			UpdateStatusEffectValues();
		};
	}

	private void Update()
	{
		Controller.TickCooldowns();
	}

	private static void UpdateStatusEffectValues()
	{
		if ((Object)(object)SE_EikthyrCurse != (Object)null)
		{
			SE_EikthyrCurse.m_ttl = CurseDuration.Value;
			float num = RunStamModifier.Value * 100f - 100f;
			float num2 = JumpStamModifier.Value * 100f - 100f;
			float num3 = SwimStamModifier.Value * 100f - 100f;
			SE_EikthyrCurse.m_tooltip = "The lightning from the mighty stag god courses through your body. Your ability to move around is impeded.\n\nRun stamina usage: <color=orange>+" + num + "%</color>\nJump stamina usage: <color=orange>+" + num2 + "%</color>\nSwim stamina usage: <color=orange>+" + num3 + "%</color>\nEffect duration: <color=orange>" + CurseDuration.Value + "</color>";
		}
		if ((Object)(object)SE_GDKingCurse != (Object)null)
		{
			SE_GDKingCurse.m_ttl = CurseDuration.Value;
			float num4 = HealthRegenModifier.Value * 100f - 100f;
			SE_GDKingCurse.m_tooltip = "The power of the forest begins to sap you. You feel your vitality no longer sustaining you.\n\nHealth regen: <color=orange>" + num4 + "%</color>\nEffect duration: <color=orange>" + CurseDuration.Value + "</color>";
		}
		if ((Object)(object)SE_BonemassCurse != (Object)null)
		{
			SE_BonemassCurse.m_ttl = CurseDuration.Value;
			float num5 = BlockStamModifier.Value * 100f - 100f;
			SE_BonemassCurse.m_tooltip = "The sludge of the mass clings to your body. Making you more vulnerable to physical attacks and requiring greater effort to block incoming blows. \n\nDamage modifier: <color=orange>" + GetWeaknessText(BonemassPhysicalWeakness.Value) + "</color> VS <color=orange>Blunt</color>\nDamage modifier: <color=orange>" + GetWeaknessText(BonemassPhysicalWeakness.Value) + "</color> VS <color=orange>Slash</color>\nDamage modifier: <color=orange>" + GetWeaknessText(BonemassPhysicalWeakness.Value) + "</color> VS <color=orange>Pierce</color>\nBlock stamina cost: <color=orange>+" + num5 + "%</color>\nEffect duration: <color=orange>" + CurseDuration.Value + "</color>";
		}
		if ((Object)(object)SE_DragonCurse != (Object)null)
		{
			SE_DragonCurse.m_ttl = CurseDuration.Value;
			float num6 = MovementSpeedModifier.Value * 100f - 100f;
			SE_DragonCurse.m_tooltip = "The extreme mountain winds freeze your limbs and makes your load heavy.\n\nDamage modifier: <color=orange>" + GetWeaknessText(DragonFrostWeakness.Value) + "</color> VS <color=orange>Frost</color>\nMovement speed: <color=orange>" + num6 + "%</color>\nEffect duration: <color=orange>" + CurseDuration.Value + "</color>";
		}
		if ((Object)(object)SE_GoblinKingCurse != (Object)null)
		{
			SE_GoblinKingCurse.m_ttl = CurseDuration.Value;
			float num7 = AttackDamageModifier.Value * 100f - 100f;
			SE_GoblinKingCurse.m_tooltip = "The fallen king is jealous of your power and seeks to claim it for his own. You feel your own power wane.\n\nDamage modifier: <color=orange>" + GetWeaknessText(GoblinKingLightningWeakness.Value) + "</color> VS <color=orange>Lightning</color>\nBlunt: <color=orange>" + num7 + "%</color>\nSlash: <color=orange>" + num7 + "%</color>\nPierce: <color=orange>" + num7 + "%</color>\nChop: <color=orange>" + num7 + "%</color>\nPickaxe: <color=orange>" + num7 + "%</color>\nFire: <color=orange>" + num7 + "%</color>\nFrost: <color=orange>" + num7 + "%</color>\nLightning: <color=orange>" + num7 + "%</color>\nPoison: <color=orange>" + num7 + "%</color>\nSpirit: <color=orange>" + num7 + "%</color>\nEffect duration: <color=orange>" + CurseDuration.Value + "</color>";
		}
		if ((Object)(object)SE_SeekerQueenCurse != (Object)null)
		{
			SE_SeekerQueenCurse.m_ttl = CurseDuration.Value;
			float num8 = EitrRegenModifier.Value * 100f - 100f;
			SE_SeekerQueenCurse.m_tooltip = "Her Majesty's magic weaves through you. Draining your ability to regain precious eitr with nausating effect.\n\nEitr regen: <color=orange>" + num8 + "%</color>\nDamage modifier: <color=orange>" + GetWeaknessText(SeekerQueenPoisonWeakness.Value) + "</color> VS <color=orange>Poison</color>\nEffect duration: <color=orange>" + CurseDuration.Value + "</color>";
		}
		if ((Object)(object)SE_FaderCurse != (Object)null)
		{
			SE_FaderCurse.m_ttl = CurseDuration.Value;
			float num9 = AdrenalineGainModifier.Value * 100f - 100f;
			SE_FaderCurse.m_tooltip = "The Emerald Flame seeks to break your will. You feel a sense of hopelessness.\n\nDamage modifier: <color=orange>" + GetWeaknessText(FaderFireWeakness.Value) + "</color> VS <color=orange>Fire</color>\nAdrenaline gain: <color=orange>" + num9 + "%</color>\nEffect duration: <color=orange>" + CurseDuration.Value + "</color>";
		}
	}

	private static string GetWeaknessText(WeaknessLevel level)
	{
		return level switch
		{
			WeaknessLevel.SlightlyWeak => "Slightly weak", 
			WeaknessLevel.Weak => "Weak", 
			WeaknessLevel.VeryWeak => "Very weak", 
			_ => "Neutral", 
		};
	}
}