Decompiled source of NightmareMode v1.5.10

Recks-Nightmare.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ModHijack")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ModHijack")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("36654a57-7ef9-41f1-a6d1-6e7615d389e3")]
[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 Reckss.ErenshorMods;

public class EliteMarker : MonoBehaviour
{
}
[BepInPlugin("com.reckss.erenshor.eliteenemy", "Elite Enemy Mod", "1.5.10")]
public class EliteEnemyMod : BaseUnityPlugin
{
	public ManualLogSource Logger;

	private ConfigEntry<float> spawnRangeCfg;

	private ConfigEntry<float> spawnIntervalCfg;

	private ConfigEntry<int> maxElitesCfg;

	private ConfigEntry<float> eliteScaleMultiplierCfg;

	private ConfigEntry<string> excludeFactionsCfg;

	private ConfigEntry<string> excludeScenesCfg;

	private ConfigEntry<string> excludeNamesCfg;

	private ConfigEntry<float> blessedDropChanceCfg;

	private ConfigEntry<float> eliteMinDistanceCfg;

	private ConfigEntry<bool> allEnemiesEliteCfg;

	private ConfigEntry<int> lowLevelThresholdCfg;

	private ConfigEntry<int> midLevelThresholdCfg;

	private ConfigEntry<float> lowLevelMultCfg;

	private ConfigEntry<float> midLevelMultCfg;

	private ConfigEntry<float> highLevelMultCfg;

	private ConfigEntry<float> eliteHPMultiplierCfg;

	private ConfigEntry<float> eliteACMultiplierCfg;

	private ConfigEntry<float> eliteDamageMultiplierCfg;

	private ConfigEntry<float> eliteMoveSpeedMultiplierCfg;

	private ConfigEntry<int> eliteFlatLevelBonusCfg;

	private ConfigEntry<float> dynamicMinMultCfg;

	private ConfigEntry<float> dynamicMaxMultCfg;

	private ConfigEntry<int> maxGameLevelCfg;

	private float lastSpawnTime;

	private readonly HashSet<Character> initialProcessed = new HashSet<Character>();

	private readonly HashSet<Character> processedElites = new HashSet<Character>();

	private readonly List<Character> currentElites = new List<Character>();

	private readonly List<Character> candidateBuffer = new List<Character>();

	private readonly List<Character> dropList = new List<Character>();

	private HashSet<Faction> excludeFactionSet;

	private HashSet<string> excludeSceneSet;

	private HashSet<string> manualExcludedNames;

	public static EliteEnemyMod Instance { get; private set; }

	private void Awake()
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Expected O, but got Unknown
		//IL_036a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0370: Expected O, but got Unknown
		Instance = this;
		Logger = ((BaseUnityPlugin)this).Logger;
		Harmony val = new Harmony("com.reckss.erenshor.eliteenemy");
		val.PatchAll();
		spawnRangeCfg = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SpawnRange", 100f, "Max distance for elite logic.");
		spawnIntervalCfg = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SpawnInterval", 15f, "Seconds between elite spawns.");
		maxElitesCfg = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxElites", 3, "Max simultaneous elites.");
		eliteScaleMultiplierCfg = ((BaseUnityPlugin)this).Config.Bind<float>("General", "EliteScaleMultiplier", 2f, "Model scale multiplier.");
		excludeFactionsCfg = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ExcludeFactions", "Player, Villager", "Factions to skip.");
		excludeScenesCfg = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ExcludeScenes", "Main, LoadScene", "Scenes to skip.");
		excludeNamesCfg = ((BaseUnityPlugin)this).Config.Bind<string>("General", "", "", "Enemy names to skip (comma-separated).");
		blessedDropChanceCfg = ((BaseUnityPlugin)this).Config.Bind<float>("General", "BlessedDropChance", 1f / 65f, "Chance for blessed drop.");
		eliteMinDistanceCfg = ((BaseUnityPlugin)this).Config.Bind<float>("General", "EliteMinDistance", 30f, "Minimum distance between elites.");
		allEnemiesEliteCfg = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AllEnemiesElite", false, "If true, all valid enemies in the scene will become elites.");
		lowLevelThresholdCfg = ((BaseUnityPlugin)this).Config.Bind<int>("LevelTiers", "LowLevelThreshold", 10, "Level below which low-level multiplier applies.");
		midLevelThresholdCfg = ((BaseUnityPlugin)this).Config.Bind<int>("LevelTiers", "MidLevelThreshold", 50, "Level below which mid-level multiplier applies.");
		lowLevelMultCfg = ((BaseUnityPlugin)this).Config.Bind<float>("LevelTiers", "LowLevelMult", 1.5f, "Multiplier for low-level players.");
		midLevelMultCfg = ((BaseUnityPlugin)this).Config.Bind<float>("LevelTiers", "MidLevelMult", 2f, "Multiplier for mid-level players.");
		highLevelMultCfg = ((BaseUnityPlugin)this).Config.Bind<float>("LevelTiers", "HighLevelMult", 2.5f, "Multiplier for high-level players.");
		eliteHPMultiplierCfg = ((BaseUnityPlugin)this).Config.Bind<float>("EliteStats", "HP_Multiplier", 2.5f, "Base HP multiplier.");
		eliteACMultiplierCfg = ((BaseUnityPlugin)this).Config.Bind<float>("EliteStats", "AC_Multiplier", 2.5f, "Base AC multiplier.");
		eliteDamageMultiplierCfg = ((BaseUnityPlugin)this).Config.Bind<float>("EliteStats", "Damage_Multiplier", 2.5f, "Base damage multiplier.");
		eliteMoveSpeedMultiplierCfg = ((BaseUnityPlugin)this).Config.Bind<float>("EliteStats", "MoveSpeed_Multiplier", 1.2f, "Speed multiplier.");
		eliteFlatLevelBonusCfg = ((BaseUnityPlugin)this).Config.Bind<int>("EliteStats", "FlatLevelBonus", 15, "Flat level bonus added to elites when spawned.");
		dynamicMinMultCfg = ((BaseUnityPlugin)this).Config.Bind<float>("Scaling", "DynamicMinMult", 1.5f, "Min extra multiplier.");
		dynamicMaxMultCfg = ((BaseUnityPlugin)this).Config.Bind<float>("Scaling", "DynamicMaxMult", 3f, "Max extra multiplier.");
		maxGameLevelCfg = ((BaseUnityPlugin)this).Config.Bind<int>("Scaling", "MaxGameLevel", 100, "Level at which scaling caps.");
		GameObject val2 = new GameObject("ZoneBossManager");
		val2.AddComponent<ZoneBossManager>();
		BuildExcludeSets();
		lastSpawnTime = 0f - spawnIntervalCfg.Value;
		Logger.LogInfo((object)"[EliteEnemyMod] v1.5.10 loaded");
	}

	private void BuildExcludeSets()
	{
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		excludeFactionSet = new HashSet<Faction>();
		string[] array = excludeFactionsCfg.Value.Split(new char[1] { ',' });
		foreach (string text in array)
		{
			if (Enum.TryParse<Faction>(text.Trim(), ignoreCase: true, out Faction result))
			{
				excludeFactionSet.Add(result);
			}
		}
		excludeSceneSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
		string[] array2 = excludeScenesCfg.Value.Split(new char[1] { ',' });
		foreach (string text2 in array2)
		{
			excludeSceneSet.Add(text2.Trim());
		}
		manualExcludedNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
		string[] array3 = excludeNamesCfg.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
		foreach (string text3 in array3)
		{
			manualExcludedNames.Add(text3.Trim());
		}
	}

	private void Update()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		Scene activeScene = SceneManager.GetActiveScene();
		string name = ((Scene)(ref activeScene)).name;
		if (!excludeSceneSet.Contains(name))
		{
			if (Input.GetKeyDown((KeyCode)291))
			{
				DumpDebugInfo();
			}
			if (Input.GetKeyDown((KeyCode)290))
			{
				ForceEliteSpawn();
			}
			HandleKeyInput();
			ProcessEliteLogic();
		}
	}

	private void DumpDebugInfo()
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0181: Unknown result type (might be due to invalid IL or missing references)
		Logger.LogInfo((object)"=== Elite Enemy Debug Info ===");
		ManualLogSource logger = Logger;
		Scene activeScene = SceneManager.GetActiveScene();
		logger.LogInfo((object)("Current Scene: " + ((Scene)(ref activeScene)).name));
		Logger.LogInfo((object)$"Current Elite Count: {currentElites.Count}");
		Logger.LogInfo((object)$"Time Since Last Spawn: {Time.time - lastSpawnTime}");
		Logger.LogInfo((object)$"Spawn Interval: {spawnIntervalCfg.Value}");
		Logger.LogInfo((object)$"Processed Elites Count: {processedElites.Count}");
		PlayerMeleeArea val = Object.FindObjectOfType<PlayerMeleeArea>();
		if ((Object)(object)val != (Object)null)
		{
			Vector3 position = ((Component)val).transform.position;
			Logger.LogInfo((object)$"Player Position: {position}");
			Character[] array = Object.FindObjectsOfType<Character>();
			Logger.LogInfo((object)$"Total Characters in Scene: {array.Length}");
			Character[] array2 = array;
			foreach (Character val2 in array2)
			{
				if ((Object)(object)val2 != (Object)null)
				{
					float num = Vector3.Distance(((Component)val2).transform.position, position);
					Logger.LogInfo((object)$"Character: {((Object)val2).name} - Distance: {num} - Faction: {val2.MyFaction}");
				}
			}
		}
		else
		{
			Logger.LogInfo((object)"No PlayerMeleeArea found!");
		}
		Logger.LogInfo((object)"===========================");
	}

	private void ForceEliteSpawn()
	{
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		PlayerMeleeArea val = Object.FindObjectOfType<PlayerMeleeArea>();
		if ((Object)(object)val == (Object)null)
		{
			Logger.LogInfo((object)"Cannot force spawn - no PlayerMeleeArea found");
			return;
		}
		Character componentInParent = ((Component)val).GetComponentInParent<Character>();
		Stats val2 = ((componentInParent != null) ? ((Component)componentInParent).GetComponent<Stats>() : null);
		if ((Object)(object)componentInParent == (Object)null || (Object)(object)val2 == (Object)null)
		{
			Logger.LogInfo((object)"Cannot force spawn - no player character/stats found");
			return;
		}
		Character val3 = null;
		float num = float.MaxValue;
		Character[] array = Object.FindObjectsOfType<Character>();
		foreach (Character val4 in array)
		{
			if (!((Object)(object)val4 == (Object)null) && !((Object)(object)val4 == (Object)(object)componentInParent) && !processedElites.Contains(val4) && !((Object)(object)((Component)val4).GetComponent<SimPlayer>() != (Object)null) && !((Object)val4).name.Contains("Summoned") && !excludeFactionSet.Contains(val4.MyFaction))
			{
				float num2 = Vector3.Distance(((Component)val4).transform.position, ((Component)val).transform.position);
				if (num2 < num)
				{
					num = num2;
					val3 = val4;
				}
			}
		}
		if ((Object)(object)val3 != (Object)null)
		{
			Logger.LogInfo((object)("Force promoting nearest valid candidate: " + ((Object)val3).name));
			PromoteToElite(val3, val2);
		}
		else
		{
			Logger.LogInfo((object)"No valid candidates found for forced elite spawn");
		}
	}

	private void HandleKeyInput()
	{
		//IL_0044: 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_0080: Unknown result type (might be due to invalid IL or missing references)
		if (Input.GetKeyDown((KeyCode)292))
		{
			PlayerControl playerControl = GameData.PlayerControl;
			object obj;
			if (playerControl == null)
			{
				obj = null;
			}
			else
			{
				Character currentTarget = playerControl.CurrentTarget;
				obj = ((currentTarget != null) ? ((Component)currentTarget).GetComponent<Character>() : null);
			}
			Character val = (Character)obj;
			if ((Object)(object)val != (Object)null)
			{
				bool flag = excludeFactionSet.Add(val.MyFaction);
				excludeFactionsCfg.Value = string.Join(", ", excludeFactionSet);
				((BaseUnityPlugin)this).Config.Save();
				UpdateSocialLog.LogAdd(flag ? $"<color=yellow>Excluding faction {val.MyFaction}</color>" : $"<color=yellow>Faction {val.MyFaction} already excluded</color>");
			}
		}
	}

	private void ProcessEliteLogic()
	{
		//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_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		PlayerMeleeArea val = Object.FindObjectOfType<PlayerMeleeArea>();
		if (!((Object)(object)val == (Object)null))
		{
			Character componentInParent = ((Component)val).GetComponentInParent<Character>();
			Stats val2 = ((componentInParent != null) ? ((Component)componentInParent).GetComponent<Stats>() : null);
			if (!((Object)(object)componentInParent == (Object)null) && !((Object)(object)val2 == (Object)null))
			{
				Vector3 position = ((Component)val).transform.position;
				float rangeSq = spawnRangeCfg.Value * spawnRangeCfg.Value;
				ProcessInitialScaling(componentInParent, val2, position, rangeSq);
				ProcessEliteSpawning(componentInParent, val2, position, rangeSq);
			}
		}
	}

	private void ProcessInitialScaling(Character playerChar, Stats playerStats, Vector3 ppos, float rangeSq)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		Character[] array = Object.FindObjectsOfType<Character>();
		foreach (Character val in array)
		{
			if (!ShouldSkipCharacter(val, playerChar, ppos, rangeSq))
			{
				Stats component = ((Component)val).GetComponent<Stats>();
				if (!((Object)(object)component == (Object)null) && component.CurrentHP > 0)
				{
					ScaleCharacter(component, playerStats);
					initialProcessed.Add(val);
				}
			}
		}
	}

	private bool ShouldSkipCharacter(Character c, Character playerChar, Vector3 ppos, float rangeSq)
	{
		//IL_0060: 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_0077: 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)
		int result;
		if (!initialProcessed.Contains(c) && !processedElites.Contains(c) && !((Object)(object)c == (Object)(object)playerChar) && !((Object)(object)((Component)c).GetComponent<SimPlayer>() != (Object)null) && !((Object)c).name.Contains("Summoned") && !manualExcludedNames.Contains(((Object)c).name) && !excludeFactionSet.Contains(c.MyFaction))
		{
			Vector3 val = ((Component)c).transform.position - ppos;
			result = ((((Vector3)(ref val)).sqrMagnitude > rangeSq) ? 1 : 0);
		}
		else
		{
			result = 1;
		}
		return (byte)result != 0;
	}

	private void ScaleCharacter(Stats st, Stats playerStats)
	{
		if (st.Level < playerStats.Level)
		{
			int num = Mathf.RoundToInt((float)playerStats.Level * 0.1f);
			st.Level = Mathf.Clamp(playerStats.Level + Random.Range(-num, num + 1), 1, int.MaxValue);
			st.CalcStats();
		}
		else
		{
			st.CurrentMaxHP = Mathf.RoundToInt((float)st.CurrentMaxHP * lowLevelMultCfg.Value);
			st.CurrentHP = st.CurrentMaxHP;
			st.CurrentAC = Mathf.RoundToInt((float)st.CurrentAC * lowLevelMultCfg.Value);
		}
	}

	private bool IsTooCloseToOtherElites(Vector3 position)
	{
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: 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)
		float num = eliteMinDistanceCfg.Value * eliteMinDistanceCfg.Value;
		foreach (Character currentElite in currentElites)
		{
			if (!((Object)(object)currentElite == (Object)null))
			{
				Vector3 val = ((Component)currentElite).transform.position - position;
				float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
				if (sqrMagnitude < num)
				{
					return true;
				}
			}
		}
		return false;
	}

	private void ProcessEliteSpawning(Character playerChar, Stats playerStats, Vector3 ppos, float rangeSq)
	{
		//IL_00cb: 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_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_013f: Unknown result type (might be due to invalid IL or missing references)
		currentElites.RemoveAll(delegate(Character e)
		{
			int result;
			if (!((Object)(object)e == (Object)null))
			{
				Stats component2 = ((Component)e).GetComponent<Stats>();
				result = ((component2 != null && component2.CurrentHP <= 0) ? 1 : 0);
			}
			else
			{
				result = 1;
			}
			return (byte)result != 0;
		});
		if (!allEnemiesEliteCfg.Value && (Time.time - lastSpawnTime < spawnIntervalCfg.Value || currentElites.Count >= maxElitesCfg.Value))
		{
			return;
		}
		List<Character> list = new List<Character>();
		Character[] array = Object.FindObjectsOfType<Character>();
		foreach (Character val in array)
		{
			if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)playerChar)
			{
				continue;
			}
			Vector3 val2 = ((Component)val).transform.position - ppos;
			float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
			if (!(sqrMagnitude > rangeSq) && !processedElites.Contains(val) && !((Object)(object)((Component)val).GetComponent<SimPlayer>() != (Object)null) && !((Object)val).name.Contains("Summoned") && !manualExcludedNames.Contains(((Object)val).name) && !excludeFactionSet.Contains(val.MyFaction))
			{
				Stats component = ((Component)val).GetComponent<Stats>();
				if ((Object)(object)component != (Object)null && component.CurrentHP >= component.CurrentMaxHP)
				{
					list.Add(val);
				}
			}
		}
		if (list.Count <= 0)
		{
			return;
		}
		if (allEnemiesEliteCfg.Value)
		{
			foreach (Character item in list)
			{
				if (!processedElites.Contains(item))
				{
					PromoteToElite(item, playerStats);
					currentElites.Add(item);
				}
			}
			lastSpawnTime = Time.time;
		}
		else
		{
			Character val3 = list[Random.Range(0, list.Count)];
			PromoteToElite(val3, playerStats);
			currentElites.Add(val3);
			lastSpawnTime = Time.time;
		}
	}

	public void PromoteToElite(Character enemy, Stats playerStats)
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)enemy == (Object)null || processedElites.Contains(enemy) || (Object)(object)((Component)enemy).GetComponent<SimPlayer>() != (Object)null || ((Object)enemy).name.Contains("Summoned") || excludeFactionSet.Contains(enemy.MyFaction))
		{
			UpdateSocialLog.LogAdd("Cannot promote that target.", "red");
			return;
		}
		Stats component = ((Component)enemy).GetComponent<Stats>();
		if (!((Object)(object)component == (Object)null))
		{
			processedElites.Add(enemy);
			((Component)enemy).gameObject.AddComponent<EliteMarker>();
			EliteAbilities eliteAbilities = ((Component)enemy).gameObject.AddComponent<EliteAbilities>();
			EliteType type = (EliteType)Random.Range(0, 6);
			eliteAbilities.Initialize(type);
			ApplyEliteStats(enemy, component, playerStats);
			EliteVisualEffect eliteVisualEffect = ((Component)enemy).gameObject.AddComponent<EliteVisualEffect>();
			eliteVisualEffect.Setup();
		}
	}

	private void ApplyEliteStats(Character enemy, Stats stats, Stats playerStats)
	{
		//IL_01aa: 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)
		if (stats.CurrentMaxHP < 25000)
		{
			stats.CurrentMaxHP = 25000;
			stats.CurrentHP = 25000;
		}
		stats.Level += eliteFlatLevelBonusCfg.Value;
		stats.CalcStats();
		float num = Mathf.Clamp01((float)playerStats.Level / (float)maxGameLevelCfg.Value);
		float num2 = Mathf.Lerp(dynamicMinMultCfg.Value, dynamicMaxMultCfg.Value, num);
		float num3 = ((playerStats.Level < lowLevelThresholdCfg.Value) ? lowLevelMultCfg.Value : ((playerStats.Level < midLevelThresholdCfg.Value) ? midLevelMultCfg.Value : highLevelMultCfg.Value));
		float num4 = num2 * num3;
		stats.CurrentMaxHP = Mathf.RoundToInt((float)stats.CurrentMaxHP * eliteHPMultiplierCfg.Value * num4);
		stats.CurrentHP = stats.CurrentMaxHP;
		stats.CurrentAC = Mathf.RoundToInt((float)stats.CurrentAC * eliteACMultiplierCfg.Value * num4);
		stats.RunSpeed *= eliteMoveSpeedMultiplierCfg.Value * num4;
		NPC val = default(NPC);
		if (((Component)enemy).TryGetComponent<NPC>(ref val))
		{
			val.BaseAtkDmg = Mathf.RoundToInt((float)val.BaseAtkDmg * eliteDamageMultiplierCfg.Value * num4);
			val.OHAtkDmg = Mathf.RoundToInt((float)val.OHAtkDmg * eliteDamageMultiplierCfg.Value * num4);
		}
		((Object)enemy).name = ((Object)enemy).name + " Elite";
		Transform transform = ((Component)enemy).transform;
		transform.localScale *= eliteScaleMultiplierCfg.Value;
	}

	public bool IsExcludedFaction(Faction faction)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		return excludeFactionSet.Contains(faction);
	}

	public bool IsExcludedName(string name)
	{
		return manualExcludedNames.Contains(name);
	}
}
public enum EliteType
{
	Berserker,
	Unstoppable,
	Nightmare,
	Warped,
	Infernal,
	Celestial
}
public class EliteAbilities : MonoBehaviour
{
	[CompilerGenerated]
	private sealed class <PhaseShift>d__21 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public EliteAbilities <>4__this;

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

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

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

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

		private bool MoveNext()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				break;
			case 1:
				<>1__state = -1;
				break;
			}
			<>4__this.isVulnerable = !<>4__this.isVulnerable;
			<>2__current = (object)new WaitForSeconds(4f);
			<>1__state = 1;
			return true;
		}

		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 EliteType eliteType;

	private Stats stats;

	private NPC npc;

	private bool deathDefied;

	private float damageReduction;

	private List<GameObject> shadows;

	private bool isVulnerable;

	private float lastHitTime;

	private float auraTickTime;

	private const float AURA_TICK_RATE = 0.5f;

	private float damageMultiplier = 1f;

	private bool lastVulnerableState = true;

	public EliteType EliteType => eliteType;

	public void Initialize(EliteType type)
	{
		eliteType = type;
		stats = ((Component)this).GetComponent<Stats>();
		npc = ((Component)this).GetComponent<NPC>();
		shadows = new List<GameObject>();
		isVulnerable = true;
		switch (eliteType)
		{
		case EliteType.Berserker:
			deathDefied = true;
			break;
		case EliteType.Unstoppable:
			damageReduction = 0.3f;
			break;
		case EliteType.Celestial:
			((MonoBehaviour)this).StartCoroutine(PhaseShift());
			break;
		}
	}

	private void Update()
	{
		if (Time.time >= auraTickTime)
		{
			auraTickTime = Time.time + 0.5f;
			ApplyAuraEffects();
		}
		if ((Object)(object)npc != (Object)null)
		{
			npc.BaseAtkDmg = Mathf.RoundToInt((float)npc.BaseAtkDmg * damageMultiplier);
			npc.OHAtkDmg = Mathf.RoundToInt((float)npc.OHAtkDmg * damageMultiplier);
		}
		if (eliteType == EliteType.Celestial)
		{
			EliteVisualEffect component = ((Component)this).GetComponent<EliteVisualEffect>();
			if ((Object)(object)component != (Object)null)
			{
				component.SetInvulnerable(!isVulnerable);
			}
		}
	}

	public float ModifyIncomingDamage(float damage)
	{
		if (!isVulnerable)
		{
			return 0f;
		}
		switch (eliteType)
		{
		case EliteType.Berserker:
			if ((float)stats.CurrentHP < (float)stats.CurrentMaxHP * 0.2f)
			{
				damageMultiplier = 3f;
			}
			return damage;
		case EliteType.Unstoppable:
			damageReduction = Mathf.Min(damageReduction + 0.1f, 0.9f);
			return damage * (1f - damageReduction);
		case EliteType.Nightmare:
		{
			float num = damage * 0.25f;
			Stats obj = stats;
			obj.CurrentHP -= Mathf.RoundToInt(num);
			if (shadows.Count < 3 && Random.value < 0.3f)
			{
				SpawnShadowClone();
			}
			return damage * 0.75f;
		}
		case EliteType.Warped:
			if (Time.time - lastHitTime > 1f)
			{
				TeleportToRandomPosition();
				Stats obj2 = stats;
				obj2.CurrentHP += Mathf.RoundToInt((float)stats.CurrentMaxHP * 0.05f);
				lastHitTime = Time.time;
			}
			return damage;
		case EliteType.Infernal:
			ReflectDamage(Mathf.RoundToInt(damage * 0.5f));
			return damage;
		case EliteType.Celestial:
			return isVulnerable ? damage : 0f;
		default:
			return damage;
		}
	}

	private void SpawnShadowClone()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = Random.insideUnitSphere * 3f;
		val.y = 0f;
		GameObject val2 = Object.Instantiate<GameObject>(((Component)this).gameObject, ((Component)this).transform.position + val, ((Component)this).transform.rotation);
		Object.Destroy((Object)(object)val2.GetComponent<EliteAbilities>());
		Object.Destroy((Object)(object)val2.GetComponent<EliteVisualEffect>());
		Stats component = val2.GetComponent<Stats>();
		if ((Object)(object)component != (Object)null)
		{
			component.CurrentMaxHP = Mathf.RoundToInt((float)stats.CurrentMaxHP * 0.3f);
			component.CurrentHP = component.CurrentMaxHP;
		}
		shadows.Add(val2);
	}

	private void TeleportToRandomPosition()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0042: 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)
		Vector3 val = Random.insideUnitSphere * 8f;
		val.y = 0f;
		RaycastHit val2 = default(RaycastHit);
		if (Physics.Raycast(((Component)this).transform.position + Vector3.up * 10f + val, Vector3.down, ref val2, 20f))
		{
			((Component)this).transform.position = ((RaycastHit)(ref val2)).point;
		}
	}

	private void ReflectDamage(int amount)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		Character val = (from c in Physics.OverlapSphere(((Component)this).transform.position, 10f)
			select ((Component)c).GetComponent<Character>() into c
			where (Object)(object)c != (Object)null && (Object)(object)((Component)c).GetComponent<SimPlayer>() != (Object)null
			orderby Vector3.Distance(((Component)c).transform.position, ((Component)this).transform.position)
			select c).FirstOrDefault();
		if ((Object)(object)val != (Object)null)
		{
			Stats component = ((Component)val).GetComponent<Stats>();
			if ((Object)(object)component != (Object)null)
			{
				component.CurrentHP -= amount;
			}
		}
	}

	private void ApplyAuraEffects()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		IEnumerable<Character> enumerable = from c in Physics.OverlapSphere(((Component)this).transform.position, 5f)
			select ((Component)c).GetComponent<Character>() into c
			where (Object)(object)c != (Object)null && (Object)(object)((Component)c).GetComponent<SimPlayer>() != (Object)null
			select c;
		foreach (Character item in enumerable)
		{
			Stats component = ((Component)item).GetComponent<Stats>();
			if ((Object)(object)component != (Object)null)
			{
				switch (eliteType)
				{
				case EliteType.Warped:
					component.CurrentHP -= Mathf.RoundToInt((float)(stats.Level * 10));
					break;
				case EliteType.Infernal:
					component.CurrentHP -= Mathf.RoundToInt((float)(stats.Level * 15));
					break;
				}
			}
		}
	}

	[IteratorStateMachine(typeof(<PhaseShift>d__21))]
	private IEnumerator PhaseShift()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <PhaseShift>d__21(0)
		{
			<>4__this = this
		};
	}

	private void OnDeath()
	{
		if (eliteType == EliteType.Berserker && deathDefied)
		{
			deathDefied = false;
			stats.CurrentHP = Mathf.RoundToInt((float)stats.CurrentMaxHP * 0.5f);
			damageMultiplier = 4f;
			return;
		}
		foreach (GameObject shadow in shadows)
		{
			if ((Object)(object)shadow != (Object)null)
			{
				Object.Destroy((Object)(object)shadow);
			}
		}
	}
}
public class DamagePatches
{
	[HarmonyPatch(typeof(Stats), "Update")]
	public class StatsUpdatePatch
	{
		private static int lastHP;

		[HarmonyPrefix]
		public static void Prefix(Stats __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				lastHP = __instance.CurrentHP;
			}
		}

		[HarmonyPostfix]
		public static void Postfix(Stats __instance)
		{
			if ((Object)(object)__instance == (Object)null || __instance.CurrentHP >= lastHP)
			{
				return;
			}
			EliteAbilities component = ((Component)__instance).GetComponent<EliteAbilities>();
			if ((Object)(object)component != (Object)null)
			{
				float num = lastHP - __instance.CurrentHP;
				float num2 = component.ModifyIncomingDamage(num);
				if (num2 != num)
				{
					__instance.CurrentHP = lastHP - Mathf.RoundToInt(num2);
				}
			}
		}
	}
}
[HarmonyPatch(typeof(PlayerControl), "ConsiderOpponent")]
public class ElitePatches
{
	[HarmonyPostfix]
	public static void ConsiderOpponent_Postfix(Character newTar)
	{
		if ((Object)(object)newTar == (Object)null)
		{
			return;
		}
		EliteMarker component = ((Component)newTar).GetComponent<EliteMarker>();
		EliteAbilities component2 = ((Component)newTar).GetComponent<EliteAbilities>();
		if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null)
		{
			Stats component3 = ((Component)newTar).GetComponent<Stats>();
			string text = component2.EliteType.ToString();
			string text2 = "\n<color=yellow>Elite Type: " + text + "</color>";
			if ((Object)(object)component3 != (Object)null)
			{
				text2 += "\n<color=red>Enhanced Stats:</color>";
				text2 += $"\n- HP: {component3.CurrentHP}/{component3.CurrentMaxHP}";
				text2 += $"\n- Armor Class: {component3.CurrentAC}";
				text2 += $"\n- Level: {component3.Level}";
			}
			string eliteSpecialInfo = GetEliteSpecialInfo(component2.EliteType);
			if (!string.IsNullOrEmpty(eliteSpecialInfo))
			{
				text2 = text2 + "\n\n<color=orange>Special Abilities:</color>\n" + eliteSpecialInfo;
			}
			UpdateSocialLog.LogAdd(text2);
		}
	}

	private static string GetEliteSpecialInfo(EliteType type)
	{
		return type switch
		{
			EliteType.Berserker => "- Gains increased damage as health drops\n- Can survive death once", 
			EliteType.Unstoppable => "- Cannot be staggered\n- Gains damage reduction when hit", 
			EliteType.Nightmare => "- Creates shadow copies\n- Deals true damage through armor", 
			EliteType.Warped => "- Teleports when hit\n- Regenerates health\n- Emits poison aura", 
			EliteType.Infernal => "- Reflects damage\n- Emits burning aura", 
			EliteType.Celestial => "- Phases between immune and vulnerable states", 
			_ => "", 
		};
	}
}
public class EliteVisualEffect : BaseVisualEffect
{
	[CompilerGenerated]
	private sealed class <PulseEffect>d__20 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public EliteVisualEffect <>4__this;

		private float <startTime>5__1;

		private float <timeElapsed>5__2;

		private float <pulse>5__3;

		private float <normalizedPulse>5__4;

		private Color <currentColor>5__5;

		private float <currentIntensity>5__6;

		private Material[] <>s__7;

		private int <>s__8;

		private Material <material>5__9;

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

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

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

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>s__7 = null;
			<material>5__9 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0094: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Expected O, but got Unknown
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: 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)
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<startTime>5__1 = Time.time;
				break;
			case 1:
				<>1__state = -1;
				break;
			}
			<timeElapsed>5__2 = Time.time - <startTime>5__1;
			<pulse>5__3 = Mathf.Sin(<timeElapsed>5__2 * <>4__this.pulseSpeed * (float)Math.PI + <>4__this.pulsePhaseOffset);
			<normalizedPulse>5__4 = (<pulse>5__3 + 1f) * 0.5f;
			<currentColor>5__5 = Color.Lerp(<>4__this.primaryColor, <>4__this.secondaryColor, <normalizedPulse>5__4);
			<currentIntensity>5__6 = Mathf.Lerp(0.4f, 0.8f, <normalizedPulse>5__4);
			if (<>4__this.glowMaterials != null)
			{
				<>s__7 = <>4__this.glowMaterials;
				for (<>s__8 = 0; <>s__8 < <>s__7.Length; <>s__8++)
				{
					<material>5__9 = <>s__7[<>s__8];
					if ((Object)(object)<material>5__9 != (Object)null)
					{
						<material>5__9.SetColor("_EmissionColor", <currentColor>5__5 * <currentIntensity>5__6 * <>4__this.baseEmission);
						<material>5__9.SetColor("_BaseColor", Color.Lerp(<>4__this.primaryColor, <currentColor>5__5, <normalizedPulse>5__4 * 0.5f));
						<material>5__9.SetColor("_Color", Color.Lerp(<>4__this.primaryColor, <currentColor>5__5, <normalizedPulse>5__4 * 0.5f));
					}
					<material>5__9 = null;
				}
				<>s__7 = null;
			}
			if ((Object)(object)<>4__this.eliteLight != (Object)null)
			{
				<>4__this.eliteLight.color = <currentColor>5__5;
				<>4__this.eliteLight.intensity = <>4__this.baseIntensity * <currentIntensity>5__6;
			}
			<>2__current = (object)new WaitForSeconds(0.033f);
			<>1__state = 1;
			return true;
		}

		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 Light eliteLight;

	private Material[] originalMaterials;

	private Material[] glowMaterials;

	private bool isInitialized = false;

	private readonly Color berserkerColor = new Color(1f, 0.2f, 0.2f);

	private readonly Color unstoppableColor = new Color(0.7f, 0.2f, 1f);

	private readonly Color nightmareColor = new Color(0.2f, 0.2f, 0.2f);

	private readonly Color warpedColor = new Color(0.2f, 1f, 0.2f);

	private readonly Color infernalColor = new Color(1f, 0.5f, 0f);

	private readonly Color celestialColor = new Color(1f, 1f, 1f);

	private float pulseSpeed;

	private float pulsePhaseOffset;

	private float baseEmission = 0.6f;

	private float baseIntensity = 0.6f;

	private Color primaryColor;

	private Color secondaryColor;

	public void Setup()
	{
		if (isInitialized)
		{
			return;
		}
		try
		{
			EliteAbilities component = ((Component)this).GetComponent<EliteAbilities>();
			if ((Object)(object)component != (Object)null)
			{
				SetupColorsForEliteType(component.EliteType);
			}
			pulseSpeed = Random.Range(0.02f, 0.04f);
			pulsePhaseOffset = Random.Range(0f, (float)Math.PI * 2f);
			SetupMaterials();
			SetupLight();
			isInitialized = true;
			((MonoBehaviour)this).StartCoroutine(PulseEffect());
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("Error in EliteVisualEffect Setup: " + ex.Message));
		}
	}

	private void SetupColorsForEliteType(EliteType type)
	{
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: 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_0083: 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_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_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_00cd: 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)
		switch (type)
		{
		case EliteType.Berserker:
			primaryColor = berserkerColor;
			secondaryColor = Color.yellow;
			break;
		case EliteType.Unstoppable:
			primaryColor = unstoppableColor;
			secondaryColor = Color.magenta;
			break;
		case EliteType.Nightmare:
			primaryColor = nightmareColor;
			secondaryColor = Color.gray;
			break;
		case EliteType.Warped:
			primaryColor = warpedColor;
			secondaryColor = Color.cyan;
			break;
		case EliteType.Infernal:
			primaryColor = infernalColor;
			secondaryColor = Color.red;
			break;
		case EliteType.Celestial:
			primaryColor = celestialColor;
			secondaryColor = Color.white;
			break;
		default:
			primaryColor = Color.blue;
			secondaryColor = Color.cyan;
			break;
		}
	}

	private void SetupMaterials()
	{
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Expected O, but got Unknown
		Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
		if (componentsInChildren.Length == 0)
		{
			return;
		}
		originalMaterials = (Material[])(object)new Material[componentsInChildren.Length];
		glowMaterials = (Material[])(object)new Material[componentsInChildren.Length];
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			if ((Object)(object)componentsInChildren[i] != (Object)null && (Object)(object)componentsInChildren[i].material != (Object)null)
			{
				originalMaterials[i] = componentsInChildren[i].material;
				glowMaterials[i] = new Material(componentsInChildren[i].material);
				glowMaterials[i].EnableKeyword("_EMISSION");
				componentsInChildren[i].material = glowMaterials[i];
			}
		}
	}

	private void SetupLight()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("EliteGlow");
		val.transform.SetParent(((Component)this).transform, false);
		val.transform.localPosition = new Vector3(0f, 1f, 0f);
		eliteLight = val.AddComponent<Light>();
		eliteLight.type = (LightType)2;
		eliteLight.intensity = baseIntensity;
		eliteLight.range = 5f;
		eliteLight.shadows = (LightShadows)2;
	}

	[IteratorStateMachine(typeof(<PulseEffect>d__20))]
	private IEnumerator PulseEffect()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <PulseEffect>d__20(0)
		{
			<>4__this = this
		};
	}

	private void OnDestroy()
	{
		if (originalMaterials != null)
		{
			Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren.Length && i < originalMaterials.Length; i++)
			{
				if ((Object)(object)componentsInChildren[i] != (Object)null && (Object)(object)originalMaterials[i] != (Object)null)
				{
					componentsInChildren[i].material = originalMaterials[i];
				}
			}
		}
		if (glowMaterials != null)
		{
			Material[] array = glowMaterials;
			foreach (Material val in array)
			{
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)val);
				}
			}
		}
		if ((Object)(object)eliteLight != (Object)null)
		{
			Object.Destroy((Object)(object)((Component)eliteLight).gameObject);
		}
	}

	public void SetInvulnerable(bool invulnerable)
	{
		if ((Object)(object)eliteLight != (Object)null)
		{
			baseIntensity = (invulnerable ? 1.2f : 0.6f);
		}
	}
}
public abstract class BaseVisualEffect : MonoBehaviour
{
	protected void TeleportToRandomPosition()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0042: 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)
		Vector3 val = Random.insideUnitSphere * 8f;
		val.y = 0f;
		RaycastHit val2 = default(RaycastHit);
		if (Physics.Raycast(((Component)this).transform.position + Vector3.up * 10f + val, Vector3.down, ref val2, 20f))
		{
			((Component)this).transform.position = ((RaycastHit)(ref val2)).point;
		}
	}
}
public class ZoneBossVisualEffect : BaseVisualEffect
{
	[CompilerGenerated]
	private sealed class <PulseEffect>d__14 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public ZoneBossVisualEffect <>4__this;

		private float <startTime>5__1;

		private float <timeElapsed>5__2;

		private float <pulse>5__3;

		private float <normalizedPulse>5__4;

		private Color <currentColor>5__5;

		private float <currentIntensity>5__6;

		private Material[] <>s__7;

		private int <>s__8;

		private Material <material>5__9;

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

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

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

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>s__7 = null;
			<material>5__9 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0094: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Expected O, but got Unknown
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: 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)
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<startTime>5__1 = Time.time;
				break;
			case 1:
				<>1__state = -1;
				break;
			}
			<timeElapsed>5__2 = Time.time - <startTime>5__1;
			<pulse>5__3 = Mathf.Sin(<timeElapsed>5__2 * <>4__this.pulseSpeed * (float)Math.PI + <>4__this.pulsePhaseOffset);
			<normalizedPulse>5__4 = (<pulse>5__3 + 1f) * 0.5f;
			<currentColor>5__5 = Color.Lerp(<>4__this.colorA, <>4__this.colorB, <normalizedPulse>5__4);
			<currentIntensity>5__6 = Mathf.Lerp(0.5f, 1f, <normalizedPulse>5__4);
			if (<>4__this.glowMaterials != null)
			{
				<>s__7 = <>4__this.glowMaterials;
				for (<>s__8 = 0; <>s__8 < <>s__7.Length; <>s__8++)
				{
					<material>5__9 = <>s__7[<>s__8];
					if ((Object)(object)<material>5__9 != (Object)null)
					{
						<material>5__9.SetColor("_EmissionColor", <currentColor>5__5 * <currentIntensity>5__6 * <>4__this.baseEmission);
						<material>5__9.SetColor("_BaseColor", Color.Lerp(<>4__this.colorA, <currentColor>5__5, <normalizedPulse>5__4 * 0.6f));
						<material>5__9.SetColor("_Color", Color.Lerp(<>4__this.colorA, <currentColor>5__5, <normalizedPulse>5__4 * 0.6f));
					}
					<material>5__9 = null;
				}
				<>s__7 = null;
			}
			if ((Object)(object)<>4__this.bossLight != (Object)null)
			{
				<>4__this.bossLight.color = <currentColor>5__5;
				<>4__this.bossLight.intensity = <>4__this.baseIntensity * <currentIntensity>5__6;
			}
			<>2__current = (object)new WaitForSeconds(0.033f);
			<>1__state = 1;
			return true;
		}

		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 Color colorA;

	private Color colorB;

	private Light bossLight;

	private Material[] originalMaterials;

	private Material[] glowMaterials;

	private bool isInitialized = false;

	private float pulseSpeed;

	private float pulsePhaseOffset;

	private float baseEmission = 0.6f;

	private float baseIntensity = 0.6f;

	private Color GenerateRandomColor()
	{
		//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_0036: Unknown result type (might be due to invalid IL or missing references)
		return new Color(Random.Range(0.2f, 1f), Random.Range(0.2f, 1f), Random.Range(0.2f, 1f));
	}

	public void Setup()
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		if (isInitialized)
		{
			return;
		}
		try
		{
			colorA = GenerateRandomColor();
			colorB = GenerateRandomColor();
			pulseSpeed = Random.Range(0.01f, 0.03f);
			pulsePhaseOffset = Random.Range(0f, (float)Math.PI * 2f);
			SetupMaterials();
			SetupLight();
			isInitialized = true;
			((MonoBehaviour)this).StartCoroutine(PulseEffect());
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("Error in ZoneBossVisualEffect Setup: " + ex.Message));
		}
	}

	private void SetupMaterials()
	{
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Expected O, but got Unknown
		Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
		if (componentsInChildren.Length == 0)
		{
			return;
		}
		originalMaterials = (Material[])(object)new Material[componentsInChildren.Length];
		glowMaterials = (Material[])(object)new Material[componentsInChildren.Length];
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			if ((Object)(object)componentsInChildren[i] != (Object)null && (Object)(object)componentsInChildren[i].material != (Object)null)
			{
				originalMaterials[i] = componentsInChildren[i].material;
				glowMaterials[i] = new Material(componentsInChildren[i].material);
				glowMaterials[i].EnableKeyword("_EMISSION");
				componentsInChildren[i].material = glowMaterials[i];
			}
		}
	}

	private void SetupLight()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("BossGlow");
		val.transform.SetParent(((Component)this).transform, false);
		val.transform.localPosition = new Vector3(0f, 1f, 0f);
		bossLight = val.AddComponent<Light>();
		bossLight.type = (LightType)2;
		bossLight.intensity = baseIntensity;
		bossLight.range = 7f;
		bossLight.shadows = (LightShadows)2;
	}

	[IteratorStateMachine(typeof(<PulseEffect>d__14))]
	private IEnumerator PulseEffect()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <PulseEffect>d__14(0)
		{
			<>4__this = this
		};
	}

	private void OnDestroy()
	{
		if (originalMaterials != null)
		{
			Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren.Length && i < originalMaterials.Length; i++)
			{
				if ((Object)(object)componentsInChildren[i] != (Object)null && (Object)(object)originalMaterials[i] != (Object)null)
				{
					componentsInChildren[i].material = originalMaterials[i];
				}
			}
		}
		if (glowMaterials != null)
		{
			Material[] array = glowMaterials;
			foreach (Material val in array)
			{
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)val);
				}
			}
		}
		if ((Object)(object)bossLight != (Object)null)
		{
			Object.Destroy((Object)(object)((Component)bossLight).gameObject);
		}
	}
}
public class ZoneBossManager : MonoBehaviour
{
	private static ZoneBossManager instance;

	private DateTime nextBossSpawnTime;

	private Character currentZoneBoss;

	private readonly float bossScale = 2.5f;

	private readonly int bossHealth = 600000;

	public static ZoneBossManager Instance => instance;

	private void Awake()
	{
		if ((Object)(object)instance == (Object)null)
		{
			instance = this;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			SetNextSpawnTime();
		}
		else
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}
	}

	private void Update()
	{
		if (DateTime.Now >= nextBossSpawnTime)
		{
			if (!((Object)(object)currentZoneBoss == (Object)null) && ((Component)currentZoneBoss).gameObject.activeInHierarchy)
			{
				Stats component = ((Component)currentZoneBoss).GetComponent<Stats>();
				if (component == null || component.CurrentHP > 0)
				{
					goto IL_0063;
				}
			}
			SpawnZoneBoss();
			goto IL_0063;
		}
		goto IL_006b;
		IL_0063:
		SetNextSpawnTime();
		goto IL_006b;
		IL_006b:
		if (Input.GetKeyDown((KeyCode)290))
		{
			ForceZoneBossSpawn();
		}
	}

	private void SetNextSpawnTime()
	{
		nextBossSpawnTime = DateTime.Now.AddHours(1.0);
		nextBossSpawnTime = nextBossSpawnTime.AddMinutes(-nextBossSpawnTime.Minute);
		nextBossSpawnTime = nextBossSpawnTime.AddSeconds(-nextBossSpawnTime.Second);
	}

	public void SpawnZoneBoss()
	{
		PlayerMeleeArea val = Object.FindObjectOfType<PlayerMeleeArea>();
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		List<Character> list = new List<Character>();
		Character[] array = Object.FindObjectsOfType<Character>();
		foreach (Character val2 in array)
		{
			if (IsValidBossCandidate(val2, val))
			{
				list.Add(val2);
			}
		}
		if (list.Count > 0)
		{
			Character enemy = list[Random.Range(0, list.Count)];
			PromoteToZoneBoss(enemy);
		}
	}

	public void ForceZoneBossSpawn()
	{
		PlayerMeleeArea val = Object.FindObjectOfType<PlayerMeleeArea>();
		if ((Object)(object)val == (Object)null)
		{
			Debug.LogWarning((object)"Cannot force spawn Zone Boss - no PlayerMeleeArea found");
			return;
		}
		List<Character> list = new List<Character>();
		Character[] array = Object.FindObjectsOfType<Character>();
		foreach (Character val2 in array)
		{
			if (IsValidBossCandidate(val2, val))
			{
				list.Add(val2);
			}
		}
		if (list.Count > 0)
		{
			Character enemy = list[Random.Range(0, list.Count)];
			PromoteToZoneBoss(enemy);
			UpdateSocialLog.LogAdd("<color=red>A Zone Boss has been manually spawned!</color>");
		}
		else
		{
			UpdateSocialLog.LogAdd("<color=yellow>No valid candidates for Zone Boss found!</color>");
		}
	}

	private bool IsValidBossCandidate(Character character, PlayerMeleeArea area)
	{
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)character == (Object)null)
		{
			return false;
		}
		if ((Object)(object)((Component)character).GetComponent<SimPlayer>() != (Object)null)
		{
			return false;
		}
		if (((Object)character).name.Contains("Summoned"))
		{
			return false;
		}
		if ((Object)(object)character == (Object)(object)((Component)area).GetComponentInParent<Character>())
		{
			return false;
		}
		EliteEnemyMod eliteEnemyMod = EliteEnemyMod.Instance;
		if ((Object)(object)eliteEnemyMod != (Object)null)
		{
			if (eliteEnemyMod.IsExcludedFaction(character.MyFaction))
			{
				return false;
			}
			if (eliteEnemyMod.IsExcludedName(((Object)character).name))
			{
				return false;
			}
		}
		Stats component = ((Component)character).GetComponent<Stats>();
		return (Object)(object)component != (Object)null && component.CurrentHP > 0;
	}

	private void PromoteToZoneBoss(Character enemy)
	{
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)enemy == (Object)null))
		{
			Stats component = ((Component)enemy).GetComponent<Stats>();
			if (!((Object)(object)component == (Object)null))
			{
				currentZoneBoss = enemy;
				((Object)enemy).name = "[ZONE BOSS] " + ((Object)enemy).name;
				component.CurrentMaxHP = bossHealth;
				component.CurrentHP = bossHealth;
				((Component)enemy).transform.localScale = Vector3.one * bossScale;
				ZoneBossVisualEffect zoneBossVisualEffect = ((Component)enemy).gameObject.AddComponent<ZoneBossVisualEffect>();
				zoneBossVisualEffect.Setup();
				UpdateSocialLog.LogAdd("<color=red>Zone Boss " + ((Object)enemy).name + " has appeared!</color>");
			}
		}
	}
}
public class ZoneBossMarker : MonoBehaviour
{
}